/** * Build Framework dependencies report * * @param string $outputPath * @return void */ protected function buildReport($outputPath) { $filePaths = $this->registrar->getPaths(ComponentRegistrar::MODULE); $filesForParse = Files::init()->getFiles($filePaths, '*'); $configFiles = Files::init()->getConfigFiles('module.xml', [], false); ServiceLocator::getFrameworkDependenciesReportBuilder()->build(['parse' => ['files_for_parse' => $filesForParse, 'config_files' => $configFiles, 'declared_namespaces' => Files::init()->getNamespaces()], 'write' => ['report_filename' => $outputPath]]); }
/** * Retrieve files * * @param ThemeInterface $theme * @param string $filePath * @return \Magento\Framework\View\File[] */ public function getFiles(ThemeInterface $theme, $filePath) { $namespace = $module = '*'; $themePath = $theme->getFullPath(); if (empty($themePath)) { return []; } $themeAbsolutePath = $this->componentRegistrar->getPath(ComponentRegistrar::THEME, $themePath); if (!$themeAbsolutePath) { return []; } $themeDir = $this->readDirFactory->create($themeAbsolutePath); $searchPattern = "{$namespace}_{$module}/{$this->subDir}{$filePath}"; $files = $themeDir->search($searchPattern); $result = []; $pattern = "#(?<moduleName>[^/]+)/{$this->subDir}" . $this->pathPatternHelper->translatePatternFromGlob($filePath) . "\$#i"; foreach ($files as $file) { $filename = $themeDir->getAbsolutePath($file); if (!preg_match($pattern, $filename, $matches)) { continue; } $result[] = $this->fileFactory->create($filename, $matches['moduleName']); } return $result; }
/** * Get directory where themes files are stored * * @param \Magento\Framework\View\Design\ThemeInterface $theme * @return string|null */ public function getThemeFilesPath(\Magento\Framework\View\Design\ThemeInterface $theme) { $path = null; if ($theme->getFullPath()) { $path = $this->componentRegistrar->getPath(ComponentRegistrar::THEME, $theme->getFullPath()); } return $path; }
/** * Propagate parameters necessary for modular rule basing on module_name parameter * * @param array $params * @return array * @throws \InvalidArgumentException */ public function getPatternDirs(array $params) { if (!array_key_exists('module_name', $params)) { throw new \InvalidArgumentException('Required parameter "module_name" is not specified.'); } $params['module_dir'] = $this->componentRegistrar->getPath(ComponentRegistrar::MODULE, $params['module_name']); return $this->rule->getPatternDirs($params); }
/** * Get all themes * * @return ThemePackage[] */ public function getThemes() { $themes = []; foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::THEME) as $key => $path) { $themes[$key] = $this->factory->create($key, $path); } return $themes; }
public function testGetPatternDirs() { $expectedResult = ['path1', 'path2']; $module = 'Some_Module'; $modulePath = '/module/path'; $this->componentRegistrar->expects($this->once())->method('getPath')->with(ComponentRegistrar::MODULE, $module)->will($this->returnValue($modulePath)); $this->rule->expects($this->once())->method('getPatternDirs')->with(['module_name' => $module, 'module_dir' => $modulePath])->will($this->returnValue($expectedResult)); $this->assertEquals($expectedResult, $this->model->getPatternDirs(['module_name' => $module])); }
public function testGetThemes() { $this->registrar->expects($this->once())->method('getPaths')->with(ComponentRegistrar::THEME)->willReturn(['theme1' => 'path1', 'theme2' => 'path2']); $themePackage = $this->getMock('\\Magento\\Framework\\View\\Design\\Theme\\ThemePackage', [], [], '', false); $this->factory->expects($this->exactly(2))->method('create')->withConsecutive(['theme1', 'path1'], ['theme2', 'path2'])->willReturn($themePackage); $actual = $this->object->getThemes(); $this->assertCount(2, $actual); foreach ($actual as $themePackage) { $this->assertSame($themePackage, $themePackage); } }
/** * Retrieve full path to a directory of certain type within a module * * @param string $moduleName Fully-qualified module name * @param string $type Type of module's directory to retrieve * @return string * @throws \InvalidArgumentException */ public function getDir($moduleName, $type = '') { $path = $this->componentRegistrar->getPath(ComponentRegistrar::MODULE, $moduleName); if ($type) { if (!in_array($type, [self::MODULE_ETC_DIR, self::MODULE_I18N_DIR, self::MODULE_VIEW_DIR, self::MODULE_CONTROLLER_DIR])) { throw new \InvalidArgumentException("Directory type '{$type}' is not recognized."); } $path .= '/' . $type; } return $path; }
public function testGetPatternDirs() { $parentTheme = $this->getMockForAbstractClass('Magento\\Framework\\View\\Design\\ThemeInterface'); $parentTheme->expects($this->any())->method('getFullPath')->will($this->returnValue('package/parent_theme')); $theme = $this->getMockForAbstractClass('Magento\\Framework\\View\\Design\\ThemeInterface'); $theme->expects($this->any())->method('getFullPath')->will($this->returnValue('package/current_theme')); $theme->expects($this->any())->method('getParentTheme')->will($this->returnValue($parentTheme)); $this->componentRegistrar->expects($this->any())->method('getPath')->will($this->returnValueMap([[ComponentRegistrar::THEME, 'package/parent_theme', '/path/to/parent/theme'], [ComponentRegistrar::THEME, 'package/current_theme', '/path/to/current/theme']])); $ruleDirsMap = [[['theme_dir' => '/path/to/current/theme'], ['package/current_theme/path/one', 'package/current_theme/path/two']], [['theme_dir' => '/path/to/parent/theme'], ['package/parent_theme/path/one', 'package/parent_theme/path/two']]]; $this->rule->expects($this->any())->method('getPatternDirs')->will($this->returnValueMap($ruleDirsMap)); $expectedResult = ['package/current_theme/path/one', 'package/current_theme/path/two', 'package/parent_theme/path/one', 'package/parent_theme/path/two']; $this->assertEquals($expectedResult, $this->model->getPatternDirs(['theme' => $theme])); }
/** * Returns module config data and a path to the module.xml file. * * Example of data returned by generator: * <code> * [ 'vendor/module/etc/module.xml', '<xml>contents</xml>' ] * </code> * * @return \Traversable * * @author Josh Di Fabio <*****@*****.**> */ private function getModuleConfigs() { $modulePaths = $this->moduleRegistry->getPaths(ComponentRegistrar::MODULE); foreach ($modulePaths as $modulePath) { $filePath = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, "{$modulePath}/etc/module.xml"); (yield [$filePath, $this->filesystemDriver->fileGetContents($filePath)]); } }
/** * Collect files in components * If $withContext is true, returns array of file objects with component context * * @param string $componentType * @param string $pattern * @param bool|false $withContext * @return array */ private function collect($componentType, $pattern, $withContext) { $files = []; foreach ($this->registrar->getPaths($componentType) as $componentName => $path) { $directoryRead = $this->readFactory->create($path); $foundFiles = $directoryRead->search($pattern); foreach ($foundFiles as $foundFile) { $foundFile = $directoryRead->getAbsolutePath($foundFile); if ($withContext) { $files[] = new ComponentFile($componentType, $componentName, $foundFile); } else { $files[] = $foundFile; } } } return $files; }
/** * Retrieve files * * @param ThemeInterface $theme * @param string $filePath * @return \Magento\Framework\View\File[] */ public function getFiles(ThemeInterface $theme, $filePath) { $list = $this->fileListFactory->create('Magento\\Framework\\Css\\PreProcessor\\File\\FileList\\Collator'); $files = $this->libraryDirectory->search($filePath); $list->add($this->createFiles($this->libraryDirectory, $theme, $files)); foreach ($theme->getInheritedThemes() as $currentTheme) { $themeFullPath = $currentTheme->getFullPath(); $path = $this->componentRegistrar->getPath(ComponentRegistrar::THEME, $themeFullPath); if (empty($path)) { continue; } $directoryRead = $this->readFactory->create($path); $foundFiles = $directoryRead->search("web/{$filePath}"); $list->replace($this->createFiles($directoryRead, $theme, $foundFiles)); } return $list->getAll(); }
/** * Propagate an underlying fallback rule to every theme in a hierarchy: parent, grandparent, etc. * * @param array $params * @return array * @throws \InvalidArgumentException */ public function getPatternDirs(array $params) { if (!array_key_exists('theme', $params) || !$params['theme'] instanceof ThemeInterface) { throw new \InvalidArgumentException('Parameter "theme" should be specified and should implement the theme interface.'); } $result = []; /** @var $theme ThemeInterface */ $theme = $params['theme']; unset($params['theme']); while ($theme) { if ($theme->getFullPath()) { $params['theme_dir'] = $this->componentRegistrar->getPath(ComponentRegistrar::THEME, $theme->getFullPath()); $result = array_merge($result, $this->rule->getPatternDirs($params)); } $theme = $theme->getParentTheme(); } return $result; }
/** * Retrieve component paths and configs from composer.json files * * @return \Traversable */ public function getComponentsInfo() { $components = [\Magento\Framework\Component\ComponentRegistrar::THEME, \Magento\Framework\Component\ComponentRegistrar::MODULE]; foreach ($components as $component) { $paths = $this->registrar->getPaths($component); foreach ($paths as $name => $path) { if (!strstr($name, 'Swissup')) { continue; } $filePath = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, "{$path}/composer.json"); try { $config = $this->filesystemDriver->fileGetContents($filePath); $config = $this->jsonDecoder->decode($config); $config['path'] = $path; (yield [$config['name'], $config]); } catch (\Exception $e) { // skip module } } } }
/** * @param array $files * @param string $filePath * @param string $pathPattern * * @dataProvider getFilesDataProvider */ public function testGetFiles($files, $filePath, $pathPattern) { $themePath = 'area/theme/path'; $theme = $this->getMockForAbstractClass('Magento\\Framework\\View\\Design\\ThemeInterface'); $theme->expects($this->once())->method('getFullPath')->willReturn($themePath); $handlePath = 'design/area/theme/path/%s/override/%s'; $returnKeys = []; foreach ($files as $file) { $returnKeys[] = sprintf($handlePath, $file['module'], $file['handle']); } $this->componentRegistrar->expects($this->once())->method('getPath')->with(ComponentRegistrar::THEME, $themePath)->will($this->returnValue('/full/theme/path')); $this->pathPatternHelperMock->expects($this->any())->method('translatePatternFromGlob')->with($filePath)->willReturn($pathPattern); $this->themeDirectory->expects($this->once())->method('search')->willReturn($returnKeys); $this->themeDirectory->expects($this->any())->method('getAbsolutePath')->willReturnArgument(0); $checkResult = []; foreach ($files as $key => $file) { $checkResult[$key] = new \Magento\Framework\View\File($file['handle'], $file['module']); $this->fileFactory->expects($this->at($key))->method('create')->with(sprintf($handlePath, $file['module'], $file['handle']), $file['module'])->willReturn($checkResult[$key]); } $this->assertSame($checkResult, $this->model->getFiles($theme, $filePath)); }
public function testCollectFilesWithContext() { $componentType = 'component_type'; $componentPaths = ['component1' => 'path1', 'component2' => 'path2']; $pattern = '*/file.xml'; $this->registrar->expects($this->once())->method('getPaths')->with($componentType)->willReturn($componentPaths); $this->readFactory->expects($this->exactly(2))->method('create')->willReturnMap([['path1', DriverPool::FILE, $this->dir], ['path2', DriverPool::FILE, $this->dir]]); $this->dir->method('search')->with($pattern)->willReturnOnConsecutiveCalls(['one/file.xml'], ['two/file.xml']); $actualFiles = $this->object->collectFilesWithContext($componentType, $pattern); $this->assertNotEmpty($actualFiles); /** @var \Magento\Framework\Component\ComponentFile $file */ foreach ($actualFiles as $file) { $this->assertInstanceOf('\\Magento\\Framework\\Component\\ComponentFile', $file); $this->assertSame($componentType, $file->getComponentType()); } $this->assertCount(2, $actualFiles); $this->assertSame('component1', $actualFiles[0]->getComponentName()); $this->assertSame('one/file.xml', $actualFiles[0]->getFullPath()); $this->assertSame('component2', $actualFiles[1]->getComponentName()); $this->assertSame('two/file.xml', $actualFiles[1]->getFullPath()); }
public function testGetFilesMultiple() { $dirPath = '/Magento_Customer/css/'; $searchPath = 'css/*.test'; $this->componentRegistrar->expects($this->once())->method('getPath')->with(ComponentRegistrar::THEME, $this->themePath)->will($this->returnValue(self::FULL_THEME_PATH)); $fileMock = $this->getMockBuilder('Magento\\Framework\\View\\File')->disableOriginalConstructor()->getMock(); $this->themeDirectoryMock->expects($this->any())->method('getAbsolutePath')->willReturnMap([['fileA.test', $dirPath . 'fileA.test'], ['fileB.tst', $dirPath . 'fileB.tst'], ['fileC.test', $dirPath . 'fileC.test']]); // Verifies correct files are searched for $this->themeDirectoryMock->expects($this->once())->method('search')->with($searchPath)->willReturn(['fileA.test', 'fileC.test']); // Verifies Magento_Customer was correctly produced from directory path $this->fileFactoryMock->expects($this->any())->method('create')->with($this->isType('string'), null, $this->themeMock)->willReturn($fileMock); // Only two files should be in array, which were returned from search $this->assertEquals([$fileMock, $fileMock], $this->themeFileCollector->getFiles($this->themeMock, $searchPath)); }
/** * Retrieve files * * @param ThemeInterface $theme * @param string $filePath * @return \Magento\Framework\View\File[] * @throws \Magento\Framework\Exception\LocalizedException */ public function getFiles(ThemeInterface $theme, $filePath) { $namespace = $module = '*'; $themePath = $theme->getFullPath(); if (empty($themePath)) { return []; } $themeAbsolutePath = $this->componentRegistrar->getPath(ComponentRegistrar::THEME, $themePath); if (!$themeAbsolutePath) { return []; } $themeDir = $this->readDirFactory->create($themeAbsolutePath); $files = $themeDir->search("{$namespace}_{$module}/{$this->subDir}*/*/{$filePath}"); if (empty($files)) { return []; } $themes = []; $currentTheme = $theme; while ($currentTheme = $currentTheme->getParentTheme()) { $themes[$currentTheme->getCode()] = $currentTheme; } $result = []; $pattern = "#/(?<module>[^/]+)/{$this->subDir}(?<themeVendor>[^/]+)/(?<themeName>[^/]+)/" . $this->pathPatternHelper->translatePatternFromGlob($filePath) . "\$#i"; foreach ($files as $file) { $filename = $themeDir->getAbsolutePath($file); if (!preg_match($pattern, $filename, $matches)) { continue; } $moduleFull = $matches['module']; $ancestorThemeCode = $matches['themeVendor'] . '/' . $matches['themeName']; if (!isset($themes[$ancestorThemeCode])) { throw new LocalizedException(new \Magento\Framework\Phrase("Trying to override modular view file '%1' for theme '%2', which is not ancestor of theme '%3'", [$filename, $ancestorThemeCode, $theme->getCode()])); } $result[] = $this->fileFactory->create($filename, $moduleFull, $themes[$ancestorThemeCode]); } return $result; }
public function testGetFilesWrongAncestor() { $themePath = 'area/theme_path'; $inputPath = '*.xml'; $filePath = 'design/area/theme_path/Module_One/override/theme/vendor/parent_theme/1.xml'; $expectedMessage = "Trying to override modular view file '{$filePath}' for theme 'vendor/parent_theme'" . ", which is not ancestor of theme 'vendor/theme_path'"; $this->setExpectedException('Magento\\Framework\\Exception\\LocalizedException', $expectedMessage); $theme = $this->getMockForAbstractClass('Magento\\Framework\\View\\Design\\ThemeInterface'); $theme->expects($this->once())->method('getFullPath')->willReturn($themePath); $theme->expects($this->once())->method('getParentTheme')->willReturn(null); $theme->expects($this->once())->method('getCode')->willReturn('vendor/theme_path'); $this->themeDirectory->expects($this->once())->method('search')->with('*_*/override/theme/*/*/*.xml')->willReturn([$filePath]); $this->pathPatternHelperMock->expects($this->any())->method('translatePatternFromGlob')->with($inputPath)->willReturn('[^/]*\\.xml'); $this->componentRegistrar->expects($this->once())->method('getPath')->with(ComponentRegistrar::THEME, $themePath)->will($this->returnValue('/full/theme/path')); $this->model->getFiles($theme, $inputPath); }
/** * * @dataProvider getFilesDataProvider * * @param $libraryFiles array Files in lib directory * @param $themeFiles array Files in theme * * * @return void */ public function testGetFiles($libraryFiles, $themeFiles) { $this->fileListMock->expects($this->any())->method('getAll')->will($this->returnValue(['returnedFile'])); $this->libraryDirectoryMock->expects($this->any())->method('search')->will($this->returnValue($libraryFiles)); $this->libraryDirectoryMock->expects($this->any())->method('getAbsolutePath')->will($this->returnCallback(function ($file) { return '/opt/Magento/lib/' . $file; })); $themePath = '/var/Magento/ATheme'; $subPath = '*'; $readerMock = $this->getMockBuilder('Magento\\Framework\\Filesystem\\Directory\\ReadInterface')->getMock(); $this->readFactoryMock->expects($this->once())->method('create')->will($this->returnValue($readerMock)); $this->componentRegistrarMock->expects($this->once())->method('getPath')->with(ComponentRegistrar::THEME, $themePath)->will($this->returnValue(['/path/to/theme'])); $readerMock->expects($this->once())->method('search')->will($this->returnValue($themeFiles)); $inheritedThemeMock = $this->getMockBuilder('\\Magento\\Framework\\View\\Design\\ThemeInterface')->getMock(); $inheritedThemeMock->expects($this->any())->method('getFullPath')->will($this->returnValue($themePath)); $this->themeMock->expects($this->any())->method('getInheritedThemes')->will($this->returnValue([$inheritedThemeMock])); $this->assertEquals(['returnedFile'], $this->library->getFiles($this->themeMock, $subPath)); }
/** * @expectedException \InvalidArgumentException * @expectedExceptionMessage Directory type 'unknown' is not recognized */ public function testGetDirModuleSubDirUnknown() { $this->moduleRegistryMock->expects($this->once())->method('getPath')->with(ComponentRegistrar::MODULE, 'Test_Module')->will($this->returnValue('/Test/Module')); $this->_model->getDir('Test_Module', 'unknown'); }
/** * @covers \Magento\Framework\View\Design\Theme\Customization\Path::getThemeFilesPath */ public function testGetThemeFilesPathNoPath() { $this->_theme->expects($this->any())->method('getFullPath')->will($this->returnValue(null)); $this->componentRegistrar->expects($this->never())->method('getPath'); $this->assertNull($this->_model->getCustomizationPath($this->_theme)); }