Ideas for an eZModuleInterface

Author Message

Peter Rudolfsen

Tuesday 02 February 2010 1:14:03 am

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?

Peter Rudolfsen

Tuesday 02 February 2010 1: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

Nicolas Pastorino

Tuesday 02 February 2010 1:34:59 am

Hallo Peter !

Welcome aboard the eZ Community, and thanks for this awesome post :)

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

--
Nicolas Pastorino
Director Community - eZ
Member of the Community Project Board

eZ Publish Community on twitter: http://twitter.com/ezcommunity

t : http://twitter.com/jeanvoye
G+ : http://plus.tl/jeanvoye

Peter Rudolfsen

Tuesday 02 February 2010 1: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 :)

Matthieu Sévère

Tuesday 02 February 2010 2:08:07 am

That's a great idea !

Methods to hook easily could be great too !

--
eZ certified developer: http://ez.no/certification/verify/346216

Felix Woldt

Tuesday 02 February 2010 5:27:06 am

I like this, too.

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

http://www.jac-systeme.de - Developers united in eZ Publish: http://www.cjw-network.com

CJW Newsletter 1.0.0 released: http://projects.ez.no/cjw_newsletter

Peter Rudolfsen

Tuesday 02 February 2010 5:46:16 am

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?

Gaetano Giunta

Tuesday 02 February 2010 2: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...

Principal Consultant International Business
Member of the Community Project Board

Gaetano Giunta

Friday 23 April 2010 1: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

Principal Consultant International Business
Member of the Community Project Board

Kristof Coomans

Saturday 24 April 2010 5:01:52 am

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.

independent eZ Publish developer and service provider | http://blog.coomanskristof.be | http://ezpedia.org

Gaetano Giunta

Saturday 24 April 2010 10:37:58 am

@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

Principal Consultant International Business
Member of the Community Project Board

Kristof Coomans

Saturday 24 April 2010 2: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.

independent eZ Publish developer and service provider | http://blog.coomanskristof.be | http://ezpedia.org

Jérôme Vieilledent

Sunday 25 April 2010 2: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 ;). 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).

Gaetano Giunta

Sunday 25 April 2010 4:00:14 am

@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...

Principal Consultant International Business
Member of the Community Project Board

Gaetano Giunta

Sunday 25 April 2010 4:08:15 am

Ps: my fave one: json + jsonschema

Principal Consultant International Business
Member of the Community Project Board

Gaetano Giunta

Sunday 25 April 2010 4:30:44 am

@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.net/viewvc/phpxmlrpc/trunk/xmlrpc/lib/xmlrpc_wrappers.inc

Principal Consultant International Business
Member of the Community Project Board

Kristof Coomans

Sunday 25 April 2010 6:21:47 am

@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.

independent eZ Publish developer and service provider | http://blog.coomanskristof.be | http://ezpedia.org

Jérôme Vieilledent

Sunday 25 April 2010 10:04:43 am

"

Willing to join?

"

Sure ! :)

Gaetano Giunta

Monday 26 April 2010 9:05:04 am

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.

Principal Consultant International Business
Member of the Community Project Board

Kristof Coomans

Monday 26 April 2010 11:17:26 am

Yes, that sounds like a good plan.

Will it be in the core of 4.4?

independent eZ Publish developer and service provider | http://blog.coomanskristof.be | http://ezpedia.org

Powered by eZ Publish™ CMS Open Source Web Content Management. Copyright © 1999-2014 eZ Systems AS (except where otherwise noted). All rights reserved.