eZ Community » Forums » Suggestions » Ideas for an eZModuleInterface
expandshrink

Ideas for an eZModuleInterface

Ideas for an eZModuleInterface

Tuesday 02 February 2010 10:14:03 am - 20 replies

First, I'd point out that I'm quite new to eZ Publish, and I only have experience with 4.2.

But one of the first things I thought of when creating my first module, was "why do I have to declare all this variables, why not just declare a class that implements a eZModuleInterface?".

I did a few changes in the eZModule class that enables a class definition in module.php instead of the normal variables (Module, ViewList and FunctionList).

The class is very simple, it implements eZModuleInterface with three public methods: getModule, getViewList and getFunctionList, which should all return arrays with the usual content, nnd the name of the class has to follow the convention modulename_ezModule.

Here's the interface:

interface eZModuleInterface
{
    public function getModule();
 
    public function getViewList();
 
    public function getFunctionList();
}

And an example class:

class my_module_eZModule implements eZModuleInterface
{
 
    public function getModule()
    {
        return array( 'name' => 'Module name' );
    }
 
    public function getViewList()
    {
        return array(
                'main' => array(
                    'functions' => array(  ),
                    'script' => 'main.php'
                ));
    }
 
    public function getFunctionList()
    {
        return array();
    }
}

The change in ezmodule.php is quite minor, and I can post that as well if there's any interest in it, but the important thing is that the change is and should be compatible with the normal way of defining modules.

This is just a quick outline, I'm sure a module class/interface can do a lot more than the above, but my experience is limited, and I could use some input on this.

What do you think? Any point in spending any more time on this?

Tuesday 02 February 2010 10:26:18 am

Here's the diff on eZModule:

 --- a/lib/ezutils/classes/ezmodule.php
+++ b/lib/ezutils/classes/ezmodule.php
@@ -32,7 +32,6 @@
   \brief Allows execution of modules and functions
 
 */
-
 class eZModule
 {
     const STATUS_IDLE = 0;
@@ -45,6 +44,8 @@ class eZModule
     const HOOK_STATUS_CANCEL_RUN = 1;
     const HOOK_STATUS_FAILED = 2;
 
+    const CLASS_POSTFIX = '_eZModule';
+
     function eZModule( $path, $file, $moduleName, $checkFileExistence = true )
     {
         $this->initialize( $path, $file, $moduleName, $checkFileExistence);
@@ -64,7 +65,28 @@ class eZModule
             unset( $FunctionList );
             unset( $Module );
             unset( $ViewList );
-            include( $file );
+
+            $moduleClass = $moduleName . self::CLASS_POSTFIX;
+            if ( !in_array( $moduleClass, get_declared_classes() ) )
+            {
+                include( $file );
+            }
+
+            if ( in_array($moduleClass, get_declared_classes() ) )
+            {
+                $moduleObject = new $moduleClass();
+
+                if ( !$moduleObject instanceof eZModuleInterface )
+                {
+                    $this->ExitStatus = eZModule::STATUS_FAILED;
+                    return;
+                }
+
+                $Module = $moduleObject->getModule();
+                $ViewList = $moduleObject->getViewList();
+                $FunctionList = $moduleObject->getFunctionList();
+            }
+
             $this->Functions = $ViewList;
             if ( isset( $FunctionList ) and
                  is_array( $FunctionList ) and

Tuesday 02 February 2010 10:34:59 am

Hallo Peter !

Welcome aboard the eZ Community, and thanks for this awesome post happy.gif Emoticon

I love this idea. This actually turns the currently 'include'-based module definitions into a proper object-oriented system, and this is not nothing. One of the immediate consequences is that it reduces the amount of required workarounds and hacks in the kernel, which leaves a larger room for maintenance-peace and tranquility: upgrades, automatic bugfixing (eZ Premium).

Have you pushed this in production yet ? Any other magical enhancements proposals like this one ?

Cheers,
PS : not sure you already did this, but check the "Track this reply" checkbox next to the "OK | "Cancel" buttons below, so that you are automatically notified when someone replies to your threads. You can also check your notification settings there : http://share.ez.no/notification/settings

Modified on Tuesday 02 February 2010 10:35:38 am by Nicolas Pastorino

Tuesday 02 February 2010 10:48:33 am

Hey Nicolas!

I haven't pushed this into production, as I wanted to post it here first to see if there was any interest in this.

There's probably even more to gain by adding support for object-oriented views as well, but that looks like a bit more work. I'll take a look at it and see if I can come up with a suggestion.

Any ideas to how that could be implemented?

I'm tracking this post now, btw happy.gif Emoticon

Tuesday 02 February 2010 11:08:07 am

That's a great idea !

Methods to hook easily could be great too !

Tuesday 02 February 2010 2:27:06 pm

I like this, too.

Then it is also easier to write a global phpdoc for a module.

Tuesday 02 February 2010 2:46:16 pm

Another ting... aren't the 'views' of eZ Publish more like a 'controller' if you think about the traditional sense of MVC?

So why not create some type of controller class with actions and have eZProcess execute them as objects instead? Or just leave eZProcess alone and write another class, say eZDispatch, that's used if the 'view' file contains a class.

Guess you should be careful with tampering with the terminology, but at least I think it's easier to think of the views as controllers.

I searched around a bit and found a few MVC tools in ez components. Is that something that could be used for this, or would that introduce too many unwanted dependencies to ezc?

Tuesday 02 February 2010 11:19:25 pm

I like this idea too.

The current interface of ezmodule is also a bit limited, as you usually end up coing the extension/module/view names a lot of times in the $Results var at the bottom of your views and in the template code.

While at it, why not removing the eztemplateautoload.php file, and other such redundant definition of stuff that can be

-neatly wrapped in php classes and methods

- can thus take advantage of autoload magic instead of having ezp scanning frantically directories to find the proper xxx-handler php class file?

I think the answer we all know, and it is: because we like to keep our binary compatibility...

Friday 23 April 2010 10:53:13 pm

@Peter I played a bit more with module introspection, and I think I might have missed the overall sense in your original post.

The first thing I want to say is that the current ezmodule class has attributes that can be used to retrieve from it the list of views; it really misses one to retrieve the list of fetch functions though!

To have a module defined via a php class, we should, imho

- rename your interface to ezmoduleimplementorInterface or ezmoduleDefinitionInterface, as it is not a module in itself you are implementing, the module being the instance of ezmodule

- maybe add a new ini setting to declare which modules use the new interface instead of module.php, instead of using the automatic 'try loading class first' approach

Saturday 24 April 2010 2:01:52 pm

Maybe it would be worth investigating as well if it would be beneficial to move away from PHP for this kind of (sometimes deeply nested) definition arrays and go for XML instead. A big advantage you will have is that if you provide a proper XML schema, it's easier for developers to create their module definition (xml intellisense/autocompletion provided by IDE's), as well as to validate it. IMHO the current nested array structures are very unhandy.

Modified on Saturday 24 April 2010 2:02:40 pm by Kristof Coomans

Saturday 24 April 2010 7:37:58 pm

@kristof: I longed a while ago for replacing module.php and also the definition of template operators and functions with ini files. Then I stumbled upon some module that dynamically created the available views and I understood the benefit of having it done in php.

I personally am not a big fan of xml - a hybrid format too hard and verbose to be read/written by humans and too complex to be efficiently parsed by machines. In 2010 you see more and more json, yaml and other simpler markup formats that are suited to represent data and less and less xml.

But moving between a php array and json/xml is a matter of 2 lines of code

What I'd like instead is

- more docs on the possible values for those arrays - most of those are hidden and never documented anywhere

- some validator script / function

Saturday 24 April 2010 11:15:29 pm

Regarding the module that dynamically created the available views, can you give us some more insight in what had to be accomplished this way what could not be accomplished with view parameters instead?

The validation you would get for free if you use XML, once you agree on the grammar through a XML schema. You need a blue print of the elements that can/should be there anyway, and better to do it formally following a W3C recommendation than with (often incomplete and out to date) documentation and some custom PHP code that checks for the existence of specific array keys.

There is some sort of schema validator as well for YAML, Kwalify, but afaik only Ruby and Java versions exist.

YAML might be less verbose to create by hand, but with an IDE with good XML schema support you're able to get equal results in no time.

Sunday 25 April 2010 11:20:04 am

I just LOVE your idea Peter !

Besides, you're right, module views are MVC controllers and they also should be classes (like in Symfony framework). It would be much cleaner IMHO !

@Kristof : Your idea is really interesting too blunk.gif Emoticon. Writing module definition is really annoying, such as for template operators, fetch functions or operations ! From this point of view I'd rather prefer YAML vs XML, plus a PHP class (extending eZModule and implementing an interface) for module views (we really should call them controllers as it's quite confusing).

Sunday 25 April 2010 1:00:14 pm

@kristof: I agree that validating xml is currently easier because of a wide array of tools available.

But I think that the validation part is not what is hampering development currently. The DOCS are. And no, saying that docs get outdated is not a good reason to avoid producing docs altogether.

Take for a simple example the following parameter in a module.php file:

 $Module = array( 'name' => 'So what?',

              'variable_params' => true );

raise your hands if you know what 'variable_params' does (ps: I am sure that Kristof does, but how many besides him do?).

And honestly, tell me if validating that to check that it is either true or false helps you a bit.

I'm not against using existing schema languages; it is of course faster than writing a custom php validator from scratch, but what we should achieve is rather making sure that the docs are embedded in the validation definition. And afaik, niether relax-ng nor xsd mandate that you document elements.

In my experience the best (basically the only) way to make sure that doc is always up-to-date is to

a - use meaningful names for variables, methods, classes, and a clean design, and

b - embedding comments in the doc

For point b, while sticking to the current php-based definition, we could add phpdoc comments to a "blueprint" module definition, and voilĂ , zero impact and a large gain. We could of course also add php classes that act as blueprint for those arrays ('struct' classes), similar to the way that ezc define options...

Sunday 25 April 2010 1:08:15 pm

Ps: my fave one: json + jsonschema

Sunday 25 April 2010 1:30:44 pm

@Jerome: writing stub code is a chore I agree;

But I think that copying and pasting xml would be no better than copying and pasting php code.

And even if we made a GUI wizard like the one that exists for tpl ops, it would not be much faster for the developer in the end.

What we need otoh is reverse engineering of existing php code that creates the stubs automatically.

I think it would make for a nice extension: scripts/php classes to wrap an existing php function/object into a template operator stub, a template fetch function stub, etc...

Willing to join?

Been there, done that, btw: http://phpxmlrpc.svn.sourceforge....trunk/xmlrpc/lib/xmlrpc_wrappers.inc

Sunday 25 April 2010 3:21:47 pm

@Gaetano: I am not talking here about copying and pasting code, but about making it possible to use auto completion in your favorite (intelligent) editor according to a defined grammar: in the case of PHP code, methods and properties of your classes and objects; in case of XML, elements and attributes defined in the schema. AFAIK there is no good auto completion support for JSON / YAML in most popular enterprise-level open source editors (just to name 2 I am using: Eclipse, Netbeans) yet. If you know existing tools to do this, let me know and I'll be happy to try them.

I would like the approach of Zeta Components' struct classes a lot more than YAML/JSON then, because of auto completion possibilities.

By the way, there is some documentation available at http://ezpedia.org/en/ez/module for a long time already, might be improved heavily language-wise though.

Sunday 25 April 2010 7:04:43 pm

Willing to join?

Sure ! happy.gif Emoticon

Monday 26 April 2010 6:05:04 pm

Excellent page on ezpedia, thanks kristof!

Summing it up, to get the power of ide introspection without hacking the kernel code, we might define new 'struct' classes for module def, view def, fetch_function def, that implement the arrayaccess interface (http://php.net/manual/en/class.arrayaccess.php) and everybody's happy.

Monday 26 April 2010 8:17:26 pm

Yes, that sounds like a good plan.

Will it be in the core of 4.4?

Modified on Monday 26 April 2010 8:18:00 pm by Kristof Coomans

Monday 21 June 2010 11:58:29 am

Taking a slightly different approach to the original problem (simplifying development of new views via php classes):

  • define a conventional dir where 'controller' php classes are to be put
  • every new public, static method of those classes becomes a view
  • those methods must return either a chunk of html code or the $results array
  • for access checking, a policy limitation is available per single method of every controller class

If this sounds yummy, please join development effort on the upcoming "eZ On rails" extension!

Under the hood:

  • no kernel hacks
  • one single new module: ezonrails
  • one new view per controller class
  • the actual class methods end up as first positional parameter
  • no validation (yet) of the parameters passed to php methods, but it can be done via introspection

http://projects.ez.no/ezonrails

expandshrink

You must be logged in to post messages in this topic!

36 542 Users on board!

Forums menu

Proudly Developed with from