This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace BootPress\Asset; |
||
4 | |||
5 | use BootPress\Page\Component as Page; |
||
6 | use BootPress\SQLite\Component as SQLite; |
||
7 | use Symfony\Component\HttpFoundation\Response; |
||
8 | use Symfony\Component\HttpFoundation\StreamedResponse; |
||
9 | use Symfony\Component\HttpFoundation\BinaryFileResponse; |
||
10 | use League\Glide\Responses\SymfonyResponseFactory; |
||
11 | use League\Glide\ServerFactory; |
||
12 | use MatthiasMullie\Minify; |
||
13 | use phpUri; |
||
14 | |||
15 | class Component |
||
16 | { |
||
17 | const PREG_TYPES = 'jpe?g|gif|png|ico|js|css|pdf|ttf|otf|svg|eot|woff2?|swf|tar|t?gz|g?zip|csv|xls?x?|word|docx?|pptx?|psd|ogg|wav|mp3|mp4|mpeg?|mpg|mov|qt'; |
||
18 | public static $instance; // made public to facilitate testing |
||
19 | public static $not_found = array(); |
||
20 | public static $urls = array(); |
||
21 | private $cached = null; |
||
22 | private $db = null; |
||
23 | |||
24 | /** |
||
25 | * Prepares a Symfony Response for you to send. |
||
26 | * |
||
27 | * @param string $file Either a file location, or the type of file you are sending eg. html, txt, less, scss, json, xml, rdf, rss, atom, js, css |
||
28 | * @param array|string $options An array of options if ``$file`` is a location, or the string of data you want to send. The available options are: |
||
29 | * |
||
30 | * - '**name**' - changes a downloadable asset's file name |
||
31 | * - |
||
32 | * - |
||
33 | * |
||
34 | * @return object A Symfony\Component\HttpFoundation\Response |
||
35 | */ |
||
36 | 8 | public static function dispatch($file, $options = array()) |
|
37 | { |
||
38 | 8 | $set = array_merge(array( |
|
39 | 8 | 'name' => '', |
|
40 | 8 | 'expires' => 0, |
|
41 | 8 | 'xsendfile' => false, |
|
42 | 8 | ), (array) $options); |
|
43 | 8 | $page = Page::html(); |
|
44 | 8 | if (preg_match('/^(html|txt|less|scss|json|xml|rdf|rss|atom|js|css)$/', $file)) { |
|
45 | 4 | if (is_array($options)) { |
|
46 | 3 | foreach ($options as $updated => $content) { |
|
47 | 3 | if (is_numeric($updated)) { |
|
48 | 3 | break; |
|
49 | } |
||
50 | 3 | } |
|
51 | 3 | } else { |
|
52 | 3 | $content = (string) $options; |
|
53 | } |
||
54 | 4 | $response = new Response($content, Response::HTTP_OK, array( |
|
0 ignored issues
–
show
|
|||
55 | 4 | 'Content-Type' => static::mime($file), |
|
56 | 4 | 'Content-Length' => mb_strlen($content), |
|
57 | 4 | )); |
|
58 | 4 | if (isset($updated) && (int) $updated > 631152000) { // 01-01-1990 |
|
59 | 3 | $response->setCache(array( |
|
60 | 3 | 'public' => true, |
|
61 | 3 | 'max_age' => $set['expires'], |
|
62 | 3 | 's_maxage' => $set['expires'], |
|
63 | 3 | 'last_modified' => \DateTime::createFromFormat('U', (int) $updated), |
|
64 | 3 | ))->isNotModified($page->request); |
|
65 | 3 | } |
|
66 | |||
67 | 4 | return $response; |
|
68 | } |
||
69 | 5 | $type = strtolower(pathinfo($file, PATHINFO_EXTENSION)); |
|
70 | 5 | if (is_null($file) || !is_file($file)) { |
|
71 | 2 | return new Response('', Response::HTTP_NOT_FOUND); |
|
72 | } |
||
73 | 4 | if (null === $mime = static::mime($type)) { |
|
74 | 1 | return new Response('', Response::HTTP_NOT_IMPLEMENTED); |
|
75 | } |
||
76 | 4 | if (preg_match('/^('.implode('|', array( |
|
77 | 4 | '(?P<download>tar|t?gz|g?zip|csv|xls?x?|word|docx?|pptx?|psd)', |
|
78 | 4 | '(?P<stream>ogg|wav|mp3|mp4|mpeg?|mpg|mov|qt)', |
|
79 | 4 | )).')$/', $type, $matches)) { |
|
80 | 2 | $response = new BinaryFileResponse($file); |
|
81 | 2 | $response->headers->set('Content-Type', $mime); |
|
82 | 2 | $response->setContentDisposition(isset($matches['download']) ? 'attachment' : 'inline', $set['name']); |
|
83 | 2 | if ($set['xsendfile']) { |
|
84 | 1 | BinaryFileResponse::trustXSendfileTypeHeader(); |
|
85 | 1 | } |
|
86 | |||
87 | 2 | return $response; |
|
88 | } |
||
89 | 3 | $file = new \SplFileInfo($file); |
|
90 | $response = new StreamedResponse(function () use ($file) { |
||
91 | 1 | if ($fp = fopen($file->getPathname(), 'rb')) { |
|
92 | 1 | rewind($fp); |
|
93 | 1 | fpassthru($fp); |
|
94 | 1 | fclose($fp); |
|
95 | 1 | } |
|
96 | 3 | }, 200, array( |
|
97 | 3 | 'Content-Type' => $mime, |
|
98 | 3 | 'Content-Length' => $file->getSize(), |
|
99 | 3 | )); |
|
100 | 3 | $response->setCache(array( |
|
101 | 3 | 'public' => true, |
|
102 | 3 | 'max_age' => $set['expires'], |
|
103 | 3 | 's_maxage' => $set['expires'], |
|
104 | 3 | 'last_modified' => \DateTime::createFromFormat('U', $file->getMTime()), |
|
105 | 3 | )); |
|
106 | 3 | $response->isNotModified($page->request); |
|
107 | |||
108 | 3 | return $response; |
|
109 | } |
||
110 | |||
111 | 6 | public static function cached($dir, array $glide = array()) |
|
112 | { |
||
113 | 6 | $page = Page::html(); |
|
114 | 6 | static::$instance = new static(); |
|
115 | 6 | $asset = static::$instance; |
|
116 | 6 | $asset->cached = $page->dir($dir); |
|
117 | 6 | $type = strtolower($page->url['format']); |
|
118 | 6 | if ($type == 'html') { |
|
119 | 2 | $page->filter('page', array($asset, 'urls'), 'this'); |
|
120 | |||
121 | 2 | return false; |
|
122 | 5 | } elseif (!preg_match('/^'.implode('', array( |
|
123 | 5 | '(?P<paths>([1-9a-z]{5}[0]?)+)', |
|
124 | 5 | '(\/.*)?', |
|
125 | 5 | '\.('.self::PREG_TYPES.')', |
|
126 | 5 | )).'$/i', $page->url['path'], $matches)) { |
|
127 | 1 | return false; |
|
128 | } |
||
129 | 5 | $paths = explode('0', rtrim($matches['paths'], '0')); |
|
130 | 5 | foreach ($paths as $key => $value) { |
|
131 | 5 | $paths[$key] = '"'.$value.'"'; |
|
132 | 5 | } |
|
133 | 5 | $minify = array(); |
|
134 | 5 | $image = null; |
|
135 | 5 | $file = null; |
|
136 | 5 | $asset->openDatabase(); |
|
137 | 5 | if ($stmt = $asset->db->query(array( |
|
138 | 5 | 'SELECT p.tiny, f.file, f.query', |
|
139 | 5 | 'FROM paths as p', |
|
140 | 5 | 'INNER JOIN files AS f ON p.file_id = f.id', |
|
141 | 5 | 'WHERE p.tiny IN('.implode(', ', $paths).')', |
|
142 | 5 | $asset->db->orderIn('p.tiny', $paths), |
|
143 | 5 | ), '', 'assoc')) { |
|
0 ignored issues
–
show
'' is of type string , but the function expects a array .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
144 | 5 | while ($row = $asset->db->fetch($stmt)) { |
|
145 | 4 | if ($type == strtolower(pathinfo($row['file'], PATHINFO_EXTENSION))) { |
|
146 | switch ($type) { |
||
147 | 4 | case 'js': |
|
148 | 4 | case 'css': |
|
149 | 2 | if (is_file($row['file'])) { |
|
150 | 2 | $minify[$row['file']] = $row; |
|
151 | 2 | } |
|
152 | 2 | break 1; |
|
153 | 2 | case 'jpeg': |
|
154 | 2 | case 'jpg': |
|
155 | 2 | case 'gif': |
|
156 | 2 | case 'png': |
|
157 | 1 | if (!empty($row['query'])) { |
|
158 | 1 | parse_str($row['query'], $params); |
|
159 | 1 | $setup = $glide; |
|
160 | $glide = array( |
||
161 | 1 | 'cache' => $asset->cached.'glide/', |
|
162 | 1 | 'source' => dirname($row['file']), |
|
163 | 1 | 'response' => new SymfonyResponseFactory($page->request), |
|
164 | 1 | ); |
|
165 | 1 | if (isset($setup['group_cache_in_folders']) && is_bool($setup['group_cache_in_folders'])) { |
|
166 | 1 | $glide['group_cache_in_folders'] = $setup['group_cache_in_folders']; |
|
167 | 1 | } |
|
168 | 1 | if (isset($setup['watermarks'])) { |
|
169 | 1 | $glide['watermarks'] = rtrim(str_replace('\\', '/', $setup['watermarks']), '/'); |
|
170 | 1 | } |
|
171 | 1 | if (isset($setup['driver']) && in_array($setup['driver'], array('gd', 'imagick'))) { |
|
172 | 1 | $glide['driver'] = $setup['driver']; |
|
173 | 1 | } |
|
174 | 1 | if (isset($setup['max_image_size']) && is_numeric($setup['max_image_size'])) { |
|
175 | 1 | $glide['max_image_size'] = (int) $setup['max_image_size']; |
|
176 | 1 | } |
|
177 | 1 | $glide = ServerFactory::create($glide); |
|
178 | 1 | $image = $glide->getImageResponse(basename($row['file']), $params); |
|
0 ignored issues
–
show
It seems like
$params can also be of type null ; however, League\Glide\Server::getImageResponse() does only seem to accept array , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
179 | 1 | break 2; |
|
180 | } |
||
181 | 1 | default: |
|
182 | 1 | $file = $row['file']; |
|
183 | 1 | break 2; |
|
184 | 1 | } |
|
185 | 2 | } |
|
186 | 2 | } |
|
187 | 5 | $asset->db->close($stmt); |
|
188 | 5 | } |
|
189 | 5 | $asset->closeDatabase(); |
|
190 | 5 | if (!empty($minify)) { |
|
191 | 2 | $paths = array(); |
|
192 | 2 | foreach ($minify as $row) { |
|
193 | 2 | $paths[] = $row['tiny']; |
|
194 | 2 | } |
|
195 | 2 | $file = implode('/', array( |
|
196 | 2 | $asset->cached.'minify', |
|
197 | 2 | md5($page->url['base']), |
|
198 | 2 | implode('0', $paths), |
|
199 | 2 | )).'.'.$type; |
|
200 | 2 | if (!is_dir(dirname($file))) { |
|
201 | 1 | mkdir(dirname($file), 0755, true); |
|
202 | 1 | } |
|
203 | 2 | if (!is_file($file)) { |
|
204 | switch ($type) { |
||
205 | 2 | case 'js': |
|
206 | 1 | $minifier = new Minify\JS(); |
|
207 | 1 | foreach ($minify as $js => $row) { |
|
208 | 1 | $minifier->add($js); |
|
209 | 1 | } |
|
210 | 1 | $minifier->minify($file); |
|
211 | 1 | break; |
|
212 | 1 | case 'css': |
|
213 | 1 | $minifier = new Minify\CSS(); |
|
214 | 1 | foreach ($minify as $css => $row) { |
|
215 | 1 | $minifier->add($asset->css($css, $row)); |
|
216 | 1 | } |
|
217 | 1 | $minifier->minify($file); |
|
218 | 1 | break; |
|
219 | } |
||
220 | 2 | } |
|
221 | 2 | } |
|
222 | |||
223 | 5 | return ($image) ? $image : static::dispatch($file, array('expires' => 31536000)); |
|
224 | } |
||
225 | |||
226 | 2 | public static function urls($html) |
|
227 | { |
||
228 | 2 | if (is_null(static::$instance) || empty($html)) { |
|
229 | 1 | return $html; |
|
230 | } |
||
231 | 2 | $asset = static::$instance; |
|
232 | 2 | $page = Page::html(); |
|
233 | 2 | $array = (is_array($html)) ? $html : false; |
|
234 | 2 | if ($array) { |
|
235 | 1 | $html = array(); |
|
236 | array_walk_recursive($array, function ($value) use (&$html) { |
||
237 | 1 | $html[] = $value; |
|
238 | 1 | }); |
|
239 | 1 | $html = implode(' ', $html); |
|
240 | 1 | } |
|
241 | 2 | preg_match_all('/'.implode('', array( |
|
242 | 2 | '('.$page->url['preg'].')', |
|
243 | 2 | '(?P<dir>['.$page->url['chars'].']+)\/', |
|
244 | 2 | '(?P<file>['.$page->url['chars'].'.\/]+\.(?P<ext>'.self::PREG_TYPES.'))', |
|
245 | 2 | '(?P<query>\?['.$page->url['chars'].'&;=.\/]+)?', |
|
246 | 2 | '(#(?P<frag>['.$page->url['chars'].'.\/#]+))?', |
|
247 | 2 | )).'/i', $html, $matches, PREG_SET_ORDER); |
|
248 | 2 | if (empty($matches)) { |
|
249 | 1 | return $array ? $array : $html; |
|
250 | } |
||
251 | 2 | $asset->openDatabase(); |
|
252 | 2 | $cache = array(); |
|
253 | 2 | $assets = array(); |
|
254 | 2 | $found = $page->dir; // in PHP7 isset($page->dir[$url]) will not work on a private property retrieved via ``__get()`` |
|
255 | 2 | foreach ($matches as $url) { |
|
256 | 2 | $dir = $url['dir']; |
|
257 | 2 | if (!isset($found[$dir])) { |
|
258 | 1 | static::$not_found[] = substr($url[0], strlen($page->url['base'])); |
|
259 | 1 | continue; |
|
260 | } |
||
261 | 2 | $ext = strtolower($url['ext']); |
|
262 | 2 | $file = $url['file']; |
|
263 | 2 | if (isset($url['query']) && in_array($ext, array('jpeg', 'jpg', 'gif', 'png'))) { |
|
264 | 2 | $file .= $url['query']; |
|
265 | 2 | } |
|
266 | 2 | $files = array(); |
|
267 | 2 | $files[$file] = pathinfo($url['file'], PATHINFO_FILENAME); |
|
268 | 2 | if (isset($url['frag'])) { |
|
269 | 1 | $frag = explode('#', $url['frag']); |
|
270 | 1 | if ($ext == 'js' || $ext == 'css') { |
|
271 | 1 | $base = phpUri::parse($page->dir[$dir].$file); |
|
272 | 1 | foreach ($frag as $file) { |
|
273 | 1 | $file = $base->join($file); |
|
274 | 1 | $info = pathinfo($file); |
|
275 | 1 | if (is_file($file) && $info['extension'] == $ext) { |
|
276 | 1 | $file = substr($file, strlen($page->dir[$dir])); |
|
277 | 1 | $files[$file] = $info['filename']; |
|
278 | 1 | } |
|
279 | 1 | } |
|
280 | 1 | } else { |
|
281 | 1 | $files[$file] = pathinfo(array_shift($frag), PATHINFO_FILENAME); |
|
282 | } |
||
283 | 1 | } |
|
284 | 2 | foreach ($files as $file => $name) { |
|
285 | 2 | $cache[$dir][$file] = array(); |
|
286 | 2 | } |
|
287 | 2 | $assets[$url[0]] = array( |
|
288 | 2 | 'dir' => $dir, |
|
289 | 2 | 'file' => array_keys($files), |
|
290 | 2 | 'name' => implode('-', $files), |
|
291 | 2 | 'ext' => '.'.$ext, |
|
292 | ); |
||
293 | 2 | } |
|
294 | 2 | $asset->paths($cache); |
|
295 | 2 | $asset->closeDatabase(); |
|
296 | 2 | $rnr = array(); |
|
297 | 2 | $base = strlen($page->url['base']); |
|
298 | 2 | foreach ($assets as $match => $url) { |
|
299 | 2 | $cached = array(); |
|
300 | 2 | foreach ($url['file'] as $file) { |
|
301 | 2 | $cached[] = $cache[$url['dir']][$file]; |
|
302 | 2 | } |
|
303 | 2 | $cached = implode(0, $cached); |
|
304 | 2 | if (!is_numeric($url['name'])) { |
|
305 | 2 | $cached .= '/'.$url['name']; |
|
306 | 2 | } |
|
307 | 2 | $cached .= $url['ext']; |
|
308 | 2 | $rnr[$page->url['base'].$cached] = $match; // replace => remove |
|
309 | 2 | static::$urls[substr($match, $base)] = $cached; |
|
310 | 2 | } |
|
311 | 2 | ksort(static::$urls); |
|
312 | 2 | uasort($rnr, function($a, $b) { // ORDER BY strlen(remove) DESC so we don't step on any toes |
|
313 | 2 | return mb_strlen($b) - mb_strlen($a); |
|
314 | 2 | }); |
|
315 | 2 | $rnr = array_flip($rnr); // remove => replace |
|
316 | 2 | return str_replace(array_keys($rnr), array_values($rnr), $array ? $array : $html); |
|
317 | } |
||
318 | |||
319 | 8 | public static function mime($type) |
|
320 | { |
||
321 | 8 | $mime = null; |
|
322 | 8 | $single = (is_array($type)) ? false : true; |
|
323 | 8 | if (is_array($type)) { |
|
324 | 1 | $type = array_shift($type); |
|
325 | 1 | } |
|
326 | 8 | switch (strtolower($type)) { |
|
327 | 8 | case 'html': |
|
328 | 3 | $mime = array('text/html', 'application/xhtml+xml', 'text/plain'); |
|
329 | 3 | break; |
|
330 | 8 | case 'txt': |
|
331 | 2 | $mime = array('text/plain'); |
|
332 | 2 | break; |
|
333 | 8 | case 'less': |
|
334 | 1 | $mime = array('text/x-less', 'text/css', 'text/plain', 'application/octet-stream'); |
|
335 | 1 | break; |
|
336 | 8 | case 'scss': |
|
337 | 1 | $mime = array('text/css', 'text/plain', 'application/octet-stream'); |
|
338 | 1 | break; |
|
339 | 8 | case 'json': |
|
340 | 1 | $mime = array('application/json', 'application/x-json', 'text/json', 'text/plain'); |
|
341 | 1 | break; |
|
342 | 8 | case 'xml': |
|
343 | 3 | $mime = array('application/xml', 'application/x-xml', 'text/xml', 'text/plain'); |
|
344 | 3 | break; |
|
345 | 6 | case 'rdf': |
|
346 | 1 | $mime = array('application/rdf+xml'); |
|
347 | 1 | break; |
|
348 | 6 | case 'rss': |
|
349 | 2 | $mime = array('application/rss+xml'); |
|
350 | 2 | break; |
|
351 | 5 | case 'atom': |
|
352 | 1 | $mime = array('application/atom+xml'); |
|
353 | 1 | break; |
|
354 | 5 | case 'jpeg': |
|
355 | 5 | case 'jpg': |
|
356 | 2 | $mime = array('image/jpeg', 'image/pjpeg'); |
|
357 | 2 | break; |
|
358 | 5 | case 'gif': |
|
359 | 1 | $mime = array('image/gif'); |
|
360 | 1 | break; |
|
361 | 5 | case 'png': |
|
362 | 1 | $mime = array('image/png', 'image/x-png'); |
|
363 | 1 | break; |
|
364 | 5 | case 'ico': |
|
365 | 1 | $mime = array('image/x-icon', 'image/vnd.microsoft.icon'); |
|
366 | 1 | break; |
|
367 | 5 | case 'js': |
|
368 | 2 | $mime = array('application/javascript', 'application/x-javascript', 'text/javascript', 'text/plain'); |
|
369 | 2 | break; |
|
370 | 4 | case 'css': |
|
371 | 2 | $mime = array('text/css', 'text/plain'); |
|
372 | 2 | break; |
|
373 | 3 | case 'pdf': |
|
374 | 1 | $mime = array('application/pdf', 'application/force-download', 'application/x-download', 'binary/octet-stream'); |
|
375 | 1 | break; |
|
376 | 3 | case 'ttf': |
|
377 | 1 | $mime = array('application/font-sfnt', 'application/font-ttf', 'application/x-font-ttf', 'font/ttf', 'font/truetype', 'application/octet-stream'); |
|
378 | 1 | break; |
|
379 | 3 | case 'otf': |
|
380 | 1 | $mime = array('application/font-sfnt', 'application/font-otf', 'application/x-font-otf', 'font/opentype', 'application/octet-stream'); |
|
381 | 1 | break; |
|
382 | 3 | case 'svg': |
|
383 | 1 | $mime = array('image/svg+xml', 'application/xml', 'text/xml'); |
|
384 | 1 | break; |
|
385 | 3 | case 'eot': |
|
386 | 1 | $mime = array('application/vnd.ms-fontobject', 'application/octet-stream'); |
|
387 | 1 | break; |
|
388 | 3 | case 'woff': |
|
389 | 1 | $mime = array('application/font-woff', 'application/x-woff', 'application/x-font-woff', 'font/x-woff', 'application/octet-stream'); |
|
390 | 1 | break; |
|
391 | 3 | case 'woff2': |
|
392 | 1 | $mime = array('application/font-woff2', 'font/woff2', 'application/octet-stream'); |
|
393 | 1 | break; |
|
394 | 3 | case 'swf': |
|
395 | 1 | $mime = array('application/x-shockwave-flash'); |
|
396 | 1 | break; |
|
397 | 3 | case 'tar': |
|
398 | 1 | $mime = array('application/x-tar'); |
|
399 | 1 | break; |
|
400 | 3 | case 'tgz': |
|
401 | 1 | $mime = array('application/x-tar', 'application/x-gzip-compressed'); |
|
402 | 1 | break; |
|
403 | 3 | case 'gz': |
|
404 | 3 | case 'gzip': |
|
405 | 1 | $mime = array('application/x-gzip'); |
|
406 | 1 | break; |
|
407 | 3 | case 'zip': |
|
408 | 1 | $mime = array('application/x-zip', 'application/zip', 'application/x-zip-compressed', 'application/s-compressed', 'multipart/x-zip'); |
|
409 | 1 | break; |
|
410 | 3 | case 'csv': |
|
411 | 3 | $mime = array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain'); |
|
412 | 3 | break; |
|
413 | 2 | case 'xl': |
|
414 | 1 | $mime = array('application/excel'); |
|
415 | 1 | break; |
|
416 | 2 | case 'xls': |
|
417 | 1 | $mime = array('application/vnd.ms-excel', 'application/msexcel', 'application/x-msexcel', 'application/x-ms-excel', 'application/x-excel', 'application/x-dos_ms_excel', 'application/xls', 'application/x-xls', 'application/excel', 'application/download', 'application/vnd.ms-office', 'application/msword'); |
|
418 | 1 | break; |
|
419 | 2 | case 'xlsx': |
|
420 | 1 | $mime = array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip', 'application/vnd.ms-excel', 'application/msword', 'application/x-zip'); |
|
421 | 1 | break; |
|
422 | 2 | case 'word': |
|
423 | 1 | $mime = array('application/msword', 'application/octet-stream'); |
|
424 | 1 | break; |
|
425 | 2 | case 'doc': |
|
426 | 1 | $mime = array('application/msword', 'application/vnd.ms-office'); |
|
427 | 1 | break; |
|
428 | 2 | case 'docx': |
|
429 | 1 | $mime = array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword', 'application/x-zip'); |
|
430 | 1 | break; |
|
431 | 2 | case 'ppt': |
|
432 | 1 | $mime = array('application/powerpoint', 'application/vnd.ms-powerpoint', 'application/vnd.ms-office', 'application/msword'); |
|
433 | 1 | break; |
|
434 | 2 | case 'pptx': |
|
435 | 1 | $mime = array('application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/x-zip', 'application/zip'); |
|
436 | 1 | break; |
|
437 | 2 | case 'psd': |
|
438 | 1 | $mime = array('application/x-photoshop', 'image/vnd.adobe.photoshop'); |
|
439 | 1 | break; |
|
440 | 2 | case 'ogg': |
|
441 | 1 | $mime = array('audio/ogg'); |
|
442 | 1 | break; |
|
443 | 2 | case 'wav': |
|
444 | 1 | $mime = array('audio/x-wav', 'audio/wave', 'audio/wav'); |
|
445 | 1 | break; |
|
446 | 2 | case 'mp3': |
|
447 | 1 | $mime = array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'); |
|
448 | 1 | break; |
|
449 | 2 | case 'mp4': |
|
450 | 1 | $mime = array('video/mp4'); |
|
451 | 1 | break; |
|
452 | 2 | case 'mpe': |
|
453 | 2 | case 'mpeg': |
|
454 | 2 | case 'mpg': |
|
455 | 1 | $mime = array('video/mpeg'); |
|
456 | 1 | break; |
|
457 | 2 | case 'mov': |
|
458 | 2 | case 'qt': |
|
459 | 1 | $mime = array('video/quicktime'); |
|
460 | 1 | break; |
|
461 | 8 | } |
|
462 | |||
463 | 8 | return ($mime && $single) ? array_shift($mime) : $mime; |
|
464 | } |
||
465 | |||
466 | 1 | private function css($file, $row) |
|
467 | { |
||
468 | 1 | $page = Page::html(); |
|
469 | 1 | $css = file_get_contents($file); |
|
470 | 1 | if (substr($css, 0, 3) == "\xef\xbb\xbf") { |
|
471 | 1 | $css = substr($css, 3); // strip BOM, if any |
|
472 | 1 | } |
|
473 | 1 | $matches = array(); |
|
474 | foreach (array( |
||
475 | 1 | '/url\(\s*(?P<quotes>["\'])?(?P<path>(?!(\s?["\']?(data:|https?:|\/\/))).+?)(?(quotes)(?P=quotes))\s*\)/ix', // url(xxx) |
|
476 | 1 | '/@import\s+(?P<quotes>["\'])(?P<path>(?!(["\']?(data:|https?:|\/\/))).+?)(?P=quotes)/ix', // @import "xxx" |
|
477 | 1 | ) as $regex) { |
|
478 | 1 | if (preg_match_all($regex, $css, $match, PREG_SET_ORDER)) { |
|
479 | 1 | $matches = array_merge($matches, $match); |
|
480 | 1 | } |
|
481 | 1 | } |
|
482 | 1 | $rnr = array(); |
|
483 | 1 | $base = phpUri::parse($row['file']); |
|
484 | 1 | $common = dirname($row['file']) . '/'; |
|
485 | 1 | foreach ($matches as $match) { |
|
486 | 1 | if (preg_match('/(?P<file>[^#\?]*)(?P<extra>.*)/', ltrim($match['path'], '/'), $path)) { |
|
487 | 1 | if (static::mime(pathinfo($path['file'], PATHINFO_EXTENSION))) { |
|
488 | 1 | $file = $base->join($path['file']).$path['extra']; |
|
489 | 1 | if ($dir = $page->commonDir(array($common, $file))) { |
|
490 | 1 | $common = $dir; |
|
491 | 1 | if (strpos($match[0], '@import') === 0) { |
|
492 | 1 | $rnr[$match[0]] = '@import "'.$file.'"'; |
|
493 | 1 | } else { |
|
494 | 1 | $rnr[$match[0]] = 'url("'.$file.'")'; |
|
495 | } |
||
496 | 1 | } |
|
497 | 1 | } |
|
498 | 1 | } |
|
499 | 1 | } |
|
500 | 1 | if (!empty($rnr)) { |
|
501 | 1 | $page->dir('set', 'css-dir', $common); |
|
502 | 1 | $url = $page->url['base'].'css-dir/'; |
|
503 | 1 | foreach ($rnr as $remove => $replace) { |
|
504 | 1 | $rnr[$remove] = str_replace($common, $url, $replace); |
|
505 | 1 | } |
|
506 | 1 | $css = static::urls(str_replace(array_keys($rnr), array_values($rnr), $css)); |
|
507 | 1 | } |
|
508 | |||
509 | 1 | return $css; |
|
510 | } |
||
511 | |||
512 | 2 | private function paths(&$cache) |
|
513 | { |
||
514 | 2 | $page = Page::html(); |
|
515 | 2 | $count = 0; |
|
516 | 2 | foreach ($cache as $dir => $files) { |
|
517 | 2 | $count += count($files); |
|
518 | 2 | } |
|
519 | 2 | $ids = $this->ids($count); |
|
520 | 2 | $insert = array(); |
|
521 | 2 | $update = array(); |
|
522 | 2 | $stmt = $this->db->prepare(array( |
|
523 | 2 | 'SELECT f.id AS file_id, f.updated, p.tiny, p.id AS path_id', |
|
524 | 2 | 'FROM files AS f INNER JOIN paths AS p ON f.id = p.file_id', |
|
525 | 2 | 'WHERE f.file = ? AND f.query = ?', |
|
526 | 2 | ), 'assoc'); |
|
527 | 2 | foreach ($cache as $dir => $files) { |
|
528 | 2 | foreach ($files as $path => $tiny) { |
|
529 | 2 | list($file, $query) = explode('?', $path.'?'); |
|
530 | 2 | $file = $page->dir[$dir].$file; |
|
531 | 2 | $updated = filemtime($file); |
|
532 | 2 | $this->db->execute($stmt, array($file, $query)); |
|
533 | 2 | if ($row = $this->db->fetch($stmt)) { |
|
534 | 2 | if ($row['updated'] == $updated) { |
|
535 | 2 | $tiny = $row['tiny']; |
|
536 | 2 | } else { |
|
537 | 1 | list($path_id, $tiny) = each($ids); |
|
538 | 1 | $update[$row['file_id']] = array($path_id, $updated); |
|
539 | } |
||
540 | 2 | } else { |
|
541 | 2 | list($path_id, $tiny) = each($ids); |
|
542 | 2 | $insert[] = array($path_id, $file, $query, $updated); |
|
543 | } |
||
544 | 2 | $cache[$dir][$path] = $tiny; |
|
545 | 2 | } |
|
546 | 2 | } |
|
547 | 2 | $this->db->close($stmt); |
|
548 | 2 | if (empty($insert) && empty($update)) { |
|
549 | 1 | return; |
|
550 | } |
||
551 | 2 | $this->db->exec('BEGIN IMMEDIATE'); |
|
552 | 2 | $paths = array(); |
|
553 | 2 | if (!empty($insert)) { |
|
554 | 2 | $stmt = $this->db->insert('files', array('path_id', 'file', 'query', 'updated')); |
|
555 | 2 | foreach ($insert as $array) { |
|
556 | 2 | $paths[$array[0]] = $this->db->insert($stmt, $array); |
|
557 | 2 | } |
|
558 | 2 | $this->db->close($stmt); |
|
559 | 2 | } |
|
560 | 2 | if (!empty($update)) { |
|
561 | 1 | $stmt = $this->db->update('files', 'id', array('path_id', 'updated')); |
|
562 | 1 | foreach ($update as $file_id => $array) { |
|
563 | 1 | $this->db->update($stmt, $file_id, $array); |
|
564 | 1 | $paths[$array[0]] = $file_id; |
|
565 | 1 | } |
|
566 | 1 | $this->db->close($stmt); |
|
567 | 1 | } |
|
568 | 2 | if (!empty($paths)) { |
|
569 | 2 | $stmt = $this->db->update('paths', 'id', array('file_id')); |
|
570 | 2 | foreach ($paths as $path_id => $file_id) { |
|
571 | 2 | $this->db->update($stmt, $path_id, array($file_id)); |
|
572 | 2 | } |
|
573 | 2 | $this->db->close($stmt); |
|
574 | 2 | } |
|
575 | 2 | $this->db->exec('COMMIT'); |
|
576 | |||
577 | 2 | return; |
|
578 | } |
||
579 | |||
580 | 2 | private function ids($count) |
|
581 | { |
||
582 | 2 | $ids = array(); |
|
583 | 2 | if ($stmt = $this->db->query(array( |
|
584 | 2 | 'SELECT id, tiny', |
|
585 | 2 | 'FROM paths', |
|
586 | 2 | 'WHERE file_id = ?', |
|
587 | 2 | 'ORDER BY id DESC LIMIT '.$count, |
|
588 | 2 | ), 0, 'row')) { |
|
0 ignored issues
–
show
0 is of type integer , but the function expects a array .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
589 | 2 | while (list($id, $tiny) = $this->db->fetch($stmt)) { |
|
590 | 2 | $ids[$id] = $tiny; |
|
591 | 2 | } |
|
592 | 2 | $this->db->close($stmt); |
|
593 | 2 | } |
|
594 | 2 | if (count($ids) == $count) { |
|
595 | 2 | return $ids; |
|
596 | } |
||
597 | 1 | $this->db->exec('BEGIN IMMEDIATE'); |
|
598 | 1 | $stmt = $this->db->insert('OR IGNORE INTO paths', array('tiny')); |
|
599 | 1 | $string = '123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; |
|
600 | 1 | for ($i = 0; $i < $count + 100; ++$i) { |
|
601 | 1 | $tiny_id = ''; // 60 (characters) ^ 5 (length) gives 777,600,000 possible combinations |
|
602 | 1 | while (strlen($tiny_id) < 5) { |
|
603 | 1 | $tiny_id .= $string[mt_rand(0, 60)]; |
|
604 | 1 | } |
|
605 | 1 | $this->db->insert($stmt, array($tiny_id)); |
|
606 | 1 | } |
|
607 | 1 | $this->db->close($stmt); |
|
608 | 1 | $this->db->exec('COMMIT'); |
|
609 | |||
610 | 1 | return $this->ids($count); |
|
611 | } |
||
612 | |||
613 | 6 | private function openDatabase() |
|
614 | { |
||
615 | 6 | if (is_null($this->db)) { |
|
616 | 6 | $this->db = new SQLite($this->cached.'Assets.db'); |
|
617 | 6 | if ($this->db->created) { |
|
618 | 1 | $this->db->create('paths', array( |
|
619 | 1 | 'id' => 'INTEGER PRIMARY KEY', |
|
620 | 1 | 'tiny' => 'TEXT UNIQUE NOT NULL DEFAULT ""', |
|
621 | 1 | 'file_id' => 'INTEGER NOT NULL DEFAULT 0', |
|
622 | 1 | )); |
|
623 | 1 | $this->db->create('files', array( |
|
624 | 1 | 'id' => 'INTEGER PRIMARY KEY', |
|
625 | 1 | 'path_id' => 'INTEGER NOT NULL DEFAULT 0', |
|
626 | 1 | 'file' => 'TEXT NOT NULL DEFAULT ""', |
|
627 | 1 | 'query' => 'TEXT NOT NULL DEFAULT ""', |
|
628 | 1 | 'updated' => 'INTEGER NOT NULL DEFAULT 0', |
|
629 | 1 | ), array('unique' => 'file, query')); |
|
630 | 1 | } |
|
631 | 6 | } |
|
632 | 6 | } |
|
633 | |||
634 | 6 | private function closeDatabase() |
|
635 | { |
||
636 | 6 | if (!is_null($this->db)) { |
|
637 | 6 | $this->db->connection()->close(); |
|
638 | 6 | } |
|
639 | 6 | $this->db = null; |
|
640 | 6 | } |
|
641 | |||
642 | 6 | private function __construct() |
|
643 | { |
||
644 | 6 | } |
|
645 | } |
||
646 |
If you define a variable conditionally, it can happen that it is not defined for all execution paths.
Let’s take a look at an example:
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.
Available Fixes
Check for existence of the variable explicitly:
Define a default value for the variable:
Add a value for the missing path: