123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Framework\App\Utility;
- use Magento\Framework\App\ObjectManager;
- use Magento\Framework\Component\ComponentRegistrar;
- use Magento\Framework\Component\DirSearch;
- use Magento\Framework\Serialize\Serializer\Json;
- use Magento\Framework\View\Design\Theme\ThemePackageList;
- use Magento\Framework\Filesystem\Glob;
- /**
- * A helper to gather specific kind of files in Magento application.
- *
- * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
- * @SuppressWarnings(PHPMD.NPathComplexity)
- */
- class Files
- {
- /**
- * Include app code
- */
- const INCLUDE_APP_CODE = 1;
- /**
- * Include tests
- */
- const INCLUDE_TESTS = 2;
- /**
- * Include dev tools
- */
- const INCLUDE_DEV_TOOLS = 4;
- /**
- * Include templates
- */
- const INCLUDE_TEMPLATES = 8;
- /**
- * Include lib files
- */
- const INCLUDE_LIBS = 16;
- /**
- * Include pub code
- */
- const INCLUDE_PUB_CODE = 32;
- /**
- * Include non classes
- */
- const INCLUDE_NON_CLASSES = 64;
- /**
- * Include setup
- */
- const INCLUDE_SETUP = 128;
- /**
- * Return as data set
- */
- const AS_DATA_SET = 1024;
- /**
- * @var ComponentRegistrar
- */
- protected $componentRegistrar;
- /**
- * @var \Magento\Framework\App\Utility\Files
- */
- protected static $_instance = null;
- /**
- * @var array
- */
- protected static $_cache = [];
- /**
- * @var DirSearch
- */
- private $dirSearch;
- /**
- * @var ThemePackageList
- */
- private $themePackageList;
- /**
- * @var Json
- */
- private $serializer;
- /**
- * @var RegexIteratorFactory
- */
- private $regexIteratorFactory;
- /**
- * Constructor
- *
- * @param ComponentRegistrar $componentRegistrar
- * @param DirSearch $dirSearch
- * @param ThemePackageList $themePackageList
- * @param Json|null $serializer
- * @param RegexIteratorFactory|null $regexIteratorFactory
- */
- public function __construct(
- ComponentRegistrar $componentRegistrar,
- DirSearch $dirSearch,
- ThemePackageList $themePackageList,
- Json $serializer = null,
- RegexIteratorFactory $regexIteratorFactory = null
- ) {
- $this->componentRegistrar = $componentRegistrar;
- $this->dirSearch = $dirSearch;
- $this->themePackageList = $themePackageList;
- $this->serializer = $serializer ?: ObjectManager::getInstance()
- ->get(Json::class);
- $this->regexIteratorFactory = $regexIteratorFactory ?: ObjectManager::getInstance()
- ->get(RegexIteratorFactory::class);
- }
- /**
- * Setter for an instance of self
- *
- * Also can unset the current instance, if no arguments are specified
- *
- * @param Files|null $instance
- * @return void
- */
- public static function setInstance(Files $instance = null)
- {
- self::$_instance = $instance;
- }
- /**
- * Getter for an instance of self
- *
- * @return \Magento\Framework\App\Utility\Files
- * @throws \Exception when there is no instance set
- */
- public static function init()
- {
- if (!self::$_instance) {
- throw new \Exception('Instance is not set yet.');
- }
- return self::$_instance;
- }
- /**
- * Compose PHPUnit's data sets that contain each file as the first argument
- *
- * @param array $files
- * @return array
- */
- public static function composeDataSets(array $files)
- {
- $result = [];
- foreach ($files as $file) {
- $key = str_replace(BP . '/', '', $file);
- $result[$key] = [$file];
- }
- return $result;
- }
- /**
- * Get list of regular expressions for matching test directories in modules
- *
- * @return array
- */
- private function getModuleTestDirsRegex()
- {
- $moduleTestDirs = [];
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) {
- $moduleTestDirs[] = str_replace('\\', '/', '#' . $moduleDir . '/Test#');
- }
- return $moduleTestDirs;
- }
- /**
- * Get base path
- *
- * @return string
- */
- public function getPathToSource()
- {
- return BP;
- }
- /**
- * Returns list of files, where expected to have class declarations
- *
- * @param int $flags
- * @return array
- */
- public function getPhpFiles($flags = 0)
- {
- // Sets default value
- if ($flags === 0) {
- $flags = self::INCLUDE_APP_CODE
- | self::INCLUDE_TESTS
- | self::INCLUDE_DEV_TOOLS
- | self::INCLUDE_LIBS
- | self::AS_DATA_SET;
- }
- $key = __METHOD__ . BP . $flags;
- if (!isset(self::$_cache[$key])) {
- $files = array_merge(
- $this->getAppCodeFiles($flags),
- $this->getTestFiles($flags),
- $this->getDevToolsFiles($flags),
- $this->getTemplateFiles($flags),
- $this->getLibraryFiles($flags),
- $this->getPubFiles($flags),
- $this->getSetupPhpFiles($flags)
- );
- self::$_cache[$key] = $files;
- }
- if ($flags & self::AS_DATA_SET) {
- return self::composeDataSets(self::$_cache[$key]);
- }
- return self::$_cache[$key];
- }
- /**
- * Return array with all template files
- *
- * @param int $flags
- * @return array
- */
- private function getTemplateFiles($flags)
- {
- if ($flags & self::INCLUDE_TEMPLATES) {
- return $this->getPhtmlFiles(false, false);
- }
- return [];
- }
- /**
- * Return array with all php files related to library
- *
- * @param int $flags
- * @return array
- */
- private function getLibraryFiles($flags)
- {
- if ($flags & self::INCLUDE_LIBS) {
- $libraryExcludeDirs = [];
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::LIBRARY) as $libraryDir) {
- $libraryExcludeDirs[] = str_replace('\\', '/', '#' . $libraryDir . '/Test#');
- $libraryExcludeDirs[] = str_replace('\\', '/', '#' . $libraryDir) . '/[\\w]+/Test#';
- if (!($flags & self::INCLUDE_NON_CLASSES)) {
- $libraryExcludeDirs[] = str_replace('\\', '/', '#' . $libraryDir . '/registration#');
- }
- }
- return $this->getFilesSubset(
- $this->componentRegistrar->getPaths(ComponentRegistrar::LIBRARY),
- '*.php',
- $libraryExcludeDirs
- );
- }
- return [];
- }
- /**
- * Return array with all php files related to pub
- *
- * @param int $flags
- * @return array
- */
- private function getPubFiles($flags)
- {
- if ($flags & self::INCLUDE_PUB_CODE) {
- return array_merge(
- Glob::glob(BP . '/*.php', Glob::GLOB_NOSORT),
- Glob::glob(BP . '/pub/*.php', Glob::GLOB_NOSORT)
- );
- }
- return [];
- }
- /**
- * Return array with all php files related to dev tools
- *
- * @param int $flags
- * @return array
- */
- private function getDevToolsFiles($flags)
- {
- if ($flags & self::INCLUDE_DEV_TOOLS) {
- return $this->getFilesSubset([BP . '/dev/tools/Magento'], '*.php', []);
- }
- return [];
- }
- /**
- * Return array with all php files related to modules
- *
- * @param int $flags
- * @return array
- */
- private function getAppCodeFiles($flags)
- {
- if ($flags & self::INCLUDE_APP_CODE) {
- $excludePaths = [];
- $paths = $this->componentRegistrar->getPaths(ComponentRegistrar::MODULE);
- if ($flags & self::INCLUDE_NON_CLASSES) {
- $paths[] = BP . '/app';
- } else {
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) {
- $excludePaths[] = str_replace('\\', '/', '#' . $moduleDir . '/registration.php#');
- $excludePaths[] = str_replace('\\', '/', '#' . $moduleDir . '/cli_commands.php#');
- }
- }
- return $this->getFilesSubset(
- $paths,
- '*.php',
- array_merge($this->getModuleTestDirsRegex(), $excludePaths)
- );
- }
- return [];
- }
- /**
- * Return array with all test files
- *
- * @param int $flags
- * @return array
- */
- private function getTestFiles($flags)
- {
- if ($flags & self::INCLUDE_TESTS) {
- $testDirs = [
- BP . '/dev/tests',
- BP . '/setup/src/Magento/Setup/Test',
- ];
- $moduleTestDir = [];
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) {
- $moduleTestDir[] = $moduleDir . '/Test';
- }
- $libraryTestDirs = [];
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::LIBRARY) as $libraryDir) {
- $libraryTestDirs[] = $libraryDir . '/Test';
- $libraryTestDirs[] = $libraryDir . '/*/Test';
- }
- $testDirs = array_merge($testDirs, $moduleTestDir, $libraryTestDirs);
- return self::getFiles($testDirs, '*.php');
- }
- return [];
- }
- /**
- * Returns list of xml files, used by Magento application
- *
- * @return array
- */
- public function getXmlFiles()
- {
- return array_merge(
- $this->getMainConfigFiles(),
- $this->getLayoutFiles(),
- $this->getPageLayoutFiles(),
- $this->getConfigFiles(),
- $this->getDiConfigs(true),
- $this->getLayoutConfigFiles(),
- $this->getPageTypeFiles()
- );
- }
- /**
- * Retrieve all config files, that participate (or have a chance to participate) in composing main config
- *
- * @param bool $asDataSet
- * @return array
- */
- public function getMainConfigFiles($asDataSet = true)
- {
- $cacheKey = __METHOD__ . '|' . implode('|', [$asDataSet]);
- if (!isset(self::$_cache[$cacheKey])) {
- $configXmlPaths = [];
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) {
- $configXmlPaths[] = $moduleDir . '/etc/config.xml';
- // Module DB-specific configs, e.g. config.mysql4.xml
- $configXmlPaths[] = $moduleDir . '/etc/config.*.xml';
- }
- $globPaths = [BP . '/app/etc/config.xml', BP . '/app/etc/*/config.xml'];
- $configXmlPaths = array_merge($globPaths, $configXmlPaths);
- $files = [];
- foreach ($configXmlPaths as $xmlPath) {
- $files = array_merge($files, glob($xmlPath, GLOB_NOSORT));
- }
- self::$_cache[$cacheKey] = $files;
- }
- if ($asDataSet) {
- return self::composeDataSets(self::$_cache[$cacheKey]);
- }
- return self::$_cache[$cacheKey];
- }
- /**
- * Returns list of configuration files, used by Magento application
- *
- * @param string $fileNamePattern
- * @param array $excludedFileNames
- * @param bool $asDataSet
- * @return array
- * @codingStandardsIgnoreStart
- */
- public function getConfigFiles(
- $fileNamePattern = '*.xml',
- $excludedFileNames = ['wsdl.xml', 'wsdl2.xml', 'wsi.xml'],
- $asDataSet = true
- ) {
- $cacheKey = __METHOD__ . '|' . $this->serializer->serialize([$fileNamePattern, $excludedFileNames, $asDataSet]);
- if (!isset(self::$_cache[$cacheKey])) {
- $files = $this->dirSearch->collectFiles(ComponentRegistrar::MODULE, "/etc/{$fileNamePattern}");
- $files = array_filter(
- $files,
- function ($file) use ($excludedFileNames) {
- return !in_array(basename($file), $excludedFileNames);
- }
- );
- self::$_cache[$cacheKey] = $files;
- }
- if ($asDataSet) {
- return self::composeDataSets(self::$_cache[$cacheKey]);
- }
- return self::$_cache[$cacheKey];
- }
- // @codingStandardsIgnoreEnd
- /**
- * Returns list of XML related files, used by Magento application
- *
- * @param string $fileNamePattern
- * @param array $excludedFileNames
- * @param bool $asDataSet
- * @return array
- */
- public function getXmlCatalogFiles(
- $fileNamePattern = '*.xsd',
- $excludedFileNames = [],
- $asDataSet = true
- ) {
- $cacheKey = __METHOD__ . '|' . $this->serializer->serialize([$fileNamePattern, $excludedFileNames, $asDataSet]);
- if (!isset(self::$_cache[$cacheKey])) {
- $files = $this->getFilesSubset(
- $this->componentRegistrar->getPaths(ComponentRegistrar::MODULE),
- $fileNamePattern,
- []
- );
- $libraryExcludeDirs = [];
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::LIBRARY) as $libraryDir) {
- $libraryExcludeDirs[] = str_replace('\\', '/', '#' . $libraryDir . '/Test#');
- $libraryExcludeDirs[] = str_replace('\\', '/', '#' . $libraryDir) . '/[\\w]+/Test#';
- }
- $files = array_merge(
- $files,
- $this->getFilesSubset(
- $this->componentRegistrar->getPaths(ComponentRegistrar::LIBRARY),
- $fileNamePattern,
- $libraryExcludeDirs
- )
- );
- $files = array_merge(
- $files,
- $this->getFilesSubset(
- $this->componentRegistrar->getPaths(ComponentRegistrar::THEME),
- $fileNamePattern,
- []
- )
- );
- $files = array_merge(
- $files,
- $this->getFilesSubset(
- $this->componentRegistrar->getPaths(ComponentRegistrar::SETUP),
- $fileNamePattern,
- []
- )
- );
- $files = array_filter(
- $files,
- function ($file) use ($excludedFileNames) {
- return !in_array(basename($file), $excludedFileNames);
- }
- );
- self::$_cache[$cacheKey] = $files;
- }
- if ($asDataSet) {
- return self::composeDataSets(self::$_cache[$cacheKey]);
- }
- return self::$_cache[$cacheKey];
- }
- /**
- * Returns a list of configuration files found under theme directories.
- *
- * @param string $fileNamePattern
- * @param bool $asDataSet
- * @return array
- */
- public function getLayoutConfigFiles($fileNamePattern = '*.xml', $asDataSet = true)
- {
- $cacheKey = __METHOD__ . '|' . implode('|', [$fileNamePattern, $asDataSet]);
- if (!isset(self::$_cache[$cacheKey])) {
- self::$_cache[$cacheKey] = $this->dirSearch->collectFiles(
- ComponentRegistrar::THEME,
- "/etc/{$fileNamePattern}"
- );
- }
- if ($asDataSet) {
- return self::composeDataSets(self::$_cache[$cacheKey]);
- }
- return self::$_cache[$cacheKey];
- }
- /**
- * Returns list of page configuration and generic layout files, used by Magento application modules
- *
- * An incoming array can contain the following items
- * array (
- * 'namespace' => 'namespace_name',
- * 'module' => 'module_name',
- * 'area' => 'area_name',
- * 'theme' => 'theme_name',
- * 'include_code' => true|false,
- * 'include_design' => true|false,
- * 'with_metainfo' => true|false,
- * )
- *
- * @param array $incomingParams
- * @param bool $asDataSet
- * @return array
- */
- public function getLayoutFiles($incomingParams = [], $asDataSet = true)
- {
- return $this->getLayoutXmlFiles('layout', $incomingParams, $asDataSet);
- }
- /**
- * Returns list of page layout files, used by Magento application modules
- *
- * An incoming array can contain the following items
- * array (
- * 'namespace' => 'namespace_name',
- * 'module' => 'module_name',
- * 'area' => 'area_name',
- * 'theme' => 'theme_name',
- * 'include_code' => true|false,
- * 'include_design' => true|false,
- * 'with_metainfo' => true|false,
- * )
- *
- * @param array $incomingParams
- * @param bool $asDataSet
- * @return array
- */
- public function getPageLayoutFiles($incomingParams = [], $asDataSet = true)
- {
- return $this->getLayoutXmlFiles('page_layout', $incomingParams, $asDataSet);
- }
- /**
- * Returns list of UI Component files, used by Magento application
- *
- * An incoming array can contain the following items
- * array (
- * 'namespace' => 'namespace_name',
- * 'module' => 'module_name',
- * 'area' => 'area_name',
- * 'theme' => 'theme_name',
- * 'include_code' => true|false,
- * 'include_design' => true|false,
- * 'with_metainfo' => true|false,
- * )
- *
- * @param array $incomingParams
- * @param bool $asDataSet
- * @return array
- */
- public function getUiComponentXmlFiles($incomingParams = [], $asDataSet = true)
- {
- return $this->getLayoutXmlFiles('ui_component', $incomingParams, $asDataSet);
- }
- /**
- * @param string $location
- * @param array $incomingParams
- * @param bool $asDataSet
- * @return array
- */
- protected function getLayoutXmlFiles($location, $incomingParams = [], $asDataSet = true)
- {
- $params = [
- 'namespace' => '*',
- 'module' => '*',
- 'area' => '*',
- 'theme_path' => '*/*',
- 'include_code' => true,
- 'include_design' => true,
- 'with_metainfo' => false
- ];
- foreach (array_keys($params) as $key) {
- if (isset($incomingParams[$key])) {
- $params[$key] = $incomingParams[$key];
- }
- }
- $cacheKey = md5($location . '|' . implode('|', $params));
- if (!isset(self::$_cache[__METHOD__][$cacheKey])) {
- $files = [];
- if ($params['include_code']) {
- $files = array_merge($files, $this->collectModuleLayoutFiles($params, $location));
- }
- if ($params['include_design']) {
- $files = array_merge($files, $this->collectThemeLayoutFiles($params, $location));
- }
- self::$_cache[__METHOD__][$cacheKey] = $files;
- }
- if ($asDataSet) {
- return self::composeDataSets(self::$_cache[__METHOD__][$cacheKey]);
- }
- return self::$_cache[__METHOD__][$cacheKey];
- }
- /**
- * Collect layout files from modules
- *
- * @param array $params
- * @param string $location
- * @return array
- */
- private function collectModuleLayoutFiles(array $params, $location)
- {
- $files = [];
- $area = $params['area'];
- $requiredModuleName = $params['namespace'] . '_' . $params['module'];
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $moduleDir) {
- if ($requiredModuleName == '*_*' || $moduleName == $requiredModuleName) {
- $moduleFiles = [];
- $this->_accumulateFilesByPatterns(
- [$moduleDir . "/view/{$area}/{$location}"],
- '*.xml',
- $moduleFiles
- );
- if ($params['with_metainfo']) {
- foreach ($moduleFiles as $moduleFile) {
- $modulePath = str_replace(DIRECTORY_SEPARATOR, '/', preg_quote($moduleDir, '#'));
- $regex = '#^' . $modulePath . '/view/(?P<area>[a-z]+)/layout/(?P<path>.+)$#i';
- if (preg_match($regex, $moduleFile, $matches)) {
- $files[] = [
- $matches['area'],
- '',
- $moduleName,
- $matches['path'],
- $moduleFile,
- ];
- } else {
- throw new \UnexpectedValueException("Could not parse modular layout file '$moduleFile'");
- }
- }
- } else {
- $files = array_merge($files, $moduleFiles);
- }
- }
- }
- return $files;
- }
- /**
- * Collect layout files from themes
- *
- * @param array $params
- * @param string $location
- * @return array
- */
- private function collectThemeLayoutFiles(array $params, $location)
- {
- $files = [];
- $area = $params['area'];
- $requiredModuleName = $params['namespace'] . '_' . $params['module'];
- $themePath = $params['theme_path'];
- foreach ($this->themePackageList->getThemes() as $theme) {
- $currentThemePath = str_replace(DIRECTORY_SEPARATOR, '/', $theme->getPath());
- $currentThemeCode = $theme->getVendor() . '/' . $theme->getName();
- if (($area == '*' || $theme->getArea() === $area)
- && ($themePath == '*' || $themePath == '*/*' || $themePath == $currentThemeCode)
- ) {
- $themeFiles = [];
- $this->_accumulateFilesByPatterns(
- [$currentThemePath . "/{$requiredModuleName}/{$location}"],
- '*.xml',
- $themeFiles
- );
- if ($params['with_metainfo']) {
- $files = array_merge($this->parseThemeFiles($themeFiles, $currentThemePath, $theme));
- } else {
- $files = array_merge($files, $themeFiles);
- }
- }
- }
- return $files;
- }
- /**
- * @param array $themeFiles
- * @param string $currentThemePath
- * @param ThemePackage $theme
- * @return array
- */
- private function parseThemeFiles($themeFiles, $currentThemePath, $theme)
- {
- $files = [];
- $regex = '#^' . $currentThemePath
- . '/(?P<module>[a-z\d]+_[a-z\d]+)/layout/(override/((base/)|(theme/[a-z\d_]+/[a-z\d_]+/)))?'
- . '(?P<path>.+)$#i';
- foreach ($themeFiles as $themeFile) {
- if (preg_match($regex, $themeFile, $matches)) {
- $files[] = [
- $theme->getArea(),
- $theme->getVendor() . '/' . $theme->getName(),
- $matches['module'],
- $matches['path'],
- $themeFile,
- ];
- } else {
- throw new \UnexpectedValueException("Could not parse theme layout file '$themeFile'");
- }
- }
- return $files;
- }
- /**
- * Returns list of page_type files, used by Magento application modules
- *
- * An incoming array can contain the following items
- * array (
- * 'namespace' => 'namespace_name',
- * 'module' => 'module_name',
- * 'area' => 'area_name',
- * 'theme' => 'theme_name',
- * )
- *
- * @param array $incomingParams
- * @param bool $asDataSet
- * @return array
- */
- public function getPageTypeFiles($incomingParams = [], $asDataSet = true)
- {
- $params = ['namespace' => '*', 'module' => '*', 'area' => '*'];
- foreach (array_keys($params) as $key) {
- if (isset($incomingParams[$key])) {
- $params[$key] = $incomingParams[$key];
- }
- }
- $cacheKey = md5(implode('|', $params));
- if (!isset(self::$_cache[__METHOD__][$cacheKey])) {
- self::$_cache[__METHOD__][$cacheKey] = self::getFiles(
- $this->getEtcAreaPaths($params['namespace'], $params['module'], $params['area']),
- 'page_types.xml'
- );
- }
- if ($asDataSet) {
- return self::composeDataSets(self::$_cache[__METHOD__][$cacheKey]);
- }
- return self::$_cache[__METHOD__][$cacheKey];
- }
- /**
- * Get module etc paths for specified area
- *
- * @param string $namespace
- * @param string $module
- * @param string $area
- * @return array
- */
- private function getEtcAreaPaths($namespace, $module, $area)
- {
- $etcAreaPaths = [];
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $moduleDir) {
- $keyInfo = explode('_', $moduleName);
- if ($keyInfo[0] == $namespace || $namespace == '*') {
- if ($keyInfo[1] == $module || $module == '*') {
- $etcAreaPaths[] = $moduleDir . "/etc/{$area}";
- }
- }
- }
- return $etcAreaPaths;
- }
- /**
- * Returns list of Javascript files in Magento
- *
- * @param string $area
- * @param string $themePath
- * @param string $namespace
- * @param string $module
- * @return array
- */
- public function getJsFiles($area = '*', $themePath = '*/*', $namespace = '*', $module = '*')
- {
- $key = $area . $themePath . $namespace . $module . __METHOD__ . BP;
- if (isset(self::$_cache[$key])) {
- return self::$_cache[$key];
- }
- $moduleWebPaths = [];
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $moduleDir) {
- $keyInfo = explode('_', $moduleName);
- if ($keyInfo[0] == $namespace || $namespace == '*') {
- if ($keyInfo[1] == $module || $module == '*') {
- $moduleWebPaths[] = $moduleDir . "/view/{$area}/web";
- }
- }
- }
- $themePaths = $this->getThemePaths($area, $namespace . '_' . $module, '/web');
- $files = self::getFiles(
- array_merge(
- [
- BP . "/lib/web/{mage,varien}"
- ],
- $themePaths,
- $moduleWebPaths
- ),
- '*.js'
- );
- $result = self::composeDataSets($files);
- self::$_cache[$key] = $result;
- return $result;
- }
- /**
- * @param string $area
- * @param string $module
- * @param string $subFolder
- * @return array
- */
- private function getThemePaths($area, $module, $subFolder)
- {
- $themePaths = [];
- foreach ($this->themePackageList->getThemes() as $theme) {
- if ($area == '*' || $theme->getArea() === $area) {
- $themePaths[] = $theme->getPath() . $subFolder;
- $themePaths[] = $theme->getPath() . "/{$module}" . $subFolder;
- }
- }
- return $themePaths;
- }
- /**
- * Returns list of Static HTML files in Magento
- *
- * @param string $area
- * @param string $themePath
- * @param string $namespace
- * @param string $module
- * @return array
- */
- public function getStaticHtmlFiles($area = '*', $themePath = '*/*', $namespace = '*', $module = '*')
- {
- $key = $area . $themePath . $namespace . $module . __METHOD__;
- if (isset(self::$_cache[$key])) {
- return self::$_cache[$key];
- }
- $moduleTemplatePaths = [];
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $moduleDir) {
- $keyInfo = explode('_', $moduleName);
- if ($keyInfo[0] == $namespace || $namespace == '*') {
- if ($keyInfo[1] == $module || $module == '*') {
- $moduleTemplatePaths[] = $moduleDir . "/view/{$area}/web/template";
- $moduleTemplatePaths[] = $moduleDir . "/view/{$area}/web/templates";
- }
- }
- }
- $themePaths = $this->getThemePaths($area, $namespace . '_' . $module, '/web/template');
- $files = self::getFiles(
- array_merge(
- $themePaths,
- $moduleTemplatePaths
- ),
- '*.html'
- );
- $result = self::composeDataSets($files);
- self::$_cache[$key] = $result;
- return $result;
- }
- /**
- * Get list of static view files that are subject of Magento static view files pre-processing system
- *
- * @param string $filePattern
- * @return array
- */
- public function getStaticPreProcessingFiles($filePattern = '*')
- {
- $key = __METHOD__ . '|' . $filePattern;
- if (isset(self::$_cache[$key])) {
- return self::$_cache[$key];
- }
- $area = '*';
- $locale = '*';
- $result = [];
- $moduleWebPath = [];
- $moduleLocalePath = [];
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) {
- $moduleWebPath[] = $moduleDir . "/view/{$area}/web";
- $moduleLocalePath[] = $moduleDir . "/view/{$area}/web/i18n/{$locale}";
- }
- $this->_accumulateFilesByPatterns($moduleWebPath, $filePattern, $result, '_parseModuleStatic');
- $this->_accumulateFilesByPatterns($moduleLocalePath, $filePattern, $result, '_parseModuleLocaleStatic');
- $this->accumulateThemeStaticFiles($area, $locale, $filePattern, $result);
- self::$_cache[$key] = $result;
- return $result;
- }
- /**
- * Accumulate files from themes
- *
- * @param string $area
- * @param string $locale
- * @param string $filePattern
- * @param array $result
- * @return void
- */
- private function accumulateThemeStaticFiles($area, $locale, $filePattern, &$result)
- {
- foreach ($this->themePackageList->getThemes() as $themePackage) {
- $themeArea = $themePackage->getArea();
- if ($area == '*' || $area == $themeArea) {
- $files = [];
- $themePath = str_replace(DIRECTORY_SEPARATOR, '/', $themePackage->getPath());
- $paths = [
- $themePath . "/web",
- $themePath . "/*_*/web",
- $themePath . "/web/i18n/{$locale}",
- $themePath . "/*_*/web/i18n/{$locale}"
- ];
- $this->_accumulateFilesByPatterns($paths, $filePattern, $files);
- $regex = '#^' . $themePath .
- '/((?P<module>[a-z\d]+_[a-z\d]+)/)?web/(i18n/(?P<locale>[a-z_]+)/)?(?P<path>.+)$#i';
- foreach ($files as $file) {
- if (preg_match($regex, $file, $matches)) {
- $result[] = [
- $themeArea,
- $themePackage->getVendor() . '/' . $themePackage->getName(),
- $matches['locale'],
- $matches['module'],
- $matches['path'],
- $file,
- ];
- } else {
- throw new \UnexpectedValueException("Could not parse theme static file '$file'");
- }
- }
- if (!$files) {
- $result[] = [
- $themeArea,
- $themePackage->getVendor() . '/' . $themePackage->getName(),
- null,
- null,
- null,
- null
- ];
- }
- }
- }
- }
- /**
- * Get all files from static library directory
- *
- * @return array
- */
- public function getStaticLibraryFiles()
- {
- $result = [];
- $this->_accumulateFilesByPatterns([BP . "/lib/web"], '*', $result, '_parseLibStatic');
- return $result;
- }
- /**
- * Parse file path from the absolute path of static library
- *
- * @param string $file
- * @param string $path
- * @return string
- */
- protected function _parseLibStatic($file, $path)
- {
- preg_match('/^' . preg_quote("{$path}/lib/web/", '/') . '(.+)$/i', $file, $matches);
- return $matches[1];
- }
- /**
- * Search files by the specified patterns and accumulate them, applying a callback to each found row
- *
- * @param array $patterns
- * @param string $filePattern
- * @param array $result
- * @param bool $subroutine
- * @return void
- */
- protected function _accumulateFilesByPatterns(array $patterns, $filePattern, array &$result, $subroutine = false)
- {
- $path = str_replace(DIRECTORY_SEPARATOR, '/', BP);
- foreach (self::getFiles($patterns, $filePattern) as $file) {
- $file = str_replace(DIRECTORY_SEPARATOR, '/', $file);
- if ($subroutine) {
- $result[] = $this->$subroutine($file, $path);
- } else {
- $result[] = $file;
- }
- }
- }
- /**
- * Parse meta-info of a static file in module
- *
- * @param string $file
- * @return array
- */
- protected function _parseModuleStatic($file)
- {
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $modulePath) {
- if (preg_match(
- '/^' . preg_quote("{$modulePath}/", '/') . 'view\/([a-z]+)\/web\/(.+)$/i',
- $file,
- $matches
- ) === 1
- ) {
- list(, $area, $filePath) = $matches;
- return [$area, '', '', $moduleName, $filePath, $file];
- }
- }
- return [];
- }
- /**
- * Parse meta-info of a localized (translated) static file in module
- *
- * @param string $file
- * @return array
- */
- protected function _parseModuleLocaleStatic($file)
- {
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $modulePath) {
- $appCode = preg_quote("{$modulePath}/", '/');
- if (preg_match('/^' . $appCode . 'view\/([a-z]+)\/web\/i18n\/([a-z_]+)\/(.+)$/i', $file, $matches) === 1) {
- list(, $area, $locale, $filePath) = $matches;
- return [$area, '', $locale, $moduleName, $filePath, $file];
- }
- }
- return [];
- }
- /**
- * Returns list of Javascript files in Magento by certain area
- *
- * @param string $area
- * @return array
- */
- public function getJsFilesForArea($area)
- {
- $key = __METHOD__ . BP . $area;
- if (isset(self::$_cache[$key])) {
- return self::$_cache[$key];
- }
- $viewAreaPaths = [];
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) {
- $viewAreaPaths[] = $moduleDir . "/view/{$area}";
- }
- $themePaths = [];
- foreach ($this->themePackageList->getThemes() as $theme) {
- if ($area == '*' || $theme->getArea() === $area) {
- $themePaths[] = $theme->getPath();
- }
- }
- $paths = [
- BP . "/lib/web/varien"
- ];
- $paths = array_merge($paths, $viewAreaPaths, $themePaths);
- $files = self::getFiles($paths, '*.js');
- if ($area == 'adminhtml') {
- $adminhtmlPaths = [BP . "/lib/web/mage/{adminhtml,backend}"];
- $files = array_merge($files, self::getFiles($adminhtmlPaths, '*.js'));
- } else {
- $frontendPaths = [BP . "/lib/web/mage"];
- /* current structure of /lib/web/mage directory contains frontend javascript in the root,
- backend javascript in subdirectories. That's why script shouldn't go recursive throught subdirectories
- to get js files for frontend */
- $files = array_merge($files, self::getFiles($frontendPaths, '*.js', false));
- }
- self::$_cache[$key] = $files;
- return $files;
- }
- /**
- * Returns list of Phtml files in Magento app directory.
- *
- * @param bool $withMetaInfo
- * @param bool $asDataSet
- * @return array
- */
- public function getPhtmlFiles($withMetaInfo = false, $asDataSet = true)
- {
- $key = __METHOD__ . (int)$withMetaInfo;
- if (!isset(self::$_cache[$key])) {
- $result = [];
- $this->accumulateModuleTemplateFiles($withMetaInfo, $result);
- $this->accumulateThemeTemplateFiles($withMetaInfo, $result);
- self::$_cache[$key] = $result;
- }
- if ($asDataSet) {
- return self::composeDataSets(self::$_cache[$key]);
- }
- return self::$_cache[$key];
- }
- /**
- * Returns list of db_schema files, used by Magento application.
- *
- * @param string $fileNamePattern
- * @param array $excludedFileNames
- * @param bool $asDataSet
- * @return array
- * @codingStandardsIgnoreStart
- */
- public function getDbSchemaFiles(
- $fileNamePattern = 'db_schema.xml',
- $excludedFileNames = [],
- $asDataSet = true
- ) {
- $cacheKey = __METHOD__ . '|' . $this->serializer->serialize([$fileNamePattern, $excludedFileNames, $asDataSet]);
- if (!isset(self::$_cache[$cacheKey])) {
- $files = $this->dirSearch->collectFiles(ComponentRegistrar::MODULE, "/etc/{$fileNamePattern}");
- $files = array_filter(
- $files,
- function ($file) use ($excludedFileNames) {
- return !in_array(basename($file), $excludedFileNames);
- }
- );
- self::$_cache[$cacheKey] = $files;
- }
- if ($asDataSet) {
- return self::composeDataSets(self::$_cache[$cacheKey]);
- }
- return self::$_cache[$cacheKey];
- }
- /**
- * Collect templates from themes
- *
- * @param bool $withMetaInfo
- * @param array $result
- * @return void
- */
- private function accumulateThemeTemplateFiles($withMetaInfo, array &$result)
- {
- foreach ($this->themePackageList->getThemes() as $theme) {
- $files = [];
- $this->_accumulateFilesByPatterns(
- [$theme->getPath() . '/*_*/templates'],
- '*.phtml',
- $files
- );
- if ($withMetaInfo) {
- $regex = '#^' . str_replace(DIRECTORY_SEPARATOR, '/', $theme->getPath())
- . '/(?P<module>[a-z\d]+_[a-z\d]+)/templates/(?P<path>.+)$#i';
- foreach ($files as $file) {
- if (preg_match($regex, $file, $matches)) {
- $result[] = [
- $theme->getArea(),
- $theme->getVendor() . '/' . $theme->getName(),
- $matches['module'],
- $matches['path'],
- $file,
- ];
- } else {
- echo $regex . " - " . $file . "\n";
- throw new \UnexpectedValueException("Could not parse theme template file '$file'");
- }
- }
- } else {
- $result = array_merge($result, $files);
- }
- }
- }
- /**
- * Collect templates from modules
- *
- * @param bool $withMetaInfo
- * @param array $result
- * @return void
- */
- private function accumulateModuleTemplateFiles($withMetaInfo, array &$result)
- {
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $moduleDir) {
- $files = [];
- $this->_accumulateFilesByPatterns(
- [$moduleDir . "/view/*/templates"],
- '*.phtml',
- $files
- );
- if ($withMetaInfo) {
- $modulePath = str_replace(DIRECTORY_SEPARATOR, '/', preg_quote($moduleDir, '#'));
- $regex = '#^' . $modulePath . '/view/(?P<area>[a-z]+)/templates/(?P<path>.+)$#i';
- foreach ($files as $file) {
- if (preg_match($regex, $file, $matches)) {
- $result[] = [
- $matches['area'],
- '',
- $moduleName,
- $matches['path'],
- $file,
- ];
- } else {
- throw new \UnexpectedValueException("Could not parse module template file '$file'");
- }
- }
- } else {
- $result = array_merge($result, $files);
- }
- }
- }
- /**
- * Returns list of email template files
- *
- * @return array
- */
- public function getEmailTemplates()
- {
- $key = __METHOD__;
- if (isset(self::$_cache[$key])) {
- return self::$_cache[$key];
- }
- $moduleEmailPaths = [];
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) {
- $moduleEmailPaths[] = $moduleDir . "/view/email";
- }
- $files = self::getFiles($moduleEmailPaths, '*.html');
- $result = self::composeDataSets($files);
- self::$_cache[$key] = $result;
- return $result;
- }
- /**
- * Return list of all files. The list excludes tool-specific files
- * (e.g. Git, IDE) or temp files (e.g. in "var/").
- *
- * @return array
- */
- public function getAllFiles()
- {
- $key = __METHOD__ . BP;
- if (isset(self::$_cache[$key])) {
- return self::$_cache[$key];
- }
- $paths = array_merge(
- [BP . '/app', BP . '/dev', BP . '/lib', BP . '/pub'],
- $this->componentRegistrar->getPaths(ComponentRegistrar::LANGUAGE),
- $this->componentRegistrar->getPaths(ComponentRegistrar::THEME),
- $this->getPaths()
- );
- $subFiles = self::getFiles($paths, '*');
- $rootFiles = glob(BP . '/*', GLOB_NOSORT);
- $rootFiles = array_filter(
- $rootFiles,
- function ($file) {
- return is_file($file);
- }
- );
- $result = array_merge($rootFiles, $subFiles);
- $result = self::composeDataSets($result);
- self::$_cache[$key] = $result;
- return $result;
- }
- /**
- * Retrieve all files in folders and sub-folders that match pattern (glob syntax)
- *
- * @param array $dirPatterns
- * @param string $fileNamePattern
- * @param bool $recursive
- * @return array
- */
- public static function getFiles(array $dirPatterns, $fileNamePattern, $recursive = true)
- {
- $result = [];
- foreach ($dirPatterns as $oneDirPattern) {
- $oneDirPattern = str_replace('\\', '/', $oneDirPattern);
- $entriesInDir = Glob::glob("{$oneDirPattern}/{$fileNamePattern}", Glob::GLOB_NOSORT | Glob::GLOB_BRACE);
- $subDirs = Glob::glob("{$oneDirPattern}/*", Glob::GLOB_ONLYDIR | Glob::GLOB_NOSORT | Glob::GLOB_BRACE);
- $filesInDir = array_diff($entriesInDir, $subDirs);
- if ($recursive) {
- $filesInSubDir = self::getFiles($subDirs, $fileNamePattern);
- $result = array_merge($result, $filesInDir, $filesInSubDir);
- }
- }
- return $result;
- }
- /**
- * Look for DI config through the system
- *
- * @param bool $asDataSet
- * @return array
- */
- public function getDiConfigs($asDataSet = false)
- {
- $primaryConfigs = Glob::glob(BP . '/app/etc/{di.xml,*/di.xml}', Glob::GLOB_BRACE);
- $moduleConfigs = [];
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) {
- $moduleConfigs = array_merge(
- $moduleConfigs,
- Glob::glob($moduleDir . '/etc/{di,*/di}.xml', Glob::GLOB_BRACE)
- );
- }
- $configs = array_merge($primaryConfigs, $moduleConfigs);
- if ($asDataSet) {
- $output = [];
- foreach ($configs as $file) {
- $output[$file] = [$file];
- }
- return $output;
- }
- return $configs;
- }
- /**
- * Get module and library paths
- *
- * @return array
- */
- private function getPaths()
- {
- $directories = [];
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $fullModuleDir) {
- $directories[] = $fullModuleDir;
- }
- foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::LIBRARY) as $libraryDir) {
- $directories[] = $libraryDir;
- }
- return $directories;
- }
- /**
- * Check if specified class exists
- *
- * @param string $class
- * @param string &$path
- * @return bool
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- */
- public function classFileExists($class, &$path = '')
- {
- if ($class[0] == '\\') {
- $class = substr($class, 1);
- }
- $classParts = explode('\\', $class);
- $className = array_pop($classParts);
- $namespace = implode('\\', $classParts);
- $path = implode('/', explode('\\', $class)) . '.php';
- $directories = [
- '/dev/tools',
- '/dev/tests/api-functional/framework',
- '/dev/tests/setup-integration/framework',
- '/dev/tests/integration/framework',
- '/dev/tests/integration/framework/tests/unit/testsuite',
- '/dev/tests/integration/testsuite',
- '/dev/tests/integration/testsuite/Magento/Test/Integrity',
- '/dev/tests/static/framework',
- '/dev/tests/static/testsuite',
- '/dev/tests/functional/tests/app',
- '/dev/tests/functional/lib',
- '/dev/tests/functional/vendor/magento/mtf',
- '/setup/src'
- ];
- foreach ($directories as $key => $dir) {
- $directories[$key] = BP . $dir;
- }
- $directories = array_merge($directories, $this->getPaths());
- foreach ($directories as $dir) {
- $fullPath = $dir . '/' . $path;
- if ($this->classFileExistsCheckContent($fullPath, $namespace, $className)) {
- return true;
- }
- $classParts = explode('/', $path, 3);
- if (count($classParts) >= 3) {
- // Check if it's PSR-4 class with trimmed vendor and package name parts
- $trimmedFullPath = $dir . '/' . $classParts[2];
- if ($this->classFileExistsCheckContent($trimmedFullPath, $namespace, $className)) {
- return true;
- }
- }
- $classParts = explode('/', $path, 4);
- if (count($classParts) >= 4) {
- // Check if it's a library under framework directory
- $trimmedFullPath = $dir . '/' . $classParts[3];
- if ($this->classFileExistsCheckContent($trimmedFullPath, $namespace, $className)) {
- return true;
- }
- $trimmedFullPath = $dir . '/' . $classParts[2] . '/' . $classParts[3];
- if ($this->classFileExistsCheckContent($trimmedFullPath, $namespace, $className)) {
- return true;
- }
- }
- }
- return false;
- }
- /**
- * Helper function for classFileExists to check file content
- *
- * @param string $fullPath
- * @param string $namespace
- * @param string $className
- * @return bool
- */
- private function classFileExistsCheckContent($fullPath, $namespace, $className)
- {
- /**
- * Use realpath() instead of file_exists() to avoid incorrect work on Windows
- * because of case insensitivity of file names
- * Note that realpath() automatically changes directory separator to the OS-native
- * Since realpath won't work with symlinks we also check file_exists if realpath failed
- */
- if (realpath($fullPath) == str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $fullPath)
- || file_exists($fullPath)
- ) {
- $fileContent = file_get_contents($fullPath);
- if (strpos($fileContent, 'namespace ' . $namespace) !== false
- && (strpos($fileContent, 'class ' . $className) !== false
- || strpos($fileContent, 'interface ' . $className) !== false
- || strpos($fileContent, 'trait ' . $className) !== false)
- ) {
- return true;
- }
- }
- return false;
- }
- /**
- * Return list of declared namespaces
- *
- * @return array
- */
- public function getNamespaces()
- {
- $key = __METHOD__;
- if (isset(self::$_cache[$key])) {
- return self::$_cache[$key];
- }
- $result = [];
- foreach (array_keys($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE)) as $moduleName) {
- $namespace = explode('_', $moduleName)[0];
- if (!in_array($namespace, $result) && $namespace !== 'Zend') {
- $result[] = $namespace;
- }
- }
- self::$_cache[$key] = $result;
- return $result;
- }
- /**
- * @param string $namespace
- * @param string $module
- * @param string $file
- * @return string
- */
- public function getModuleFile($namespace, $module, $file)
- {
- return $this->componentRegistrar->getPath(ComponentRegistrar::MODULE, $namespace . '_' . $module) .
- '/' . $file;
- }
- /**
- * Returns array of PHP-files for specified module
- *
- * @param string $module
- * @param bool $asDataSet
- * @return array
- */
- public function getModulePhpFiles($module, $asDataSet = true)
- {
- $key = __METHOD__ . "/{$module}";
- if (!isset(self::$_cache[$key])) {
- $files = self::getFiles(
- [$this->componentRegistrar->getPath(ComponentRegistrar::MODULE, 'Magento_' . $module)],
- '*.php'
- );
- self::$_cache[$key] = $files;
- }
- if ($asDataSet) {
- return self::composeDataSets(self::$_cache[$key]);
- }
- return self::$_cache[$key];
- }
- /**
- * 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__ . '|' . implode('|', [$componentType, $asDataSet]);
- 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];
- }
- /**
- * Read all text files by specified glob pattern and combine them into an array of valid files/directories
- *
- * The Magento root path is prepended to all (non-empty) entries
- *
- * @param string $globPattern
- * @return array
- * @throws \Exception if any of the patterns don't return any result
- */
- public function readLists($globPattern)
- {
- $patterns = [];
- foreach (glob($globPattern) as $list) {
- $patterns = array_merge($patterns, file($list, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES));
- }
- // Expand glob patterns
- $result = [];
- $incorrectPatterns = [];
- foreach ($patterns as $pattern) {
- if (0 === strpos($pattern, '#')) {
- continue;
- }
- $patternParts = explode(' ', $pattern);
- if (count($patternParts) == 3) {
- list($componentType, $componentName, $pathPattern) = $patternParts;
- $files = $this->getPathByComponentPattern($componentType, $componentName, $pathPattern);
- } elseif (count($patternParts) == 1) {
- /**
- * Note that glob() for directories will be returned as is,
- * but passing directory is supported by the tools (phpcpd, phpmd, phpcs)
- */
- $files = Glob::glob(BP . '/' . $pattern, Glob::GLOB_BRACE);
- } else {
- throw new \UnexpectedValueException(
- "Incorrect pattern record '$pattern'. Supported formats: "
- . "'<componentType> <componentName> <glob_pattern>' or '<glob_pattern>'"
- );
- }
- if (empty($files)) {
- $incorrectPatterns[] = $pattern;
- }
- $result = array_merge($result, $files);
- }
- if (!empty($incorrectPatterns)) {
- throw new \Exception("The following patterns didn't return any result:\n" . join("\n", $incorrectPatterns));
- }
- return $result;
- }
- /**
- * Get paths by pattern for specified component component
- *
- * @param string $componentType
- * @param string $componentName
- * @param string $pathPattern
- * @return array
- */
- private function getPathByComponentPattern($componentType, $componentName, $pathPattern)
- {
- $files = [];
- if ($componentType == '*') {
- $componentTypes = [
- ComponentRegistrar::MODULE,
- ComponentRegistrar::LIBRARY,
- ComponentRegistrar::THEME,
- ComponentRegistrar::LANGUAGE,
- ];
- } else {
- $componentTypes = [$componentType];
- }
- foreach ($componentTypes as $type) {
- if ($componentName == '*') {
- $files = array_merge($files, $this->dirSearch->collectFiles($type, $pathPattern));
- } else {
- $componentDir = $this->componentRegistrar->getPath($type, $componentName);
- if (!empty($componentDir)) {
- $files = array_merge($files, Glob::glob($componentDir . '/' . $pathPattern, Glob::GLOB_BRACE));
- }
- }
- }
- return $files;
- }
- /**
- * Check module existence
- *
- * @param string $moduleName
- * @return bool
- */
- public function isModuleExists($moduleName)
- {
- $key = __METHOD__ . "/{$moduleName}";
- if (!isset(self::$_cache[$key])) {
- self::$_cache[$key] = file_exists(
- $this->componentRegistrar->getPath(ComponentRegistrar::MODULE, $moduleName)
- );
- }
- return self::$_cache[$key];
- }
- /**
- * Returns list of files in a given directory, minus files in specifically excluded directories.
- *
- * @param array $dirPatterns Directories to search in
- * @param string $fileNamePattern Pattern for filename
- * @param string|array $excludes Subdirectories to exlude, represented as regex
- * @return array Files in $dirPatterns but not in $excludes
- */
- protected function getFilesSubset(array $dirPatterns, $fileNamePattern, $excludes)
- {
- if (!is_array($excludes)) {
- $excludes = [$excludes];
- }
- $fileSet = self::getFiles($dirPatterns, $fileNamePattern);
- foreach ($excludes as $excludeRegex) {
- $fileSet = preg_grep($excludeRegex, $fileSet, PREG_GREP_INVERT);
- }
- return $fileSet;
- }
- /**
- * Get list of PHP files in setup application
- *
- * @param int $flags
- * @return array
- */
- private function getSetupPhpFiles($flags = null)
- {
- $files = [];
- $setupAppPath = BP . '/setup';
- if ($flags & self::INCLUDE_SETUP && file_exists($setupAppPath)) {
- $regexIterator = $this->regexIteratorFactory->create(
- $setupAppPath,
- '/.*php$/'
- );
- foreach ($regexIterator as $file) {
- $files[] = $file[0];
- }
- }
- return $files;
- }
- }
|