/** * Get file path by type * * @param string $type * @param \Magento\Framework\View\Design\ThemeInterface $theme * @return string * @throws \Magento\Framework\Exception */ protected function _getFilePathByType($type, $theme) { if (!isset($this->_fileNames[$type])) { throw new \Magento\Framework\Exception("Unknown control configuration type: \"{$type}\""); } return $this->assetRepo->createAsset($this->_fileNames[$type], ['area' => \Magento\Framework\View\DesignInterface::DEFAULT_AREA, 'themeModel' => $theme])->getSourceFile(); }
/** * Injecting less.js compiler * * @param array $resultGroups * * @return mixed */ private function renderLessJsScripts($resultGroups) { // less js have to be injected before any *.js in developer mode $lessJsConfigAsset = $this->assetRepo->createAsset('less/config.less.js'); $resultGroups['js'] .= sprintf('<script src="%s"></script>' . "\n", $lessJsConfigAsset->getUrl()); $lessJsAsset = $this->assetRepo->createAsset('less/less.min.js'); $resultGroups['js'] .= sprintf('<script src="%s"></script>' . "\n", $lessJsAsset->getUrl()); return $resultGroups; }
/** * Finds requested resource and provides it to the client * * @return \Magento\Framework\App\ResponseInterface * @throws \Exception */ public function launch() { $appMode = $this->state->getMode(); if ($appMode == \Magento\Framework\App\State::MODE_PRODUCTION) { $this->response->setHttpResponseCode(404); } else { try { $path = $this->request->get('resource'); $params = $this->parsePath($path); $this->state->setAreaCode($params['area']); $this->objectManager->configure($this->configLoader->load($params['area'])); $file = $params['file']; unset($params['file']); $asset = $this->assetRepo->createAsset($file, $params); $this->response->setFilePath($asset->getSourceFile()); $this->publisher->publish($asset); } catch (\Exception $e) { if ($appMode == \Magento\Framework\App\State::MODE_DEVELOPER) { throw $e; } $this->response->setHttpResponseCode(404); } } return $this->response; }
/** * @return File */ public function build() { $params = ['area' => $this->area, 'theme' => $this->theme, 'locale' => $this->locale, 'module' => $this->module]; $asset = $this->repository->createAsset($this->path, $params); unset($this->path, $this->module, $this->locale, $this->theme, $this->area); return $asset; }
/** * @param string $file * @param array $properties * @param string|null $name * @return $this */ public function addPageAsset($file, array $properties = [], $name = null) { $asset = $this->assetRepo->createAsset($file); $name = $name ?: $file; $this->pageAssets->add($name, $asset, $properties); return $this; }
/** * {@inheritdoc} * @throws \InvalidArgumentException */ protected function execute(InputInterface $input, OutputInterface $output) { $area = $input->getOption(self::AREA_OPTION); $locale = $input->getOption(self::LOCALE_OPTION); $theme = $input->getOption(self::THEME_OPTION); $type = $input->getOption(self::TYPE_ARGUMENT); $files = $input->getArgument(self::FILE_ARGUMENT); if (!$this->validator->isValid($locale)) { throw new \InvalidArgumentException($locale . ' argument has invalid value, please run info:language:list for list of available locales'); } if (!preg_match('#^[\\w\\-]+\\/[\\w\\-]+$#', $theme)) { throw new \InvalidArgumentException('Value "' . $theme . '" of the option "' . self::THEME_OPTION . '" has invalid format. The format should be "Vendor/theme".'); } $message = sprintf('<info>Processed Area: %s, Locale: %s, Theme: %s, File type: %s.</info>', $area, $locale, $theme, $type); $output->writeln($message); foreach ($files as $file) { $fileInfo = pathinfo($file); $asset = $this->assetRepository->createAsset($fileInfo['dirname'] . DIRECTORY_SEPARATOR . $fileInfo['basename'] . '.' . $type, ['area' => $area, 'theme' => $theme, 'locale' => $locale]); try { $this->assetPublisher->publish($asset); } catch (\Magento\Framework\View\Asset\File\NotFoundException $e) { throw new \InvalidArgumentException('Verify entered values of the argument and options. ' . $e->getMessage()); } $output->writeln('<comment>-> ' . $asset->getFilePath() . '</comment>'); } $output->writeln('<info>Successfully processed.</info>'); }
/** * Deploy a static view file * * @param string $filePath * @param string $area * @param string $themePath * @param string $locale * @param string $module * @return void */ private function deployFile($filePath, $area, $themePath, $locale, $module) { $requestedPath = $filePath; if (substr($filePath, -5) == '.less') { $requestedPath = preg_replace('/.less$/', '.css', $filePath); } $logMessage = "Processing file '{$filePath}' for area '{$area}', theme '{$themePath}', locale '{$locale}'"; if ($module) { $logMessage .= ", module '{$module}'"; } $this->logger->logDebug($logMessage); try { $asset = $this->assetRepo->createAsset($requestedPath, ['area' => $area, 'theme' => $themePath, 'locale' => $locale, 'module' => $module]); $asset = $this->minifyService->getAssets([$asset], true)[0]; $this->logger->logDebug("\tDeploying the file to '{$asset->getPath()}'", '.'); if ($this->isDryRun) { $asset->getContent(); } else { $this->assetPublisher->publish($asset); $this->bundleManager->addAsset($asset); } $this->count++; } catch (\Magento\Framework\View\Asset\File\NotFoundException $e) { // File was not found by Fallback (possibly because it's wrong context for it) - there is nothing to publish $this->logger->logDebug("\tNotice: Could not find file '{$filePath}'. This file may not be relevant for the theme or area."); } catch (\Less_Exception_Compiler $e) { $this->logger->logDebug("\tNotice: Could not parse LESS file '{$filePath}'. " . "This may indicate that the file is incomplete, but this is acceptable. " . "The file '{$filePath}' will be combined with another LESS file."); } catch (\Exception $e) { $this->logger->logError($e->getMessage() . " ({$logMessage})"); $this->logger->logDebug((string) $e); $this->errorCount++; } }
/** * {@inheritdoc} * @throws \InvalidArgumentException */ protected function execute(InputInterface $input, OutputInterface $output) { $locale = $input->getOption(self::LOCALE_OPTION); if (!$this->validator->isValid($locale)) { throw new \InvalidArgumentException($locale . ' argument has invalid value, please run info:language:list for list of available locales'); } $area = $input->getOption(self::AREA_OPTION); $theme = $input->getOption(self::THEME_OPTION); $type = $input->getArgument(self::TYPE_ARGUMENT); $this->state->setAreaCode($area); $this->objectManager->configure($this->configLoader->load($area)); $sourceFileGenerator = $this->sourceFileGeneratorPool->create($type); foreach ($input->getArgument(self::FILE_ARGUMENT) as $file) { $file .= '.' . $type; $output->writeln("<info>Gathering {$file} sources.</info>"); $asset = $this->assetRepo->createAsset($file, ['area' => $area, 'theme' => $theme, 'locale' => $locale]); $rootDir = $this->filesystem->getDirectoryWrite(DirectoryList::ROOT); $sourceFile = $this->assetSource->findSource($asset); $relativePath = $rootDir->getRelativePath($sourceFile); $content = $rootDir->readFile($relativePath); $chain = $this->chainFactory->create(['asset' => $asset, 'origContent' => $content, 'origContentType' => $asset->getContentType(), 'origAssetPath' => $relativePath]); $processedCoreFile = $sourceFileGenerator->generateFileTree($chain); $targetDir = $this->filesystem->getDirectoryWrite(DirectoryList::STATIC_VIEW); $source = $rootDir->getRelativePath($processedCoreFile); $destination = $asset->getPath(); $rootDir->copyFile($source, $destination, $targetDir); $output->writeln("<info>Successfully processed dynamic stylesheet into CSS</info>"); } }
/** * @return void */ public function testCreateAsset() { $this->themeProvider->expects($this->any())->method('getThemeByFullPath')->willReturnArgument(0); $fallbackContextMock = $this->getMockBuilder('Magento\\Framework\\View\\Asset\\File\\FallbackContex')->disableOriginalConstructor()->getMock(); $this->fallbackFactoryMock->expects($this->once())->method('create')->with(['baseUrl' => '', 'areaType' => '', 'themePath' => 'Default', 'localeCode' => '', 'isSecure' => ''])->willReturn($fallbackContextMock); $assetMock = $this->getMockBuilder('Magento\\Framework\\View\\Asset\\File')->disableOriginalConstructor()->getMock(); $this->fileFactoryMock->expects($this->once())->method('create')->with(['source' => $this->sourceMock, 'context' => $fallbackContextMock, 'filePath' => 'test/file.js', 'module' => 'Test', 'contentType' => ''])->willReturn($assetMock); $this->assertEquals($assetMock, $this->repository->createAsset('test/file.js', ['module' => 'Test', 'theme' => 'Default'])); }
public function testGetStaticViewFileContext() { $this->mockDesign(); $context = $this->object->getStaticViewFileContext(); $this->assertInstanceOf('\\Magento\\Framework\\View\\Asset\\ContextInterface', $context); $this->assertSame($context, $this->object->getStaticViewFileContext()); // to ensure in-memory caching $asset = $this->object->createAsset('test/file.js'); $this->assertSame($context, $asset->getContext()); // and once again to ensure in-memory caching for real }
/** * Finds requested resource and provides it to the client * * @return \Magento\Framework\App\ResponseInterface * @throws \Exception */ public function launch() { // disabling profiling when retrieving static resource \Magento\Framework\Profiler::reset(); $appMode = $this->state->getMode(); if ($appMode == \Magento\Framework\App\State::MODE_PRODUCTION) { $this->response->setHttpResponseCode(404); } else { $path = $this->request->get('resource'); $params = $this->parsePath($path); $this->state->setAreaCode($params['area']); $this->objectManager->configure($this->configLoader->load($params['area'])); $file = $params['file']; unset($params['file']); $asset = $this->assetRepo->createAsset($file, $params); $this->response->setFilePath($asset->getSourceFile()); $this->publisher->publish($asset); } return $this->response; }
/** * Get CSS files of a given theme * * Returns an associative array of local assets with FileId used as keys: * array('Magento_Catalog::widgets.css' => \Magento\Framework\View\Asset\LocalInterface) * The array will be sorted by keys * * @param \Magento\Framework\View\Design\ThemeInterface $theme * @return \Magento\Framework\View\Asset\LocalInterface[] */ public function getCssAssets($theme) { /** @var $layoutProcessor \Magento\Framework\View\Layout\ProcessorInterface */ $layoutProcessor = $this->_layoutProcessorFactory->create(['theme' => $theme]); $layoutElement = $layoutProcessor->getFileLayoutUpdatesXml(); /** * XPath selector to get CSS files from layout added for HEAD block directly */ $xpathSelectorBlocks = '//block[@class="Magento\\Theme\\Block\\Html\\Head"]' . '/block[@class="Magento\\Theme\\Block\\Html\\Head\\Css"]/arguments/argument[@name="file"]'; /** * XPath selector to get CSS files from layout added for HEAD block using reference */ $xpathSelectorRefs = '//referenceBlock[@name="head"]' . '/block[@class="Magento\\Theme\\Block\\Html\\Head\\Css"]/arguments/argument[@name="file"]'; $elements = array_merge($layoutElement->xpath($xpathSelectorBlocks) ?: [], $layoutElement->xpath($xpathSelectorRefs) ?: []); $params = ['area' => $theme->getArea(), 'themeModel' => $theme]; $result = []; foreach ($elements as $fileId) { $fileId = (string) $fileId; $result[$fileId] = $this->_assetRepo->createAsset($fileId, $params); } ksort($result); return $result; }
/** * Load CSS file from materialized static view directory * * @param [] $files * @return string * @throws \Magento\Framework\Exception\MailException */ public function getCssFilesContent(array $files) { // Remove duplicate files $files = array_unique($files); $designParams = $this->getDesignParams(); if (!count($designParams)) { throw new \Magento\Framework\Exception\MailException(__('Design params must be set before calling this method')); } $css = ''; foreach ($files as $file) { $asset = $this->_assetRepo->createAsset($file, $designParams); $css .= $asset->getContent(); } return $css; }
/** * Get image URL of WYSIWYG placeholder image * * @param string $type * @return string */ public function getPlaceholderImageUrl($type) { $placeholder = false; $widget = $this->getWidgetByClassType($type); if (is_array($widget) && isset($widget['placeholder_image'])) { $placeholder = (string) $widget['placeholder_image']; } if ($placeholder) { $asset = $this->assetRepo->createAsset($placeholder); $placeholder = $this->assetSource->getFile($asset); if ($placeholder) { return $asset->getUrl(); } } return $this->assetRepo->getUrl('Magento_Widget::placeholder.gif'); }
/** * Deploy a static view file * * @param string $filePath * @param string $area * @param string $themePath * @param string $locale * @param string $module * @return void * @SuppressWarnings(PHPMD.NPathComplexity) */ private function deployFile($filePath, $area, $themePath, $locale, $module) { $requestedPath = $filePath; if (substr($filePath, -5) == '.less') { $requestedPath = preg_replace('/.less$/', '.css', $filePath); } $logMessage = "Processing file '$filePath' for area '$area', theme '$themePath', locale '$locale'"; if ($module) { $logMessage .= ", module '$module'"; } if ($this->output->isVeryVerbose()) { $this->output->writeln($logMessage); } try { $asset = $this->assetRepo->createAsset( $requestedPath, ['area' => $area, 'theme' => $themePath, 'locale' => $locale, 'module' => $module] ); $asset = $this->minifyService->getAssets([$asset], true)[0]; if ($this->output->isVeryVerbose()) { $this->output->writeln("\tDeploying the file to '{$asset->getPath()}'"); } else { $this->output->write('.'); } if ($this->isDryRun) { $asset->getContent(); } else { $this->assetPublisher->publish($asset); $this->bundleManager->addAsset($asset); } $this->count++; } catch (\Less_Exception_Compiler $e) { $this->verboseLog( "\tNotice: Could not parse LESS file '$filePath'. " . "This may indicate that the file is incomplete, but this is acceptable. " . "The file '$filePath' will be combined with another LESS file." ); $this->verboseLog("\tCompiler error: " . $e->getMessage()); } catch (\Exception $e) { $this->output->writeln($e->getMessage() . " ($logMessage)"); $this->verboseLog($e->getTraceAsString()); $this->errorCount++; } }
/** * Deploy a static view file * * @param string $filePath * @param string $area * @param string $themePath * @param string $locale * @param string $module * @param string|null $fullPath * @return string * @throws \InvalidArgumentException * @throws LocalizedException * * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ private function deployFile($filePath, $area, $themePath, $locale, $module, $fullPath = null) { $compiledFile = ''; $extension = pathinfo($filePath, PATHINFO_EXTENSION); foreach ($this->alternativeSources as $name => $alternative) { if (in_array($extension, $alternative->getAlternativesExtensionsNames(), true) && strpos(basename($filePath), '_') !== 0) { $compiledFile = substr($filePath, 0, strlen($filePath) - strlen($extension) - 1); $compiledFile = $compiledFile . '.' . $name; } } if ($this->output->isVeryVerbose()) { $logMessage = "Processing file '{$filePath}' for area '{$area}', theme '{$themePath}', locale '{$locale}'"; if ($module) { $logMessage .= ", module '{$module}'"; } $this->output->writeln($logMessage); } try { $asset = $this->assetRepo->createAsset($filePath, ['area' => $area, 'theme' => $themePath, 'locale' => $locale, 'module' => $module]); if ($this->output->isVeryVerbose()) { $this->output->writeln("\tDeploying the file to '{$asset->getPath()}'"); } else { $this->output->write('.'); } if ($this->getOption(Options::DRY_RUN)) { $asset->getContent(); } else { $this->assetPublisher->publish($asset); $this->bundleManager->addAsset($asset); } $this->count++; } catch (ContentProcessorException $exception) { $pathInfo = $fullPath ?: $filePath; $errorMessage = __('Compilation from source: ') . $pathInfo . PHP_EOL . $exception->getMessage(); $this->errorCount++; $this->output->write(PHP_EOL . PHP_EOL . $errorMessage . PHP_EOL, true); $this->getLogger()->critical($errorMessage); } catch (\Exception $exception) { $this->output->write('.'); $this->verboseLog($exception->getTraceAsString()); $this->errorCount++; } return $compiledFile; }
/** * @inheritdoc * @throws \InvalidArgumentException */ protected function execute(InputInterface $input, OutputInterface $output) { $area = $input->getOption(self::AREA_OPTION); $locale = $input->getOption(self::LOCALE_OPTION); $theme = $input->getOption(self::THEME_OPTION); $type = $input->getOption(self::TYPE_ARGUMENT); $files = $input->getArgument(self::FILE_ARGUMENT); if (!$this->validator->isValid($locale)) { throw new \InvalidArgumentException($locale . ' argument has invalid value, please run info:language:list for list of available locales'); } $message = sprintf('<info>Processed Area: %s, Locale: %s, Theme: %s, File type: %s.</info>', $area, $locale, $theme, $type); $output->writeln($message); foreach ($files as $file) { $fileInfo = pathinfo($file); $asset = $this->assetRepository->createAsset($fileInfo['dirname'] . DIRECTORY_SEPARATOR . $fileInfo['basename'] . '.' . $type, ['area' => $area, 'theme' => $theme, 'locale' => $locale]); $this->assetPublisher->publish($asset); $output->writeln('<comment>-> ' . $asset->getFilePath() . '</comment>'); } $output->writeln('<info>Successfully processed.</info>'); }
/** * Deploy a static view file * * @param string $filePath * @param string $area * @param string $themePath * @param string $locale * @param string $module * @return void */ private function deployFile($filePath, $area, $themePath, $locale, $module) { $requestedPath = $filePath; if (substr($filePath, -5) == '.less') { $requestedPath = preg_replace('/.less$/', '.css', $filePath); } $logModule = $module ? "<{$module}>" : (null === $module ? '<lib>' : '<theme>'); try { $asset = $this->assetRepo->createAsset($requestedPath, ['area' => $area, 'theme' => $themePath, 'locale' => $locale, 'module' => $module]); $this->logger->logDebug("{$logModule} {$filePath} -> {$asset->getPath()}"); if ($this->isDryRun) { $asset->getContent(); } else { $this->assetPublisher->publish($asset); } $this->count++; } catch (\Exception $e) { $this->logger->logError("{$logModule} {$filePath}"); $this->logger->logDebug((string) $e); $this->errorCount++; } }
/** * Launch application * * @return \Magento\Framework\App\ResponseInterface */ public function launch() { $this->state->setAreaCode($this->params->getArea()); $this->objectManager->configure($this->configLoader->load($this->params->getArea())); $sourceFileGenerator = $this->sourceFileGeneratorPool->create($this->params->getExt()); foreach ($this->params->getFiles() as $file) { $file .= '.' . $this->params->getExt(); $this->logger->logMessage("Gathering {$file} sources."); $asset = $this->assetRepo->createAsset($file, ['area' => $this->params->getArea(), 'theme' => $this->params->getTheme(), 'locale' => $this->params->getLocale()]); $sourceFile = $this->assetSource->findSource($asset); $content = \file_get_contents($sourceFile); $chain = $this->chainFactory->create(['asset' => $asset, 'origContent' => $content, 'origContentType' => $asset->getContentType()]); $processedCoreFile = $sourceFileGenerator->generateFileTree($chain); $targetDir = $this->filesystem->getDirectoryWrite(DirectoryList::STATIC_VIEW); $rootDir = $this->filesystem->getDirectoryWrite(DirectoryList::ROOT); $source = $rootDir->getRelativePath($processedCoreFile); $destination = $asset->getPath(); $rootDir->copyFile($source, $destination, $targetDir); $this->logger->logMessage("Done"); } $this->response->setCode(Response::SUCCESS); return $this->response; }
/** * Create a file asset that's subject of fallback system * * @param string $fileId * @param array $params * @return \Magento\Framework\View\Asset\File */ public function createAsset($fileId, array $params = []) { $params = array_merge(['_secure' => $this->request->isSecure()], $params); return $this->assetRepo->createAsset($fileId, $params); }
/** * Get path to preview image * * @param \Magento\Core\Model\Theme|ThemeInterface $theme * @return string */ public function getPreviewImagePath(ThemeInterface $theme) { return $theme->isPhysical() ? $this->assetRepo->createAsset($theme->getPreviewImage(), ['area' => $theme->getData('area'), 'themeModel' => $theme])->getSourceFile() : $this->mediaDirectory->getAbsolutePath(self::PREVIEW_DIRECTORY_PATH . '/' . $theme->getPreviewImage()); }
/** * Return path for skin images placeholder * * @return string */ public function getSkinImagePlaceholderPath() { $staticPath = $this->_storeManager->getStore()->getBaseStaticDir(); $placeholderPath = $this->_assetRepo->createAsset(self::WYSIWYG_SKIN_IMAGE_PLACEHOLDER_ID)->getPath(); return $staticPath . '/' . $placeholderPath; }
/** * Return resized product image information * * @return array */ public function getResizedImageInfo() { if ($this->_newFile === true) { $fileInfo = getimagesize($this->_assetRepo->createAsset("Magento_Catalog::images/product/placeholder/{$this->getDestinationSubdir()}.jpg")->getSourceFile()); } else { $fileInfo = getimagesize($this->_mediaDirectory->getAbsolutePath($this->_newFile)); } return $fileInfo; }