Manager.php 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\View\Asset\Bundle;
  7. use Magento\Framework\View\Asset;
  8. use Magento\Framework\Filesystem;
  9. use Magento\Framework\View\Asset\Bundle;
  10. use Magento\Framework\View\Asset\LocalInterface;
  11. use Magento\Framework\App\Filesystem\DirectoryList;
  12. /**
  13. * BundleService model
  14. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  15. * @deprecated 101.0.0
  16. * @see \Magento\Deploy\Service\Bundle
  17. */
  18. class Manager
  19. {
  20. const BUNDLE_JS_DIR = 'js/bundle';
  21. const BUNDLE_PATH = '/js/bundle/bundle';
  22. const ASSET_TYPE_JS = 'js';
  23. const ASSET_TYPE_HTML = 'html';
  24. /**
  25. * @var \Magento\Framework\Filesystem
  26. */
  27. protected $filesystem;
  28. /**
  29. * @var \Magento\Framework\View\Asset\Bundle
  30. */
  31. protected $bundle;
  32. /**
  33. * @var \Magento\Framework\View\Asset\Bundle\ConfigInterface
  34. */
  35. protected $bundleConfig;
  36. /**
  37. * @var \Magento\Framework\View\Asset\ConfigInterface
  38. */
  39. protected $assetConfig;
  40. /**
  41. * @var array
  42. */
  43. protected $excluded = [];
  44. /**
  45. * @var array
  46. */
  47. public static $availableTypes = [self::ASSET_TYPE_JS, self::ASSET_TYPE_HTML];
  48. /**
  49. * @var Asset\Minification
  50. */
  51. private $minification;
  52. /**
  53. * @param Filesystem $filesystem
  54. * @param Bundle $bundle
  55. * @param Bundle\ConfigInterface $bundleConfig
  56. * @param Asset\ConfigInterface $assetConfig
  57. * @param Asset\Minification $minification
  58. */
  59. public function __construct(
  60. Filesystem $filesystem,
  61. Bundle $bundle,
  62. Bundle\ConfigInterface $bundleConfig,
  63. Asset\ConfigInterface $assetConfig,
  64. Asset\Minification $minification
  65. ) {
  66. $this->filesystem = $filesystem;
  67. $this->assetConfig = $assetConfig;
  68. $this->bundleConfig = $bundleConfig;
  69. $this->bundle = $bundle;
  70. $this->minification = $minification;
  71. }
  72. /**
  73. * Check if asset in exclude list
  74. *
  75. * @param LocalInterface $asset
  76. * @return bool
  77. */
  78. protected function isExcluded(LocalInterface $asset)
  79. {
  80. $excludedFiles = array_merge(
  81. $this->bundleConfig->getConfig($asset->getContext())->getExcludedFiles(),
  82. $this->excluded
  83. );
  84. foreach ($excludedFiles as $file) {
  85. if ($this->isExcludedFile($file, $asset)) {
  86. return true;
  87. }
  88. }
  89. foreach ($this->bundleConfig->getConfig($asset->getContext())->getExcludedDir() as $directory) {
  90. if ($this->isExcludedDirectory($directory, $asset)) {
  91. return true;
  92. }
  93. }
  94. return false;
  95. }
  96. /**
  97. * Check if asset file in excluded directory
  98. *
  99. * @param string $directoryPath
  100. * @param LocalInterface $asset
  101. * @return bool
  102. */
  103. protected function isExcludedDirectory($directoryPath, $asset)
  104. {
  105. /** @var $asset LocalInterface */
  106. $assetDirectory = dirname($asset->getFilePath());
  107. $assetDirectory .= substr($assetDirectory, -1) != '/' ? '/' : '';
  108. $directoryPath .= substr($directoryPath, -1) != '/' ? '/' : '';
  109. /** @var $asset LocalInterface */
  110. $directoryPathInfo = $this->splitPath($directoryPath);
  111. if ($directoryPathInfo && $this->compareModules($directoryPathInfo, $asset)) {
  112. return strpos($assetDirectory, $directoryPathInfo['excludedPath']) === 0;
  113. }
  114. return false;
  115. }
  116. /**
  117. * Check if asset file is excluded
  118. *
  119. * @param string $filePath
  120. * @param LocalInterface $asset
  121. * @return bool
  122. */
  123. protected function isExcludedFile($filePath, $asset)
  124. {
  125. /** @var $asset LocalInterface */
  126. $filePathInfo = $this->splitPath($filePath);
  127. if ($filePathInfo && $this->compareModules($filePathInfo, $asset)) {
  128. return $asset->getFilePath() == $filePathInfo['excludedPath'];
  129. }
  130. return false;
  131. }
  132. /**
  133. * Compare asset module with excluded module
  134. *
  135. * @param array $filePathInfo
  136. * @param LocalInterface $asset
  137. * @return bool
  138. */
  139. protected function compareModules($filePathInfo, $asset)
  140. {
  141. /** @var $asset LocalInterface */
  142. if (($filePathInfo['excludedModule'] == 'Lib' && $asset->getModule() == '')
  143. || ($filePathInfo['excludedModule'] == $asset->getModule())
  144. ) {
  145. return true;
  146. }
  147. return false;
  148. }
  149. /**
  150. * Get excluded module and path from complex string
  151. *
  152. * @param string $path
  153. * @return array|bool
  154. */
  155. protected function splitPath($path)
  156. {
  157. if (strpos($path, '::') !== false) {
  158. list($excludedModule, $excludedPath) = explode('::', $path);
  159. return [
  160. 'excludedModule' => $excludedModule,
  161. 'excludedPath' => $excludedPath,
  162. ];
  163. }
  164. return false;
  165. }
  166. /**
  167. * Add asset to the bundle
  168. *
  169. * @param LocalInterface $asset
  170. * @return bool
  171. */
  172. public function addAsset(LocalInterface $asset)
  173. {
  174. if (!$this->isValidAsset($asset)) {
  175. return false;
  176. }
  177. $this->bundle->addAsset($asset);
  178. return true;
  179. }
  180. /**
  181. * @param LocalInterface $asset
  182. * @return bool
  183. */
  184. protected function isAssetMinification(LocalInterface $asset)
  185. {
  186. $sourceFile = $asset->getSourceFile();
  187. $extension = $asset->getContentType();
  188. if (in_array($sourceFile, $this->excluded)) {
  189. return false;
  190. }
  191. if (strpos($sourceFile, '.min.') === false) {
  192. $info = pathinfo($asset->getPath());
  193. $assetMinifiedPath = $info['dirname'] . '/' . $info['filename'] . '.min.' . $info['extension'];
  194. if ($this->filesystem->getDirectoryRead(DirectoryList::APP)->isExist($assetMinifiedPath)) {
  195. $this->excluded[] = $sourceFile;
  196. return false;
  197. }
  198. } else {
  199. $this->excluded[] = $this->filesystem->getDirectoryRead(DirectoryList::APP)
  200. ->getAbsolutePath(str_replace(".min.$extension", ".$extension", $asset->getPath()));
  201. }
  202. return true;
  203. }
  204. /**
  205. * @param LocalInterface $asset
  206. * @return bool
  207. */
  208. protected function isValidAsset(LocalInterface $asset)
  209. {
  210. if ($this->isValidType($asset)
  211. && $this->isAssetMinification($asset)
  212. && !$this->isExcluded($asset)
  213. ) {
  214. return true;
  215. }
  216. return false;
  217. }
  218. /**
  219. * @param LocalInterface $asset
  220. * @return bool
  221. */
  222. protected function isValidType(LocalInterface $asset)
  223. {
  224. $type = $asset->getContentType();
  225. if (!in_array($type, self::$availableTypes)) {
  226. return false;
  227. }
  228. return true;
  229. }
  230. /**
  231. * Flush bundle
  232. *
  233. * @return void
  234. */
  235. public function flush()
  236. {
  237. $this->bundle->flush();
  238. }
  239. }