/** * @return \RegexIterator */ protected function _getFiles() { $filesCollector = new FilesCollector(); $componentRegistrar = new ComponentRegistrar(); $paths = array_merge($componentRegistrar->getPaths(ComponentRegistrar::MODULE), $componentRegistrar->getPaths(ComponentRegistrar::LIBRARY)); return $filesCollector->getFiles($paths, '/\\.(php|phtml)$/'); }
public function testGetPathsForModule() { ComponentRegistrar::register(ComponentRegistrar::MODULE, "test_module_one", "some/path/name/one"); ComponentRegistrar::register(ComponentRegistrar::MODULE, "test_module_two", "some/path/name/two"); $expected = ['test_module_one' => "some/path/name/one", 'test_module_two' => "some/path/name/two"]; $this->assertContains($expected['test_module_one'], $this->object->getPaths(ComponentRegistrar::MODULE)); $this->assertContains($expected['test_module_two'], $this->object->getPaths(ComponentRegistrar::MODULE)); }
/** * Class constructor * * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfigInterface * @param ComponentRegistrar $componentRegistrar * @param string|null $scope */ public function __construct(\Magento\Framework\Filesystem $filesystem, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfigInterface, ComponentRegistrar $componentRegistrar, $scope = null) { $this->_filesystem = $filesystem; $this->_isAllowSymlinks = $scopeConfigInterface->getValue(self::XML_PATH_TEMPLATE_ALLOW_SYMLINK, $scope); $this->_themesDir = $componentRegistrar->getPaths(ComponentRegistrar::THEME); $this->moduleDirs = $componentRegistrar->getPaths(ComponentRegistrar::MODULE); $this->_compiledDir = $this->_filesystem->getDirectoryRead(DirectoryList::TEMPLATE_MINIFICATION_DIR)->getAbsolutePath(); }
/** * Try to get component name by path, return false if not found * * @param string $componentType * @param string $path * @return bool|string */ private function getComponentName($componentType, $path) { foreach ($this->componentRegistrar->getPaths($componentType) as $componentName => $componentDir) { $componentDir .= '/'; if (strpos($path, $componentDir) !== false) { return $componentName; } } return false; }
/** * Retrieve suggested sample data packages from modules composer.json * * @return array */ protected function getSuggestsFromModules() { $suggests = []; foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) { $file = $moduleDir . '/composer.json'; /** @var Package $package */ $package = $this->getModuleComposerPackage($file); $suggest = json_decode(json_encode($package->get('suggest')), true); if (!empty($suggest)) { $suggests += $suggest; } } return $suggests; }
public function setUp() { $componentRegistrar = new ComponentRegistrar(); $dirSearch = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\\Framework\\Component\\DirSearch'); $themePackageList = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\\Framework\\View\\Design\\Theme\\ThemePackageList'); $this->model = new Files($componentRegistrar, $dirSearch, $themePackageList); foreach ($componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) { $this->moduleTests[] = '#' . $moduleDir . '/Test#'; } foreach ($componentRegistrar->getPaths(ComponentRegistrar::LIBRARY) as $libraryDir) { $this->libTests[] = '#' . $libraryDir . '/Test#'; $this->frameworkTests[] = '#' . $libraryDir . '/[\\w]+/Test#'; } }
/** * Initialize package name to full theme path map * * @return void * @throws \Zend_Json_Exception */ private function initializeMap() { $themePaths = $this->componentRegistrar->getPaths(ComponentRegistrar::THEME); /** @var \Magento\Theme\Model\Theme $theme */ foreach ($themePaths as $fullThemePath => $themeDir) { $themeDirRead = $this->readDirFactory->create($themeDir); if ($themeDirRead->isExist('composer.json')) { $rawData = \Zend_Json::decode($themeDirRead->readFile('composer.json')); if (isset($rawData['name'])) { $this->packageNameToFullPathMap[$rawData['name']] = $fullThemePath; } } } }
/** * @return array */ public function getLocalePlacePath() { $pathToSource = BP; $places = []; $componentRegistrar = new ComponentRegistrar(); foreach ($componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $modulePath) { $places[basename($modulePath)] = ['placePath' => $modulePath]; } foreach ($componentRegistrar->getPaths(ComponentRegistrar::THEME) as $themePath) { $placeName = basename(dirname(dirname($themePath))) . '_' . basename($themePath); $places[$placeName] = ['placePath' => $themePath]; } $places['lib_web'] = ['placePath' => "{$pathToSource}/lib/web"]; return $places; }
/** * Constructor */ public function __construct() { $componentRegistrar = new ComponentRegistrar(); /** @var \Magento\Framework\Filesystem $filesystem */ foreach ($componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) { $key = $moduleDir . '/'; $value = $key . 'Test/Unit/'; self::$_cleanableFolders[$key] = [$value]; } foreach ($componentRegistrar->getPaths(ComponentRegistrar::LIBRARY) as $libraryDir) { $key = $libraryDir . '/'; $valueRootFolder = $key . '/Test/Unit/'; $valueSubFolder = $key . '/*/Test/Unit/'; self::$_cleanableFolders[$key] = [$valueSubFolder, $valueRootFolder]; } }
public function testLocalXmlFilesAbsent() { $componentRegistrar = new ComponentRegistrar(); foreach ($componentRegistrar->getPaths(ComponentRegistrar::THEME) as $themeDir) { $this->assertEmpty(glob($themeDir . '/local.xml')); } }
public function testRouteConfigsValidation() { $invalidFiles = []; $componentRegistrar = new ComponentRegistrar(); $files = []; foreach ($componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) { $mask = $moduleDir . '/etc/*/routes.xml'; $files = array_merge($files, glob($mask)); } $mergedConfig = new \Magento\Framework\Config\Dom('<config></config>', $this->_idAttributes); foreach ($files as $file) { $content = file_get_contents($file); try { new \Magento\Framework\Config\Dom($content, $this->_idAttributes, null, $this->schemaFile); //merge won't be performed if file is invalid because of exception thrown $mergedConfig->merge($content); } catch (\Magento\Framework\Config\Dom\ValidationException $e) { $invalidFiles[] = $file; } } if (!empty($invalidFiles)) { $this->fail('Found broken files: ' . implode("\n", $invalidFiles)); } try { $errors = []; $mergedConfig->validate($this->mergedSchemaFile, $errors); } catch (\Exception $e) { $this->fail('Merged routes config is invalid: ' . "\n" . implode("\n", $errors)); } }
public function testCheckDependencies() { $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this); $invoker(function ($file) { $componentRegistrar = new ComponentRegistrar(); $fileReflection = new FileReflection($file); $tokens = new Tokens($fileReflection->getContents(), new ParserFactory()); $tokens->parseContent(); $dependencies = array_merge((new Injectable())->getDependencies($fileReflection), $tokens->getDependencies()); $pattern = '#^(\\\\|)' . implode('|', $this->getForbiddenNamespaces()) . '\\\\#'; foreach ($dependencies as $dependency) { $dependencyPaths = explode('/', $dependency); $dependencyPaths = array_slice($dependencyPaths, 2); $dependency = implode('\\', $dependencyPaths); $libraryPaths = $componentRegistrar->getPaths(ComponentRegistrar::LIBRARY); foreach ($libraryPaths as $libraryPath) { $filePath = str_replace('\\', '/', $libraryPath . '/' . $dependency . '.php'); if (preg_match($pattern, $dependency) && !file_exists($filePath)) { $this->errors[$fileReflection->getFileName()][] = $dependency; } } } if (!empty($this->errors)) { $this->fail($this->getFailMessage()); } }, $this->libraryDataProvider()); }
/** * Test circular dependencies between languages */ public function testCircularDependencies() { $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $componentRegistrar = new ComponentRegistrar(); $declaredLanguages = $componentRegistrar->getPaths(ComponentRegistrar::LANGUAGE); $validationStateMock = $this->getMock('\\Magento\\Framework\\Config\\ValidationStateInterface', [], [], '', false); $validationStateMock->method('isValidationRequired')->willReturn(true); $domFactoryMock = $this->getMock('Magento\\Framework\\Config\\DomFactory', [], [], '', false); $domFactoryMock->expects($this->any())->method('createDom')->willReturnCallback(function ($arguments) use($validationStateMock) { return new \Magento\Framework\Config\Dom($arguments['xml'], $validationStateMock, [], null, $arguments['schemaFile']); }); $packs = []; foreach ($declaredLanguages as $language) { $languageConfig = $objectManager->getObject('Magento\\Framework\\App\\Language\\Config', ['source' => file_get_contents($language . '/language.xml'), 'domFactory' => $domFactoryMock]); $this->packs[$languageConfig->getVendor()][$languageConfig->getPackage()] = $languageConfig; $packs[] = $languageConfig; } /** @var $languageConfig Config */ foreach ($packs as $languageConfig) { $languages = []; /** @var $config Config */ foreach ($this->collectCircularInheritance($languageConfig) as $config) { $languages[] = $config->getVendor() . '/' . $config->getPackage(); } if (!empty($languages)) { $this->fail("Circular dependency detected:\n" . implode(' -> ', $languages)); } } }
/** * Get the given type component directories * * @param string $componentType * @return array */ private function getComponentDirectories($componentType) { $dirs = []; foreach ($this->componentRegistrar->getPaths($componentType) as $componentDir) { $dirs[] = $componentDir . '/'; } return $dirs; }
public function getXmlFiles() { $componentRegistrar = new ComponentRegistrar(); $codeXml = []; foreach ($componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $modulePath) { $codeXml = array_merge($codeXml, $this->_getFiles($modulePath, '*.xml', '/.\\/Test\\/Unit\\/./')); } $this->_filterSpecialCases($codeXml); $designXml = []; foreach ($componentRegistrar->getPaths(ComponentRegistrar::THEME) as $themePath) { $designXml = array_merge($designXml, $this->_getFiles($themePath, '*.xml')); } $libXml = []; foreach ($componentRegistrar->getPaths(ComponentRegistrar::LIBRARY) as $libraryPath) { $libXml = array_merge($libXml, $this->_getFiles($libraryPath, '*.xml', '/.\\/Test\\/./')); } return $this->_dataSet(array_merge($codeXml, $designXml, $libXml)); }
/** * @return array */ public function validateComposerJsonDataProvider() { $root = \Magento\Framework\App\Utility\Files::init()->getPathToSource(); $componentRegistrar = new ComponentRegistrar(); $result = []; foreach ($componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $dir) { $result[$dir] = [$dir, 'magento2-module']; } foreach ($componentRegistrar->getPaths(ComponentRegistrar::LANGUAGE) as $dir) { $result[$dir] = [$dir, 'magento2-language']; } foreach ($componentRegistrar->getPaths(ComponentRegistrar::THEME) as $dir) { $result[$dir] = [$dir, 'magento2-theme']; } foreach ($componentRegistrar->getPaths(ComponentRegistrar::LIBRARY) as $dir) { $result[$dir] = [$dir, 'magento2-library']; } $result[$root] = [$root, 'project']; return $result; }
public function testObsoleteViewPaths() { $allowedFiles = ['requirejs-config.js', 'layouts.xml']; $allowedThemeFiles = array_merge($allowedFiles, ['composer.json', 'theme.xml', 'LICENSE.txt', 'LICENSE_EE.txt', 'LICENSE_AFL.txt', 'registration.php']); $areas = '{frontend,adminhtml,base}'; $componentRegistrar = new ComponentRegistrar(); $pathsToCheck = []; foreach ($componentRegistrar->getPaths(ComponentRegistrar::THEME) as $themeDir) { $pathsToCheck[$themeDir . '/*'] = ['allowed_files' => $allowedThemeFiles, 'allowed_dirs' => ['layout', 'page_layout', 'templates', 'web', 'etc', 'i18n', 'media', '\\w+_\\w+']]; $pathsToCheck[$themeDir . '/*_*/*'] = ['allowed_files' => $allowedThemeFiles, 'allowed_dirs' => ['layout', 'page_layout', 'templates', 'web', 'email']]; } foreach ($componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) { $pathsToCheck[$moduleDir . "/view/{$areas}/*"] = ['allowed_files' => $allowedFiles, 'allowed_dirs' => ['layout', 'page_layout', 'templates', 'web', 'ui_component', 'email']]; } $errors = []; foreach ($pathsToCheck as $path => $allowed) { $allowedFiles = $allowed['allowed_files']; $allowedDirs = $allowed['allowed_dirs']; $foundFiles = glob($path, GLOB_BRACE); if (!$foundFiles) { continue; } foreach ($foundFiles as $file) { $baseName = basename($file); if (is_dir($file)) { foreach ($allowedDirs as $allowedDir) { if (preg_match("#^{$allowedDir}\$#", $baseName)) { continue 2; } } } if (in_array($baseName, $allowedFiles)) { continue; } $errors[] = $file; } } if (!empty($errors)) { $this->fail('Unexpected files or directories found. Make sure they are not at obsolete locations:' . PHP_EOL . implode(PHP_EOL, $errors)); } }
/** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $errors = $this->checkEnvironment(); if ($errors) { foreach ($errors as $line) { $output->writeln($line); } // we must have an exit code higher than zero to indicate something was wrong return \Magento\Framework\Console\Cli::RETURN_FAILURE; } $modulePaths = $this->componentRegistrar->getPaths(ComponentRegistrar::MODULE); $libraryPaths = $this->componentRegistrar->getPaths(ComponentRegistrar::LIBRARY); $generationPath = $this->directoryList->getPath(DirectoryList::GENERATION); $this->objectManager->get('Magento\\Framework\\App\\Cache')->clean(); $compiledPathsList = ['application' => $modulePaths, 'library' => $libraryPaths, 'generated_helpers' => $generationPath]; $excludedModulePaths = []; foreach ($modulePaths as $appCodePath) { $excludedModulePaths[] = '#^' . $appCodePath . '/Test#'; } $excludedLibraryPaths = []; foreach ($libraryPaths as $libraryPath) { $excludedLibraryPaths[] = '#^' . $libraryPath . '/([\\w]+/)?Test#'; } $this->excludedPathsList = ['application' => $excludedModulePaths, 'framework' => $excludedLibraryPaths]; $this->configureObjectManager($output); $operations = $this->getOperationsConfiguration($compiledPathsList); try { $this->cleanupFilesystem([DirectoryList::CACHE, DirectoryList::DI]); foreach ($operations as $operationCode => $arguments) { $this->taskManager->addOperation($operationCode, $arguments); } /** @var ProgressBar $progressBar */ $progressBar = $this->objectManager->create('Symfony\\Component\\Console\\Helper\\ProgressBar', ['output' => $output, 'max' => count($operations)]); $progressBar->setFormat('<info>%message%</info> %current%/%max% [%bar%] %percent:3s%% %elapsed% %memory:6s%'); $output->writeln('<info>Compilation was started.</info>'); $progressBar->start(); $progressBar->display(); $this->taskManager->process(function (OperationInterface $operation) use($progressBar) { $progressBar->setMessage($operation->getName() . '...'); $progressBar->display(); }, function (OperationInterface $operation) use($progressBar) { $progressBar->advance(); }); $progressBar->finish(); $output->writeln(''); $output->writeln('<info>Generated code and dependency injection configuration successfully.</info>'); } catch (OperationException $e) { $output->writeln('<error>' . $e->getMessage() . '</error>'); // we must have an exit code higher than zero to indicate something was wrong return \Magento\Framework\Console\Cli::RETURN_FAILURE; } }
/** * Returns array of composer.json for components of specified type * * @param string $componentType * @param bool $asDataSet * @return array */ public function getComposerFiles($componentType, $asDataSet = true) { $key = __METHOD__ . '|' . serialize(func_get_args()); if (!isset(self::$_cache[$key])) { $excludes = $componentType == ComponentRegistrar::MODULE ? $this->getModuleTestDirsRegex() : []; $files = $this->getFilesSubset($this->componentRegistrar->getPaths($componentType), 'composer.json', $excludes); self::$_cache[$key] = $files; } if ($asDataSet) { return self::composeDataSets(self::$_cache[$key]); } return self::$_cache[$key]; }
public function testAppCodeUsage() { $files = Files::init(); $componentRegistrar = new ComponentRegistrar(); $libPaths = $componentRegistrar->getPaths(ComponentRegistrar::LIBRARY); $invoker = new AggregateInvoker($this); $invoker(function ($file) use($libPaths) { $content = file_get_contents($file); foreach ($libPaths as $libPath) { if (strpos($file, $libPath) === 0) { $this->assertSame(0, preg_match('~(?<![a-z\\d_:]|->|function\\s)__\\s*\\(~iS', $content), 'Function __() is defined outside of the library and must not be used there. ' . 'Replacement suggestion: new \\Magento\\Framework\\Phrase()'); } } }, $files->getPhpFiles(Files::INCLUDE_PUB_CODE | Files::INCLUDE_LIBS | Files::AS_DATA_SET | Files::INCLUDE_NON_CLASSES)); }
/** * Load the packages information * * @return void */ private function load() { if ($this->packageModuleMap === null) { $jsonData = $this->reader->getComposerJsonFiles()->toArray(); foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $moduleDir) { $key = $moduleDir . '/composer.json'; if (isset($jsonData[$key]) && $jsonData[$key]) { $packageData = \Zend_Json::decode($jsonData[$key]); if (isset($packageData['name'])) { $this->packageModuleMap[$packageData['name']] = $moduleName; } if (isset($packageData['version'])) { $this->modulePackageVersionMap[$moduleName] = $packageData['version']; } if (!empty($packageData['require'])) { $this->requireMap[$moduleName] = array_keys($packageData['require']); } if (!empty($packageData['conflict'])) { $this->conflictMap[$moduleName] = $packageData['conflict']; } } } } }
public function testForOldInstallUpgradeScripts() { $scriptPattern = []; $componentRegistrar = new ComponentRegistrar(); foreach ($componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) { $scriptPattern[] = $moduleDir . '/sql'; $scriptPattern[] = $moduleDir . '/data'; } $invoker = new AggregateInvoker($this); $invoker(function ($file) { $this->assertStringStartsNotWith('install-', basename($file), 'Install scripts are obsolete. Please create class InstallSchema in module\'s Setup folder'); $this->assertStringStartsNotWith('data-install-', basename($file), 'Install scripts are obsolete. Please create class InstallData in module\'s Setup folder'); $this->assertStringStartsNotWith('upgrade-', basename($file), 'Upgrade scripts are obsolete. Please create class UpgradeSchema in module\'s Setup folder'); $this->assertStringStartsNotWith('data-upgrade-', basename($file), 'Upgrade scripts are obsolete. Please create class UpgradeData in module\'s Setup folder'); $this->assertStringStartsNotWith('recurring', basename($file), 'Recurring scripts are obsolete. Please create class Recurring in module\'s Setup folder'); $this->fail('Invalid directory. Please convert data/sql scripts to a class within module\'s Setup folder'); }, $this->convertArray(Files::init()->getFiles($scriptPattern, '*.php'))); }
/** * Test circular dependencies between languages */ public function testCircularDependencies() { $componentRegistrar = new ComponentRegistrar(); $declaredLanguages = $componentRegistrar->getPaths(ComponentRegistrar::LANGUAGE); $urnResolver = new UrnResolver(); $packs = []; foreach ($declaredLanguages as $language) { $languageConfig = new Config(file_get_contents($language . '/language.xml'), $urnResolver); $this->packs[$languageConfig->getVendor()][$languageConfig->getPackage()] = $languageConfig; $packs[] = $languageConfig; } /** @var $languageConfig Config */ foreach ($packs as $languageConfig) { $languages = []; /** @var $config Config */ foreach ($this->collectCircularInheritance($languageConfig) as $config) { $languages[] = $config->getVendor() . '/' . $config->getPackage(); } if (!empty($languages)) { $this->fail("Circular dependency detected:\n" . implode(' -> ', $languages)); } } }
/** * @param ComponentRegistrar $componentRegistrar * @param string $namespacePath * @param string $badClass * @param array $badClasses * @return bool */ private function removeSpecialCasesForAllOthers($componentRegistrar, $namespacePath, $badClass, &$badClasses) { // Remove usage of classes that do NOT using fully-qualified class names (possibly under same namespace) $directories = [BP . '/dev/tools/', BP . '/dev/tests/api-functional/framework/', BP . '/dev/tests/functional/', BP . '/dev/tests/integration/framework/', BP . '/dev/tests/integration/framework/tests/unit/testsuite/', BP . '/dev/tests/integration/testsuite/', BP . '/dev/tests/integration/testsuite/Magento/Test/Integrity/', BP . '/dev/tests/static/framework/', BP . '/dev/tests/static/testsuite/', BP . '/setup/src/']; $libraryPaths = $componentRegistrar->getPaths(ComponentRegistrar::LIBRARY); $directories = array_merge($directories, $libraryPaths); // Full list of directories where there may be namespace classes foreach ($directories as $directory) { $fullPath = $directory . $namespacePath . '/' . str_replace('\\', '/', $badClass) . '.php'; if (file_exists($fullPath)) { unset($badClasses[array_search($badClass, $badClasses)]); return true; } } return false; }
public function testTheModuleIsRegistered() { $registrar = new ComponentRegistrar(); $this->assertArrayHasKey($this->moduleName, $registrar->getPaths(ComponentRegistrar::MODULE)); }
/** * Compile Code * * @param string $generationDir * @param array $fileExcludePatterns * @param InputInterface $input * @return void * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ private function compileCode($generationDir, $fileExcludePatterns, $input) { $diDir = $input->getOption(self::INPUT_KEY_DI) ? $input->getOption(self::INPUT_KEY_DI) : $this->directoryList->getPath(DirectoryList::DI); $relationsFile = $diDir . '/relations.ser'; $pluginDefFile = $diDir . '/plugins.ser'; $compilationDirs = [$this->directoryList->getPath(DirectoryList::SETUP) . '/Magento/Setup/Module', $this->directoryList->getRoot() . '/dev/tools/Magento/Tools']; $compilationDirs = array_merge($compilationDirs, $this->componentRegistrar->getPaths(ComponentRegistrar::MODULE), $this->componentRegistrar->getPaths(ComponentRegistrar::LIBRARY)); $serializer = $input->getOption(self::INPUT_KEY_SERIALIZER) == Igbinary::NAME ? new Igbinary() : new Standard(); // 2.1 Code scan $validator = new \Magento\Framework\Code\Validator(); $validator->add(new \Magento\Framework\Code\Validator\ConstructorIntegrity()); $validator->add(new \Magento\Framework\Code\Validator\ContextAggregation()); $classesScanner = new \Magento\Setup\Module\Di\Code\Reader\ClassesScanner(); $classesScanner->addExcludePatterns($fileExcludePatterns); $directoryInstancesNamesList = new \Magento\Setup\Module\Di\Code\Reader\Decorator\Directory($this->log, new \Magento\Framework\Code\Reader\ClassReader(), $classesScanner, $validator, $generationDir); foreach ($compilationDirs as $path) { if (is_readable($path)) { $directoryInstancesNamesList->getList($path); } } $inheritanceScanner = new Scanner\InheritanceInterceptorScanner(); $this->entities['interceptors'] = $inheritanceScanner->collectEntities(get_declared_classes(), $this->entities['interceptors']); // 2.1.1 Generation of Proxy and Interceptor Classes foreach (['interceptors', 'di'] as $type) { foreach ($this->entities[$type] as $entityName) { switch ($this->generator->generateClass($entityName)) { case \Magento\Framework\Code\Generator::GENERATION_SUCCESS: $this->log->add(Log::GENERATION_SUCCESS, $entityName); break; case \Magento\Framework\Code\Generator::GENERATION_ERROR: $this->log->add(Log::GENERATION_ERROR, $entityName); break; case \Magento\Framework\Code\Generator::GENERATION_SKIP: default: //no log break; } } } //2.1.2 Compile relations for Proxy/Interceptor classes $directoryInstancesNamesList->getList($generationDir); $relations = $directoryInstancesNamesList->getRelations(); // 2.2 Compression $relationsFileDir = dirname($relationsFile); if (!file_exists($relationsFileDir)) { mkdir($relationsFileDir, DriverInterface::WRITEABLE_DIRECTORY_MODE, true); } $relations = array_filter($relations); file_put_contents($relationsFile, $serializer->serialize($relations)); // 3. Plugin Definition Compilation $pluginScanner = new Scanner\CompositeScanner(); $pluginScanner->addChild(new Scanner\PluginScanner(), 'di'); $pluginDefinitions = []; $pluginList = $pluginScanner->collectEntities($this->files); $pluginDefinitionList = new \Magento\Framework\Interception\Definition\Runtime(); foreach ($pluginList as $type => $entityList) { foreach ($entityList as $entity) { $pluginDefinitions[ltrim($entity, '\\')] = $pluginDefinitionList->getMethodList($entity); } } $outputContent = $serializer->serialize($pluginDefinitions); $pluginDefFileDir = dirname($pluginDefFile); if (!file_exists($pluginDefFileDir)) { mkdir($pluginDefFileDir, DriverInterface::WRITEABLE_DIRECTORY_MODE, true); } file_put_contents($pluginDefFile, $outputContent); }
/** * Special case: don't allow usage of getChild() method anywhere within app directory * * In Magento 1.x it used to belong only to abstract block (therefore all blocks) * At the same time, the name is pretty generic and can be encountered in other directories, such as lib * * @param string $content * @param string $file */ protected function _testGetChildSpecialCase($content, $file) { $componentRegistrar = new ComponentRegistrar(); foreach ($componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $modulePath) { if (0 === strpos($file, $modulePath)) { $this->_assertNotRegexp('/[^a-z\\d_]getChild\\s*\\(/iS', $content, 'Block method getChild() is obsolete. ' . 'Replacement suggestion: \\Magento\\Framework\\View\\Element\\AbstractBlock::getChildBlock()'); } } }
public function testUndeclared() { $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this); $invoker(function ($fileType, $file) { // Validates file when it is belonged to default themes $componentRegistrar = new ComponentRegistrar(); foreach ($componentRegistrar->getPaths(ComponentRegistrar::THEME) as $themeDir) { if (strpos($file, $themeDir . '/') !== false) { return; } } $foundModuleName = ''; foreach ($componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $moduleDir) { if (strpos($file, $moduleDir . '/') !== false) { $foundModuleName = str_replace('_', '\\', $moduleName); break; } } if (empty($foundModuleName)) { return; } $module = $foundModuleName; $contents = $this->_getCleanedFileContents($fileType, $file); $dependencies = $this->getDependenciesFromFiles($module, $fileType, $file, $contents); // Collect dependencies $undeclaredDependency = $this->_collectDependencies($module, $dependencies); // Prepare output message $result = []; foreach ($undeclaredDependency as $type => $modules) { $modules = array_unique($modules); if (!count($modules)) { continue; } $result[] = sprintf("%s [%s]", $type, implode(', ', $modules)); } if (count($result)) { $this->fail('Module ' . $module . ' has undeclared dependencies: ' . implode(', ', $result)); } }, $this->getAllFiles()); }
/** * Scan application source code and find classes * * Sub-type pattern allows to distinguish "type" of a class within a module (for example, Block, Model) * Returns array(<class> => <module>) * * @param string $subTypePattern * @return array */ public static function collectModuleClasses($subTypePattern = '[A-Za-z]+') { $componentRegistrar = new ComponentRegistrar(); $result = []; foreach ($componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $modulePath) { $pattern = '/^' . preg_quote($modulePath, '/') . '\\/(' . $subTypePattern . '\\/.+)\\.php$/'; foreach (Files::init()->getFiles([$modulePath], '*.php') as $file) { if (preg_match($pattern, $file)) { $partialFileName = substr($file, strlen($modulePath) + 1); $partialFileName = substr($partialFileName, 0, strlen($partialFileName) - strlen('.php')); $partialClassName = str_replace('/', '\\', $partialFileName); $className = str_replace('_', '\\', $moduleName) . '\\' . $partialClassName; $result[$className] = $moduleName; } } } return $result; }
/** * Get php classes list * * @return array */ protected function _phpClassesDataProvider() { $generationPath = str_replace('/', '\\', $this->_generationDir); $files = Files::init()->getPhpFiles(Files::INCLUDE_APP_CODE | Files::INCLUDE_LIBS); $patterns = ['/' . preg_quote($generationPath) . '/']; $replacements = ['']; $componentRegistrar = new ComponentRegistrar(); foreach ($componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $modulePath) { $patterns[] = '/' . preg_quote(str_replace('/', '\\', $modulePath)) . '/'; $replacements[] = '\\' . str_replace('_', '\\', $moduleName); } foreach ($componentRegistrar->getPaths(ComponentRegistrar::LIBRARY) as $libPath) { $patterns[] = '/' . preg_quote(str_replace('/', '\\', $libPath)) . '/'; $replacements[] = '\\Magento\\Framework'; } /** Convert file names into class name format */ $classes = []; foreach ($files as $file) { $file = str_replace('/', '\\', $file); $filePath = preg_replace($patterns, $replacements, $file); $className = substr($filePath, 0, -4); if (class_exists($className, false)) { $file = str_replace('\\', DIRECTORY_SEPARATOR, $file); $classes[$file] = $className; } } /** Build class inheritance hierarchy */ $output = []; $allowedFiles = array_keys($classes); foreach ($classes as $class) { if (!in_array($class, $output)) { $output = array_merge($output, $this->_buildInheritanceHierarchyTree($class, $allowedFiles)); $output = array_unique($output); } } /** Convert data into data provider format */ $outputClasses = []; foreach ($output as $className) { $outputClasses[] = [$className]; } return $outputClasses; }