Minification.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\View\Asset;
  7. use Magento\Framework\App\Config\ScopeConfigInterface;
  8. use Magento\Framework\App\State;
  9. /**
  10. * Helper class for static files minification related processes.
  11. * @api
  12. * @since 100.0.2
  13. */
  14. class Minification
  15. {
  16. /**
  17. * XML path for asset minification configuration
  18. */
  19. const XML_PATH_MINIFICATION_ENABLED = 'dev/%s/minify_files';
  20. const XML_PATH_MINIFICATION_EXCLUDES = 'dev/%s/minify_exclude';
  21. /**
  22. * @var ScopeConfigInterface
  23. */
  24. private $scopeConfig;
  25. /**
  26. * @var State
  27. */
  28. private $appState;
  29. /**
  30. * @var string
  31. */
  32. private $scope;
  33. /**
  34. * @var array
  35. */
  36. private $configCache = [];
  37. /**
  38. * @param ScopeConfigInterface $scopeConfig
  39. * @param State $appState
  40. * @param string $scope
  41. */
  42. public function __construct(ScopeConfigInterface $scopeConfig, State $appState, $scope = 'store')
  43. {
  44. $this->scopeConfig = $scopeConfig;
  45. $this->appState = $appState;
  46. $this->scope = $scope;
  47. }
  48. /**
  49. * Check whether asset minification is on for specified content type
  50. *
  51. * @param string $contentType
  52. * @return bool
  53. */
  54. public function isEnabled($contentType)
  55. {
  56. if (!isset($this->configCache[self::XML_PATH_MINIFICATION_ENABLED][$contentType])) {
  57. $this->configCache[self::XML_PATH_MINIFICATION_ENABLED][$contentType] =
  58. $this->appState->getMode() != State::MODE_DEVELOPER &&
  59. $this->scopeConfig->isSetFlag(
  60. sprintf(self::XML_PATH_MINIFICATION_ENABLED, $contentType),
  61. $this->scope
  62. );
  63. }
  64. return $this->configCache[self::XML_PATH_MINIFICATION_ENABLED][$contentType];
  65. }
  66. /**
  67. * Add 'min' suffix if minification is enabled and $filename has no one.
  68. *
  69. * @param string $filename
  70. * @return string
  71. */
  72. public function addMinifiedSign($filename)
  73. {
  74. $extension = pathinfo($filename, PATHINFO_EXTENSION);
  75. if ($this->isEnabled($extension) &&
  76. !$this->isExcluded($filename) &&
  77. !$this->isMinifiedFilename($filename)
  78. ) {
  79. $filename = substr($filename, 0, -strlen($extension)) . 'min.' . $extension;
  80. }
  81. return $filename;
  82. }
  83. /**
  84. * Remove 'min' suffix if exists and minification is enabled
  85. *
  86. * @param string $filename
  87. * @return string
  88. */
  89. public function removeMinifiedSign($filename)
  90. {
  91. $extension = pathinfo($filename, PATHINFO_EXTENSION);
  92. if ($this->isEnabled($extension) &&
  93. !$this->isExcluded($filename) &&
  94. $this->isMinifiedFilename($filename)
  95. ) {
  96. $filename = substr($filename, 0, -strlen($extension) - 4) . $extension;
  97. }
  98. return $filename;
  99. }
  100. /**
  101. * Is Minified Filename
  102. *
  103. * @param string $filename
  104. * @return bool
  105. */
  106. public function isMinifiedFilename($filename)
  107. {
  108. return substr($filename, strrpos($filename, '.') - 4, 5) == '.min.';
  109. }
  110. /**
  111. * Is Excluded
  112. *
  113. * @param string $filename
  114. * @return boolean
  115. */
  116. public function isExcluded($filename)
  117. {
  118. foreach ($this->getExcludes(pathinfo($filename, PATHINFO_EXTENSION)) as $exclude) {
  119. if (preg_match('/' . str_replace('/', '\/', $exclude) . '/', $filename)) {
  120. return true;
  121. }
  122. }
  123. return false;
  124. }
  125. /**
  126. * Get Excludes
  127. *
  128. * @param string $contentType
  129. * @return string[]
  130. */
  131. public function getExcludes($contentType)
  132. {
  133. if (!isset($this->configCache[self::XML_PATH_MINIFICATION_EXCLUDES][$contentType])) {
  134. $this->configCache[self::XML_PATH_MINIFICATION_EXCLUDES][$contentType] = [];
  135. $key = sprintf(self::XML_PATH_MINIFICATION_EXCLUDES, $contentType);
  136. $excludeValues = $this->getMinificationExcludeValues($key);
  137. foreach ($excludeValues as $exclude) {
  138. if (trim($exclude) != '') {
  139. $this->configCache[self::XML_PATH_MINIFICATION_EXCLUDES][$contentType][] = trim($exclude);
  140. }
  141. }
  142. }
  143. return $this->configCache[self::XML_PATH_MINIFICATION_EXCLUDES][$contentType];
  144. }
  145. /**
  146. * Get minification exclude values from configuration
  147. *
  148. * @param string $key
  149. * @return string[]
  150. */
  151. private function getMinificationExcludeValues($key)
  152. {
  153. $configValues = $this->scopeConfig->getValue($key, $this->scope) ?? [];
  154. //value used to be a string separated by 'newline' separator so we need to convert it to array
  155. if (!is_array($configValues)) {
  156. $configValuesFromString = [];
  157. foreach (explode("\n", $configValues) as $exclude) {
  158. if (trim($exclude) != '') {
  159. $configValuesFromString[] = trim($exclude);
  160. }
  161. }
  162. $configValues = $configValuesFromString;
  163. }
  164. return array_values($configValues);
  165. }
  166. }