/** * Fetch factories from class constructor * * @param $file string * @param $reflectionClass mixed * @return array */ protected function _fetchDataBuilders($file, $reflectionClass) { $absentDataBuilders = []; if ($reflectionClass->hasMethod('__construct')) { $constructor = $reflectionClass->getMethod('__construct'); $parameters = $constructor->getParameters(); /** @var $parameter \ReflectionParameter */ foreach ($parameters as $parameter) { preg_match('/\\[\\s\\<\\w+?>\\s([\\w\\\\]+)/s', $parameter->__toString(), $matches); if (isset($matches[1]) && substr($matches[1], -11) == 'DataBuilder') { $factoryClassName = $matches[1]; if (class_exists($factoryClassName)) { continue; } $entityName = rtrim(substr($factoryClassName, 0, -11), '\\'); if (!class_exists($entityName) && !interface_exists($entityName . 'Interface')) { $this->_log->add(Log::CONFIGURATION_ERROR, $factoryClassName, 'Invalid DataBuilder for nonexistent class ' . $entityName . ' in file ' . $file); continue; } $absentDataBuilders[] = $factoryClassName; } } } return $absentDataBuilders; }
/** * Compile class definitions * * @param string $path * @param bool $validate * @return void */ public function compile($path, $validate = true) { $rdi = new \RecursiveDirectoryIterator(realpath($path)); $recursiveIterator = new \RecursiveIteratorIterator($rdi, 1); /** @var $item \SplFileInfo */ foreach ($recursiveIterator as $item) { if ($item->isFile() && pathinfo($item->getRealPath(), PATHINFO_EXTENSION) == 'php') { $fileScanner = new FileScanner($item->getRealPath()); $classNames = $fileScanner->getClassNames(); foreach ($classNames as $className) { $this->_current = $className; if (!class_exists($className)) { require_once $item->getRealPath(); } try { if ($validate) { $this->_validator->validate($className); } $signatureReader = new \Magento\Framework\Code\Reader\ClassReader(); $this->_definitions[$className] = $signatureReader->getConstructor($className); $this->_relations[$className] = $signatureReader->getParents($className); } catch (\Magento\Framework\Code\ValidationException $exception) { $this->_log->add(Log::COMPILATION_ERROR, $className, $exception->getMessage()); } catch (\ReflectionException $e) { $this->_log->add(Log::COMPILATION_ERROR, $className, $e->getMessage()); } $this->_processedClasses[$className] = 1; } } } }
/** * Filter found entities if needed * * @param array $output * @return array */ protected function _filterEntities(array $output) { $filteredEntities = array(); foreach ($output as $className) { $entityName = substr($className, -6) === '\\Proxy' ? substr($className, 0, -6) : $className; if (false === class_exists($className)) { if (class_exists($entityName) || interface_exists($entityName)) { array_push($filteredEntities, $className); } else { $this->_log->add(\Magento\Tools\Di\Compiler\Log\Log::CONFIGURATION_ERROR, $className, 'Invalid proxy class for ' . substr($className, 0, -5)); } } } return $filteredEntities; }
/** * Retrieves list of classes for given path * * @param string $path path to dir with files * * @return array */ public function getList($path) { $nameList = []; foreach ($this->classesScanner->getList($path) as $className) { try { if (!strpos($path, 'generation')) { // validate all classes except classes in var/generation dir $this->validator->validate($className); } $nameList[] = $className; } catch (\Magento\Framework\Code\ValidationException $exception) { $this->log->add(Log::COMPILATION_ERROR, $className, $exception->getMessage()); } catch (\ReflectionException $e) { $this->log->add(Log::COMPILATION_ERROR, $className, $e->getMessage()); } } $this->log->report(); return $nameList; }
/** * Filter found entities if needed * * @param array $output * @return array */ protected function _filterEntities(array $output) { $entitySuffix = '\\' . ucfirst(ProxyGenerator::ENTITY_TYPE); $filteredEntities = []; foreach ($output as $className) { $entityName = substr($className, -strlen($entitySuffix)) === $entitySuffix ? substr($className, 0, -strlen($entitySuffix)) : $className; $isClassExists = false; try { $isClassExists = class_exists($className); } catch (\Magento\Framework\Exception $e) { } if (false === $isClassExists) { if (class_exists($entityName) || interface_exists($entityName)) { array_push($filteredEntities, $className); } else { $this->_log->add(\Magento\Tools\Di\Compiler\Log\Log::CONFIGURATION_ERROR, $className, 'Invalid proxy class for ' . substr($className, 0, -5)); } } } return $filteredEntities; }
/** * Fetch factories from class constructor * * @param \ReflectionClass $reflectionClass * @param string $file * @return string[] */ protected function _fetchFactories($reflectionClass, $file) { $factorySuffix = '\\' . ucfirst(FactoryGenerator::ENTITY_TYPE); $absentFactories = $this->_findMissingClasses($file, $reflectionClass, '__construct', ucfirst(FactoryGenerator::ENTITY_TYPE)); foreach ($absentFactories as $key => $absentFactory) { if (substr($absentFactory, -strlen($factorySuffix)) == $factorySuffix) { $entityName = rtrim(substr($absentFactory, 0, -strlen($factorySuffix)), '\\'); $this->_log->add(Log::CONFIGURATION_ERROR, $absentFactory, 'Invalid Factory declaration for class ' . $entityName . ' in file ' . $file); unset($absentFactories[$key]); } } return $absentFactories; }
/** * Retrieves list of classes for given path * * @param string $path path to dir with files * * @return array */ public function getList($path) { foreach ($this->classesScanner->getList($path) as $className) { $this->current = $className; // for errorHandler function try { if ($path != $this->generationDir) { // validate all classes except classes in generation dir $this->validator->validate($className); } $this->relations[$className] = $this->classReader->getParents($className); } catch (\Magento\Framework\Code\ValidationException $exception) { $this->log->add(Log::COMPILATION_ERROR, $className, $exception->getMessage()); } catch (\ReflectionException $e) { $this->log->add(Log::COMPILATION_ERROR, $className, $e->getMessage()); } } return $this->relations; }
$entities = $scanner->collectEntities($files); $interceptorScanner = new Scanner\XmlInterceptorScanner(); $entities['interceptors'] = $interceptorScanner->collectEntities($files['di']); // 1.2 Generation of Factory and Additional Classes $generatorIo = new \Magento\Framework\Code\Generator\Io(new \Magento\Framework\Filesystem\Driver\File(), $generationDir); $generator = new \Magento\Framework\Code\Generator($generatorIo, [Interceptor::ENTITY_TYPE => 'Magento\\Framework\\Interception\\Code\\Generator\\Interceptor', Proxy::ENTITY_TYPE => 'Magento\\Framework\\ObjectManager\\Code\\Generator\\Proxy', Factory::ENTITY_TYPE => 'Magento\\Framework\\ObjectManager\\Code\\Generator\\Factory', Mapper::ENTITY_TYPE => 'Magento\\Framework\\Api\\Code\\Generator\\Mapper', Persistor::ENTITY_TYPE => 'Magento\\Framework\\ObjectManager\\Code\\Generator\\Persistor', Repository::ENTITY_TYPE => 'Magento\\Framework\\ObjectManager\\Code\\Generator\\Repository', Converter::ENTITY_TYPE => 'Magento\\Framework\\ObjectManager\\Code\\Generator\\Converter', SearchResults::ENTITY_TYPE => 'Magento\\Framework\\Api\\Code\\Generator\\SearchResults', ExtensionAttributesInterfaceGenerator::ENTITY_TYPE => 'Magento\\Framework\\Api\\Code\\Generator\\ExtensionAttributesInterfaceGenerator', ExtensionAttributesGenerator::ENTITY_TYPE => 'Magento\\Framework\\Api\\Code\\Generator\\ExtensionAttributesGenerator']); /** Initialize object manager for code generation based on configs */ $magentoObjectManagerFactory = \Magento\Framework\App\Bootstrap::createObjectManagerFactory(BP, $_SERVER); $objectManager = $magentoObjectManagerFactory->create($_SERVER); $generator->setObjectManager($objectManager); $generatorAutoloader = new \Magento\Framework\Code\Generator\Autoloader($generator); spl_autoload_register([$generatorAutoloader, 'load']); foreach ($repositories as $entityName) { switch ($generator->generateClass($entityName)) { case \Magento\Framework\Code\Generator::GENERATION_SUCCESS: $log->add(Log::GENERATION_SUCCESS, $entityName); break; case \Magento\Framework\Code\Generator::GENERATION_ERROR: $log->add(Log::GENERATION_ERROR, $entityName); break; case \Magento\Framework\Code\Generator::GENERATION_SKIP: default: //no log break; } } foreach (['php', 'additional'] as $type) { sort($entities[$type]); foreach ($entities[$type] as $entityName) { switch ($generator->generateClass($entityName)) { case \Magento\Framework\Code\Generator::GENERATION_SUCCESS: