This is a blog post greatly inspired by a slide that I have found created by Christophe Coevet, his slide can be found here.
I spend a lot of my time on #zftalk freenode.net helping people to solve their problems or just chatting away. One of the things I am noticing every day is that people despite our tries to help them keep building their own "custom" modules. Why? I mean a very simple example for this is ZfcUser. Every day I see someone asking about authentication problem or how to create a login or even acl. When we tell them there is a module existing we get the most diverse answers to this.
Some of these answers are:
- I would need to learn this module
- I need a customized solution
- I want to learn how the system works
- I just need something simple
- My boss does not pay me to learn/fix someone elses module
Let's just take a look at some of these answers.
I Would need to learn this module. Yes, i absolutely agree but even if you build your own solution don't you have to invest time and effort also to make it do what you want? Lot of people who answered this are also learning Zend Framework 2 but I see none of them building their own framework.
I need a customized solution. This is mostly with reference to ZfcUser. I agree this module is not perfect but mostly it fits every need I can think of. It has been designed with scalability in mind so you can just change your form the way you require it or adapt your database to hold new information. If it still does not support the required feature you can also modify it and submit a pr to make it a better module.
I want to learn how the system works. No arguments against that but why learn how to build something that is existing? Why not try and build your own application in a fast way. Having an application up and running in no time gives me the greatest learning experience as I have this nice and cozy feeling when I see what I have accomplished in a short time instead of wasting hours trying to build something which is existing.
I just need something simple. Again... Most modules are designed with scalability in mind and mostly just solve the most basic use cases by default. What could be simpler?
My boss does not pay me to learn/fix someone elses module. I don't know about you, but my boss also does not pay to sit around and build something which exists. My boss wants results and that as fast as possible. If I can show my boss that instead of building our own solution we can use some module and modify it to our needs which might take less time or even the same and justifying it by explaining that this has been tested by many people out of the community, he hardly never says no.
Let's be honest, you or I might be thinking that we are the greatest programmers in the world but there is always someone better out there or someone who has some genius idea. Use the power of this great community, most of us are more then willing to help you find your module or even build one together with you if it does not exist.
The time of sitting alone and grumbling how the module could be made reusable is over. Invest your time to find a suitable module or even discuss with people on how to create a module that can be useful to the community. I personally cannot think of a greater feeling when someone comes and tells me "hey I used your module and it just took me a few minutes to get up and running". Having helped myself and someone else by creating a reusable module is more then I could ask for.
This brings me to another point. As I am currently building the modules.zendframework.com website I mostly also observe every module that get's submitted there. It's really great to see all these contributions and new modules popping up on a daily basis. Again, check first if a module is existing. I see a lot of modules solving problems which others already have.
Search before you create a module!!!
Flexibility of Modules and how to override them
You can nearly override anything with in a module from views to controller over services and mappers
Create your own module which can extend/modify the original module. All you need to do is register it after the original Module in application.config.php
<?php return array( 'modules' => array( 'OriginalModule', 'MyModule',//this will override OriginalModule with any custom configurations you require ), 'module_listener_options' => array( 'config_glob_paths' => array( 'config/autoload/{,*.}{global,local}.php', ), 'module_paths' => array( './module', './vendor', ), ), );
Override a template
create the same view structure as the OriginalModule and place your custom templates there. Example:
OriginalModule
Config: 'view_manager' => array( 'template_path_stack' => array( __DIR__ . '/../view', ), ), Folder Structure: view/ index/ index/ index.phtml
MyModule
Config: 'view_manager' => array( 'template_path_stack' => array( __DIR__ . '/../view', ), ), Folder Structure: view/ index/ index/ index.phtml //Overrides the Original index.phtml with our custom code
Override a Controller/Service
Mostly all controllers and services are registered with the servicemanager and can be overriden bey they key
OriginalModule
'controllers' => array( 'invokables' => array( 'Application\Controller\Index' => 'Application\Controller\IndexController', ), ),
MyModule
'controllers' => array( 'invokables' => array( 'Application\Controller\Index' => 'MyModule\Controller\IndexController', ), ),
Just by assigning my Custom controller to the Key Application\Controller\Index
i have now replaced it. Same goes for the services or anything else that was configured using the service configuration
Extending Forms in ZfcUser
I am taking this as an example as there is a nice way of extending forms in ZfcUser just by using an event.
Just place the following code as also explained in the wiki into your Module.php
public function onBootstrap($e) { $events = $e->getApplication()->getEventManager()->getSharedManager(); $events->attach('ZfcUser\Form\Register','init', function($e) { $form = $e->getTarget(); // Do what you please with the form instance ($form) }); $events->attach('ZfcUser\Form\RegisterFilter','init', function($e) { $filter = $e->getTarget(); // Do what you please with the filter instance ($filter) }); }
As you can see you can attach anything to the formobject here and modify it to do exactly what you require
If you are unsure on how to contribute, you can come and ask us on irc #zftalk and most people will be more then willing to help. Furthermore just get started by forking existing modules on github and submit a pr
I hope that you are going to think of this post in the future and will keep in mind the essence of it There is a module for that
and if not, create one that can be used by the community. I hope you enjoyed reading this and hope to see you soon creating and contributing to existing modules. So long!
If you need to write your own module or are looking for some usefull tips on writing better modules have a look at Michaƫl Gallego's blog for writing better Zend Framework 2 Modules.