PluginProbe
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell / 3.12.2
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell v3.12.2
3.13.3 3.13.2 3.13.1 3.13.0 3.12.13 3.12.12 3.12.11 3.12.10 3.12.9 3.12.8 3.12.7 3.12.6 3.12.5 3.12.4 3.12.3 3.12.1 3.12.2 3.12.0 3.11.1 3.11.0 3.10.9 3.10.8 3.10.7 3.10.6 2.8.16 All 261 releases
wpfunnels / vendor / league / glide / src / Server.php

Server.php in WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell 3.12.2, at vendor/league/glide/src/Server.php

707 lines 16.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace League\Glide;
4
5 use Closure;
6 use InvalidArgumentException;
7 use League\Flysystem\FilesystemException as FilesystemV2Exception;
8 use League\Flysystem\FilesystemOperator;
9 use League\Glide\Api\ApiInterface;
10 use League\Glide\Filesystem\FileNotFoundException;
11 use League\Glide\Filesystem\FilesystemException;
12 use League\Glide\Responses\ResponseFactoryInterface;
13
14 class Server
15 {
16 /**
17 * Source file system.
18 *
19 * @var FilesystemOperator
20 */
21 protected $source;
22
23 /**
24 * Source path prefix.
25 *
26 * @var string
27 */
28 protected $sourcePathPrefix;
29
30 /**
31 * Cache file system.
32 *
33 * @var FilesystemOperator
34 */
35 protected $cache;
36
37 /**
38 * Cache path prefix.
39 *
40 * @var string
41 */
42 protected $cachePathPrefix;
43
44 /**
45 * Temporary EXIF data directory.
46 *
47 * @var string
48 */
49 protected $tempDir;
50
51 /**
52 * Whether to group cache in folders.
53 *
54 * @var bool
55 */
56 protected $groupCacheInFolders = true;
57
58 /**
59 * Whether to cache with file extensions.
60 *
61 * @var bool
62 */
63 protected $cacheWithFileExtensions = false;
64
65 /**
66 * Image manipulation API.
67 *
68 * @var ApiInterface
69 */
70 protected $api;
71
72 /**
73 * Response factory.
74 *
75 * @var ResponseFactoryInterface|null
76 */
77 protected $responseFactory;
78
79 /**
80 * Base URL.
81 *
82 * @var string
83 */
84 protected $baseUrl;
85
86 /**
87 * Default image manipulations.
88 *
89 * @var array
90 */
91 protected $defaults = [];
92
93 /**
94 * Preset image manipulations.
95 *
96 * @var array
97 */
98 protected $presets = [];
99
100 /**
101 * Custom cache path callable.
102 *
103 * @var \Closure|null
104 */
105 protected $cachePathCallable;
106
107 /**
108 * Create Server instance.
109 *
110 * @param FilesystemOperator $source Source file system.
111 * @param FilesystemOperator $cache Cache file system.
112 * @param ApiInterface $api Image manipulation API.
113 */
114 public function __construct(FilesystemOperator $source, FilesystemOperator $cache, ApiInterface $api)
115 {
116 $this->setSource($source);
117 $this->setCache($cache);
118 $this->setApi($api);
119 $this->tempDir = sys_get_temp_dir();
120 }
121
122 /**
123 * Set source file system.
124 *
125 * @param FilesystemOperator $source Source file system.
126 *
127 * @return void
128 */
129 public function setSource(FilesystemOperator $source)
130 {
131 $this->source = $source;
132 }
133
134 /**
135 * Get source file system.
136 *
137 * @return FilesystemOperator Source file system.
138 */
139 public function getSource()
140 {
141 return $this->source;
142 }
143
144 /**
145 * Set source path prefix.
146 *
147 * @param string $sourcePathPrefix Source path prefix.
148 *
149 * @return void
150 */
151 public function setSourcePathPrefix($sourcePathPrefix)
152 {
153 $this->sourcePathPrefix = trim($sourcePathPrefix, '/');
154 }
155
156 /**
157 * Get source path prefix.
158 *
159 * @return string Source path prefix.
160 */
161 public function getSourcePathPrefix()
162 {
163 return $this->sourcePathPrefix;
164 }
165
166 /**
167 * Get source path.
168 *
169 * @param string $path Image path.
170 *
171 * @return string The source path.
172 *
173 * @throws FileNotFoundException
174 */
175 public function getSourcePath($path)
176 {
177 $path = trim($path, '/');
178
179 $baseUrl = $this->baseUrl.'/';
180
181 if (substr($path, 0, strlen($baseUrl)) === $baseUrl) {
182 $path = trim(substr($path, strlen($baseUrl)), '/');
183 }
184
185 if ('' === $path) {
186 throw new FileNotFoundException('Image path missing.');
187 }
188
189 if ($this->sourcePathPrefix) {
190 $path = $this->sourcePathPrefix.'/'.$path;
191 }
192
193 return rawurldecode($path);
194 }
195
196 /**
197 * Check if a source file exists.
198 *
199 * @param string $path Image path.
200 *
201 * @return bool Whether the source file exists.
202 */
203 public function sourceFileExists($path)
204 {
205 try {
206 return $this->source->fileExists($this->getSourcePath($path));
207 } catch (FilesystemV2Exception $exception) {
208 return false;
209 }
210 }
211
212 /**
213 * Set base URL.
214 *
215 * @param string $baseUrl Base URL.
216 *
217 * @return void
218 */
219 public function setBaseUrl($baseUrl)
220 {
221 $this->baseUrl = trim($baseUrl, '/');
222 }
223
224 /**
225 * Get base URL.
226 *
227 * @return string Base URL.
228 */
229 public function getBaseUrl()
230 {
231 return $this->baseUrl;
232 }
233
234 /**
235 * Set cache file system.
236 *
237 * @param FilesystemOperator $cache Cache file system.
238 *
239 * @return void
240 */
241 public function setCache(FilesystemOperator $cache)
242 {
243 $this->cache = $cache;
244 }
245
246 /**
247 * Get cache file system.
248 *
249 * @return FilesystemOperator Cache file system.
250 */
251 public function getCache()
252 {
253 return $this->cache;
254 }
255
256 /**
257 * Set cache path prefix.
258 *
259 * @param string $cachePathPrefix Cache path prefix.
260 *
261 * @return void
262 */
263 public function setCachePathPrefix($cachePathPrefix)
264 {
265 $this->cachePathPrefix = trim($cachePathPrefix, '/');
266 }
267
268 /**
269 * Get cache path prefix.
270 *
271 * @return string Cache path prefix.
272 */
273 public function getCachePathPrefix()
274 {
275 return $this->cachePathPrefix;
276 }
277
278 /**
279 * Get temporary EXIF data directory.
280 *
281 * @return string
282 */
283 public function getTempDir()
284 {
285 return $this->tempDir;
286 }
287
288 /**
289 * Set temporary EXIF data directory. This directory must be a local path and exists on the filesystem.
290 *
291 * @param string $tempDir
292 *
293 * @return void
294 *
295 * @throws InvalidArgumentException
296 */
297 public function setTempDir($tempDir)
298 {
299 if (!$tempDir || !is_dir($tempDir)) {
300 throw new InvalidArgumentException(sprintf('Invalid temp dir provided: "%s" does not exist.', $tempDir));
301 }
302
303 $this->tempDir = rtrim($tempDir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
304 }
305
306 /**
307 * Set the group cache in folders setting.
308 *
309 * @param bool $groupCacheInFolders Whether to group cache in folders.
310 *
311 * @return void
312 */
313 public function setGroupCacheInFolders($groupCacheInFolders)
314 {
315 $this->groupCacheInFolders = $groupCacheInFolders;
316 }
317
318 /**
319 * Get the group cache in folders setting.
320 *
321 * @return bool Whether to group cache in folders.
322 */
323 public function getGroupCacheInFolders()
324 {
325 return $this->groupCacheInFolders;
326 }
327
328 /**
329 * Set the cache with file extensions setting.
330 *
331 * @param bool $cacheWithFileExtensions Whether to cache with file extensions.
332 *
333 * @return void
334 */
335 public function setCacheWithFileExtensions($cacheWithFileExtensions)
336 {
337 $this->cacheWithFileExtensions = $cacheWithFileExtensions;
338 }
339
340 /**
341 * Get the cache with file extensions setting.
342 *
343 * @return bool Whether to cache with file extensions.
344 */
345 public function getCacheWithFileExtensions()
346 {
347 return $this->cacheWithFileExtensions;
348 }
349
350 /**
351 * Set a custom cachePathCallable.
352 *
353 * @param \Closure|null $cachePathCallable The custom cache path callable. It receives the same arguments as @see getCachePath
354 */
355 public function setCachePathCallable(?Closure $cachePathCallable)
356 {
357 $this->cachePathCallable = $cachePathCallable;
358 }
359
360 /**
361 * Gets the custom cachePathCallable.
362 *
363 * @return \Closure|null The custom cache path callable. It receives the same arguments as @see getCachePath
364 */
365 public function getCachePathCallable()
366 {
367 return $this->cachePathCallable;
368 }
369
370 /**
371 * Get cache path.
372 *
373 * @param string $path Image path.
374 * @param array $params Image manipulation params.
375 *
376 * @return string Cache path.
377 *
378 * @throws FileNotFoundException
379 */
380 public function getCachePath($path, array $params = [])
381 {
382 $customCallable = $this->getCachePathCallable();
383 if (null !== $customCallable) {
384 $boundCallable = Closure::bind($customCallable, $this, static::class);
385
386 return $boundCallable($path, $params);
387 }
388
389 $sourcePath = $this->getSourcePath($path);
390
391 if ($this->sourcePathPrefix) {
392 $sourcePath = substr($sourcePath, strlen($this->sourcePathPrefix) + 1);
393 }
394
395 $params = $this->getAllParams($params);
396 unset($params['s'], $params['p']);
397 ksort($params);
398
399 $cachedPath = md5($sourcePath.'?'.http_build_query($params));
400
401 if ($this->groupCacheInFolders) {
402 $cachedPath = $sourcePath.'/'.$cachedPath;
403 }
404
405 if ($this->cachePathPrefix) {
406 $cachedPath = $this->cachePathPrefix.'/'.$cachedPath;
407 }
408
409 if ($this->cacheWithFileExtensions) {
410 $ext = (isset($params['fm']) ? $params['fm'] : pathinfo($path)['extension']);
411 $ext = ('pjpg' === $ext) ? 'jpg' : $ext;
412 $cachedPath .= '.'.$ext;
413 }
414
415 return $cachedPath;
416 }
417
418 /**
419 * Check if a cache file exists.
420 *
421 * @param string $path Image path.
422 * @param array $params Image manipulation params.
423 *
424 * @return bool Whether the cache file exists.
425 */
426 public function cacheFileExists($path, array $params)
427 {
428 try {
429 return $this->cache->fileExists(
430 $this->getCachePath($path, $params)
431 );
432 } catch (FilesystemV2Exception $exception) {
433 return false;
434 }
435 }
436
437 /**
438 * Delete cached manipulations for an image.
439 *
440 * @param string $path Image path.
441 *
442 * @return bool Whether the delete succeeded.
443 */
444 public function deleteCache($path)
445 {
446 if (!$this->groupCacheInFolders) {
447 throw new InvalidArgumentException('Deleting cached image manipulations is not possible when grouping cache into folders is disabled.');
448 }
449
450 try {
451 $this->cache->deleteDirectory(
452 dirname($this->getCachePath($path))
453 );
454
455 return true;
456 } catch (FilesystemV2Exception $exception) {
457 return false;
458 }
459 }
460
461 /**
462 * Set image manipulation API.
463 *
464 * @param ApiInterface $api Image manipulation API.
465 *
466 * @return void
467 */
468 public function setApi(ApiInterface $api)
469 {
470 $this->api = $api;
471 }
472
473 /**
474 * Get image manipulation API.
475 *
476 * @return ApiInterface Image manipulation API.
477 */
478 public function getApi()
479 {
480 return $this->api;
481 }
482
483 /**
484 * Set default image manipulations.
485 *
486 * @param array $defaults Default image manipulations.
487 *
488 * @return void
489 */
490 public function setDefaults(array $defaults)
491 {
492 $this->defaults = $defaults;
493 }
494
495 /**
496 * Get default image manipulations.
497 *
498 * @return array Default image manipulations.
499 */
500 public function getDefaults()
501 {
502 return $this->defaults;
503 }
504
505 /**
506 * Set preset image manipulations.
507 *
508 * @param array $presets Preset image manipulations.
509 *
510 * @return void
511 */
512 public function setPresets(array $presets)
513 {
514 $this->presets = $presets;
515 }
516
517 /**
518 * Get preset image manipulations.
519 *
520 * @return array Preset image manipulations.
521 */
522 public function getPresets()
523 {
524 return $this->presets;
525 }
526
527 /**
528 * Get all image manipulations params, including defaults and presets.
529 *
530 * @param array $params Image manipulation params.
531 *
532 * @return array All image manipulation params.
533 */
534 public function getAllParams(array $params)
535 {
536 $all = $this->defaults;
537
538 if (isset($params['p'])) {
539 foreach (explode(',', $params['p']) as $preset) {
540 if (isset($this->presets[$preset])) {
541 $all = array_merge($all, $this->presets[$preset]);
542 }
543 }
544 }
545
546 return array_merge($all, $params);
547 }
548
549 /**
550 * Set response factory.
551 *
552 * @param ResponseFactoryInterface|null $responseFactory Response factory.
553 *
554 * @return void
555 */
556 public function setResponseFactory(?ResponseFactoryInterface $responseFactory = null)
557 {
558 $this->responseFactory = $responseFactory;
559 }
560
561 /**
562 * Get response factory.
563 *
564 * @return ResponseFactoryInterface|null Response factory.
565 */
566 public function getResponseFactory()
567 {
568 return $this->responseFactory;
569 }
570
571 /**
572 * Generate and return image response.
573 *
574 * @param string $path Image path.
575 * @param array $params Image manipulation params.
576 *
577 * @return mixed Image response.
578 *
579 * @throws InvalidArgumentException
580 * @throws FileNotFoundException
581 * @throws FilesystemException
582 */
583 public function getImageResponse($path, array $params)
584 {
585 if (is_null($this->responseFactory)) {
586 throw new InvalidArgumentException('Unable to get image response, no response factory defined.');
587 }
588
589 $path = $this->makeImage($path, $params);
590
591 return $this->responseFactory->create($this->cache, $path);
592 }
593
594 /**
595 * Generate and return Base64 encoded image.
596 *
597 * @param string $path Image path.
598 * @param array $params Image manipulation params.
599 *
600 * @return string Base64 encoded image.
601 *
602 * @throws FileNotFoundException
603 * @throws FilesystemException
604 */
605 public function getImageAsBase64($path, array $params)
606 {
607 $path = $this->makeImage($path, $params);
608
609 try {
610 $source = $this->cache->read($path);
611
612 return 'data:'.$this->cache->mimeType($path).';base64,'.base64_encode($source);
613 } catch (FilesystemV2Exception $exception) {
614 throw new FilesystemException('Could not read the image `'.$path.'`.');
615 }
616 }
617
618 /**
619 * Generate and output image.
620 *
621 * @param string $path Image path.
622 * @param array $params Image manipulation params.
623 *
624 * @throws InvalidArgumentException
625 * @throws FileNotFoundException
626 * @throws FilesystemException
627 *
628 * @return void
629 */
630 public function outputImage($path, array $params)
631 {
632 $path = $this->makeImage($path, $params);
633
634 try {
635 header('Content-Type:'.$this->cache->mimeType($path));
636 header('Content-Length:'.$this->cache->fileSize($path));
637 header('Cache-Control:'.'max-age=31536000, public');
638 header('Expires:'.date_create('+1 years')->format('D, d M Y H:i:s').' GMT');
639
640 $stream = $this->cache->readStream($path);
641
642 if (0 !== ftell($stream)) {
643 rewind($stream);
644 }
645 fpassthru($stream);
646 fclose($stream);
647 } catch (FilesystemV2Exception $exception) {
648 throw new FilesystemException('Could not read the image `'.$path.'`.');
649 }
650 }
651
652 /**
653 * Generate manipulated image.
654 *
655 * @param string $path Image path.
656 * @param array $params Image manipulation params.
657 *
658 * @return string Cache path.
659 *
660 * @throws FileNotFoundException
661 * @throws FilesystemException
662 */
663 public function makeImage($path, array $params)
664 {
665 $sourcePath = $this->getSourcePath($path);
666 $cachedPath = $this->getCachePath($path, $params);
667
668 if (true === $this->cacheFileExists($path, $params)) {
669 return $cachedPath;
670 }
671
672 if (false === $this->sourceFileExists($path)) {
673 throw new FileNotFoundException('Could not find the image `'.$sourcePath.'`.');
674 }
675
676 try {
677 $source = $this->source->read(
678 $sourcePath
679 );
680 } catch (FilesystemV2Exception $exception) {
681 throw new FilesystemException('Could not read the image `'.$sourcePath.'`.');
682 }
683
684 // We need to write the image to the local disk before
685 // doing any manipulations. This is because EXIF data
686 // can only be read from an actual file.
687 $tmp = tempnam($this->tempDir, 'Glide');
688
689 if (false === file_put_contents($tmp, $source)) {
690 throw new FilesystemException('Unable to write temp file for `'.$sourcePath.'`.');
691 }
692
693 try {
694 $this->cache->write(
695 $cachedPath,
696 $this->api->run($tmp, $this->getAllParams($params))
697 );
698 } catch (FilesystemV2Exception $exception) {
699 throw new FilesystemException('Could not write the image `'.$cachedPath.'`.', 0, $exception);
700 } finally {
701 unlink($tmp);
702 }
703
704 return $cachedPath;
705 }
706 }
707