PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 4.5.4
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v4.5.4
4.7.0 4.6.1 4.6.0 4.5.5 4.5.4 4.5.3 4.5.2 3.2.20 3.2.21 3.2.22 3.2.3 3.2.5 3.2.6 3.2.7 3.2.9 3.3.0 3.3.1 3.3.2 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.7.0 3.7.1 All 111 releases
wp-optimize / vendor / mrclay / minify / lib / Minify / Source / Factory.php

Factory.php in WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance 4.5.4, at vendor/mrclay/minify/lib/Minify/Source/Factory.php

198 lines 6.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class Minify_Source_Factory
4 {
5
6 /**
7 * @var array
8 */
9 protected $options;
10
11 /**
12 * @var callable[]
13 */
14 protected $handlers = array();
15
16 /**
17 * @var Minify_Env
18 */
19 protected $env;
20
21 /**
22 * @param Minify_Env $env
23 * @param array $options
24 *
25 * noMinPattern : Pattern matched against basename of the filepath (if present). If the pattern
26 * matches, Minify will try to avoid re-compressing the resource.
27 *
28 * fileChecker : Callable responsible for verifying the existence of the file.
29 *
30 * resolveDocRoot : If true, a leading "//" will be replaced with the document root.
31 *
32 * checkAllowDirs : If true, the filepath will be verified to be within one of the directories
33 * specified by allowDirs.
34 *
35 * allowDirs : Directory paths in which sources can be served.
36 *
37 * uploaderHoursBehind : How many hours behind are the file modification times of uploaded files?
38 * If you upload files from Windows to a non-Windows server, Windows may report
39 * incorrect mtimes for the files. Immediately after modifying and uploading a
40 * file, use the touch command to update the mtime on the server. If the mtime
41 * jumps ahead by a number of hours, set this variable to that number. If the mtime
42 * moves back, this should not be needed.
43 *
44 * @param Minify_CacheInterface $cache Optional cache for handling .less files.
45 *
46 */
47 public function __construct(Minify_Env $env, array $options = array(), Minify_CacheInterface $cache = null)
48 {
49 $this->env = $env;
50 $this->options = array_merge(array(
51 'noMinPattern' => '@[-\\.]min\\.(?:[a-zA-Z]+)$@i', // matched against basename
52 'fileChecker' => array($this, 'checkIsFile'),
53 'resolveDocRoot' => true,
54 'checkAllowDirs' => true,
55 'allowDirs' => array('//'),
56 'uploaderHoursBehind' => 0,
57 ), $options);
58
59 // resolve // in allowDirs
60 $docRoot = $env->getDocRoot();
61 foreach ($this->options['allowDirs'] as $i => $dir) {
62 if (0 === strpos($dir, '//')) {
63 $this->options['allowDirs'][$i] = $docRoot . substr($dir, 1);
64 }
65 }
66
67 if ($this->options['fileChecker'] && !is_callable($this->options['fileChecker'])) {
68 throw new InvalidArgumentException("fileChecker option is not callable");
69 }
70
71 $this->setHandler('~\.less$~i', function ($spec) use ($cache) {
72 return new Minify_LessCssSource($spec, $cache);
73 });
74
75 $this->setHandler('~\.scss~i', function ($spec) use ($cache) {
76 return new Minify_ScssCssSource($spec, $cache);
77 });
78
79 $this->setHandler('~\.(js|css)$~i', function ($spec) {
80 return new Minify_Source($spec);
81 });
82 }
83
84 /**
85 * @param string $basenamePattern A pattern tested against basename. E.g. "~\.css$~"
86 * @param callable $handler Function that recieves a $spec array and returns a Minify_SourceInterface
87 */
88 public function setHandler($basenamePattern, $handler)
89 {
90 $this->handlers[$basenamePattern] = $handler;
91 }
92
93 /**
94 * @param string $file
95 * @return string
96 *
97 * @throws Minify_Source_FactoryException
98 */
99 public function checkIsFile($file)
100 {
101 $realpath = realpath($file);
102 if (!$realpath) {
103 throw new Minify_Source_FactoryException("File failed realpath(): $file");
104 }
105
106 $basename = basename($file);
107 if (0 === strpos($basename, '.')) {
108 throw new Minify_Source_FactoryException("Filename starts with period (may be hidden): $basename");
109 }
110
111 if (!is_file($realpath) || !is_readable($realpath)) {
112 throw new Minify_Source_FactoryException("Not a file or isn't readable: $file");
113 }
114
115 return $realpath;
116 }
117
118 /**
119 * @param mixed $spec
120 *
121 * @return Minify_SourceInterface
122 *
123 * @throws Minify_Source_FactoryException
124 */
125 public function makeSource($spec)
126 {
127 if (is_string($spec)) {
128 $spec = array(
129 'filepath' => $spec,
130 );
131 } elseif ($spec instanceof Minify_SourceInterface) {
132 return $spec;
133 }
134
135 $source = null;
136
137 if (empty($spec['filepath'])) {
138 // not much we can check
139 return new Minify_Source($spec);
140 }
141
142 if ($this->options['resolveDocRoot'] && 0 === strpos($spec['filepath'], '//')) {
143 $spec['filepath'] = $this->env->getDocRoot() . substr($spec['filepath'], 1);
144 }
145
146 if (!empty($this->options['fileChecker'])) {
147 $spec['filepath'] = call_user_func($this->options['fileChecker'], $spec['filepath']);
148 }
149
150 if ($this->options['checkAllowDirs']) {
151 $allowDirs = (array)$this->options['allowDirs'];
152 $inAllowedDir = false;
153 $filePath = $this->env->normalizePath($spec['filepath']);
154 foreach ($allowDirs as $allowDir) {
155 if (strpos($filePath, $this->env->normalizePath($allowDir)) === 0) {
156 $inAllowedDir = true;
157 }
158 }
159
160 if (!$inAllowedDir) {
161 $allowDirsStr = implode(';', $allowDirs);
162 throw new Minify_Source_FactoryException("File '{$spec['filepath']}' is outside \$allowDirs "
163 . "($allowDirsStr). If the path is resolved via an alias/symlink, look into the "
164 . "\$min_symlinks option.");
165 }
166 }
167
168 $basename = basename($spec['filepath']);
169
170 if ($this->options['noMinPattern'] && preg_match($this->options['noMinPattern'], $basename)) {
171 if (preg_match('~\.(css|less)$~i', $basename)) {
172 $spec['minifyOptions']['compress'] = false;
173 // we still want URI rewriting to work for CSS
174 } else {
175 $spec['minifier'] = 'Minify::nullMinifier';
176 }
177 }
178
179 $hoursBehind = $this->options['uploaderHoursBehind'];
180 if ($hoursBehind != 0) {
181 $spec['uploaderHoursBehind'] = $hoursBehind;
182 }
183
184 foreach ($this->handlers as $basenamePattern => $handler) {
185 if (preg_match($basenamePattern, $basename)) {
186 $source = call_user_func($handler, $spec);
187 break;
188 }
189 }
190
191 if (!$source) {
192 throw new Minify_Source_FactoryException("Handler not found for file: $basename");
193 }
194
195 return $source;
196 }
197 }
198