/vendor/magento/framework/View/Asset/Source.php

https://gitlab.com/yousafsyed/easternglamor · PHP · 258 lines · 132 code · 22 blank · 104 comment · 9 complexity · 1d4a6805292c8da5e36543a5786fab33 MD5 · raw file

  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\View\Asset;
  7. use Magento\Framework\App\Filesystem\DirectoryList;
  8. use Magento\Framework\View\Asset\PreProcessor\ChainFactoryInterface;
  9. use Magento\Framework\View\Design\FileResolution\Fallback\Resolver\Simple;
  10. /**
  11. * A service for preprocessing content of assets
  12. *
  13. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  14. */
  15. class Source
  16. {
  17. /**
  18. * @var \Magento\Framework\Filesystem
  19. */
  20. private $filesystem;
  21. /**
  22. * @var \Magento\Framework\Filesystem\Directory\ReadInterface
  23. */
  24. protected $rootDir;
  25. /**
  26. * @var \Magento\Framework\Filesystem\Directory\WriteInterface
  27. */
  28. protected $varDir;
  29. /**
  30. * @var \Magento\Framework\View\Asset\PreProcessor\Pool
  31. */
  32. private $preProcessorPool;
  33. /**
  34. * @var \Magento\Framework\View\Design\FileResolution\Fallback\StaticFile
  35. */
  36. protected $fallback;
  37. /**
  38. * @var \Magento\Framework\View\Design\Theme\ListInterface
  39. */
  40. private $themeList;
  41. /**
  42. * @var ChainFactoryInterface
  43. */
  44. private $chainFactory;
  45. /**
  46. * @param \Magento\Framework\Filesystem $filesystem
  47. * @param PreProcessor\Pool $preProcessorPool
  48. * @param \Magento\Framework\View\Design\FileResolution\Fallback\StaticFile $fallback
  49. * @param \Magento\Framework\View\Design\Theme\ListInterface $themeList
  50. * @param ChainFactoryInterface $chainFactory
  51. */
  52. public function __construct(
  53. \Magento\Framework\Filesystem $filesystem,
  54. PreProcessor\Pool $preProcessorPool,
  55. \Magento\Framework\View\Design\FileResolution\Fallback\StaticFile $fallback,
  56. \Magento\Framework\View\Design\Theme\ListInterface $themeList,
  57. ChainFactoryInterface $chainFactory
  58. ) {
  59. $this->filesystem = $filesystem;
  60. $this->rootDir = $filesystem->getDirectoryRead(DirectoryList::ROOT);
  61. $this->varDir = $filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
  62. $this->preProcessorPool = $preProcessorPool;
  63. $this->fallback = $fallback;
  64. $this->themeList = $themeList;
  65. $this->chainFactory = $chainFactory;
  66. }
  67. /**
  68. * Get absolute path to the asset file
  69. *
  70. * @param LocalInterface $asset
  71. * @return bool|string
  72. */
  73. public function getFile(LocalInterface $asset)
  74. {
  75. $result = $this->preProcess($asset);
  76. if (!$result) {
  77. return false;
  78. }
  79. list($dirCode, $path) = $result;
  80. return $this->filesystem->getDirectoryRead($dirCode)->getAbsolutePath($path);
  81. }
  82. /**
  83. * Get content of an asset
  84. *
  85. * @param LocalInterface $asset
  86. * @return bool|string
  87. */
  88. public function getContent(LocalInterface $asset)
  89. {
  90. $result = $this->preProcess($asset);
  91. if (!$result) {
  92. return false;
  93. }
  94. list($dirCode, $path) = $result;
  95. return $this->filesystem->getDirectoryRead($dirCode)->readFile($path);
  96. }
  97. /**
  98. * Perform necessary preprocessing and materialization when the specified asset is requested
  99. *
  100. * Returns an array of two elements:
  101. * - directory code where the file is supposed to be found
  102. * - relative path to the file
  103. *
  104. * returns false if source file was not found
  105. *
  106. * @param LocalInterface $asset
  107. * @return array|bool
  108. */
  109. private function preProcess(LocalInterface $asset)
  110. {
  111. $sourceFile = $this->findSourceFile($asset);
  112. $path = $this->rootDir->getRelativePath($sourceFile);
  113. $chain = $this->createChain($asset, $path);
  114. $this->preProcessorPool->process($chain);
  115. $chain->assertValid();
  116. $dirCode = DirectoryList::ROOT;
  117. if ($chain->isChanged()) {
  118. $dirCode = DirectoryList::VAR_DIR;
  119. $path = DirectoryList::TMP_MATERIALIZATION_DIR . '/source/' . $chain->getTargetAssetPath();
  120. $this->varDir->writeFile($path, $chain->getContent());
  121. }
  122. $result = [$dirCode, $path];
  123. return $result;
  124. }
  125. /**
  126. * @param LocalInterface $asset
  127. * @return bool|string
  128. */
  129. public function findSource(LocalInterface $asset)
  130. {
  131. return $this->findSourceFile($asset);
  132. }
  133. /**
  134. * Infer a content type from the specified path
  135. *
  136. * @param string $path
  137. * @return string
  138. */
  139. public function getContentType($path)
  140. {
  141. return strtolower(pathinfo($path, PATHINFO_EXTENSION));
  142. }
  143. /**
  144. * Search for asset file depending on its context type
  145. *
  146. * @param LocalInterface $asset
  147. * @return bool|string
  148. * @throws \LogicException
  149. */
  150. private function findSourceFile(LocalInterface $asset)
  151. {
  152. $context = $asset->getContext();
  153. if ($context instanceof \Magento\Framework\View\Asset\File\FallbackContext) {
  154. $result = $this->findFileThroughFallback($asset, $context);
  155. } elseif ($context instanceof \Magento\Framework\View\Asset\File\Context) {
  156. $result = $this->findFile($asset, $context);
  157. } else {
  158. $type = get_class($context);
  159. throw new \LogicException("Support for {$type} is not implemented.");
  160. }
  161. return $result;
  162. }
  163. /**
  164. * Find asset file via fallback mechanism
  165. *
  166. * @param LocalInterface $asset
  167. * @param \Magento\Framework\View\Asset\File\FallbackContext $context
  168. * @return bool|string
  169. */
  170. private function findFileThroughFallback(
  171. LocalInterface $asset,
  172. \Magento\Framework\View\Asset\File\FallbackContext $context
  173. ) {
  174. $themeModel = $this->themeList->getThemeByFullPath($context->getAreaCode() . '/' . $context->getThemePath());
  175. $sourceFile = $this->fallback->getFile(
  176. $context->getAreaCode(),
  177. $themeModel,
  178. $context->getLocale(),
  179. $asset->getFilePath(),
  180. $asset->getModule()
  181. );
  182. return $sourceFile;
  183. }
  184. /**
  185. * Find asset file by simply appending its path to the directory in context
  186. *
  187. * @param LocalInterface $asset
  188. * @param \Magento\Framework\View\Asset\File\Context $context
  189. * @return string
  190. */
  191. private function findFile(LocalInterface $asset, \Magento\Framework\View\Asset\File\Context $context)
  192. {
  193. $dir = $this->filesystem->getDirectoryRead($context->getBaseDirType());
  194. Simple::assertFilePathFormat($asset->getFilePath());
  195. return $dir->getAbsolutePath($asset->getPath());
  196. }
  197. /**
  198. * @param \Magento\Framework\View\Asset\LocalInterface $asset
  199. *
  200. * @return bool|string
  201. */
  202. public function findRelativeSourceFilePath(LocalInterface $asset)
  203. {
  204. $sourceFile = $this->findSourceFile($asset);
  205. if (!$sourceFile) {
  206. return false;
  207. }
  208. return $this->rootDir->getRelativePath($sourceFile);
  209. }
  210. /**
  211. * Creates a chain for pre-processing
  212. *
  213. * @param LocalInterface $asset
  214. * @param string|bool $path
  215. * @return PreProcessor\Chain
  216. */
  217. private function createChain(LocalInterface $asset, $path)
  218. {
  219. if ($path) {
  220. $origContent = $this->rootDir->readFile($path);
  221. $origContentType = $this->getContentType($path);
  222. } else {
  223. $origContent = '';
  224. $origContentType = $asset->getContentType();
  225. }
  226. $chain = $this->chainFactory->create(
  227. [
  228. 'asset' => $asset,
  229. 'origContent' => $origContent,
  230. 'origContentType' => $origContentType,
  231. 'origAssetPath' => $path
  232. ]
  233. );
  234. return $chain;
  235. }
  236. }