@@ -16,104 +16,104 @@ |
||
16 | 16 | */ |
17 | 17 | class Minify_Controller_Version1 extends Minify_Controller_Base { |
18 | 18 | |
19 | - /** |
|
20 | - * Set up groups of files as sources |
|
21 | - * |
|
22 | - * @param array $options controller and Minify options |
|
23 | - * @return array Minify options |
|
24 | - * |
|
25 | - */ |
|
26 | - public function setupSources($options) { |
|
27 | - // PHP insecure by default: realpath() and other FS functions can't handle null bytes. |
|
28 | - if (isset($_GET['files'])) { |
|
29 | - $_GET['files'] = str_replace("\x00", '', (string)$_GET['files']); |
|
30 | - } |
|
19 | + /** |
|
20 | + * Set up groups of files as sources |
|
21 | + * |
|
22 | + * @param array $options controller and Minify options |
|
23 | + * @return array Minify options |
|
24 | + * |
|
25 | + */ |
|
26 | + public function setupSources($options) { |
|
27 | + // PHP insecure by default: realpath() and other FS functions can't handle null bytes. |
|
28 | + if (isset($_GET['files'])) { |
|
29 | + $_GET['files'] = str_replace("\x00", '', (string)$_GET['files']); |
|
30 | + } |
|
31 | 31 | |
32 | - self::_setupDefines(); |
|
33 | - if (MINIFY_USE_CACHE) { |
|
34 | - $cacheDir = defined('MINIFY_CACHE_DIR') |
|
35 | - ? MINIFY_CACHE_DIR |
|
36 | - : ''; |
|
37 | - Minify::setCache($cacheDir); |
|
38 | - } |
|
39 | - $options['badRequestHeader'] = 'HTTP/1.0 404 Not Found'; |
|
40 | - $options['contentTypeCharset'] = MINIFY_ENCODING; |
|
32 | + self::_setupDefines(); |
|
33 | + if (MINIFY_USE_CACHE) { |
|
34 | + $cacheDir = defined('MINIFY_CACHE_DIR') |
|
35 | + ? MINIFY_CACHE_DIR |
|
36 | + : ''; |
|
37 | + Minify::setCache($cacheDir); |
|
38 | + } |
|
39 | + $options['badRequestHeader'] = 'HTTP/1.0 404 Not Found'; |
|
40 | + $options['contentTypeCharset'] = MINIFY_ENCODING; |
|
41 | 41 | |
42 | - // The following restrictions are to limit the URLs that minify will |
|
43 | - // respond to. Ideally there should be only one way to reference a file. |
|
44 | - if (! isset($_GET['files']) |
|
45 | - // verify at least one file, files are single comma separated, |
|
46 | - // and are all same extension |
|
47 | - || ! preg_match('/^[^,]+\\.(css|js)(,[^,]+\\.\\1)*$/', $_GET['files'], $m) |
|
48 | - // no "//" (makes URL rewriting easier) |
|
49 | - || strpos($_GET['files'], '//') !== false |
|
50 | - // no "\" |
|
51 | - || strpos($_GET['files'], '\\') !== false |
|
52 | - // no "./" |
|
53 | - || preg_match('/(?:^|[^\\.])\\.\\//', $_GET['files']) |
|
54 | - ) { |
|
55 | - return $options; |
|
56 | - } |
|
42 | + // The following restrictions are to limit the URLs that minify will |
|
43 | + // respond to. Ideally there should be only one way to reference a file. |
|
44 | + if (! isset($_GET['files']) |
|
45 | + // verify at least one file, files are single comma separated, |
|
46 | + // and are all same extension |
|
47 | + || ! preg_match('/^[^,]+\\.(css|js)(,[^,]+\\.\\1)*$/', $_GET['files'], $m) |
|
48 | + // no "//" (makes URL rewriting easier) |
|
49 | + || strpos($_GET['files'], '//') !== false |
|
50 | + // no "\" |
|
51 | + || strpos($_GET['files'], '\\') !== false |
|
52 | + // no "./" |
|
53 | + || preg_match('/(?:^|[^\\.])\\.\\//', $_GET['files']) |
|
54 | + ) { |
|
55 | + return $options; |
|
56 | + } |
|
57 | 57 | |
58 | - $files = explode(',', $_GET['files']); |
|
59 | - if (count($files) > MINIFY_MAX_FILES) { |
|
60 | - return $options; |
|
61 | - } |
|
58 | + $files = explode(',', $_GET['files']); |
|
59 | + if (count($files) > MINIFY_MAX_FILES) { |
|
60 | + return $options; |
|
61 | + } |
|
62 | 62 | |
63 | - // strings for prepending to relative/absolute paths |
|
64 | - $prependRelPaths = dirname($_SERVER['SCRIPT_FILENAME']) |
|
65 | - . DIRECTORY_SEPARATOR; |
|
66 | - $prependAbsPaths = $_SERVER['DOCUMENT_ROOT']; |
|
63 | + // strings for prepending to relative/absolute paths |
|
64 | + $prependRelPaths = dirname($_SERVER['SCRIPT_FILENAME']) |
|
65 | + . DIRECTORY_SEPARATOR; |
|
66 | + $prependAbsPaths = $_SERVER['DOCUMENT_ROOT']; |
|
67 | 67 | |
68 | - $goodFiles = array(); |
|
69 | - $hasBadSource = false; |
|
68 | + $goodFiles = array(); |
|
69 | + $hasBadSource = false; |
|
70 | 70 | |
71 | - $allowDirs = isset($options['allowDirs']) |
|
72 | - ? $options['allowDirs'] |
|
73 | - : MINIFY_BASE_DIR; |
|
71 | + $allowDirs = isset($options['allowDirs']) |
|
72 | + ? $options['allowDirs'] |
|
73 | + : MINIFY_BASE_DIR; |
|
74 | 74 | |
75 | - foreach ($files as $file) { |
|
76 | - // prepend appropriate string for abs/rel paths |
|
77 | - $file = ($file[0] === '/' ? $prependAbsPaths : $prependRelPaths) . $file; |
|
78 | - // make sure a real file! |
|
79 | - $file = realpath($file); |
|
80 | - // don't allow unsafe or duplicate files |
|
81 | - if (parent::_fileIsSafe($file, $allowDirs) |
|
82 | - && !in_array($file, $goodFiles)) |
|
83 | - { |
|
84 | - $goodFiles[] = $file; |
|
85 | - $srcOptions = array( |
|
86 | - 'filepath' => $file |
|
87 | - ); |
|
88 | - $this->sources[] = new Minify_Source($srcOptions); |
|
89 | - } else { |
|
90 | - $hasBadSource = true; |
|
91 | - break; |
|
92 | - } |
|
93 | - } |
|
94 | - if ($hasBadSource) { |
|
95 | - $this->sources = array(); |
|
96 | - } |
|
97 | - if (! MINIFY_REWRITE_CSS_URLS) { |
|
98 | - $options['rewriteCssUris'] = false; |
|
99 | - } |
|
100 | - return $options; |
|
101 | - } |
|
75 | + foreach ($files as $file) { |
|
76 | + // prepend appropriate string for abs/rel paths |
|
77 | + $file = ($file[0] === '/' ? $prependAbsPaths : $prependRelPaths) . $file; |
|
78 | + // make sure a real file! |
|
79 | + $file = realpath($file); |
|
80 | + // don't allow unsafe or duplicate files |
|
81 | + if (parent::_fileIsSafe($file, $allowDirs) |
|
82 | + && !in_array($file, $goodFiles)) |
|
83 | + { |
|
84 | + $goodFiles[] = $file; |
|
85 | + $srcOptions = array( |
|
86 | + 'filepath' => $file |
|
87 | + ); |
|
88 | + $this->sources[] = new Minify_Source($srcOptions); |
|
89 | + } else { |
|
90 | + $hasBadSource = true; |
|
91 | + break; |
|
92 | + } |
|
93 | + } |
|
94 | + if ($hasBadSource) { |
|
95 | + $this->sources = array(); |
|
96 | + } |
|
97 | + if (! MINIFY_REWRITE_CSS_URLS) { |
|
98 | + $options['rewriteCssUris'] = false; |
|
99 | + } |
|
100 | + return $options; |
|
101 | + } |
|
102 | 102 | |
103 | - private static function _setupDefines() |
|
104 | - { |
|
105 | - $defaults = array( |
|
106 | - 'MINIFY_BASE_DIR' => realpath($_SERVER['DOCUMENT_ROOT']) |
|
107 | - ,'MINIFY_ENCODING' => 'utf-8' |
|
108 | - ,'MINIFY_MAX_FILES' => 16 |
|
109 | - ,'MINIFY_REWRITE_CSS_URLS' => true |
|
110 | - ,'MINIFY_USE_CACHE' => true |
|
111 | - ); |
|
112 | - foreach ($defaults as $const => $val) { |
|
113 | - if (! defined($const)) { |
|
114 | - define($const, $val); |
|
115 | - } |
|
116 | - } |
|
117 | - } |
|
103 | + private static function _setupDefines() |
|
104 | + { |
|
105 | + $defaults = array( |
|
106 | + 'MINIFY_BASE_DIR' => realpath($_SERVER['DOCUMENT_ROOT']) |
|
107 | + ,'MINIFY_ENCODING' => 'utf-8' |
|
108 | + ,'MINIFY_MAX_FILES' => 16 |
|
109 | + ,'MINIFY_REWRITE_CSS_URLS' => true |
|
110 | + ,'MINIFY_USE_CACHE' => true |
|
111 | + ); |
|
112 | + foreach ($defaults as $const => $val) { |
|
113 | + if (! defined($const)) { |
|
114 | + define($const, $val); |
|
115 | + } |
|
116 | + } |
|
117 | + } |
|
118 | 118 | } |
119 | 119 |
@@ -7,20 +7,20 @@ |
||
7 | 7 | * @author Stephen Clay <[email protected]> |
8 | 8 | */ |
9 | 9 | class Minify_DebugDetector { |
10 | - public static function shouldDebugRequest($cookie, $get, $requestUri) |
|
11 | - { |
|
12 | - if (isset($get['debug'])) { |
|
13 | - return true; |
|
14 | - } |
|
15 | - if (! empty($cookie['minifyDebug'])) { |
|
16 | - foreach (preg_split('/\\s+/', $cookie['minifyDebug']) as $debugUri) { |
|
17 | - $pattern = '@' . preg_quote($debugUri, '@') . '@i'; |
|
18 | - $pattern = str_replace(array('\\*', '\\?'), array('.*', '.'), $pattern); |
|
19 | - if (preg_match($pattern, $requestUri)) { |
|
20 | - return true; |
|
21 | - } |
|
22 | - } |
|
23 | - } |
|
24 | - return false; |
|
25 | - } |
|
10 | + public static function shouldDebugRequest($cookie, $get, $requestUri) |
|
11 | + { |
|
12 | + if (isset($get['debug'])) { |
|
13 | + return true; |
|
14 | + } |
|
15 | + if (! empty($cookie['minifyDebug'])) { |
|
16 | + foreach (preg_split('/\\s+/', $cookie['minifyDebug']) as $debugUri) { |
|
17 | + $pattern = '@' . preg_quote($debugUri, '@') . '@i'; |
|
18 | + $pattern = str_replace(array('\\*', '\\?'), array('.*', '.'), $pattern); |
|
19 | + if (preg_match($pattern, $requestUri)) { |
|
20 | + return true; |
|
21 | + } |
|
22 | + } |
|
23 | + } |
|
24 | + return false; |
|
25 | + } |
|
26 | 26 | } |
@@ -14,34 +14,34 @@ |
||
14 | 14 | */ |
15 | 15 | class Minify_Logger { |
16 | 16 | |
17 | - /** |
|
18 | - * Set logger object. |
|
19 | - * |
|
20 | - * The object should have a method "log" that accepts a value as 1st argument and |
|
21 | - * an optional string label as the 2nd. |
|
22 | - * |
|
23 | - * @param mixed $obj or a "falsey" value to disable |
|
24 | - * @return null |
|
25 | - */ |
|
26 | - public static function setLogger($obj = null) { |
|
27 | - self::$_logger = $obj |
|
28 | - ? $obj |
|
29 | - : null; |
|
30 | - } |
|
17 | + /** |
|
18 | + * Set logger object. |
|
19 | + * |
|
20 | + * The object should have a method "log" that accepts a value as 1st argument and |
|
21 | + * an optional string label as the 2nd. |
|
22 | + * |
|
23 | + * @param mixed $obj or a "falsey" value to disable |
|
24 | + * @return null |
|
25 | + */ |
|
26 | + public static function setLogger($obj = null) { |
|
27 | + self::$_logger = $obj |
|
28 | + ? $obj |
|
29 | + : null; |
|
30 | + } |
|
31 | 31 | |
32 | - /** |
|
33 | - * Pass a message to the logger (if set) |
|
34 | - * |
|
35 | - * @param string $msg message to log |
|
36 | - * @return null |
|
37 | - */ |
|
38 | - public static function log($msg, $label = 'Minify') { |
|
39 | - if (! self::$_logger) return; |
|
40 | - self::$_logger->log($msg, $label); |
|
41 | - } |
|
32 | + /** |
|
33 | + * Pass a message to the logger (if set) |
|
34 | + * |
|
35 | + * @param string $msg message to log |
|
36 | + * @return null |
|
37 | + */ |
|
38 | + public static function log($msg, $label = 'Minify') { |
|
39 | + if (! self::$_logger) return; |
|
40 | + self::$_logger->log($msg, $label); |
|
41 | + } |
|
42 | 42 | |
43 | - /** |
|
44 | - * @var mixed logger object (like FirePHP) or null (i.e. no logger available) |
|
45 | - */ |
|
46 | - private static $_logger = null; |
|
43 | + /** |
|
44 | + * @var mixed logger object (like FirePHP) or null (i.e. no logger available) |
|
45 | + */ |
|
46 | + private static $_logger = null; |
|
47 | 47 | } |
@@ -15,173 +15,173 @@ |
||
15 | 15 | */ |
16 | 16 | class Minify_Source { |
17 | 17 | |
18 | - /** |
|
19 | - * @var int time of last modification |
|
20 | - */ |
|
21 | - public $lastModified = null; |
|
18 | + /** |
|
19 | + * @var int time of last modification |
|
20 | + */ |
|
21 | + public $lastModified = null; |
|
22 | 22 | |
23 | - /** |
|
24 | - * @var callback minifier function specifically for this source. |
|
25 | - */ |
|
26 | - public $minifier = null; |
|
23 | + /** |
|
24 | + * @var callback minifier function specifically for this source. |
|
25 | + */ |
|
26 | + public $minifier = null; |
|
27 | 27 | |
28 | - /** |
|
29 | - * @var array minification options specific to this source. |
|
30 | - */ |
|
31 | - public $minifyOptions = null; |
|
28 | + /** |
|
29 | + * @var array minification options specific to this source. |
|
30 | + */ |
|
31 | + public $minifyOptions = null; |
|
32 | 32 | |
33 | - /** |
|
34 | - * @var string full path of file |
|
35 | - */ |
|
36 | - public $filepath = null; |
|
33 | + /** |
|
34 | + * @var string full path of file |
|
35 | + */ |
|
36 | + public $filepath = null; |
|
37 | 37 | |
38 | - /** |
|
39 | - * @var string HTTP Content Type (Minify requires one of the constants Minify::TYPE_*) |
|
40 | - */ |
|
41 | - public $contentType = null; |
|
38 | + /** |
|
39 | + * @var string HTTP Content Type (Minify requires one of the constants Minify::TYPE_*) |
|
40 | + */ |
|
41 | + public $contentType = null; |
|
42 | 42 | |
43 | - /** |
|
44 | - * Create a Minify_Source |
|
45 | - * |
|
46 | - * In the $spec array(), you can either provide a 'filepath' to an existing |
|
47 | - * file (existence will not be checked!) or give 'id' (unique string for |
|
48 | - * the content), 'content' (the string content) and 'lastModified' |
|
49 | - * (unixtime of last update). |
|
50 | - * |
|
51 | - * As a shortcut, the controller will replace "//" at the beginning |
|
52 | - * of a filepath with $_SERVER['DOCUMENT_ROOT'] . '/'. |
|
53 | - * |
|
54 | - * @param array $spec options |
|
55 | - */ |
|
56 | - public function __construct($spec) |
|
57 | - { |
|
58 | - if (isset($spec['filepath'])) { |
|
59 | - if (0 === strpos($spec['filepath'], '//')) { |
|
60 | - $spec['filepath'] = $_SERVER['DOCUMENT_ROOT'] . substr($spec['filepath'], 1); |
|
61 | - } |
|
62 | - $segments = explode('.', $spec['filepath']); |
|
63 | - $ext = strtolower(array_pop($segments)); |
|
64 | - switch ($ext) { |
|
65 | - case 'js' : $this->contentType = 'application/x-javascript'; |
|
66 | - break; |
|
67 | - case 'css' : $this->contentType = 'text/css'; |
|
68 | - break; |
|
69 | - case 'htm' : // fallthrough |
|
70 | - case 'html' : $this->contentType = 'text/html'; |
|
71 | - break; |
|
72 | - } |
|
73 | - $this->filepath = $spec['filepath']; |
|
74 | - $this->_id = $spec['filepath']; |
|
75 | - $this->lastModified = filemtime($spec['filepath']) |
|
76 | - // offset for Windows uploaders with out of sync clocks |
|
77 | - + round(Minify::$uploaderHoursBehind * 3600); |
|
78 | - } elseif (isset($spec['id'])) { |
|
79 | - $this->_id = 'id::' . $spec['id']; |
|
80 | - if (isset($spec['content'])) { |
|
81 | - $this->_content = $spec['content']; |
|
82 | - } else { |
|
83 | - $this->_getContentFunc = $spec['getContentFunc']; |
|
84 | - } |
|
85 | - $this->lastModified = isset($spec['lastModified']) |
|
86 | - ? $spec['lastModified'] |
|
87 | - : time(); |
|
88 | - } |
|
89 | - if (isset($spec['contentType'])) { |
|
90 | - $this->contentType = $spec['contentType']; |
|
91 | - } |
|
92 | - if (isset($spec['minifier'])) { |
|
93 | - $this->minifier = $spec['minifier']; |
|
94 | - } |
|
95 | - if (isset($spec['minifyOptions'])) { |
|
96 | - $this->minifyOptions = $spec['minifyOptions']; |
|
97 | - } |
|
98 | - } |
|
43 | + /** |
|
44 | + * Create a Minify_Source |
|
45 | + * |
|
46 | + * In the $spec array(), you can either provide a 'filepath' to an existing |
|
47 | + * file (existence will not be checked!) or give 'id' (unique string for |
|
48 | + * the content), 'content' (the string content) and 'lastModified' |
|
49 | + * (unixtime of last update). |
|
50 | + * |
|
51 | + * As a shortcut, the controller will replace "//" at the beginning |
|
52 | + * of a filepath with $_SERVER['DOCUMENT_ROOT'] . '/'. |
|
53 | + * |
|
54 | + * @param array $spec options |
|
55 | + */ |
|
56 | + public function __construct($spec) |
|
57 | + { |
|
58 | + if (isset($spec['filepath'])) { |
|
59 | + if (0 === strpos($spec['filepath'], '//')) { |
|
60 | + $spec['filepath'] = $_SERVER['DOCUMENT_ROOT'] . substr($spec['filepath'], 1); |
|
61 | + } |
|
62 | + $segments = explode('.', $spec['filepath']); |
|
63 | + $ext = strtolower(array_pop($segments)); |
|
64 | + switch ($ext) { |
|
65 | + case 'js' : $this->contentType = 'application/x-javascript'; |
|
66 | + break; |
|
67 | + case 'css' : $this->contentType = 'text/css'; |
|
68 | + break; |
|
69 | + case 'htm' : // fallthrough |
|
70 | + case 'html' : $this->contentType = 'text/html'; |
|
71 | + break; |
|
72 | + } |
|
73 | + $this->filepath = $spec['filepath']; |
|
74 | + $this->_id = $spec['filepath']; |
|
75 | + $this->lastModified = filemtime($spec['filepath']) |
|
76 | + // offset for Windows uploaders with out of sync clocks |
|
77 | + + round(Minify::$uploaderHoursBehind * 3600); |
|
78 | + } elseif (isset($spec['id'])) { |
|
79 | + $this->_id = 'id::' . $spec['id']; |
|
80 | + if (isset($spec['content'])) { |
|
81 | + $this->_content = $spec['content']; |
|
82 | + } else { |
|
83 | + $this->_getContentFunc = $spec['getContentFunc']; |
|
84 | + } |
|
85 | + $this->lastModified = isset($spec['lastModified']) |
|
86 | + ? $spec['lastModified'] |
|
87 | + : time(); |
|
88 | + } |
|
89 | + if (isset($spec['contentType'])) { |
|
90 | + $this->contentType = $spec['contentType']; |
|
91 | + } |
|
92 | + if (isset($spec['minifier'])) { |
|
93 | + $this->minifier = $spec['minifier']; |
|
94 | + } |
|
95 | + if (isset($spec['minifyOptions'])) { |
|
96 | + $this->minifyOptions = $spec['minifyOptions']; |
|
97 | + } |
|
98 | + } |
|
99 | 99 | |
100 | - /** |
|
101 | - * Get content |
|
102 | - * |
|
103 | - * @return string |
|
104 | - */ |
|
105 | - public function getContent() |
|
106 | - { |
|
107 | - $content = (null !== $this->filepath) |
|
108 | - ? file_get_contents($this->filepath) |
|
109 | - : ((null !== $this->_content) |
|
110 | - ? $this->_content |
|
111 | - : call_user_func($this->_getContentFunc, $this->_id) |
|
112 | - ); |
|
113 | - // remove UTF-8 BOM if present |
|
114 | - return (pack("CCC",0xef,0xbb,0xbf) === substr($content, 0, 3)) |
|
115 | - ? substr($content, 3) |
|
116 | - : $content; |
|
117 | - } |
|
100 | + /** |
|
101 | + * Get content |
|
102 | + * |
|
103 | + * @return string |
|
104 | + */ |
|
105 | + public function getContent() |
|
106 | + { |
|
107 | + $content = (null !== $this->filepath) |
|
108 | + ? file_get_contents($this->filepath) |
|
109 | + : ((null !== $this->_content) |
|
110 | + ? $this->_content |
|
111 | + : call_user_func($this->_getContentFunc, $this->_id) |
|
112 | + ); |
|
113 | + // remove UTF-8 BOM if present |
|
114 | + return (pack("CCC",0xef,0xbb,0xbf) === substr($content, 0, 3)) |
|
115 | + ? substr($content, 3) |
|
116 | + : $content; |
|
117 | + } |
|
118 | 118 | |
119 | - /** |
|
120 | - * Get id |
|
121 | - * |
|
122 | - * @return string |
|
123 | - */ |
|
124 | - public function getId() |
|
125 | - { |
|
126 | - return $this->_id; |
|
127 | - } |
|
119 | + /** |
|
120 | + * Get id |
|
121 | + * |
|
122 | + * @return string |
|
123 | + */ |
|
124 | + public function getId() |
|
125 | + { |
|
126 | + return $this->_id; |
|
127 | + } |
|
128 | 128 | |
129 | - /** |
|
130 | - * Verifies a single minification call can handle all sources |
|
131 | - * |
|
132 | - * @param array $sources Minify_Source instances |
|
133 | - * |
|
134 | - * @return bool true iff there no sources with specific minifier preferences. |
|
135 | - */ |
|
136 | - public static function haveNoMinifyPrefs($sources) |
|
137 | - { |
|
138 | - foreach ($sources as $source) { |
|
139 | - if (null !== $source->minifier |
|
140 | - || null !== $source->minifyOptions) { |
|
141 | - return false; |
|
142 | - } |
|
143 | - } |
|
144 | - return true; |
|
145 | - } |
|
129 | + /** |
|
130 | + * Verifies a single minification call can handle all sources |
|
131 | + * |
|
132 | + * @param array $sources Minify_Source instances |
|
133 | + * |
|
134 | + * @return bool true iff there no sources with specific minifier preferences. |
|
135 | + */ |
|
136 | + public static function haveNoMinifyPrefs($sources) |
|
137 | + { |
|
138 | + foreach ($sources as $source) { |
|
139 | + if (null !== $source->minifier |
|
140 | + || null !== $source->minifyOptions) { |
|
141 | + return false; |
|
142 | + } |
|
143 | + } |
|
144 | + return true; |
|
145 | + } |
|
146 | 146 | |
147 | - /** |
|
148 | - * Get unique string for a set of sources |
|
149 | - * |
|
150 | - * @param array $sources Minify_Source instances |
|
151 | - * |
|
152 | - * @return string |
|
153 | - */ |
|
154 | - public static function getDigest($sources) |
|
155 | - { |
|
156 | - foreach ($sources as $source) { |
|
157 | - $info[] = array( |
|
158 | - $source->_id, $source->minifier, $source->minifyOptions |
|
159 | - ); |
|
160 | - } |
|
161 | - return md5(serialize($info)); |
|
162 | - } |
|
147 | + /** |
|
148 | + * Get unique string for a set of sources |
|
149 | + * |
|
150 | + * @param array $sources Minify_Source instances |
|
151 | + * |
|
152 | + * @return string |
|
153 | + */ |
|
154 | + public static function getDigest($sources) |
|
155 | + { |
|
156 | + foreach ($sources as $source) { |
|
157 | + $info[] = array( |
|
158 | + $source->_id, $source->minifier, $source->minifyOptions |
|
159 | + ); |
|
160 | + } |
|
161 | + return md5(serialize($info)); |
|
162 | + } |
|
163 | 163 | |
164 | - /** |
|
165 | - * Get content type from a group of sources |
|
166 | - * |
|
167 | - * This is called if the user doesn't pass in a 'contentType' options |
|
168 | - * |
|
169 | - * @param array $sources Minify_Source instances |
|
170 | - * |
|
171 | - * @return string content type. e.g. 'text/css' |
|
172 | - */ |
|
173 | - public static function getContentType($sources) |
|
174 | - { |
|
175 | - foreach ($sources as $source) { |
|
176 | - if ($source->contentType !== null) { |
|
177 | - return $source->contentType; |
|
178 | - } |
|
179 | - } |
|
180 | - return 'text/plain'; |
|
181 | - } |
|
164 | + /** |
|
165 | + * Get content type from a group of sources |
|
166 | + * |
|
167 | + * This is called if the user doesn't pass in a 'contentType' options |
|
168 | + * |
|
169 | + * @param array $sources Minify_Source instances |
|
170 | + * |
|
171 | + * @return string content type. e.g. 'text/css' |
|
172 | + */ |
|
173 | + public static function getContentType($sources) |
|
174 | + { |
|
175 | + foreach ($sources as $source) { |
|
176 | + if ($source->contentType !== null) { |
|
177 | + return $source->contentType; |
|
178 | + } |
|
179 | + } |
|
180 | + return 'text/plain'; |
|
181 | + } |
|
182 | 182 | |
183 | - protected $_content = null; |
|
184 | - protected $_getContentFunc = null; |
|
185 | - protected $_id = null; |
|
183 | + protected $_content = null; |
|
184 | + protected $_getContentFunc = null; |
|
185 | + protected $_id = null; |
|
186 | 186 | } |
187 | 187 |
@@ -16,84 +16,84 @@ |
||
16 | 16 | */ |
17 | 17 | class Minify_CSS { |
18 | 18 | |
19 | - /** |
|
20 | - * Minify a CSS string |
|
21 | - * |
|
22 | - * @param string $css |
|
23 | - * |
|
24 | - * @param array $options available options: |
|
25 | - * |
|
26 | - * 'preserveComments': (default true) multi-line comments that begin |
|
27 | - * with "/*!" will be preserved with newlines before and after to |
|
28 | - * enhance readability. |
|
29 | - * |
|
30 | - * 'removeCharsets': (default true) remove all @charset at-rules |
|
31 | - * |
|
32 | - * 'prependRelativePath': (default null) if given, this string will be |
|
33 | - * prepended to all relative URIs in import/url declarations |
|
34 | - * |
|
35 | - * 'currentDir': (default null) if given, this is assumed to be the |
|
36 | - * directory of the current CSS file. Using this, minify will rewrite |
|
37 | - * all relative URIs in import/url declarations to correctly point to |
|
38 | - * the desired files. For this to work, the files *must* exist and be |
|
39 | - * visible by the PHP process. |
|
40 | - * |
|
41 | - * 'symlinks': (default = array()) If the CSS file is stored in |
|
42 | - * a symlink-ed directory, provide an array of link paths to |
|
43 | - * target paths, where the link paths are within the document root. Because |
|
44 | - * paths need to be normalized for this to work, use "//" to substitute |
|
45 | - * the doc root in the link paths (the array keys). E.g.: |
|
46 | - * <code> |
|
47 | - * array('//symlink' => '/real/target/path') // unix |
|
48 | - * array('//static' => 'D:\\staticStorage') // Windows |
|
49 | - * </code> |
|
50 | - * |
|
51 | - * 'docRoot': (default = $_SERVER['DOCUMENT_ROOT']) |
|
52 | - * see Minify_CSS_UriRewriter::rewrite |
|
53 | - * |
|
54 | - * @return string |
|
55 | - */ |
|
56 | - public static function minify($css, $options = array()) |
|
57 | - { |
|
58 | - $options = array_merge(array( |
|
59 | - 'compress' => true, |
|
60 | - 'removeCharsets' => true, |
|
61 | - 'preserveComments' => true, |
|
62 | - 'currentDir' => null, |
|
63 | - 'docRoot' => $_SERVER['DOCUMENT_ROOT'], |
|
64 | - 'prependRelativePath' => null, |
|
65 | - 'symlinks' => array(), |
|
66 | - ), $options); |
|
19 | + /** |
|
20 | + * Minify a CSS string |
|
21 | + * |
|
22 | + * @param string $css |
|
23 | + * |
|
24 | + * @param array $options available options: |
|
25 | + * |
|
26 | + * 'preserveComments': (default true) multi-line comments that begin |
|
27 | + * with "/*!" will be preserved with newlines before and after to |
|
28 | + * enhance readability. |
|
29 | + * |
|
30 | + * 'removeCharsets': (default true) remove all @charset at-rules |
|
31 | + * |
|
32 | + * 'prependRelativePath': (default null) if given, this string will be |
|
33 | + * prepended to all relative URIs in import/url declarations |
|
34 | + * |
|
35 | + * 'currentDir': (default null) if given, this is assumed to be the |
|
36 | + * directory of the current CSS file. Using this, minify will rewrite |
|
37 | + * all relative URIs in import/url declarations to correctly point to |
|
38 | + * the desired files. For this to work, the files *must* exist and be |
|
39 | + * visible by the PHP process. |
|
40 | + * |
|
41 | + * 'symlinks': (default = array()) If the CSS file is stored in |
|
42 | + * a symlink-ed directory, provide an array of link paths to |
|
43 | + * target paths, where the link paths are within the document root. Because |
|
44 | + * paths need to be normalized for this to work, use "//" to substitute |
|
45 | + * the doc root in the link paths (the array keys). E.g.: |
|
46 | + * <code> |
|
47 | + * array('//symlink' => '/real/target/path') // unix |
|
48 | + * array('//static' => 'D:\\staticStorage') // Windows |
|
49 | + * </code> |
|
50 | + * |
|
51 | + * 'docRoot': (default = $_SERVER['DOCUMENT_ROOT']) |
|
52 | + * see Minify_CSS_UriRewriter::rewrite |
|
53 | + * |
|
54 | + * @return string |
|
55 | + */ |
|
56 | + public static function minify($css, $options = array()) |
|
57 | + { |
|
58 | + $options = array_merge(array( |
|
59 | + 'compress' => true, |
|
60 | + 'removeCharsets' => true, |
|
61 | + 'preserveComments' => true, |
|
62 | + 'currentDir' => null, |
|
63 | + 'docRoot' => $_SERVER['DOCUMENT_ROOT'], |
|
64 | + 'prependRelativePath' => null, |
|
65 | + 'symlinks' => array(), |
|
66 | + ), $options); |
|
67 | 67 | |
68 | - if ($options['removeCharsets']) { |
|
69 | - $css = preg_replace('/@charset[^;]+;\\s*/', '', $css); |
|
70 | - } |
|
71 | - if ($options['compress']) { |
|
72 | - if (! $options['preserveComments']) { |
|
73 | - $css = Minify_CSS_Compressor::process($css, $options); |
|
74 | - } else { |
|
75 | - $css = Minify_CommentPreserver::process( |
|
76 | - $css |
|
77 | - ,array('Minify_CSS_Compressor', 'process') |
|
78 | - ,array($options) |
|
79 | - ); |
|
80 | - } |
|
81 | - } |
|
82 | - if (! $options['currentDir'] && ! $options['prependRelativePath']) { |
|
83 | - return $css; |
|
84 | - } |
|
85 | - if ($options['currentDir']) { |
|
86 | - return Minify_CSS_UriRewriter::rewrite( |
|
87 | - $css |
|
88 | - ,$options['currentDir'] |
|
89 | - ,$options['docRoot'] |
|
90 | - ,$options['symlinks'] |
|
91 | - ); |
|
92 | - } else { |
|
93 | - return Minify_CSS_UriRewriter::prepend( |
|
94 | - $css |
|
95 | - ,$options['prependRelativePath'] |
|
96 | - ); |
|
97 | - } |
|
98 | - } |
|
68 | + if ($options['removeCharsets']) { |
|
69 | + $css = preg_replace('/@charset[^;]+;\\s*/', '', $css); |
|
70 | + } |
|
71 | + if ($options['compress']) { |
|
72 | + if (! $options['preserveComments']) { |
|
73 | + $css = Minify_CSS_Compressor::process($css, $options); |
|
74 | + } else { |
|
75 | + $css = Minify_CommentPreserver::process( |
|
76 | + $css |
|
77 | + ,array('Minify_CSS_Compressor', 'process') |
|
78 | + ,array($options) |
|
79 | + ); |
|
80 | + } |
|
81 | + } |
|
82 | + if (! $options['currentDir'] && ! $options['prependRelativePath']) { |
|
83 | + return $css; |
|
84 | + } |
|
85 | + if ($options['currentDir']) { |
|
86 | + return Minify_CSS_UriRewriter::rewrite( |
|
87 | + $css |
|
88 | + ,$options['currentDir'] |
|
89 | + ,$options['docRoot'] |
|
90 | + ,$options['symlinks'] |
|
91 | + ); |
|
92 | + } else { |
|
93 | + return Minify_CSS_UriRewriter::prepend( |
|
94 | + $css |
|
95 | + ,$options['prependRelativePath'] |
|
96 | + ); |
|
97 | + } |
|
98 | + } |
|
99 | 99 | } |
@@ -20,60 +20,60 @@ discard block |
||
20 | 20 | */ |
21 | 21 | class Minify_ImportProcessor { |
22 | 22 | |
23 | - public static $filesIncluded = array(); |
|
24 | - |
|
25 | - public static function process($file) |
|
26 | - { |
|
27 | - self::$filesIncluded = array(); |
|
28 | - self::$_isCss = (strtolower(substr($file, -4)) === '.css'); |
|
29 | - $obj = new Minify_ImportProcessor(dirname($file)); |
|
30 | - return $obj->_getContent($file); |
|
31 | - } |
|
32 | - |
|
33 | - // allows callback funcs to know the current directory |
|
34 | - private $_currentDir = null; |
|
35 | - |
|
36 | - // allows callback funcs to know the directory of the file that inherits this one |
|
37 | - private $_previewsDir = null; |
|
38 | - |
|
39 | - // allows _importCB to write the fetched content back to the obj |
|
40 | - private $_importedContent = ''; |
|
41 | - |
|
42 | - private static $_isCss = null; |
|
43 | - |
|
44 | - /** |
|
45 | - * @param String $currentDir |
|
46 | - * @param String $previewsDir Is only used internally |
|
47 | - */ |
|
48 | - private function __construct($currentDir, $previewsDir = "") |
|
49 | - { |
|
50 | - $this->_currentDir = $currentDir; |
|
51 | - $this->_previewsDir = $previewsDir; |
|
52 | - } |
|
53 | - |
|
54 | - private function _getContent($file, $is_imported = false) |
|
55 | - { |
|
56 | - $file = realpath($file); |
|
57 | - if (! $file |
|
58 | - || in_array($file, self::$filesIncluded) |
|
59 | - || false === ($content = @file_get_contents($file)) |
|
60 | - ) { |
|
61 | - // file missing, already included, or failed read |
|
62 | - return ''; |
|
63 | - } |
|
64 | - self::$filesIncluded[] = realpath($file); |
|
65 | - $this->_currentDir = dirname($file); |
|
66 | - |
|
67 | - // remove UTF-8 BOM if present |
|
68 | - if (pack("CCC",0xef,0xbb,0xbf) === substr($content, 0, 3)) { |
|
69 | - $content = substr($content, 3); |
|
70 | - } |
|
71 | - // ensure uniform EOLs |
|
72 | - $content = str_replace("\r\n", "\n", $content); |
|
73 | - |
|
74 | - // process @imports |
|
75 | - $content = preg_replace_callback( |
|
76 | - '/ |
|
23 | + public static $filesIncluded = array(); |
|
24 | + |
|
25 | + public static function process($file) |
|
26 | + { |
|
27 | + self::$filesIncluded = array(); |
|
28 | + self::$_isCss = (strtolower(substr($file, -4)) === '.css'); |
|
29 | + $obj = new Minify_ImportProcessor(dirname($file)); |
|
30 | + return $obj->_getContent($file); |
|
31 | + } |
|
32 | + |
|
33 | + // allows callback funcs to know the current directory |
|
34 | + private $_currentDir = null; |
|
35 | + |
|
36 | + // allows callback funcs to know the directory of the file that inherits this one |
|
37 | + private $_previewsDir = null; |
|
38 | + |
|
39 | + // allows _importCB to write the fetched content back to the obj |
|
40 | + private $_importedContent = ''; |
|
41 | + |
|
42 | + private static $_isCss = null; |
|
43 | + |
|
44 | + /** |
|
45 | + * @param String $currentDir |
|
46 | + * @param String $previewsDir Is only used internally |
|
47 | + */ |
|
48 | + private function __construct($currentDir, $previewsDir = "") |
|
49 | + { |
|
50 | + $this->_currentDir = $currentDir; |
|
51 | + $this->_previewsDir = $previewsDir; |
|
52 | + } |
|
53 | + |
|
54 | + private function _getContent($file, $is_imported = false) |
|
55 | + { |
|
56 | + $file = realpath($file); |
|
57 | + if (! $file |
|
58 | + || in_array($file, self::$filesIncluded) |
|
59 | + || false === ($content = @file_get_contents($file)) |
|
60 | + ) { |
|
61 | + // file missing, already included, or failed read |
|
62 | + return ''; |
|
63 | + } |
|
64 | + self::$filesIncluded[] = realpath($file); |
|
65 | + $this->_currentDir = dirname($file); |
|
66 | + |
|
67 | + // remove UTF-8 BOM if present |
|
68 | + if (pack("CCC",0xef,0xbb,0xbf) === substr($content, 0, 3)) { |
|
69 | + $content = substr($content, 3); |
|
70 | + } |
|
71 | + // ensure uniform EOLs |
|
72 | + $content = str_replace("\r\n", "\n", $content); |
|
73 | + |
|
74 | + // process @imports |
|
75 | + $content = preg_replace_callback( |
|
76 | + '/ |
|
77 | 77 | @import\\s+ |
78 | 78 | (?:url\\(\\s*)? # maybe url( |
79 | 79 | [\'"]? # maybe quote |
@@ -83,134 +83,134 @@ discard block |
||
83 | 83 | ([a-zA-Z,\\s]*)? # 2 = media list |
84 | 84 | ; # end token |
85 | 85 | /x' |
86 | - ,array($this, '_importCB') |
|
87 | - ,$content |
|
88 | - ); |
|
89 | - |
|
90 | - // You only need to rework the import-path if the script is imported |
|
91 | - if (self::$_isCss && $is_imported) { |
|
92 | - // rewrite remaining relative URIs |
|
93 | - $content = preg_replace_callback( |
|
94 | - '/url\\(\\s*([^\\)\\s]+)\\s*\\)/' |
|
95 | - ,array($this, '_urlCB') |
|
96 | - ,$content |
|
97 | - ); |
|
98 | - } |
|
99 | - |
|
100 | - return $this->_importedContent . $content; |
|
101 | - } |
|
102 | - |
|
103 | - private function _importCB($m) |
|
104 | - { |
|
105 | - $url = $m[1]; |
|
106 | - $mediaList = preg_replace('/\\s+/', '', $m[2]); |
|
107 | - |
|
108 | - if (strpos($url, '://') > 0) { |
|
109 | - // protocol, leave in place for CSS, comment for JS |
|
110 | - return self::$_isCss |
|
111 | - ? $m[0] |
|
112 | - : "/* Minify_ImportProcessor will not include remote content */"; |
|
113 | - } |
|
114 | - if ('/' === $url[0]) { |
|
115 | - // protocol-relative or root path |
|
116 | - $url = ltrim($url, '/'); |
|
117 | - $file = realpath($_SERVER['DOCUMENT_ROOT']) . DIRECTORY_SEPARATOR |
|
118 | - . strtr($url, '/', DIRECTORY_SEPARATOR); |
|
119 | - } else { |
|
120 | - // relative to current path |
|
121 | - $file = $this->_currentDir . DIRECTORY_SEPARATOR |
|
122 | - . strtr($url, '/', DIRECTORY_SEPARATOR); |
|
123 | - } |
|
124 | - $obj = new Minify_ImportProcessor(dirname($file), $this->_currentDir); |
|
125 | - $content = $obj->_getContent($file, true); |
|
126 | - if ('' === $content) { |
|
127 | - // failed. leave in place for CSS, comment for JS |
|
128 | - return self::$_isCss |
|
129 | - ? $m[0] |
|
130 | - : "/* Minify_ImportProcessor could not fetch '{$file}' */"; |
|
131 | - } |
|
132 | - return (!self::$_isCss || preg_match('@(?:^$|\\ball\\b)@', $mediaList)) |
|
133 | - ? $content |
|
134 | - : "@media {$mediaList} {\n{$content}\n}\n"; |
|
135 | - } |
|
136 | - |
|
137 | - private function _urlCB($m) |
|
138 | - { |
|
139 | - // $m[1] is either quoted or not |
|
140 | - $quote = ($m[1][0] === "'" || $m[1][0] === '"') |
|
141 | - ? $m[1][0] |
|
142 | - : ''; |
|
143 | - $url = ($quote === '') |
|
144 | - ? $m[1] |
|
145 | - : substr($m[1], 1, strlen($m[1]) - 2); |
|
146 | - if ('/' !== $url[0]) { |
|
147 | - if (strpos($url, '//') > 0) { |
|
148 | - // probably starts with protocol, do not alter |
|
149 | - } else { |
|
150 | - // prepend path with current dir separator (OS-independent) |
|
151 | - $path = $this->_currentDir |
|
152 | - . DIRECTORY_SEPARATOR . strtr($url, '/', DIRECTORY_SEPARATOR); |
|
153 | - // update the relative path by the directory of the file that imported this one |
|
154 | - $url = self::getPathDiff(realpath($this->_previewsDir), $path); |
|
155 | - } |
|
156 | - } |
|
157 | - return "url({$quote}{$url}{$quote})"; |
|
158 | - } |
|
159 | - |
|
160 | - /** |
|
161 | - * @param string $from |
|
162 | - * @param string $to |
|
163 | - * @param string $ps |
|
164 | - * @return string |
|
165 | - */ |
|
166 | - private function getPathDiff($from, $to, $ps = DIRECTORY_SEPARATOR) |
|
167 | - { |
|
168 | - $realFrom = $this->truepath($from); |
|
169 | - $realTo = $this->truepath($to); |
|
170 | - |
|
171 | - $arFrom = explode($ps, rtrim($realFrom, $ps)); |
|
172 | - $arTo = explode($ps, rtrim($realTo, $ps)); |
|
173 | - while (count($arFrom) && count($arTo) && ($arFrom[0] == $arTo[0])) |
|
174 | - { |
|
175 | - array_shift($arFrom); |
|
176 | - array_shift($arTo); |
|
177 | - } |
|
178 | - return str_pad("", count($arFrom) * 3, '..' . $ps) . implode($ps, $arTo); |
|
179 | - } |
|
180 | - |
|
181 | - /** |
|
182 | - * This function is to replace PHP's extremely buggy realpath(). |
|
183 | - * @param string $path The original path, can be relative etc. |
|
184 | - * @return string The resolved path, it might not exist. |
|
185 | - * @see http://stackoverflow.com/questions/4049856/replace-phps-realpath |
|
186 | - */ |
|
187 | - function truepath($path) |
|
188 | - { |
|
189 | - // whether $path is unix or not |
|
190 | - $unipath = strlen($path) == 0 || $path{0} != '/'; |
|
191 | - // attempts to detect if path is relative in which case, add cwd |
|
192 | - if (strpos($path, ':') === false && $unipath) |
|
193 | - $path = $this->_currentDir . DIRECTORY_SEPARATOR . $path; |
|
194 | - |
|
195 | - // resolve path parts (single dot, double dot and double delimiters) |
|
196 | - $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path); |
|
197 | - $parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen'); |
|
198 | - $absolutes = array(); |
|
199 | - foreach ($parts as $part) { |
|
200 | - if ('.' == $part) |
|
201 | - continue; |
|
202 | - if ('..' == $part) { |
|
203 | - array_pop($absolutes); |
|
204 | - } else { |
|
205 | - $absolutes[] = $part; |
|
206 | - } |
|
207 | - } |
|
208 | - $path = implode(DIRECTORY_SEPARATOR, $absolutes); |
|
209 | - // resolve any symlinks |
|
210 | - if (file_exists($path) && linkinfo($path) > 0) |
|
211 | - $path = readlink($path); |
|
212 | - // put initial separator that could have been lost |
|
213 | - $path = !$unipath ? '/' . $path : $path; |
|
214 | - return $path; |
|
215 | - } |
|
86 | + ,array($this, '_importCB') |
|
87 | + ,$content |
|
88 | + ); |
|
89 | + |
|
90 | + // You only need to rework the import-path if the script is imported |
|
91 | + if (self::$_isCss && $is_imported) { |
|
92 | + // rewrite remaining relative URIs |
|
93 | + $content = preg_replace_callback( |
|
94 | + '/url\\(\\s*([^\\)\\s]+)\\s*\\)/' |
|
95 | + ,array($this, '_urlCB') |
|
96 | + ,$content |
|
97 | + ); |
|
98 | + } |
|
99 | + |
|
100 | + return $this->_importedContent . $content; |
|
101 | + } |
|
102 | + |
|
103 | + private function _importCB($m) |
|
104 | + { |
|
105 | + $url = $m[1]; |
|
106 | + $mediaList = preg_replace('/\\s+/', '', $m[2]); |
|
107 | + |
|
108 | + if (strpos($url, '://') > 0) { |
|
109 | + // protocol, leave in place for CSS, comment for JS |
|
110 | + return self::$_isCss |
|
111 | + ? $m[0] |
|
112 | + : "/* Minify_ImportProcessor will not include remote content */"; |
|
113 | + } |
|
114 | + if ('/' === $url[0]) { |
|
115 | + // protocol-relative or root path |
|
116 | + $url = ltrim($url, '/'); |
|
117 | + $file = realpath($_SERVER['DOCUMENT_ROOT']) . DIRECTORY_SEPARATOR |
|
118 | + . strtr($url, '/', DIRECTORY_SEPARATOR); |
|
119 | + } else { |
|
120 | + // relative to current path |
|
121 | + $file = $this->_currentDir . DIRECTORY_SEPARATOR |
|
122 | + . strtr($url, '/', DIRECTORY_SEPARATOR); |
|
123 | + } |
|
124 | + $obj = new Minify_ImportProcessor(dirname($file), $this->_currentDir); |
|
125 | + $content = $obj->_getContent($file, true); |
|
126 | + if ('' === $content) { |
|
127 | + // failed. leave in place for CSS, comment for JS |
|
128 | + return self::$_isCss |
|
129 | + ? $m[0] |
|
130 | + : "/* Minify_ImportProcessor could not fetch '{$file}' */"; |
|
131 | + } |
|
132 | + return (!self::$_isCss || preg_match('@(?:^$|\\ball\\b)@', $mediaList)) |
|
133 | + ? $content |
|
134 | + : "@media {$mediaList} {\n{$content}\n}\n"; |
|
135 | + } |
|
136 | + |
|
137 | + private function _urlCB($m) |
|
138 | + { |
|
139 | + // $m[1] is either quoted or not |
|
140 | + $quote = ($m[1][0] === "'" || $m[1][0] === '"') |
|
141 | + ? $m[1][0] |
|
142 | + : ''; |
|
143 | + $url = ($quote === '') |
|
144 | + ? $m[1] |
|
145 | + : substr($m[1], 1, strlen($m[1]) - 2); |
|
146 | + if ('/' !== $url[0]) { |
|
147 | + if (strpos($url, '//') > 0) { |
|
148 | + // probably starts with protocol, do not alter |
|
149 | + } else { |
|
150 | + // prepend path with current dir separator (OS-independent) |
|
151 | + $path = $this->_currentDir |
|
152 | + . DIRECTORY_SEPARATOR . strtr($url, '/', DIRECTORY_SEPARATOR); |
|
153 | + // update the relative path by the directory of the file that imported this one |
|
154 | + $url = self::getPathDiff(realpath($this->_previewsDir), $path); |
|
155 | + } |
|
156 | + } |
|
157 | + return "url({$quote}{$url}{$quote})"; |
|
158 | + } |
|
159 | + |
|
160 | + /** |
|
161 | + * @param string $from |
|
162 | + * @param string $to |
|
163 | + * @param string $ps |
|
164 | + * @return string |
|
165 | + */ |
|
166 | + private function getPathDiff($from, $to, $ps = DIRECTORY_SEPARATOR) |
|
167 | + { |
|
168 | + $realFrom = $this->truepath($from); |
|
169 | + $realTo = $this->truepath($to); |
|
170 | + |
|
171 | + $arFrom = explode($ps, rtrim($realFrom, $ps)); |
|
172 | + $arTo = explode($ps, rtrim($realTo, $ps)); |
|
173 | + while (count($arFrom) && count($arTo) && ($arFrom[0] == $arTo[0])) |
|
174 | + { |
|
175 | + array_shift($arFrom); |
|
176 | + array_shift($arTo); |
|
177 | + } |
|
178 | + return str_pad("", count($arFrom) * 3, '..' . $ps) . implode($ps, $arTo); |
|
179 | + } |
|
180 | + |
|
181 | + /** |
|
182 | + * This function is to replace PHP's extremely buggy realpath(). |
|
183 | + * @param string $path The original path, can be relative etc. |
|
184 | + * @return string The resolved path, it might not exist. |
|
185 | + * @see http://stackoverflow.com/questions/4049856/replace-phps-realpath |
|
186 | + */ |
|
187 | + function truepath($path) |
|
188 | + { |
|
189 | + // whether $path is unix or not |
|
190 | + $unipath = strlen($path) == 0 || $path{0} != '/'; |
|
191 | + // attempts to detect if path is relative in which case, add cwd |
|
192 | + if (strpos($path, ':') === false && $unipath) |
|
193 | + $path = $this->_currentDir . DIRECTORY_SEPARATOR . $path; |
|
194 | + |
|
195 | + // resolve path parts (single dot, double dot and double delimiters) |
|
196 | + $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path); |
|
197 | + $parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen'); |
|
198 | + $absolutes = array(); |
|
199 | + foreach ($parts as $part) { |
|
200 | + if ('.' == $part) |
|
201 | + continue; |
|
202 | + if ('..' == $part) { |
|
203 | + array_pop($absolutes); |
|
204 | + } else { |
|
205 | + $absolutes[] = $part; |
|
206 | + } |
|
207 | + } |
|
208 | + $path = implode(DIRECTORY_SEPARATOR, $absolutes); |
|
209 | + // resolve any symlinks |
|
210 | + if (file_exists($path) && linkinfo($path) > 0) |
|
211 | + $path = readlink($path); |
|
212 | + // put initial separator that could have been lost |
|
213 | + $path = !$unipath ? '/' . $path : $path; |
|
214 | + return $path; |
|
215 | + } |
|
216 | 216 | } |
@@ -12,78 +12,78 @@ |
||
12 | 12 | */ |
13 | 13 | class Minify_CommentPreserver { |
14 | 14 | |
15 | - /** |
|
16 | - * String to be prepended to each preserved comment |
|
17 | - * |
|
18 | - * @var string |
|
19 | - */ |
|
20 | - public static $prepend = "\n"; |
|
15 | + /** |
|
16 | + * String to be prepended to each preserved comment |
|
17 | + * |
|
18 | + * @var string |
|
19 | + */ |
|
20 | + public static $prepend = "\n"; |
|
21 | 21 | |
22 | - /** |
|
23 | - * String to be appended to each preserved comment |
|
24 | - * |
|
25 | - * @var string |
|
26 | - */ |
|
27 | - public static $append = "\n"; |
|
22 | + /** |
|
23 | + * String to be appended to each preserved comment |
|
24 | + * |
|
25 | + * @var string |
|
26 | + */ |
|
27 | + public static $append = "\n"; |
|
28 | 28 | |
29 | - /** |
|
30 | - * Process a string outside of C-style comments that begin with "/*!" |
|
31 | - * |
|
32 | - * On each non-empty string outside these comments, the given processor |
|
33 | - * function will be called. The comments will be surrounded by |
|
34 | - * Minify_CommentPreserver::$preprend and Minify_CommentPreserver::$append. |
|
35 | - * |
|
36 | - * @param string $content |
|
37 | - * @param callback $processor function |
|
38 | - * @param array $args array of extra arguments to pass to the processor |
|
39 | - * function (default = array()) |
|
40 | - * @return string |
|
41 | - */ |
|
42 | - public static function process($content, $processor, $args = array()) |
|
43 | - { |
|
44 | - $ret = ''; |
|
45 | - while (true) { |
|
46 | - list($beforeComment, $comment, $afterComment) = self::_nextComment($content); |
|
47 | - if ('' !== $beforeComment) { |
|
48 | - $callArgs = $args; |
|
49 | - array_unshift($callArgs, $beforeComment); |
|
50 | - $ret .= call_user_func_array($processor, $callArgs); |
|
51 | - } |
|
52 | - if (false === $comment) { |
|
53 | - break; |
|
54 | - } |
|
55 | - $ret .= $comment; |
|
56 | - $content = $afterComment; |
|
57 | - } |
|
58 | - return $ret; |
|
59 | - } |
|
29 | + /** |
|
30 | + * Process a string outside of C-style comments that begin with "/*!" |
|
31 | + * |
|
32 | + * On each non-empty string outside these comments, the given processor |
|
33 | + * function will be called. The comments will be surrounded by |
|
34 | + * Minify_CommentPreserver::$preprend and Minify_CommentPreserver::$append. |
|
35 | + * |
|
36 | + * @param string $content |
|
37 | + * @param callback $processor function |
|
38 | + * @param array $args array of extra arguments to pass to the processor |
|
39 | + * function (default = array()) |
|
40 | + * @return string |
|
41 | + */ |
|
42 | + public static function process($content, $processor, $args = array()) |
|
43 | + { |
|
44 | + $ret = ''; |
|
45 | + while (true) { |
|
46 | + list($beforeComment, $comment, $afterComment) = self::_nextComment($content); |
|
47 | + if ('' !== $beforeComment) { |
|
48 | + $callArgs = $args; |
|
49 | + array_unshift($callArgs, $beforeComment); |
|
50 | + $ret .= call_user_func_array($processor, $callArgs); |
|
51 | + } |
|
52 | + if (false === $comment) { |
|
53 | + break; |
|
54 | + } |
|
55 | + $ret .= $comment; |
|
56 | + $content = $afterComment; |
|
57 | + } |
|
58 | + return $ret; |
|
59 | + } |
|
60 | 60 | |
61 | - /** |
|
62 | - * Extract comments that YUI Compressor preserves. |
|
63 | - * |
|
64 | - * @param string $in input |
|
65 | - * |
|
66 | - * @return array 3 elements are returned. If a YUI comment is found, the |
|
67 | - * 2nd element is the comment and the 1st and 3rd are the surrounding |
|
68 | - * strings. If no comment is found, the entire string is returned as the |
|
69 | - * 1st element and the other two are false. |
|
70 | - */ |
|
71 | - private static function _nextComment($in) |
|
72 | - { |
|
73 | - if ( |
|
74 | - false === ($start = strpos($in, '/*!')) |
|
75 | - || false === ($end = strpos($in, '*/', $start + 3)) |
|
76 | - ) { |
|
77 | - return array($in, false, false); |
|
78 | - } |
|
79 | - $ret = array( |
|
80 | - substr($in, 0, $start) |
|
81 | - ,self::$prepend . '/*!' . substr($in, $start + 3, $end - $start - 1) . self::$append |
|
82 | - ); |
|
83 | - $endChars = (strlen($in) - $end - 2); |
|
84 | - $ret[] = (0 === $endChars) |
|
85 | - ? '' |
|
86 | - : substr($in, -$endChars); |
|
87 | - return $ret; |
|
88 | - } |
|
61 | + /** |
|
62 | + * Extract comments that YUI Compressor preserves. |
|
63 | + * |
|
64 | + * @param string $in input |
|
65 | + * |
|
66 | + * @return array 3 elements are returned. If a YUI comment is found, the |
|
67 | + * 2nd element is the comment and the 1st and 3rd are the surrounding |
|
68 | + * strings. If no comment is found, the entire string is returned as the |
|
69 | + * 1st element and the other two are false. |
|
70 | + */ |
|
71 | + private static function _nextComment($in) |
|
72 | + { |
|
73 | + if ( |
|
74 | + false === ($start = strpos($in, '/*!')) |
|
75 | + || false === ($end = strpos($in, '*/', $start + 3)) |
|
76 | + ) { |
|
77 | + return array($in, false, false); |
|
78 | + } |
|
79 | + $ret = array( |
|
80 | + substr($in, 0, $start) |
|
81 | + ,self::$prepend . '/*!' . substr($in, $start + 3, $end - $start - 1) . self::$append |
|
82 | + ); |
|
83 | + $endChars = (strlen($in) - $end - 2); |
|
84 | + $ret[] = (0 === $endChars) |
|
85 | + ? '' |
|
86 | + : substr($in, -$endChars); |
|
87 | + return $ret; |
|
88 | + } |
|
89 | 89 | } |
@@ -20,123 +20,123 @@ |
||
20 | 20 | class Minify_Cache_ZendPlatform { |
21 | 21 | |
22 | 22 | |
23 | - /** |
|
24 | - * Create a Minify_Cache_ZendPlatform object, to be passed to |
|
25 | - * Minify::setCache(). |
|
26 | - * |
|
27 | - * @param int $expire seconds until expiration (default = 0 |
|
28 | - * meaning the item will not get an expiration date) |
|
29 | - * |
|
30 | - * @return null |
|
31 | - */ |
|
32 | - public function __construct($expire = 0) |
|
33 | - { |
|
34 | - $this->_exp = $expire; |
|
35 | - } |
|
36 | - |
|
37 | - |
|
38 | - /** |
|
39 | - * Write data to cache. |
|
40 | - * |
|
41 | - * @param string $id cache id |
|
42 | - * |
|
43 | - * @param string $data |
|
44 | - * |
|
45 | - * @return bool success |
|
46 | - */ |
|
47 | - public function store($id, $data) |
|
48 | - { |
|
49 | - return output_cache_put($id, "{$_SERVER['REQUEST_TIME']}|{$data}"); |
|
50 | - } |
|
51 | - |
|
52 | - |
|
53 | - /** |
|
54 | - * Get the size of a cache entry |
|
55 | - * |
|
56 | - * @param string $id cache id |
|
57 | - * |
|
58 | - * @return int size in bytes |
|
59 | - */ |
|
60 | - public function getSize($id) |
|
61 | - { |
|
62 | - return $this->_fetch($id) |
|
63 | - ? strlen($this->_data) |
|
64 | - : false; |
|
65 | - } |
|
66 | - |
|
67 | - |
|
68 | - /** |
|
69 | - * Does a valid cache entry exist? |
|
70 | - * |
|
71 | - * @param string $id cache id |
|
72 | - * |
|
73 | - * @param int $srcMtime mtime of the original source file(s) |
|
74 | - * |
|
75 | - * @return bool exists |
|
76 | - */ |
|
77 | - public function isValid($id, $srcMtime) |
|
78 | - { |
|
79 | - $ret = ($this->_fetch($id) && ($this->_lm >= $srcMtime)); |
|
80 | - return $ret; |
|
81 | - } |
|
82 | - |
|
83 | - |
|
84 | - /** |
|
85 | - * Send the cached content to output |
|
86 | - * |
|
87 | - * @param string $id cache id |
|
88 | - */ |
|
89 | - public function display($id) |
|
90 | - { |
|
91 | - echo $this->_fetch($id) |
|
92 | - ? $this->_data |
|
93 | - : ''; |
|
94 | - } |
|
95 | - |
|
96 | - |
|
97 | - /** |
|
98 | - * Fetch the cached content |
|
99 | - * |
|
100 | - * @param string $id cache id |
|
101 | - * |
|
102 | - * @return string |
|
103 | - */ |
|
104 | - public function fetch($id) |
|
105 | - { |
|
106 | - return $this->_fetch($id) |
|
107 | - ? $this->_data |
|
108 | - : ''; |
|
109 | - } |
|
110 | - |
|
111 | - |
|
112 | - private $_exp = null; |
|
113 | - |
|
114 | - |
|
115 | - // cache of most recently fetched id |
|
116 | - private $_lm = null; |
|
117 | - private $_data = null; |
|
118 | - private $_id = null; |
|
119 | - |
|
120 | - |
|
121 | - /** |
|
122 | - * Fetch data and timestamp from ZendPlatform, store in instance |
|
123 | - * |
|
124 | - * @param string $id |
|
125 | - * |
|
126 | - * @return bool success |
|
127 | - */ |
|
128 | - private function _fetch($id) |
|
129 | - { |
|
130 | - if ($this->_id === $id) { |
|
131 | - return true; |
|
132 | - } |
|
133 | - $ret = output_cache_get($id, $this->_exp); |
|
134 | - if (false === $ret) { |
|
135 | - $this->_id = null; |
|
136 | - return false; |
|
137 | - } |
|
138 | - list($this->_lm, $this->_data) = explode('|', $ret, 2); |
|
139 | - $this->_id = $id; |
|
140 | - return true; |
|
141 | - } |
|
23 | + /** |
|
24 | + * Create a Minify_Cache_ZendPlatform object, to be passed to |
|
25 | + * Minify::setCache(). |
|
26 | + * |
|
27 | + * @param int $expire seconds until expiration (default = 0 |
|
28 | + * meaning the item will not get an expiration date) |
|
29 | + * |
|
30 | + * @return null |
|
31 | + */ |
|
32 | + public function __construct($expire = 0) |
|
33 | + { |
|
34 | + $this->_exp = $expire; |
|
35 | + } |
|
36 | + |
|
37 | + |
|
38 | + /** |
|
39 | + * Write data to cache. |
|
40 | + * |
|
41 | + * @param string $id cache id |
|
42 | + * |
|
43 | + * @param string $data |
|
44 | + * |
|
45 | + * @return bool success |
|
46 | + */ |
|
47 | + public function store($id, $data) |
|
48 | + { |
|
49 | + return output_cache_put($id, "{$_SERVER['REQUEST_TIME']}|{$data}"); |
|
50 | + } |
|
51 | + |
|
52 | + |
|
53 | + /** |
|
54 | + * Get the size of a cache entry |
|
55 | + * |
|
56 | + * @param string $id cache id |
|
57 | + * |
|
58 | + * @return int size in bytes |
|
59 | + */ |
|
60 | + public function getSize($id) |
|
61 | + { |
|
62 | + return $this->_fetch($id) |
|
63 | + ? strlen($this->_data) |
|
64 | + : false; |
|
65 | + } |
|
66 | + |
|
67 | + |
|
68 | + /** |
|
69 | + * Does a valid cache entry exist? |
|
70 | + * |
|
71 | + * @param string $id cache id |
|
72 | + * |
|
73 | + * @param int $srcMtime mtime of the original source file(s) |
|
74 | + * |
|
75 | + * @return bool exists |
|
76 | + */ |
|
77 | + public function isValid($id, $srcMtime) |
|
78 | + { |
|
79 | + $ret = ($this->_fetch($id) && ($this->_lm >= $srcMtime)); |
|
80 | + return $ret; |
|
81 | + } |
|
82 | + |
|
83 | + |
|
84 | + /** |
|
85 | + * Send the cached content to output |
|
86 | + * |
|
87 | + * @param string $id cache id |
|
88 | + */ |
|
89 | + public function display($id) |
|
90 | + { |
|
91 | + echo $this->_fetch($id) |
|
92 | + ? $this->_data |
|
93 | + : ''; |
|
94 | + } |
|
95 | + |
|
96 | + |
|
97 | + /** |
|
98 | + * Fetch the cached content |
|
99 | + * |
|
100 | + * @param string $id cache id |
|
101 | + * |
|
102 | + * @return string |
|
103 | + */ |
|
104 | + public function fetch($id) |
|
105 | + { |
|
106 | + return $this->_fetch($id) |
|
107 | + ? $this->_data |
|
108 | + : ''; |
|
109 | + } |
|
110 | + |
|
111 | + |
|
112 | + private $_exp = null; |
|
113 | + |
|
114 | + |
|
115 | + // cache of most recently fetched id |
|
116 | + private $_lm = null; |
|
117 | + private $_data = null; |
|
118 | + private $_id = null; |
|
119 | + |
|
120 | + |
|
121 | + /** |
|
122 | + * Fetch data and timestamp from ZendPlatform, store in instance |
|
123 | + * |
|
124 | + * @param string $id |
|
125 | + * |
|
126 | + * @return bool success |
|
127 | + */ |
|
128 | + private function _fetch($id) |
|
129 | + { |
|
130 | + if ($this->_id === $id) { |
|
131 | + return true; |
|
132 | + } |
|
133 | + $ret = output_cache_get($id, $this->_exp); |
|
134 | + if (false === $ret) { |
|
135 | + $this->_id = null; |
|
136 | + return false; |
|
137 | + } |
|
138 | + list($this->_lm, $this->_data) = explode('|', $ret, 2); |
|
139 | + $this->_id = $id; |
|
140 | + return true; |
|
141 | + } |
|
142 | 142 | } |
@@ -19,122 +19,122 @@ |
||
19 | 19 | **/ |
20 | 20 | class Minify_Cache_Memcache { |
21 | 21 | |
22 | - /** |
|
23 | - * Create a Minify_Cache_Memcache object, to be passed to |
|
24 | - * Minify::setCache(). |
|
25 | - * |
|
26 | - * @param Memcache $memcache already-connected instance |
|
27 | - * |
|
28 | - * @param int $expire seconds until expiration (default = 0 |
|
29 | - * meaning the item will not get an expiration date) |
|
30 | - * |
|
31 | - * @return null |
|
32 | - */ |
|
33 | - public function __construct($memcache, $expire = 0) |
|
34 | - { |
|
35 | - $this->_mc = $memcache; |
|
36 | - $this->_exp = $expire; |
|
37 | - } |
|
22 | + /** |
|
23 | + * Create a Minify_Cache_Memcache object, to be passed to |
|
24 | + * Minify::setCache(). |
|
25 | + * |
|
26 | + * @param Memcache $memcache already-connected instance |
|
27 | + * |
|
28 | + * @param int $expire seconds until expiration (default = 0 |
|
29 | + * meaning the item will not get an expiration date) |
|
30 | + * |
|
31 | + * @return null |
|
32 | + */ |
|
33 | + public function __construct($memcache, $expire = 0) |
|
34 | + { |
|
35 | + $this->_mc = $memcache; |
|
36 | + $this->_exp = $expire; |
|
37 | + } |
|
38 | 38 | |
39 | - /** |
|
40 | - * Write data to cache. |
|
41 | - * |
|
42 | - * @param string $id cache id |
|
43 | - * |
|
44 | - * @param string $data |
|
45 | - * |
|
46 | - * @return bool success |
|
47 | - */ |
|
48 | - public function store($id, $data) |
|
49 | - { |
|
50 | - return $this->_mc->set($id, "{$_SERVER['REQUEST_TIME']}|{$data}", 0, $this->_exp); |
|
51 | - } |
|
39 | + /** |
|
40 | + * Write data to cache. |
|
41 | + * |
|
42 | + * @param string $id cache id |
|
43 | + * |
|
44 | + * @param string $data |
|
45 | + * |
|
46 | + * @return bool success |
|
47 | + */ |
|
48 | + public function store($id, $data) |
|
49 | + { |
|
50 | + return $this->_mc->set($id, "{$_SERVER['REQUEST_TIME']}|{$data}", 0, $this->_exp); |
|
51 | + } |
|
52 | 52 | |
53 | 53 | |
54 | - /** |
|
55 | - * Get the size of a cache entry |
|
56 | - * |
|
57 | - * @param string $id cache id |
|
58 | - * |
|
59 | - * @return int size in bytes |
|
60 | - */ |
|
61 | - public function getSize($id) |
|
62 | - { |
|
63 | - if (! $this->_fetch($id)) { |
|
64 | - return false; |
|
65 | - } |
|
66 | - return (function_exists('mb_strlen') && ((int)ini_get('mbstring.func_overload') & 2)) |
|
67 | - ? mb_strlen($this->_data, '8bit') |
|
68 | - : strlen($this->_data); |
|
69 | - } |
|
54 | + /** |
|
55 | + * Get the size of a cache entry |
|
56 | + * |
|
57 | + * @param string $id cache id |
|
58 | + * |
|
59 | + * @return int size in bytes |
|
60 | + */ |
|
61 | + public function getSize($id) |
|
62 | + { |
|
63 | + if (! $this->_fetch($id)) { |
|
64 | + return false; |
|
65 | + } |
|
66 | + return (function_exists('mb_strlen') && ((int)ini_get('mbstring.func_overload') & 2)) |
|
67 | + ? mb_strlen($this->_data, '8bit') |
|
68 | + : strlen($this->_data); |
|
69 | + } |
|
70 | 70 | |
71 | - /** |
|
72 | - * Does a valid cache entry exist? |
|
73 | - * |
|
74 | - * @param string $id cache id |
|
75 | - * |
|
76 | - * @param int $srcMtime mtime of the original source file(s) |
|
77 | - * |
|
78 | - * @return bool exists |
|
79 | - */ |
|
80 | - public function isValid($id, $srcMtime) |
|
81 | - { |
|
82 | - return ($this->_fetch($id) && ($this->_lm >= $srcMtime)); |
|
83 | - } |
|
71 | + /** |
|
72 | + * Does a valid cache entry exist? |
|
73 | + * |
|
74 | + * @param string $id cache id |
|
75 | + * |
|
76 | + * @param int $srcMtime mtime of the original source file(s) |
|
77 | + * |
|
78 | + * @return bool exists |
|
79 | + */ |
|
80 | + public function isValid($id, $srcMtime) |
|
81 | + { |
|
82 | + return ($this->_fetch($id) && ($this->_lm >= $srcMtime)); |
|
83 | + } |
|
84 | 84 | |
85 | - /** |
|
86 | - * Send the cached content to output |
|
87 | - * |
|
88 | - * @param string $id cache id |
|
89 | - */ |
|
90 | - public function display($id) |
|
91 | - { |
|
92 | - echo $this->_fetch($id) |
|
93 | - ? $this->_data |
|
94 | - : ''; |
|
95 | - } |
|
85 | + /** |
|
86 | + * Send the cached content to output |
|
87 | + * |
|
88 | + * @param string $id cache id |
|
89 | + */ |
|
90 | + public function display($id) |
|
91 | + { |
|
92 | + echo $this->_fetch($id) |
|
93 | + ? $this->_data |
|
94 | + : ''; |
|
95 | + } |
|
96 | 96 | |
97 | 97 | /** |
98 | - * Fetch the cached content |
|
99 | - * |
|
100 | - * @param string $id cache id |
|
101 | - * |
|
102 | - * @return string |
|
103 | - */ |
|
104 | - public function fetch($id) |
|
105 | - { |
|
106 | - return $this->_fetch($id) |
|
107 | - ? $this->_data |
|
108 | - : ''; |
|
109 | - } |
|
98 | + * Fetch the cached content |
|
99 | + * |
|
100 | + * @param string $id cache id |
|
101 | + * |
|
102 | + * @return string |
|
103 | + */ |
|
104 | + public function fetch($id) |
|
105 | + { |
|
106 | + return $this->_fetch($id) |
|
107 | + ? $this->_data |
|
108 | + : ''; |
|
109 | + } |
|
110 | 110 | |
111 | - private $_mc = null; |
|
112 | - private $_exp = null; |
|
111 | + private $_mc = null; |
|
112 | + private $_exp = null; |
|
113 | 113 | |
114 | - // cache of most recently fetched id |
|
115 | - private $_lm = null; |
|
116 | - private $_data = null; |
|
117 | - private $_id = null; |
|
114 | + // cache of most recently fetched id |
|
115 | + private $_lm = null; |
|
116 | + private $_data = null; |
|
117 | + private $_id = null; |
|
118 | 118 | |
119 | 119 | /** |
120 | - * Fetch data and timestamp from memcache, store in instance |
|
121 | - * |
|
122 | - * @param string $id |
|
123 | - * |
|
124 | - * @return bool success |
|
125 | - */ |
|
126 | - private function _fetch($id) |
|
127 | - { |
|
128 | - if ($this->_id === $id) { |
|
129 | - return true; |
|
130 | - } |
|
131 | - $ret = $this->_mc->get($id); |
|
132 | - if (false === $ret) { |
|
133 | - $this->_id = null; |
|
134 | - return false; |
|
135 | - } |
|
136 | - list($this->_lm, $this->_data) = explode('|', $ret, 2); |
|
137 | - $this->_id = $id; |
|
138 | - return true; |
|
139 | - } |
|
120 | + * Fetch data and timestamp from memcache, store in instance |
|
121 | + * |
|
122 | + * @param string $id |
|
123 | + * |
|
124 | + * @return bool success |
|
125 | + */ |
|
126 | + private function _fetch($id) |
|
127 | + { |
|
128 | + if ($this->_id === $id) { |
|
129 | + return true; |
|
130 | + } |
|
131 | + $ret = $this->_mc->get($id); |
|
132 | + if (false === $ret) { |
|
133 | + $this->_id = null; |
|
134 | + return false; |
|
135 | + } |
|
136 | + list($this->_lm, $this->_data) = explode('|', $ret, 2); |
|
137 | + $this->_id = $id; |
|
138 | + return true; |
|
139 | + } |
|
140 | 140 | } |