vendor/rickysu/di-extra-bundle/Converter/DefinitionConverter.php line 79

Open in your IDE?
  1. <?php
  2. namespace RS\DiExtraBundle\Converter;
  3. use Doctrine\Common\Annotations\AnnotationReader;
  4. use Doctrine\Common\Annotations\AnnotationRegistry;
  5. use Doctrine\Common\Annotations\DocParser;
  6. use Doctrine\Common\Annotations\Reader;
  7. use RS\DiExtraBundle\Converter\Parser\ClassParser;
  8. use RS\DiExtraBundle\Generator\Factory\ControllerGenerator;
  9. use Symfony\Component\DependencyInjection\ChildDefinition;
  10. use Symfony\Component\DependencyInjection\Definition;
  11. class DefinitionConverter
  12. {
  13.     /** @var Reader */
  14.     protected $reader;
  15.     /** @var string */
  16.     protected $environment;
  17.     /** @var string */
  18.     protected $cacheDir;
  19.     public function inject($environment$cacheDir)
  20.     {
  21.         $this->environment $environment;
  22.         $this->cacheDir $cacheDir;
  23.         $parser = new DocParser();
  24.         $parser->setIgnoreNotImportedAnnotations(true);
  25.         $this->reader = new AnnotationReader($parser);
  26.     }
  27.     /**
  28.      * @param $classFile
  29.      * @return Definition[]
  30.      */
  31.     public function convert($classFile)
  32.     {
  33.         $definitions = array();
  34.         $classMeta $this->parseClassFile($classFile);
  35.         $this->convertFactoryService($classMeta);
  36.         while($classMeta) {
  37.             if($definition $this->convertDefinition($classMeta)){
  38.                 $definitions[$classMeta->id] = $definition;
  39.             }
  40.             $classMeta $classMeta->nextClassMeta;
  41.         }
  42.         return $definitions;
  43.     }
  44.     protected function convertDefinition(ClassMeta $classMeta)
  45.     {
  46.         if($classMeta->id === null){
  47.             return null;
  48.         }
  49.         if(!$this->isEnabledInEnvironment($classMeta->environments)){
  50.             return null;
  51.         }
  52.         if($classMeta->parent){
  53.             $definition = new ChildDefinition($classMeta->parent);
  54.             $definition->setClass($classMeta->class);
  55.         }
  56.         else {
  57.             $definition = new Definition($classMeta->class);
  58.             $definition
  59.                 ->setAutoconfigured($classMeta->autoconfigured);
  60.         }
  61.         if($classMeta->controllerProperties){
  62.             $this->createControllerFactory($classMeta$definition);
  63.             return $definition;
  64.         }
  65.         return $definition
  66.             ->setPrivate($classMeta->private)
  67.             ->setPublic($classMeta->public)
  68.             ->setShared($classMeta->shared)
  69.             ->setAbstract($classMeta->abstract)
  70.             ->setDeprecated($classMeta->deprecated)
  71.             ->setSynthetic($classMeta->synthetic)
  72.             ->setTags($classMeta->tags)
  73.             ->setFactory($classMeta->factoryMethod)
  74.             ->setMethodCalls($classMeta->methodCalls)
  75.             ->setAutowired($classMeta->autowire)
  76.             ->setArguments($classMeta->arguments)
  77.             ->setLazy($classMeta->lazy)
  78.             ->setProperties($classMeta->properties)
  79.             ->setDecoratedService($classMeta->decorates$classMeta->decorationInnerName$classMeta->decorationPriority)
  80.             ;
  81.     }
  82.     protected function getReflectionClass($classFile)
  83.     {
  84.         $className $this->getClassName($classFile);
  85.         require_once $classFile;
  86.         return new \ReflectionClass($className);
  87.     }
  88.     protected function getClassName($classFile)
  89.     {
  90.         $src file_get_contents($classFile);
  91.         if (!preg_match('/\bnamespace\s+([^;\{\s]+)\s*?[;\{]/s'$src$match)) {
  92.             throw new \RuntimeException(sprintf('Namespace could not be determined for file "%s".'$classFile));
  93.         }
  94.         $namespace $match[1];
  95.         if (!preg_match('/\b(?:class|trait)\s+([^\s]+)\s+(?:extends|implements|{)/is'$src$match)) {
  96.             throw new \RuntimeException(sprintf('Could not extract class name from file "%s".'$classFile));
  97.         }
  98.         return $namespace.'\\'.$match[1];
  99.     }
  100.     protected function isEnabledInEnvironment(array $environments)
  101.     {
  102.         if(count($environments) == 0){
  103.             return true;
  104.         }
  105.         return in_array($this->environment$environments);
  106.     }
  107.     /**
  108.      * @param $classFile
  109.      * @return ClassMeta
  110.      */
  111.     protected function parseClassFile($classFile)
  112.     {
  113.         $classMeta = new ClassMeta();
  114.         $reflectionClass $this->getReflectionClass($classFile);
  115.         $classParser = new ClassParser($this->reader$reflectionClass);
  116.         $classParser->parse($classMeta);
  117.         return $classMeta;
  118.     }
  119.     protected function createControllerFactory(ClassMeta $classMetaDefinition $definition)
  120.     {
  121.         $outputPath $this->cacheDir."/controllers";
  122.         @mkdir($outputPath0777true);
  123.         $injectParameters array_combine(array_column($classMeta->methodCalls0), array_column($classMeta->methodCalls1));
  124.         $generator = new ControllerGenerator(
  125.             $classMeta->class,
  126.             array_keys($classMeta->arguments),
  127.             $injectParameters,
  128.             array_keys($classMeta->controllerProperties)
  129.         );
  130.         $filePath "$outputPath/{$generator->getFactoryClassName()}.php";
  131.         file_put_contents($filePath$generator->getDefine());
  132.         include_once $filePath;
  133.         $definition
  134.             ->setFile($filePath)
  135.             ->setFactory(array($generator->getFactoryClassFullName(), 'create'))
  136.             ->setPublic(true);
  137.         foreach ($classMeta->arguments as $argument){
  138.             $definition->addArgument($argument);
  139.         }
  140.         foreach ($injectParameters as $arguments){
  141.             foreach ($arguments as $argument) {
  142.                 $definition->addArgument($argument);
  143.             }
  144.         }
  145.         foreach ($classMeta->controllerProperties as $argument){
  146.             $definition->addArgument($argument);
  147.         }
  148.     }
  149.     protected function convertFactoryService(ClassMeta $classMeta)
  150.     {
  151.         if(!$classMeta->nextClassMeta){
  152.             return;
  153.         }
  154.         $this->convertFactoryServiceInject($classMeta);
  155.         $this->convertFactoryServiceTag($classMeta);
  156.     }
  157.     /**
  158.      * @param ClassMeta $classMeta
  159.      */
  160.     protected function convertFactoryServiceInject(ClassMeta $classMeta)
  161.     {
  162.         if(!$classMeta->methodCalls){
  163.            return;
  164.         }
  165.         $methodCalls = array();
  166.         foreach ($classMeta->methodCalls as $methodCall) {
  167.             list($methodName$arguments) = $methodCall;
  168.             $factoryClassMeta $classMeta->nextClassMeta;
  169.             /** @var ClassMeta $factoryClassMeta */
  170.             while ($factoryClassMeta) {
  171.                 list($serviceName$factoryMethodName) = $factoryClassMeta->factoryMethod;
  172.                 if ($factoryMethodName == $methodName) {
  173.                     $factoryClassMeta->arguments $arguments;
  174.                     continue 2;
  175.                 }
  176.                 $factoryClassMeta $factoryClassMeta->nextClassMeta;
  177.             }
  178.             $methodCalls[] = $methodCall;
  179.         }
  180.         $classMeta->methodCalls $methodCalls;
  181.     }
  182.     protected function convertFactoryServiceTag(ClassMeta $classMeta)
  183.     {
  184.         if(!$classMeta->factoryTags){
  185.             return;
  186.         }
  187.         foreach ($classMeta->factoryTags as $factory => $tags){
  188.             list($factoryClass$factoryMethod) = explode(':'$factory);
  189.             $factoryClassMeta $classMeta->nextClassMeta;
  190.             /** @var ClassMeta $factoryClassMeta */
  191.             while ($factoryClassMeta) {
  192.                 list($serviceName$factoryMethodName) = $factoryClassMeta->factoryMethod;
  193.                 if("{$factoryClassMeta->factoryClass}:$factoryMethodName== $factory){
  194.                     foreach ($tags as $tagName => $tag){
  195.                         if(!isset($factoryClassMeta->tags[$tagName])){
  196.                             $factoryClassMeta->tags[$tagName] = array();
  197.                         }
  198.                         $factoryClassMeta->tags[$tagName] = array_merge($factoryClassMeta->tags[$tagName], $tag);
  199.                     }
  200.                 }
  201.                 $factoryClassMeta $factoryClassMeta->nextClassMeta;
  202.             }
  203.         }
  204.         $classMeta->factoryTags = array();
  205.     }
  206. }