Zend Framework 2 : Getting Closer with PluginManager
In ZF2, there is PluginManager that we can use to collect services with same contract interfaces or ancestor class into single class properties. After that, we can validate whenever the plugins as services are instance of that interfaces or ancestor class ( usually an abstract class ). There are properties of PluginManager class that can collect the services :
1. $factories
2. $invokableClasses
3. $aliases(aliasing registered services at $factories or $invokableClasses)
The basic class structure of PluginManager is like this :
namespace YourModule; use Zend\ServiceManager\AbstractPluginManager; class PluginManager extends AbstractPluginManager { protected $factories = array( //represent factories key ); protected $invokableClasses = array( //represent invokables key ); protected $aliases = array( //represent aliases key ); public function validatePlugin($plugin) { if ($plugin instanceof Plugin\PluginInterface) { // we're okay return; } throw new \InvalidArgumentException(sprintf( 'Plugin of type %s is invalid; must implement %s\Plugin\PluginInterface', (is_object($plugin) ? get_class($plugin) : gettype($plugin)), __NAMESPACE__ )); } }
For example, you need to create collection of services that can convert content into another format, for example, you want to create services that can convert to ‘xls’, ‘pdf’, or other. so you can create pluginmanager to collect that services, like the following :
Let’s code!
1. create the ConverterContentPluginManager PluginManager
//filename : module/Tutorial/src/Tutorial/ConverterContentPluginManager.php namespace Tutorial; use Zend\ServiceManager\AbstractPluginManager; class ConverterContentPluginManager extends AbstractPluginManager { protected $invokableClasses = array( //represent invokables key 'xls' => 'Tutorial\Plugin\Xls', 'pdf' => 'Tutorial\Plugin\Pdf' ); public function validatePlugin($plugin) { if ($plugin instanceof Plugin\PluginInterface) { // we're okay return; } throw new \InvalidArgumentException(sprintf( 'Plugin of type %s is invalid; must implement %s\Plugin\PluginInterface', (is_object($plugin) ? get_class($plugin) : gettype($plugin)), __NAMESPACE__ )); } }
2. Create the plugin interface to be implemented
//filename : module/Tutorial/src/Tutorial/Plugin/PluginInterface.php namespace Tutorial\Plugin; interface PluginInterface { public function convert($content); }
3. Create that services
a. the Xls service
//filename : module/Tutorial/src/Tutorial/Plugin/Xls.php namespace Tutorial\Plugin; class Xls implements PluginInterface { public function convert($content) { echo 'xls convert here'; //implementation of convert $content to convert content into xls } }
b. the Pdf service
//filename : module/Tutorial/src/Tutorial/Plugin/Pdf.php namespace Tutorial\Plugin; class Pdf implements PluginInterface { public function convert($content) { echo 'pdf convert here'; //implementation of convert $content to convert content into pdf } }
4. Create a factory class for the ConverterContentPluginManager
//filename : module/Tutorial/src/Tutorial/Service/ConverterContentPluginManagerFactory.php namespace Tutorial\Service; use Zend\Mvc\Service\AbstractPluginManagerFactory; class ConverterContentPluginManagerFactory extends AbstractPluginManagerFactory { const PLUGIN_MANAGER_CLASS = 'Tutorial\ConverterContentPluginManager'; }
5. Last step, register into service manager ( just one service, the ConverterContentPluginManagerFactory one )
//filename : module/Tutorial/config/module.config.php return array( 'service_manager' => array( 'factories' => array( 'convertercontent' => 'Tutorial\Service\ConverterContentPluginManagerFactory' ), ), );
Ok, now you can grab the plugins via :
$content = 'sample content you want to convert'; $converter = $this->getServiceLocator()->get('convertercontent') $converter->get('xls')->convert($content); $converter->get('pdf')->convert($content);
Done 😉
References :
1. http://raing3.gshi.org/2013/05/26/creating-custom-plugin-manager-in-zend-framework-2/
2. http://zf2.readthedocs.org/en/latest/modules/zend.mvc.services.html
Oh yeah. Just the right blog post at the right moment! I’m gonna read this soon 😀
Excellent post, thank you ! PluginManager are not easy to understand, your article is really helpful.
you’re welcome 😉
[…] is an optional parameter that we can pass on 2nd parameter when we get service from PluginManager. It can ease coding process when we need to pass a different parameter or injection on the fly […]
very useful: I was just trying to figure out how to mimic a plugin interface with the minimum effort: thanks!
I’m glad its useful. you’re welcome 😉
This post is very nice .. thanks .. 🙂
this post is excellence bro..its really helpful for me
[…] Zend Framework 2 : Getting Closer with PluginManager 28th Jul '16 […]
How to use config to set different converters for our PluginManager
you can register more services into PluginManager’s factories and invokableClasses for another converters.