/**
  * @param string $file
  * @param string $content
  * @dataProvider provider
  */
 public function testGenerateFactory($file, $content)
 {
     if (strtolower(substr(php_uname(), 0, 7)) == 'windows') {
         $this->markTestSkipped('Skipped since doesnt work on windows.');
     }
     FactoryDependencyInjectionContainer::$prefix = '';
     $config = new Configuration(null, '');
     $config->setClassConfig('rg\\injektor\\generators\\FGTestClassOne', array('singleton' => true));
     $config->setClassConfig('rg\\injektor\\generators\\FGTestClassFour', array('singleton' => true));
     $config->setClassConfig('rg\\injektor\\generators\\FGTestClassThree', array('params' => array('foo' => array('value' => 'foo'), 'four' => array('class' => 'rg\\injektor\\generators\\FGTestClassFour'))));
     $factoryGenerator = new TestingFactoryGenerator($config, '');
     $factoryGenerator->processFileForClass('rg\\injektor\\generators\\FGTestClassOne');
     $this->assertEquals($content, $factoryGenerator->files[$file]);
 }
 /**
  * @param string $argumentClass
  * @param string $docComment
  * @param string $argumentName
  * @return string
  */
 public function getNamedClassOfArgument($argumentClass, $docComment, $argumentName = null)
 {
     $argumentClassConfig = $this->config->getClassConfig($argumentClass);
     $implementationName = $this->getImplementationName($docComment, $argumentName);
     if ($implementationName) {
         return $this->getImplementingClassBecauseOfName($argumentClass, $argumentClassConfig, $implementationName);
     }
     return null;
 }
Exemple #3
0
 protected function analyze()
 {
     $argumentClass = null;
     $isInjectable = $this->dic->isInjectable($this->docComment);
     if (!empty($this->classConfig['params'][$this->name]['class'])) {
         $argumentClass = $this->classConfig['params'][$this->name]['class'];
         $isInjectable = true;
     } else {
         if ($this->hasClass()) {
             $argumentClass = $this->getClass();
         }
     }
     if ($argumentClass && $isInjectable) {
         try {
             $namedClass = $this->dic->getNamedClassOfArgument($argumentClass, $this->docComment, $this->nameForAnnotationParsing);
             if ($namedClass) {
                 $argumentClass = $namedClass;
             }
         } catch (InjectionException $e) {
         }
         if ($argumentClass === 'rg\\injektor\\DependencyInjectionContainer') {
             $this->defaultValue = '\\' . $argumentClass . '::getDefaultInstance()';
         } else {
             $providerClassName = $this->dic->getProviderClassName($this->config->getClassConfig($argumentClass), new \ReflectionClass($argumentClass), $this->dic->getImplementationName($this->docComment, $this->nameForAnnotationParsing));
             if ($providerClassName && $providerClassName->getClassName()) {
                 $argumentFactory = $this->dic->getFullFactoryClassName($providerClassName->getClassName());
                 $this->className = $providerClassName->getClassName();
                 $this->factoryName = $argumentFactory;
                 $this->defaultValue = '\\' . $argumentFactory . '::getInstance(' . var_export(array_merge($providerClassName->getParameters(), $this->additionalArguments), true) . ')->get()';
             } else {
                 $argumentClass = $this->dic->getRealConfiguredClassName($this->config->getClassConfig($argumentClass), new \ReflectionClass($argumentClass));
                 $argumentClassReflection = new \ReflectionClass($argumentClass);
                 if (!$argumentClassReflection->isInstantiable() && !$argumentClassReflection->hasMethod('getInstance')) {
                     $this->setParameterToDefault();
                     return;
                 }
                 $argumentFactory = $this->dic->getFullFactoryClassName($argumentClass);
                 $this->className = $argumentClass;
                 $this->factoryName = $argumentFactory;
                 $this->defaultValue = '\\' . $argumentFactory . '::getInstance(' . var_export($this->additionalArguments, true) . ')';
             }
         }
     } else {
         $this->setParameterToDefault();
     }
 }
 /**
  * @return \Zend\Code\Generator\FileGenerator|null
  */
 public function getGeneratedFile()
 {
     $classConfig = $this->config->getClassConfig($this->fullClassName);
     $factoryName = $this->dic->getFactoryClassName($this->fullClassName);
     $classReflection = $this->dic->getClassReflection($this->fullClassName);
     if (strpos($classReflection->getDocComment(), '@generator ignore') !== false) {
         return null;
     }
     $file = new Generator\FileGenerator();
     $factoryClass = new \rg\injektor\generators\FactoryClass($factoryName);
     $instanceMethod = new \rg\injektor\generators\InstanceMethod($this->factoryGenerator);
     $arguments = array();
     $constructorMethodReflection = null;
     if ($this->dic->isSingleton($classReflection)) {
         $constructorMethodReflection = $classReflection->getMethod('getInstance');
         $arguments = $constructorMethodReflection->getParameters();
     } else {
         if ($classReflection->hasMethod('__construct')) {
             $constructorMethodReflection = $classReflection->getMethod('__construct');
             $arguments = $constructorMethodReflection->getParameters();
         }
     }
     $isSingleton = $this->dic->isConfiguredAsSingleton($classConfig, $classReflection);
     $isService = $this->dic->isConfiguredAsService($classConfig, $classReflection);
     $body = '$i = 0;' . PHP_EOL;
     if ($isSingleton || $isService) {
         $defaultValue = new Generator\PropertyValueGenerator(array(), Generator\ValueGenerator::TYPE_ARRAY, Generator\ValueGenerator::OUTPUT_SINGLE_LINE);
         $property = new Generator\PropertyGenerator('instance', $defaultValue, Generator\PropertyGenerator::FLAG_PRIVATE);
         $property->setStatic(true);
         $factoryClass->addPropertyFromGenerator($property);
     }
     if ($isSingleton) {
         $body .= '$singletonKey = serialize($parameters) . "#" . getmypid();' . PHP_EOL;
         $body .= 'if (isset(self::$instance[$singletonKey])) {' . PHP_EOL;
         $body .= '    return self::$instance[$singletonKey];' . PHP_EOL;
         $body .= '}' . PHP_EOL . PHP_EOL;
     }
     if ($isService) {
         $body .= 'if (self::$instance) {' . PHP_EOL;
         $body .= '    return self::$instance;' . PHP_EOL;
         $body .= '}' . PHP_EOL . PHP_EOL;
     }
     $providerClassName = $this->dic->getProviderClassName($classConfig, new \ReflectionClass($this->fullClassName), null);
     if ($providerClassName && $providerClassName->getClassName()) {
         $argumentFactory = $this->dic->getFullFactoryClassName($providerClassName->getClassName());
         $this->factoryGenerator->processFileForClass($providerClassName->getClassName());
         $body .= '$instance = \\' . $argumentFactory . '::getInstance(array())->get();' . PHP_EOL;
         $this->usedFactories[] = $argumentFactory;
     } else {
         // constructor method arguments
         if (count($arguments) > 0) {
             foreach ($arguments as $argument) {
                 /** @var \ReflectionParameter $argument */
                 $argumentName = $argument->name;
                 $this->constructorArguments[] = $argumentName;
                 $this->constructorArgumentStringParts[] = '$' . $argumentName;
                 $this->realConstructorArgumentStringParts[] = '$' . $argumentName;
             }
             $body .= 'if (!$parameters) {' . PHP_EOL;
             foreach ($arguments as $argument) {
                 /** @var \ReflectionParameter $argument */
                 $injectionParameter = new \rg\injektor\generators\InjectionParameter($argument, $classConfig, $this->config, $this->dic, InjectionParameter::MODE_NO_ARGUMENTS);
                 try {
                     if ($injectionParameter->getClassName()) {
                         $this->factoryGenerator->processFileForClass($injectionParameter->getClassName());
                     }
                     if ($injectionParameter->getFactoryName()) {
                         $this->usedFactories[] = $injectionParameter->getFactoryName();
                     }
                     $body .= '    ' . $injectionParameter->getProcessingBody();
                 } catch (\Exception $e) {
                     $body .= '    ' . $injectionParameter->getDefaultProcessingBody();
                 }
             }
             $body .= '}' . PHP_EOL;
             $body .= 'else if (array_key_exists(0, $parameters)) {' . PHP_EOL;
             foreach ($arguments as $argument) {
                 /** @var \ReflectionParameter $argument */
                 $injectionParameter = new \rg\injektor\generators\InjectionParameter($argument, $classConfig, $this->config, $this->dic, InjectionParameter::MODE_NUMERIC);
                 try {
                     if ($injectionParameter->getClassName()) {
                         $this->factoryGenerator->processFileForClass($injectionParameter->getClassName());
                     }
                     if ($injectionParameter->getFactoryName()) {
                         $this->usedFactories[] = $injectionParameter->getFactoryName();
                     }
                     $body .= '    ' . $injectionParameter->getProcessingBody();
                 } catch (\Exception $e) {
                     $body .= '    ' . $injectionParameter->getDefaultProcessingBody();
                 }
             }
             $body .= '}' . PHP_EOL;
             $body .= 'else {' . PHP_EOL;
             foreach ($arguments as $argument) {
                 /** @var \ReflectionParameter $argument */
                 $injectionParameter = new \rg\injektor\generators\InjectionParameter($argument, $classConfig, $this->config, $this->dic, InjectionParameter::MODE_STRING);
                 try {
                     if ($injectionParameter->getClassName()) {
                         $this->factoryGenerator->processFileForClass($injectionParameter->getClassName());
                     }
                     if ($injectionParameter->getFactoryName()) {
                         $this->usedFactories[] = $injectionParameter->getFactoryName();
                     }
                     $body .= '    ' . $injectionParameter->getProcessingBody();
                 } catch (\Exception $e) {
                     $body .= '    ' . $injectionParameter->getDefaultProcessingBody();
                 }
             }
             $body .= '}' . PHP_EOL;
         }
         // Property injection
         $this->injectProperties($classConfig, $classReflection);
         if (count($this->injectableProperties) > 0) {
             $proxyName = $this->dic->getProxyClassName($this->fullClassName);
             if ($this->dic->isSingleton($classReflection)) {
                 $file->setClass($this->createProxyClass($proxyName));
                 $body .= PHP_EOL . '$instance = ' . $proxyName . '::getInstance(' . implode(', ', $this->constructorArgumentStringParts) . ');' . PHP_EOL;
             } else {
                 $file->setClass($this->createProxyClass($proxyName));
                 $body .= PHP_EOL . '$instance = new ' . $proxyName . '(' . implode(', ', $this->constructorArgumentStringParts) . ');' . PHP_EOL;
             }
         } else {
             if ($this->dic->isSingleton($classReflection)) {
                 $body .= PHP_EOL . '$instance = \\' . $this->fullClassName . '::getInstance(' . implode(', ', $this->constructorArgumentStringParts) . ');' . PHP_EOL;
             } else {
                 $body .= PHP_EOL . '$instance = new \\' . $this->fullClassName . '(' . implode(', ', $this->constructorArgumentStringParts) . ');' . PHP_EOL;
             }
         }
     }
     if ($isSingleton) {
         $body .= 'self::$instance[$singletonKey] = $instance;' . PHP_EOL;
     }
     if ($isService) {
         $body .= 'self::$instance = $instance;' . PHP_EOL;
     }
     foreach ($this->injectableArguments as $injectableArgument) {
         $body .= '$instance->propertyInjection' . $injectableArgument->getName() . '();' . PHP_EOL;
     }
     $body .= 'return $instance;' . PHP_EOL;
     $instanceMethod->setBody($body);
     $instanceMethod->setStatic(true);
     $factoryClass->addMethodFromGenerator($instanceMethod);
     // Add Factory Method
     $methods = $classReflection->getMethods();
     foreach ($methods as $method) {
         /** @var \ReflectionMethod $method */
         if ($method->isPublic() && substr($method->name, 0, 2) !== '__') {
             $factoryMethod = $this->getFactoryMethod($method, $classConfig);
             $factoryClass->addMethodFromGenerator($factoryMethod);
         }
     }
     // Generate File
     $file->setNamespace('rg\\injektor\\generated');
     $this->usedFactories = array_unique($this->usedFactories);
     foreach ($this->usedFactories as &$usedFactory) {
         $usedFactory = str_replace('rg\\injektor\\generated\\', '', $usedFactory);
         $usedFactory = $usedFactory . '.php';
     }
     $file->setRequiredFiles($this->usedFactories);
     $file->setClass($factoryClass);
     $file->setFilename($this->factoryPath . DIRECTORY_SEPARATOR . $factoryName . '.php');
     return $file;
 }