PluginProbe
Easy Invoice – Invoice Generator, PDF Quotes & Payments / 2.4.2
Easy Invoice – Invoice Generator, PDF Quotes & Payments v2.4.2
2.4.3 2.4.4 2.4.2 2.4.0 2.4.1 2.3.8 2.3.7 2.3.6 2.3.5 2.3.4 2.3.3 2.3.2 2.3.1 2.2.0 2.1.21 2.1.20 2.1.19 2.1.18 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 All 60 releases
easy-invoice / vendor / dompdf / dompdf / src / Options.php

Options.php in Easy Invoice – Invoice Generator, PDF Quotes & Payments 2.4.2, at vendor/dompdf/dompdf/src/Options.php

1,277 lines 31.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package dompdf
4 * @link https://github.com/dompdf/dompdf
5 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
6 */
7 namespace Dompdf;
8
9 class Options
10 {
11 /**
12 * The root of your DOMPDF installation
13 *
14 * @var string
15 */
16 private $rootDir;
17
18 /**
19 * The location of a temporary directory.
20 *
21 * The directory specified must be writable by the executing process.
22 * The temporary directory is required to download remote images and when
23 * using the PFDLib back end.
24 *
25 * @var string
26 */
27 private $tempDir;
28
29 /**
30 * The location of the DOMPDF font directory
31 *
32 * The location of the directory where DOMPDF will store fonts and font metrics
33 * Note: This directory must exist and be writable by the executing process.
34 *
35 * @var string
36 */
37 private $fontDir;
38
39 /**
40 * The location of the DOMPDF font cache directory
41 *
42 * This directory contains the cached font metrics for the fonts used by DOMPDF.
43 * This directory can be the same as $fontDir
44 *
45 * Note: This directory must exist and be writable by the executing process.
46 *
47 * @var string
48 */
49 private $fontCache;
50
51 /**
52 * dompdf's "chroot"
53 *
54 * Utilized by Dompdf's default file:// protocol URI validation rule.
55 * All local files opened by dompdf must be in a subdirectory of the directory
56 * or directories specified by this option.
57 * DO NOT set this value to '/' since this could allow an attacker to use dompdf to
58 * read any files on the server. This should be an absolute path.
59 *
60 * ==== IMPORTANT ====
61 * This setting may increase the risk of system exploit. Do not change
62 * this settings without understanding the consequences. Additional
63 * documentation is available on the dompdf wiki at:
64 * https://github.com/dompdf/dompdf/wiki
65 *
66 * @var array
67 */
68 private $chroot;
69
70 /**
71 * Protocol whitelist
72 *
73 * Protocols and PHP wrappers allowed in URIs, and the validation rules
74 * that determine if a resource may be loaded. Full support is not guaranteed
75 * for the protocols/wrappers specified
76 * by this array.
77 *
78 * @var array
79 */
80 private $allowedProtocols = [
81 "data://" => ["rules" => []],
82 "file://" => ["rules" => []],
83 "http://" => ["rules" => []],
84 "https://" => ["rules" => []]
85 ];
86
87 /**
88 * Operational artifact (log files, temporary files) path validation
89 *
90 * @var callable
91 */
92 private $artifactPathValidation = null;
93
94 /**
95 * @var string
96 */
97 private $logOutputFile = '';
98
99 /**
100 * Styles targeted to this media type are applied to the document.
101 * This is on top of the media types that are always applied:
102 * all, static, visual, bitmap, paged, dompdf
103 *
104 * @var string
105 */
106 private $defaultMediaType = "screen";
107
108 /**
109 * The default paper size.
110 *
111 * North America standard is "letter"; other countries generally "a4"
112 * @see \Dompdf\Adapter\CPDF::PAPER_SIZES for valid sizes
113 *
114 * @var string|float[]
115 */
116 private $defaultPaperSize = "letter";
117
118 /**
119 * The default paper orientation.
120 *
121 * The orientation of the page (portrait or landscape).
122 *
123 * @var string
124 */
125 private $defaultPaperOrientation = "portrait";
126
127 /**
128 * The default font family
129 *
130 * Used if no suitable fonts can be found. This must exist in the font folder.
131 *
132 * @var string
133 */
134 private $defaultFont = "serif";
135
136 /**
137 * Image DPI setting
138 *
139 * This setting determines the default DPI setting for images and fonts. The
140 * DPI may be overridden for inline images by explicitly setting the
141 * image's width & height style attributes (i.e. if the image's native
142 * width is 600 pixels and you specify the image's width as 72 points,
143 * the image will have a DPI of 600 in the rendered PDF. The DPI of
144 * background images can not be overridden and is controlled entirely
145 * via this parameter.
146 *
147 * For the purposes of DOMPDF, pixels per inch (PPI) = dots per inch (DPI).
148 * If a size in html is given as px (or without unit as image size),
149 * this tells the corresponding size in pt at 72 DPI.
150 * This adjusts the relative sizes to be similar to the rendering of the
151 * html page in a reference browser.
152 *
153 * In pdf, always 1 pt = 1/72 inch
154 *
155 * @var int
156 */
157 private $dpi = 96;
158
159 /**
160 * A ratio applied to the fonts height to be more like browsers' line height
161 *
162 * @var float
163 */
164 private $fontHeightRatio = 1.1;
165
166 /**
167 * The maximum estimated in-memory size of an image allowed to be rendered, in bytes.
168 *
169 * @var int
170 */
171 private $imageByteSizeLimit = -1;
172
173 /**
174 * Enable embedded PHP
175 *
176 * If this setting is set to true then DOMPDF will automatically evaluate
177 * embedded PHP contained within <script type="text/php"> ... </script> tags.
178 *
179 * ==== IMPORTANT ====
180 * Enabling this for documents you do not trust (e.g. arbitrary remote html
181 * pages) is a security risk. Embedded scripts are run with the same level of
182 * system access available to dompdf. Set this option to false (recommended)
183 * if you wish to process untrusted documents.
184 *
185 * This setting may increase the risk of system exploit. Do not change
186 * this settings without understanding the consequences. Additional
187 * documentation is available on the dompdf wiki at:
188 * https://github.com/dompdf/dompdf/wiki
189 *
190 * @var bool
191 */
192 private $isPhpEnabled = false;
193
194 /**
195 * Enable remote file access
196 *
197 * If this setting is set to true, DOMPDF will access remote sites for
198 * images and CSS files as required.
199 *
200 * ==== IMPORTANT ====
201 * This can be a security risk, in particular in combination with isPhpEnabled and
202 * allowing remote html code to be passed to $dompdf = new DOMPDF(); $dompdf->load_html(...);
203 * This allows anonymous users to download legally doubtful internet content which on
204 * tracing back appears to being downloaded by your server, or allows malicious php code
205 * in remote html pages to be executed by your server with your account privileges.
206 *
207 * This setting may increase the risk of system exploit. Do not change
208 * this settings without understanding the consequences. Additional
209 * documentation is available on the dompdf wiki at:
210 * https://github.com/dompdf/dompdf/wiki
211 *
212 * @var bool
213 */
214 private $isRemoteEnabled = false;
215
216 /**
217 * List of allowed remote hosts
218 *
219 * Each value of the array must be a valid hostname.
220 *
221 * This will be used to filter which resources can be loaded in combination with
222 * isRemoteEnabled. If isRemoteEnabled is FALSE, then this will have no effect.
223 *
224 * Leave to NULL to allow any remote host.
225 *
226 * @var array|null
227 */
228 private $allowedRemoteHosts = null;
229
230 /**
231 * Enable PDF/A-3 compliance mode
232 *
233 * ==== EXPERIMENTAL ====
234 * This feature is currently only supported with the CPDF backend and will
235 * have no effect if used with any other.
236 *
237 * Currently this mode only takes care of adding the necessary metadata, output intents, etc.
238 * It does not enforce font embedding, it's up to you to embed the fonts you plan on using.
239 *
240 * @var bool
241 */
242 private $isPdfAEnabled = false;
243
244 /**
245 * Enable inline JavaScript
246 *
247 * If this setting is set to true then DOMPDF will automatically insert
248 * JavaScript code contained within <script type="text/javascript"> ... </script>
249 * tags as written into the PDF.
250 *
251 * NOTE: This is PDF-based JavaScript to be executed by the PDF viewer,
252 * not browser-based JavaScript executed by Dompdf.
253 *
254 * @var bool
255 */
256 private $isJavascriptEnabled = true;
257
258 /**
259 * Use the HTML5 Lib parser
260 *
261 * @deprecated
262 * @var bool
263 */
264 private $isHtml5ParserEnabled = true;
265
266 /**
267 * Whether to enable font subsetting or not.
268 *
269 * @var bool
270 */
271 private $isFontSubsettingEnabled = true;
272
273 /**
274 * @var bool
275 */
276 private $debugPng = false;
277
278 /**
279 * @var bool
280 */
281 private $debugKeepTemp = false;
282
283 /**
284 * @var bool
285 */
286 private $debugCss = false;
287
288 /**
289 * @var bool
290 */
291 private $debugLayout = false;
292
293 /**
294 * @var bool
295 */
296 private $debugLayoutLines = true;
297
298 /**
299 * @var bool
300 */
301 private $debugLayoutBlocks = true;
302
303 /**
304 * @var bool
305 */
306 private $debugLayoutInline = true;
307
308 /**
309 * @var bool
310 */
311 private $debugLayoutPaddingBox = true;
312
313 /**
314 * The PDF rendering backend to use
315 *
316 * Valid settings are 'PDFLib', 'CPDF', 'GD', and 'auto'. 'auto' will
317 * look for PDFLib and use it if found, or if not it will fall back on
318 * CPDF. 'GD' renders PDFs to graphic files. {@link Dompdf\CanvasFactory}
319 * ultimately determines which rendering class to instantiate
320 * based on this setting.
321 *
322 * @var string
323 */
324 private $pdfBackend = "CPDF";
325
326 /**
327 * PDFlib license key
328 *
329 * If you are using a licensed, commercial version of PDFlib, specify
330 * your license key here. If you are using PDFlib-Lite or are evaluating
331 * the commercial version of PDFlib, comment out this setting.
332 *
333 * @link http://www.pdflib.com
334 *
335 * If pdflib present in web server and auto or selected explicitly above,
336 * a real license code must exist!
337 *
338 * @var string
339 */
340 private $pdflibLicense = "";
341
342 /**
343 * HTTP context created with stream_context_create()
344 * Will be used for file_get_contents
345 *
346 * @link https://www.php.net/manual/context.php
347 *
348 * @var resource
349 */
350 private $httpContext;
351
352 /**
353 * @param array $attributes
354 */
355 public function __construct(?array $attributes = null)
356 {
357 $rootDir = realpath(__DIR__ . "/../");
358 $this->setChroot(array($rootDir));
359 $this->setRootDir($rootDir);
360 $this->setTempDir(sys_get_temp_dir());
361 $this->setFontDir($rootDir . "/lib/fonts");
362 $this->setFontCache($this->getFontDir());
363
364 $ver = "";
365 $versionFile = realpath(__DIR__ . '/../VERSION');
366 if (file_exists($versionFile) && ($version = file_get_contents($versionFile)) !== false) {
367 $version = trim($version);
368 if ($version !== '$Format:<%h>$') {
369 $ver = "/$version";
370 }
371 }
372 $this->setHttpContext([
373 "http" => [
374 "follow_location" => false,
375 "user_agent" => "Dompdf$ver https://github.com/dompdf/dompdf"
376 ]
377 ]);
378
379 $this->setAllowedProtocols(["data://", "file://", "http://", "https://"]);
380
381 $this->setArtifactPathValidation([$this, "validateArtifactPath"]);
382
383 // Get the memory limit
384 $memory_limit = ini_get('memory_limit');
385 $this->setImageByteSizeLimit($memory_limit);
386
387 if (null !== $attributes) {
388 $this->set($attributes);
389 }
390 }
391
392 /**
393 * @param array|string $attributes
394 * @param null|mixed $value
395 * @return $this
396 */
397 public function set($attributes, $value = null)
398 {
399 if (!is_array($attributes)) {
400 $attributes = [$attributes => $value];
401 }
402
403 foreach ($attributes as $key => $value) {
404 $methodForMatch = lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $key))));
405 $methodForCall = "set" . ucfirst($methodForMatch);
406
407 if ($methodForMatch === 'enablePhp') {
408 $methodForCall = "setIsPhpEnabled";
409 } elseif ($methodForMatch === 'enableRemote') {
410 $methodForCall = "setIsRemoteEnabled";
411 } elseif ($methodForMatch === 'enablePdfA') {
412 $methodForCall = "setIsPdfAEnabled";
413 } elseif ($methodForMatch === 'enableJavascript') {
414 $methodForCall = "setIsJavascriptEnabled";
415 } elseif ($methodForMatch === 'enableHtml5Parser') {
416 $methodForCall = "setIsHtml5ParserEnabled";
417 } elseif ($methodForMatch === 'enableFontSubsetting') {
418 $methodForCall = "setIsFontSubsettingEnabled";
419 }
420
421 if (method_exists($this, $methodForCall)) {
422 $this->{$methodForCall}($value);
423 }
424 }
425
426 return $this;
427 }
428
429 /**
430 * @param string $key
431 * @return mixed
432 */
433 public function get($key)
434 {
435 $methodForMatch = lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $key))));
436 $methodForCall = "get" . ucfirst($methodForMatch);
437
438 if ($methodForMatch === 'enablePhp') {
439 $methodForCall = "getIsPhpEnabled";
440 } elseif ($methodForMatch === 'enableRemote') {
441 $methodForCall = "getIsRemoteEnabled";
442 } elseif ($methodForMatch === 'enablePdfA') {
443 $methodForCall = "getIsPdfAEnabled";
444 } elseif ($methodForMatch === 'enableJavascript') {
445 $methodForCall = "getIsJavascriptEnabled";
446 } elseif ($methodForMatch === 'enableHtml5Parser') {
447 $methodForCall = "getIsHtml5ParserEnabled";
448 } elseif ($methodForMatch === 'enableFontSubsetting') {
449 $methodForCall = "getIsFontSubsettingEnabled";
450 }
451
452 if (method_exists($this, $methodForCall)) {
453 return $this->{$methodForCall}();
454 }
455
456 return null;
457 }
458
459 /**
460 * @param string $pdfBackend
461 * @return $this
462 */
463 public function setPdfBackend($pdfBackend)
464 {
465 $this->pdfBackend = $pdfBackend;
466 return $this;
467 }
468
469 /**
470 * @return string
471 */
472 public function getPdfBackend()
473 {
474 return $this->pdfBackend;
475 }
476
477 /**
478 * @param string $pdflibLicense
479 * @return $this
480 */
481 public function setPdflibLicense($pdflibLicense)
482 {
483 $this->pdflibLicense = $pdflibLicense;
484 return $this;
485 }
486
487 /**
488 * @return string
489 */
490 public function getPdflibLicense()
491 {
492 return $this->pdflibLicense;
493 }
494
495 /**
496 * @param array|string $chroot
497 * @return $this
498 */
499 public function setChroot($chroot, $delimiter = ',')
500 {
501 if (is_string($chroot)) {
502 $this->chroot = explode($delimiter, $chroot);
503 } elseif (is_array($chroot)) {
504 $this->chroot = $chroot;
505 }
506 return $this;
507 }
508
509 /**
510 * @return array
511 */
512 public function getAllowedProtocols()
513 {
514 return $this->allowedProtocols;
515 }
516
517 /**
518 * @param array $allowedProtocols The protocols to allow, as an array
519 * formatted as ["protocol://" => ["rules" => [callable]], ...]
520 * or ["protocol://", ...]
521 *
522 * @return $this
523 */
524 public function setAllowedProtocols(array $allowedProtocols)
525 {
526 $protocols = [];
527 foreach ($allowedProtocols as $protocol => $config) {
528 if (is_string($protocol)) {
529 $protocols[$protocol] = [];
530 if (is_array($config)) {
531 $protocols[$protocol] = $config;
532 }
533 } elseif (is_string($config)) {
534 $protocols[$config] = [];
535 }
536 }
537 $this->allowedProtocols = [];
538 foreach ($protocols as $protocol => $config) {
539 $this->addAllowedProtocol($protocol, ...($config["rules"] ?? []));
540 }
541 return $this;
542 }
543
544 /**
545 * Adds a new protocol to the allowed protocols collection
546 *
547 * @param string $protocol The scheme to add (e.g. "http://")
548 * @param callable $rule A callable that validates the protocol
549 * @return $this
550 */
551 public function addAllowedProtocol(string $protocol, callable ...$rules)
552 {
553 $protocol = strtolower($protocol);
554 if (empty($rules)) {
555 $rules = [];
556 switch ($protocol) {
557 case "data://":
558 break;
559 case "file://":
560 $rules[] = [$this, "validateLocalUri"];
561 break;
562 case "http://":
563 case "https://":
564 $rules[] = [$this, "validateRemoteUri"];
565 break;
566 case "phar://":
567 $rules[] = [$this, "validatePharUri"];
568 break;
569 }
570 }
571 $this->allowedProtocols[$protocol] = ["rules" => $rules];
572 return $this;
573 }
574
575 /**
576 * @return array
577 */
578 public function getArtifactPathValidation()
579 {
580 return $this->artifactPathValidation;
581 }
582
583 /**
584 * @param callable $validator
585 * @return $this
586 */
587 public function setArtifactPathValidation($validator)
588 {
589 $this->artifactPathValidation = $validator;
590 return $this;
591 }
592
593 /**
594 * @return array
595 */
596 public function getChroot()
597 {
598 $chroot = [];
599 if (is_array($this->chroot)) {
600 $chroot = $this->chroot;
601 }
602 return $chroot;
603 }
604
605 /**
606 * @param boolean $debugCss
607 * @return $this
608 */
609 public function setDebugCss($debugCss)
610 {
611 $this->debugCss = $debugCss;
612 return $this;
613 }
614
615 /**
616 * @return boolean
617 */
618 public function getDebugCss()
619 {
620 return $this->debugCss;
621 }
622
623 /**
624 * @param boolean $debugKeepTemp
625 * @return $this
626 */
627 public function setDebugKeepTemp($debugKeepTemp)
628 {
629 $this->debugKeepTemp = $debugKeepTemp;
630 return $this;
631 }
632
633 /**
634 * @return boolean
635 */
636 public function getDebugKeepTemp()
637 {
638 return $this->debugKeepTemp;
639 }
640
641 /**
642 * @param boolean $debugLayout
643 * @return $this
644 */
645 public function setDebugLayout($debugLayout)
646 {
647 $this->debugLayout = $debugLayout;
648 return $this;
649 }
650
651 /**
652 * @return boolean
653 */
654 public function getDebugLayout()
655 {
656 return $this->debugLayout;
657 }
658
659 /**
660 * @param boolean $debugLayoutBlocks
661 * @return $this
662 */
663 public function setDebugLayoutBlocks($debugLayoutBlocks)
664 {
665 $this->debugLayoutBlocks = $debugLayoutBlocks;
666 return $this;
667 }
668
669 /**
670 * @return boolean
671 */
672 public function getDebugLayoutBlocks()
673 {
674 return $this->debugLayoutBlocks;
675 }
676
677 /**
678 * @param boolean $debugLayoutInline
679 * @return $this
680 */
681 public function setDebugLayoutInline($debugLayoutInline)
682 {
683 $this->debugLayoutInline = $debugLayoutInline;
684 return $this;
685 }
686
687 /**
688 * @return boolean
689 */
690 public function getDebugLayoutInline()
691 {
692 return $this->debugLayoutInline;
693 }
694
695 /**
696 * @param boolean $debugLayoutLines
697 * @return $this
698 */
699 public function setDebugLayoutLines($debugLayoutLines)
700 {
701 $this->debugLayoutLines = $debugLayoutLines;
702 return $this;
703 }
704
705 /**
706 * @return boolean
707 */
708 public function getDebugLayoutLines()
709 {
710 return $this->debugLayoutLines;
711 }
712
713 /**
714 * @param boolean $debugLayoutPaddingBox
715 * @return $this
716 */
717 public function setDebugLayoutPaddingBox($debugLayoutPaddingBox)
718 {
719 $this->debugLayoutPaddingBox = $debugLayoutPaddingBox;
720 return $this;
721 }
722
723 /**
724 * @return boolean
725 */
726 public function getDebugLayoutPaddingBox()
727 {
728 return $this->debugLayoutPaddingBox;
729 }
730
731 /**
732 * @param boolean $debugPng
733 * @return $this
734 */
735 public function setDebugPng($debugPng)
736 {
737 $this->debugPng = $debugPng;
738 return $this;
739 }
740
741 /**
742 * @return boolean
743 */
744 public function getDebugPng()
745 {
746 return $this->debugPng;
747 }
748
749 /**
750 * @param string $defaultFont
751 * @return $this
752 */
753 public function setDefaultFont($defaultFont)
754 {
755 if (!($defaultFont === null || trim($defaultFont) === "")) {
756 $this->defaultFont = $defaultFont;
757 } else {
758 $this->defaultFont = "serif";
759 }
760 return $this;
761 }
762
763 /**
764 * @return string
765 */
766 public function getDefaultFont()
767 {
768 return $this->defaultFont;
769 }
770
771 /**
772 * @param string $defaultMediaType
773 * @return $this
774 */
775 public function setDefaultMediaType($defaultMediaType)
776 {
777 $this->defaultMediaType = $defaultMediaType;
778 return $this;
779 }
780
781 /**
782 * @return string
783 */
784 public function getDefaultMediaType()
785 {
786 return $this->defaultMediaType;
787 }
788
789 /**
790 * @param string|float[] $defaultPaperSize
791 * @return $this
792 */
793 public function setDefaultPaperSize($defaultPaperSize): self
794 {
795 $this->defaultPaperSize = $defaultPaperSize;
796 return $this;
797 }
798
799 /**
800 * @param string $defaultPaperOrientation
801 * @return $this
802 */
803 public function setDefaultPaperOrientation(string $defaultPaperOrientation): self
804 {
805 $this->defaultPaperOrientation = $defaultPaperOrientation;
806 return $this;
807 }
808
809 /**
810 * @return string|float[]
811 */
812 public function getDefaultPaperSize()
813 {
814 return $this->defaultPaperSize;
815 }
816
817 /**
818 * @return string
819 */
820 public function getDefaultPaperOrientation(): string
821 {
822 return $this->defaultPaperOrientation;
823 }
824
825 /**
826 * @param int $dpi
827 * @return $this
828 */
829 public function setDpi($dpi)
830 {
831 $this->dpi = $dpi;
832 return $this;
833 }
834
835 /**
836 * @return int
837 */
838 public function getDpi()
839 {
840 return $this->dpi;
841 }
842
843 /**
844 * @param string $fontCache
845 * @return $this
846 */
847 public function setFontCache($fontCache)
848 {
849 if (!is_callable($this->artifactPathValidation) || ($this->artifactPathValidation)($fontCache, "fontCache") === true) {
850 $this->fontCache = $fontCache;
851 }
852 return $this;
853 }
854
855 /**
856 * @return string
857 */
858 public function getFontCache()
859 {
860 return $this->fontCache;
861 }
862
863 /**
864 * @param string $fontDir
865 * @return $this
866 */
867 public function setFontDir($fontDir)
868 {
869 if (!is_callable($this->artifactPathValidation) || ($this->artifactPathValidation)($fontDir, "fontDir") === true) {
870 $this->fontDir = $fontDir;
871 }
872 return $this;
873 }
874
875 /**
876 * @return string
877 */
878 public function getFontDir()
879 {
880 return $this->fontDir;
881 }
882
883 /**
884 * @param float $fontHeightRatio
885 * @return $this
886 */
887 public function setFontHeightRatio($fontHeightRatio)
888 {
889 $this->fontHeightRatio = $fontHeightRatio;
890 return $this;
891 }
892
893 /**
894 * @return float
895 */
896 public function getFontHeightRatio()
897 {
898 return $this->fontHeightRatio;
899 }
900
901 /**
902 * @param int $imageMemoryLimit
903 * @return $this
904 */
905 public function setImageByteSizeLimit($imageByteSizeLimit)
906 {
907 // Convert shorthand notation to bytes
908 if (preg_match('/^(\\d+)([KMG])$/i', $imageByteSizeLimit, $matches)) {
909 if (strtoupper($matches[2]) == 'K') {
910 $imageByteSizeLimit = (int)$matches[1] * 1024;
911 } elseif (strtoupper($matches[2]) == 'M') {
912 $imageByteSizeLimit = (int)$matches[1] * 1024 * 1024;
913 } elseif (strtoupper($matches[2]) == 'G') {
914 $imageByteSizeLimit = (int)$matches[1] * 1024 * 1024 * 1024;
915 }
916 }
917 if (is_numeric($imageByteSizeLimit)) {
918 $this->imageByteSizeLimit = $imageByteSizeLimit > 0 ? $imageByteSizeLimit : -1;
919 }
920 return $this;
921 }
922
923 /**
924 * @return int
925 */
926 public function getImageByteSizeLimit()
927 {
928 return $this->imageByteSizeLimit;
929 }
930
931 /**
932 * @param boolean $isFontSubsettingEnabled
933 * @return $this
934 */
935 public function setIsFontSubsettingEnabled($isFontSubsettingEnabled)
936 {
937 $this->isFontSubsettingEnabled = $isFontSubsettingEnabled;
938 return $this;
939 }
940
941 /**
942 * @return boolean
943 */
944 public function getIsFontSubsettingEnabled()
945 {
946 return $this->isFontSubsettingEnabled;
947 }
948
949 /**
950 * @return boolean
951 */
952 public function isFontSubsettingEnabled()
953 {
954 return $this->getIsFontSubsettingEnabled();
955 }
956
957 /**
958 * @deprecated
959 * @param boolean $isHtml5ParserEnabled
960 * @return $this
961 */
962 public function setIsHtml5ParserEnabled($isHtml5ParserEnabled)
963 {
964 $this->isHtml5ParserEnabled = $isHtml5ParserEnabled;
965 return $this;
966 }
967
968 /**
969 * @deprecated
970 * @return boolean
971 */
972 public function getIsHtml5ParserEnabled()
973 {
974 return $this->isHtml5ParserEnabled;
975 }
976
977 /**
978 * @deprecated
979 * @return boolean
980 */
981 public function isHtml5ParserEnabled()
982 {
983 return $this->getIsHtml5ParserEnabled();
984 }
985
986 /**
987 * @param boolean $isJavascriptEnabled
988 * @return $this
989 */
990 public function setIsJavascriptEnabled($isJavascriptEnabled)
991 {
992 $this->isJavascriptEnabled = $isJavascriptEnabled;
993 return $this;
994 }
995
996 /**
997 * @return boolean
998 */
999 public function getIsJavascriptEnabled()
1000 {
1001 return $this->isJavascriptEnabled;
1002 }
1003
1004 /**
1005 * @return boolean
1006 */
1007 public function isJavascriptEnabled()
1008 {
1009 return $this->getIsJavascriptEnabled();
1010 }
1011
1012 /**
1013 * @param boolean $isPhpEnabled
1014 * @return $this
1015 */
1016 public function setIsPhpEnabled($isPhpEnabled)
1017 {
1018 $this->isPhpEnabled = $isPhpEnabled;
1019 return $this;
1020 }
1021
1022 /**
1023 * @return boolean
1024 */
1025 public function getIsPhpEnabled()
1026 {
1027 return $this->isPhpEnabled;
1028 }
1029
1030 /**
1031 * @return boolean
1032 */
1033 public function isPhpEnabled()
1034 {
1035 return $this->getIsPhpEnabled();
1036 }
1037
1038 /**
1039 * @param boolean $isRemoteEnabled
1040 * @return $this
1041 */
1042 public function setIsRemoteEnabled($isRemoteEnabled)
1043 {
1044 $this->isRemoteEnabled = $isRemoteEnabled;
1045 return $this;
1046 }
1047
1048 /**
1049 * @return boolean
1050 */
1051 public function getIsRemoteEnabled()
1052 {
1053 return $this->isRemoteEnabled;
1054 }
1055
1056 /**
1057 * @return boolean
1058 */
1059 public function isRemoteEnabled()
1060 {
1061 return $this->getIsRemoteEnabled();
1062 }
1063
1064 /**
1065 * @param array|null $allowedRemoteHosts
1066 * @return $this
1067 */
1068 public function setAllowedRemoteHosts($allowedRemoteHosts)
1069 {
1070 if (is_array($allowedRemoteHosts)) {
1071 // Set hosts to lowercase
1072 foreach ($allowedRemoteHosts as &$host) {
1073 $host = mb_strtolower($host, "UTF-8");
1074 }
1075
1076 unset($host);
1077 }
1078
1079 $this->allowedRemoteHosts = $allowedRemoteHosts;
1080 return $this;
1081 }
1082
1083 /**
1084 * @return array|null
1085 */
1086 public function getAllowedRemoteHosts()
1087 {
1088 return $this->allowedRemoteHosts;
1089 }
1090
1091 /**
1092 * @param boolean $isRemoteEnabled
1093 * @return $this
1094 */
1095 public function setIsPdfAEnabled($isPdfAEnabled)
1096 {
1097 $this->isPdfAEnabled = $isPdfAEnabled;
1098 return $this;
1099 }
1100
1101 /**
1102 * @return boolean
1103 */
1104 public function getIsPdfAEnabled()
1105 {
1106 return $this->isPdfAEnabled;
1107 }
1108
1109 /**
1110 * @return boolean
1111 */
1112 public function isPdfAEnabled()
1113 {
1114 return $this->getIsPdfAEnabled();
1115 }
1116
1117 /**
1118 * @param string $logOutputFile
1119 * @return $this
1120 */
1121 public function setLogOutputFile($logOutputFile)
1122 {
1123 if (!is_callable($this->artifactPathValidation) || ($this->artifactPathValidation)($logOutputFile, "logOutputFile") === true) {
1124 $this->logOutputFile = $logOutputFile;
1125 }
1126 return $this;
1127 }
1128
1129 /**
1130 * @return string
1131 */
1132 public function getLogOutputFile()
1133 {
1134 return $this->logOutputFile;
1135 }
1136
1137 /**
1138 * @param string $tempDir
1139 * @return $this
1140 */
1141 public function setTempDir($tempDir)
1142 {
1143 if (!is_callable($this->artifactPathValidation) || ($this->artifactPathValidation)($tempDir, "tempDir") === true) {
1144 $this->tempDir = $tempDir;
1145 }
1146 return $this;
1147 }
1148
1149 /**
1150 * @return string
1151 */
1152 public function getTempDir()
1153 {
1154 return $this->tempDir;
1155 }
1156
1157 /**
1158 * @param string $rootDir
1159 * @return $this
1160 */
1161 public function setRootDir($rootDir)
1162 {
1163 if (!is_callable($this->artifactPathValidation) || ($this->artifactPathValidation)($rootDir, "rootDir") === true) {
1164 $this->rootDir = $rootDir;
1165 }
1166 return $this;
1167 }
1168
1169 /**
1170 * @return string
1171 */
1172 public function getRootDir()
1173 {
1174 return $this->rootDir;
1175 }
1176
1177 /**
1178 * Sets the HTTP context
1179 *
1180 * @param resource|array $httpContext
1181 * @return $this
1182 */
1183 public function setHttpContext($httpContext)
1184 {
1185 $this->httpContext = is_array($httpContext) ? stream_context_create($httpContext) : $httpContext;
1186 return $this;
1187 }
1188
1189 /**
1190 * Returns the HTTP context
1191 *
1192 * @return resource
1193 */
1194 public function getHttpContext()
1195 {
1196 return $this->httpContext;
1197 }
1198
1199
1200 public function validateArtifactPath(?string $path, string $option)
1201 {
1202 if ($path === null) {
1203 return true;
1204 }
1205 $parsed_uri = parse_url($path);
1206 if ($parsed_uri === false || (array_key_exists("scheme", $parsed_uri) && strtolower($parsed_uri["scheme"]) === "phar")) {
1207 return false;
1208 }
1209 return true;
1210 }
1211
1212 public function validateLocalUri(string $uri)
1213 {
1214 if ($uri === null || strlen($uri) === 0) {
1215 return [false, "The URI must not be empty."];
1216 }
1217
1218 $realfile = realpath(str_replace("file://", "", $uri));
1219 if ($realfile === false) {
1220 return [false, "File not found."];
1221 }
1222
1223 $dirs = $this->chroot;
1224 $dirs[] = $this->rootDir;
1225 $chrootValid = false;
1226 foreach ($dirs as $chrootPath) {
1227 $chrootPath = realpath($chrootPath);
1228 if ($chrootPath === false) {
1229 continue;
1230 }
1231
1232 $normalizedChrootPath = rtrim($chrootPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
1233 if ($realfile === $chrootPath || strncmp($realfile, $normalizedChrootPath, strlen($normalizedChrootPath)) === 0) {
1234 $chrootValid = true;
1235 break;
1236 }
1237 }
1238 if ($chrootValid !== true) {
1239 return [false, "Permission denied. The file could not be found under the paths specified by Options::chroot."];
1240 }
1241
1242 return [true, null];
1243 }
1244
1245 public function validatePharUri(string $uri)
1246 {
1247 if ($uri === null || strlen($uri) === 0) {
1248 return [false, "The URI must not be empty."];
1249 }
1250
1251 $file = substr(substr($uri, 0, strpos($uri, ".phar") + 5), 7);
1252 return $this->validateLocalUri($file);
1253 }
1254
1255 public function validateRemoteUri(string $uri)
1256 {
1257 if ($uri === null || strlen($uri) === 0) {
1258 return [false, "The URI must not be empty."];
1259 }
1260
1261 if (!$this->isRemoteEnabled) {
1262 return [false, "Remote file requested, but remote file download is disabled."];
1263 }
1264
1265 if (is_array($this->allowedRemoteHosts) && count($this->allowedRemoteHosts) > 0) {
1266 $host = parse_url($uri, PHP_URL_HOST);
1267 $host = mb_strtolower($host, "UTF-8");
1268
1269 if (!in_array($host, $this->allowedRemoteHosts, true)) {
1270 return [false, "Remote host is not in allowed list: " . $host];
1271 }
1272 }
1273
1274 return [true, null];
1275 }
1276 }
1277