123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- <?php
- /**
- * Class Minify_HTML_Helper
- * @package Minify
- */
- /**
- * Helpers for writing Minfy URIs into HTML
- *
- * @package Minify
- * @author Stephen Clay <steve@mrclay.org>
- */
- class Minify_HTML_Helper {
- public $rewriteWorks = true;
- public $minAppUri = '/min';
- public $groupsConfigFile = '';
- /**
- * Get an HTML-escaped Minify URI for a group or set of files
- *
- * @param string|array $keyOrFiles a group key or array of filepaths/URIs
- * @param array $opts options:
- * 'farExpires' : (default true) append a modified timestamp for cache revving
- * 'debug' : (default false) append debug flag
- * 'charset' : (default 'UTF-8') for htmlspecialchars
- * 'minAppUri' : (default '/min') URI of min directory
- * 'rewriteWorks' : (default true) does mod_rewrite work in min app?
- * 'groupsConfigFile' : specify if different
- * @return string
- */
- public static function getUri($keyOrFiles, $opts = array())
- {
- $opts = array_merge(array( // default options
- 'farExpires' => true
- ,'debug' => false
- ,'charset' => 'UTF-8'
- ,'minAppUri' => '/min'
- ,'rewriteWorks' => true
- ,'groupsConfigFile' => ''
- ), $opts);
- $h = new self;
- $h->minAppUri = $opts['minAppUri'];
- $h->rewriteWorks = $opts['rewriteWorks'];
- $h->groupsConfigFile = $opts['groupsConfigFile'];
- if (is_array($keyOrFiles)) {
- $h->setFiles($keyOrFiles, $opts['farExpires']);
- } else {
- $h->setGroup($keyOrFiles, $opts['farExpires']);
- }
- $uri = $h->getRawUri($opts['farExpires'], $opts['debug']);
- return htmlspecialchars($uri, ENT_QUOTES, $opts['charset']);
- }
- /**
- * Get non-HTML-escaped URI to minify the specified files
- *
- * @param bool $farExpires
- * @param bool $debug
- * @return string
- */
- public function getRawUri($farExpires = true, $debug = false)
- {
- $path = rtrim($this->minAppUri, '/') . '/';
- if (! $this->rewriteWorks) {
- $path .= '?';
- }
- if (null === $this->_groupKey) {
- // @todo: implement shortest uri
- $path = self::_getShortestUri($this->_filePaths, $path);
- } else {
- $path .= "g=" . $this->_groupKey;
- }
- if ($debug) {
- $path .= "&debug";
- } elseif ($farExpires && $this->_lastModified) {
- $path .= "&" . $this->_lastModified;
- }
- return $path;
- }
- /**
- * Set the files that will comprise the URI we're building
- *
- * @param array $files
- * @param bool $checkLastModified
- */
- public function setFiles($files, $checkLastModified = true)
- {
- $this->_groupKey = null;
- if ($checkLastModified) {
- $this->_lastModified = self::getLastModified($files);
- }
- // normalize paths like in /min/f=<paths>
- foreach ($files as $k => $file) {
- if (0 === strpos($file, '//')) {
- $file = substr($file, 2);
- } elseif (0 === strpos($file, '/')
- || 1 === strpos($file, ':\\')) {
- $file = substr($file, strlen($_SERVER['DOCUMENT_ROOT']) + 1);
- }
- $file = strtr($file, '\\', '/');
- $files[$k] = $file;
- }
- $this->_filePaths = $files;
- }
- /**
- * Set the group of files that will comprise the URI we're building
- *
- * @param string $key
- * @param bool $checkLastModified
- */
- public function setGroup($key, $checkLastModified = true)
- {
- $this->_groupKey = $key;
- if ($checkLastModified) {
- if (! $this->groupsConfigFile) {
- $this->groupsConfigFile = dirname(dirname(dirname(dirname(__FILE__)))) . '/groupsConfig.php';
- }
- if (is_file($this->groupsConfigFile)) {
- $gc = (require $this->groupsConfigFile);
- $keys = explode(',', $key);
- foreach ($keys as $key) {
- if (isset($gc[$key])) {
- $this->_lastModified = self::getLastModified($gc[$key], $this->_lastModified);
- }
- }
- }
- }
- }
- /**
- * Get the max(lastModified) of all files
- *
- * @param array|string $sources
- * @param int $lastModified
- * @return int
- */
- public static function getLastModified($sources, $lastModified = 0)
- {
- $max = $lastModified;
- foreach ((array)$sources as $source) {
- if (is_object($source) && isset($source->lastModified)) {
- $max = max($max, $source->lastModified);
- } elseif (is_string($source)) {
- if (0 === strpos($source, '//')) {
- $source = $_SERVER['DOCUMENT_ROOT'] . substr($source, 1);
- }
- if (is_file($source)) {
- $max = max($max, filemtime($source));
- }
- }
- }
- return $max;
- }
- protected $_groupKey = null; // if present, URI will be like g=...
- protected $_filePaths = array();
- protected $_lastModified = null;
-
- /**
- * In a given array of strings, find the character they all have at
- * a particular index
- *
- * @param array $arr array of strings
- * @param int $pos index to check
- * @return mixed a common char or '' if any do not match
- */
- protected static function _getCommonCharAtPos($arr, $pos) {
- if (!isset($arr[0][$pos])) {
- return '';
- }
- $c = $arr[0][$pos];
- $l = count($arr);
- if ($l === 1) {
- return $c;
- }
- for ($i = 1; $i < $l; ++$i) {
- if ($arr[$i][$pos] !== $c) {
- return '';
- }
- }
- return $c;
- }
- /**
- * Get the shortest URI to minify the set of source files
- *
- * @param array $paths root-relative URIs of files
- * @param string $minRoot root-relative URI of the "min" application
- * @return string
- */
- protected static function _getShortestUri($paths, $minRoot = '/min/') {
- $pos = 0;
- $base = '';
- while (true) {
- $c = self::_getCommonCharAtPos($paths, $pos);
- if ($c === '') {
- break;
- } else {
- $base .= $c;
- }
- ++$pos;
- }
- $base = preg_replace('@[^/]+$@', '', $base);
- $uri = $minRoot . 'f=' . implode(',', $paths);
-
- if (substr($base, -1) === '/') {
- // we have a base dir!
- $basedPaths = $paths;
- $l = count($paths);
- for ($i = 0; $i < $l; ++$i) {
- $basedPaths[$i] = substr($paths[$i], strlen($base));
- }
- $base = substr($base, 0, strlen($base) - 1);
- $bUri = $minRoot . 'b=' . $base . '&f=' . implode(',', $basedPaths);
- $uri = strlen($uri) < strlen($bUri)
- ? $uri
- : $bUri;
- }
- return $uri;
- }
- }
|