/application/library/Thirdpart/Minify/lib/Minify/HTML/Helper.php

https://gitlab.com/flyhope/Hiblog · PHP · 226 lines · 146 code · 12 blank · 68 comment · 26 complexity · 1fe94e035ba3feba7ca67d347d3c9c53 MD5 · raw file

  1. <?php
  2. /**
  3. * Class Minify_HTML_Helper
  4. * @package Minify
  5. */
  6. /**
  7. * Helpers for writing Minfy URIs into HTML
  8. *
  9. * @package Minify
  10. * @author Stephen Clay <steve@mrclay.org>
  11. */
  12. class Minify_HTML_Helper {
  13. public $rewriteWorks = true;
  14. public $minAppUri = '/min';
  15. public $groupsConfigFile = '';
  16. /**
  17. * Get an HTML-escaped Minify URI for a group or set of files
  18. *
  19. * @param string|array $keyOrFiles a group key or array of filepaths/URIs
  20. * @param array $opts options:
  21. * 'farExpires' : (default true) append a modified timestamp for cache revving
  22. * 'debug' : (default false) append debug flag
  23. * 'charset' : (default 'UTF-8') for htmlspecialchars
  24. * 'minAppUri' : (default '/min') URI of min directory
  25. * 'rewriteWorks' : (default true) does mod_rewrite work in min app?
  26. * 'groupsConfigFile' : specify if different
  27. * @return string
  28. */
  29. public static function getUri($keyOrFiles, $opts = array())
  30. {
  31. $opts = array_merge(array( // default options
  32. 'farExpires' => true
  33. ,'debug' => false
  34. ,'charset' => 'UTF-8'
  35. ,'minAppUri' => '/min'
  36. ,'rewriteWorks' => true
  37. ,'groupsConfigFile' => ''
  38. ), $opts);
  39. $h = new self;
  40. $h->minAppUri = $opts['minAppUri'];
  41. $h->rewriteWorks = $opts['rewriteWorks'];
  42. $h->groupsConfigFile = $opts['groupsConfigFile'];
  43. if (is_array($keyOrFiles)) {
  44. $h->setFiles($keyOrFiles, $opts['farExpires']);
  45. } else {
  46. $h->setGroup($keyOrFiles, $opts['farExpires']);
  47. }
  48. $uri = $h->getRawUri($opts['farExpires'], $opts['debug']);
  49. return htmlspecialchars($uri, ENT_QUOTES, $opts['charset']);
  50. }
  51. /**
  52. * Get non-HTML-escaped URI to minify the specified files
  53. *
  54. * @param bool $farExpires
  55. * @param bool $debug
  56. * @return string
  57. */
  58. public function getRawUri($farExpires = true, $debug = false)
  59. {
  60. $path = rtrim($this->minAppUri, '/') . '/';
  61. if (! $this->rewriteWorks) {
  62. $path .= '?';
  63. }
  64. if (null === $this->_groupKey) {
  65. // @todo: implement shortest uri
  66. $path = self::_getShortestUri($this->_filePaths, $path);
  67. } else {
  68. $path .= "g=" . $this->_groupKey;
  69. }
  70. if ($debug) {
  71. $path .= "&debug";
  72. } elseif ($farExpires && $this->_lastModified) {
  73. $path .= "&" . $this->_lastModified;
  74. }
  75. return $path;
  76. }
  77. /**
  78. * Set the files that will comprise the URI we're building
  79. *
  80. * @param array $files
  81. * @param bool $checkLastModified
  82. */
  83. public function setFiles($files, $checkLastModified = true)
  84. {
  85. $this->_groupKey = null;
  86. if ($checkLastModified) {
  87. $this->_lastModified = self::getLastModified($files);
  88. }
  89. // normalize paths like in /min/f=<paths>
  90. foreach ($files as $k => $file) {
  91. if (0 === strpos($file, '//')) {
  92. $file = substr($file, 2);
  93. } elseif (0 === strpos($file, '/')
  94. || 1 === strpos($file, ':\\')) {
  95. $file = substr($file, strlen($_SERVER['DOCUMENT_ROOT']) + 1);
  96. }
  97. $file = strtr($file, '\\', '/');
  98. $files[$k] = $file;
  99. }
  100. $this->_filePaths = $files;
  101. }
  102. /**
  103. * Set the group of files that will comprise the URI we're building
  104. *
  105. * @param string $key
  106. * @param bool $checkLastModified
  107. */
  108. public function setGroup($key, $checkLastModified = true)
  109. {
  110. $this->_groupKey = $key;
  111. if ($checkLastModified) {
  112. if (! $this->groupsConfigFile) {
  113. $this->groupsConfigFile = dirname(dirname(dirname(__DIR__))) . '/groupsConfig.php';
  114. }
  115. if (is_file($this->groupsConfigFile)) {
  116. $gc = (require $this->groupsConfigFile);
  117. $keys = explode(',', $key);
  118. foreach ($keys as $key) {
  119. if (isset($gc[$key])) {
  120. $this->_lastModified = self::getLastModified($gc[$key], $this->_lastModified);
  121. }
  122. }
  123. }
  124. }
  125. }
  126. /**
  127. * Get the max(lastModified) of all files
  128. *
  129. * @param array|string $sources
  130. * @param int $lastModified
  131. * @return int
  132. */
  133. public static function getLastModified($sources, $lastModified = 0)
  134. {
  135. $max = $lastModified;
  136. /** @var Minify_Source $source */
  137. foreach ((array)$sources as $source) {
  138. if ($source instanceof Minify_Source) {
  139. $max = max($max, $source->getLastModified());
  140. } elseif (is_string($source)) {
  141. if (0 === strpos($source, '//')) {
  142. $source = $_SERVER['DOCUMENT_ROOT'] . substr($source, 1);
  143. }
  144. if (is_file($source)) {
  145. $max = max($max, filemtime($source));
  146. }
  147. }
  148. }
  149. return $max;
  150. }
  151. protected $_groupKey = null; // if present, URI will be like g=...
  152. protected $_filePaths = array();
  153. protected $_lastModified = null;
  154. /**
  155. * In a given array of strings, find the character they all have at
  156. * a particular index
  157. *
  158. * @param array $arr array of strings
  159. * @param int $pos index to check
  160. * @return mixed a common char or '' if any do not match
  161. */
  162. protected static function _getCommonCharAtPos($arr, $pos) {
  163. if (!isset($arr[0][$pos])) {
  164. return '';
  165. }
  166. $c = $arr[0][$pos];
  167. $l = count($arr);
  168. if ($l === 1) {
  169. return $c;
  170. }
  171. for ($i = 1; $i < $l; ++$i) {
  172. if ($arr[$i][$pos] !== $c) {
  173. return '';
  174. }
  175. }
  176. return $c;
  177. }
  178. /**
  179. * Get the shortest URI to minify the set of source files
  180. *
  181. * @param array $paths root-relative URIs of files
  182. * @param string $minRoot root-relative URI of the "min" application
  183. * @return string
  184. */
  185. protected static function _getShortestUri($paths, $minRoot = '/min/') {
  186. $pos = 0;
  187. $base = '';
  188. while (true) {
  189. $c = self::_getCommonCharAtPos($paths, $pos);
  190. if ($c === '') {
  191. break;
  192. } else {
  193. $base .= $c;
  194. }
  195. ++$pos;
  196. }
  197. $base = preg_replace('@[^/]+$@', '', $base);
  198. $uri = $minRoot . 'f=' . implode(',', $paths);
  199. if (substr($base, -1) === '/') {
  200. // we have a base dir!
  201. $basedPaths = $paths;
  202. $l = count($paths);
  203. for ($i = 0; $i < $l; ++$i) {
  204. $basedPaths[$i] = substr($paths[$i], strlen($base));
  205. }
  206. $base = substr($base, 0, strlen($base) - 1);
  207. $bUri = $minRoot . 'b=' . $base . '&f=' . implode(',', $basedPaths);
  208. $uri = strlen($uri) < strlen($bUri)
  209. ? $uri
  210. : $bUri;
  211. }
  212. return $uri;
  213. }
  214. }