Skip to content

Instantly share code, notes, and snippets.

@Saeven
Last active April 11, 2016 20:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Saeven/ad6ef3c57de1d0e61082 to your computer and use it in GitHub Desktop.
Save Saeven/ad6ef3c57de1d0e61082 to your computer and use it in GitHub Desktop.
Lazy controller factory that auto-injects dependencies based on controller params.
<?php
class LazyControllerFactory implements AbstractFactoryInterface
{
/**
* Determine if we can create a service with name
*
* @param ServiceLocatorInterface $serviceLocator
* @param $name
* @param $requestedName
*
* @return bool
*/
public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
list( $module, ) = explode( '\\', __NAMESPACE__, 2 );
return strstr( $requestedName, $module . '\Controller') !== false;
}
/**
* These aliases work to substitute class names with SM types that are buried in ZF
* @var array
*/
protected $aliases = [
'Zend\Form\FormElementManager' => 'FormElementManager',
'Zend\Validator\ValidatorPluginManager' => 'ValidatorManager',
'Zend\Mvc\I18n\Translator' => 'translator',
];
/**
* Create service with name
*
* @param ServiceLocatorInterface $serviceLocator
* @param $name
* @param $requestedName
*
* @return mixed
*/
public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
$class = new \ReflectionClass($requestedName);
$parentLocator = $serviceLocator->getServiceLocator();
if( $constructor = $class->getConstructor() )
{
if( $params = $constructor->getParameters() )
{
$parameter_instances = [];
foreach( $params as $p )
{
if( $p->getClass() ) {
$cn = $p->getClass()->getName();
if (array_key_exists($cn, $this->aliases)) {
$cn = $this->aliases[$cn];
}
try {
$parameter_instances[] = $parentLocator->get($cn);
}
catch (\Exception $x) {
echo __CLASS__
. " couldn't create an instance of $cn to satisfy the constructor for $requestedName.";
exit;
}
}
else{
if( $p->isArray() && $p->getName() == 'config' )
$parameter_instances[] = $parentLocator->get('config');
}
}
return $class->newInstanceArgs($parameter_instances);
}
}
return new $requestedName;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment