From efdac910e2edc3a1e0194c4151a75301b4a62b4b Mon Sep 17 00:00:00 2001 From: UFOMelkor Date: Mon, 23 Dec 2013 01:15:25 +0100 Subject: [PATCH] added service factory creation --- config/module.config.php | 9 ++ src/ZFTool/Controller/CreateController.php | 96 ++++++++++++++++++++++ src/ZFTool/Module.php | 7 ++ 3 files changed, 112 insertions(+) diff --git a/config/module.config.php b/config/module.config.php index e9abdca..0cc84fa 100644 --- a/config/module.config.php +++ b/config/module.config.php @@ -117,6 +117,15 @@ ), ), ), + 'zftool-create-service-factory' => array( + 'options' => array( + 'route' => 'create service-factory [] []', + 'defaults' => array( + 'controller' => 'ZFTool\Controller\Create', + 'action' => 'service-factory' + ), + ), + ), 'zftool-install-zf' => array( 'options' => array( 'route' => 'install zf []', diff --git a/src/ZFTool/Controller/CreateController.php b/src/ZFTool/Controller/CreateController.php index e4b1f04..910d1ab 100644 --- a/src/ZFTool/Controller/CreateController.php +++ b/src/ZFTool/Controller/CreateController.php @@ -301,6 +301,102 @@ public function moduleAction() } } + public function serviceFactoryAction() + { + $console = $this->getServiceLocator()->get('console'); + $request = $this->getRequest(); + $serviceFQCN = $request->getParam('service'); + $factoryFQCN = $request->getParam('factory', $serviceFQCN . 'Factory'); + $path = $request->getParam('path', '.'); + $module = strstr($serviceFQCN, '\\', true); + $factoryNamespace = substr($factoryFQCN, 0, strrpos($factoryFQCN, '\\')); + $factoryShortName = substr($factoryFQCN, strrpos($factoryFQCN, '\\')+1); + $servicePath = sprintf('%s/module/%s/src/%s.php', $path, $module, str_replace('\\', '/', $serviceFQCN)); + $factoryPath = sprintf('%s/module/%s/src/%s.php', $path, $module, str_replace('\\', '/', $factoryFQCN)); + + $console->writeLine("Creating factory '$factoryFQCN' for service '$serviceFQCN'.", Color::YELLOW); + + if (!file_exists("$path/module") || !file_exists($servicePath)) { + return $this->sendError( + "The path $path doesn't contain a ZF2 application. I cannot create a service factory" + ); + } + + if (!file_exists($servicePath)) { + return $this->sendError("The service for which to create a factory does not exist in $servicePath"); + } + + if (file_exists($factoryPath)) { + return $this->sendError("The file $factoryPath already exists"); + } + + $fileReflection = new Reflection\FileReflection($servicePath, true); + $classReflection = $fileReflection->getClass($serviceFQCN); + + $parameters = array(); + if ($classReflection->getConstructor()) { + foreach ($classReflection->getConstructor()->getParameters() as $each) { + if ($each->isOptional()) { + break; + } + + if ($each->getClass()) { + $parameters[] = sprintf(" \$services->get('%s')", addslashes($each->getClass()->name)); + continue; + } + + if ($each->isArray()) { + $parameters[] = " array()"; + continue; + } + + if ($each->isCallable()) { + $parameters[] = " function () {}"; + continue; + } + + $parameters[] = " null"; + } + } + + $useFQCN = $classReflection->getShortName() === $factoryShortName; + $methodBody = sprintf( + 'return new %s(', + $useFQCN ? '\\' . $classReflection->name : $classReflection->getShortName()) + ; + if (count($parameters) > 0) { + $methodBody .= "\n" . implode(",\n", $parameters) . "\n"; + } + $methodBody .= ");"; + + $code = new Generator\ClassGenerator(); + $code->setNamespaceName($factoryNamespace) + ->addUse('Zend\ServiceManager\FactoryInterface') + ->addUse('Zend\ServiceManager\ServiceLocatorInterface'); + + if (!$useFQCN && $classReflection->getNamespaceName() != $factoryNamespace) { + $code->addUse($classReflection->name); + } + + $code->setName($factoryFQCN) + ->setImplementedInterfaces(array('FactoryInterface')) + ->addMethods(array( + new Generator\MethodGenerator( + 'createService', + array(new Generator\ParameterGenerator('services', 'ServiceLocatorInterface')), + Generator\MethodGenerator::FLAG_PUBLIC, + $methodBody + ), + )); + + $file = new Generator\FileGenerator(array('classes' => array($code))); + if (file_put_contents($factoryPath, $file->generate())) { + $console->writeLine("The service factory $factoryFQCN has been created.", Color::GREEN); + } else { + $console->writeLine("There was an error during service factory creation.", Color::RED); + } + } + /** * Send an error message to the console * diff --git a/src/ZFTool/Module.php b/src/ZFTool/Module.php index 4f4beca..79086dd 100644 --- a/src/ZFTool/Module.php +++ b/src/ZFTool/Module.php @@ -94,6 +94,13 @@ public function getConsoleUsage(ConsoleAdapterInterface $console) array('', 'The module containing the controller'), array('', 'The root path of a ZF2 application where to create the action'), + 'Service Factory creation:', + 'create service-factory [] []' => 'create a factory for a service', + array('', 'The class for which a factory should be created.'), + array('', 'The class which should contain the factory. ' + . 'If not supplied, defaults to Factory.'), + array('', 'The root path of a ZF2 application where to create the factory.'), + 'Classmap generator:', 'classmap generate [--append|-a] [--overwrite|-w]' => '', array('', 'The directory to scan for PHP classes (use "." to use current directory)'),