ok
Direktori : /home2/selectio/www/ecommerce-website/website/vendor/dompdf/dompdf/src/Image/ |
Current File : /home2/selectio/www/ecommerce-website/website/vendor/dompdf/dompdf/src/Image/Cache.php |
<?php /** * @package dompdf * @link https://github.com/dompdf/dompdf * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\Image; use Dompdf\Options; use Dompdf\Helpers; use Dompdf\Exception\ImageException; /** * Static class that resolves image urls and downloads and caches * remote images if required. * * @package dompdf */ class Cache { /** * Array of downloaded images. Cached so that identical images are * not needlessly downloaded. * * @var array */ protected static $_cache = []; /** * @var array */ protected static $tempImages = []; /** * The url to the "broken image" used when images can't be loaded * * @var string */ public static $broken_image = "data:image/svg+xml;charset=utf8,%3C?xml version='1.0'?%3E%3Csvg width='64' height='64' xmlns='http://www.w3.org/2000/svg'%3E%3Cg%3E%3Crect stroke='%23666666' id='svg_1' height='60.499994' width='60.166667' y='1.666669' x='1.999998' stroke-width='1.5' fill='none'/%3E%3Cline stroke-linecap='null' stroke-linejoin='null' id='svg_3' y2='59.333253' x2='59.749916' y1='4.333415' x1='4.250079' stroke-width='1.5' stroke='%23999999' fill='none'/%3E%3Cline stroke-linecap='null' stroke-linejoin='null' id='svg_4' y2='59.999665' x2='4.062838' y1='3.750342' x1='60.062164' stroke-width='1.5' stroke='%23999999' fill='none'/%3E%3C/g%3E%3C/svg%3E"; public static $error_message = "Image not found or type unknown"; /** * Resolve and fetch an image for use. * * @param string $url The url of the image * @param string $protocol Default protocol if none specified in $url * @param string $host Default host if none specified in $url * @param string $base_path Default path if none specified in $url * @param Options $options An instance of Dompdf\Options * * @return array An array with three elements: The local path to the image, the image * extension, and an error message if the image could not be cached */ static function resolve_url($url, $protocol, $host, $base_path, Options $options) { $tempfile = null; $resolved_url = null; $type = null; $message = null; try { $full_url = Helpers::build_url($protocol, $host, $base_path, $url); if ($full_url === null) { throw new ImageException("Unable to parse image URL $url.", E_WARNING); } $parsed_url = Helpers::explode_url($full_url); $protocol = strtolower($parsed_url["protocol"]); $is_data_uri = strpos($protocol, "data:") === 0; if (!$is_data_uri) { $allowed_protocols = $options->getAllowedProtocols(); if (!array_key_exists($protocol, $allowed_protocols)) { throw new ImageException("Permission denied on $url. The communication protocol is not supported.", E_WARNING); } foreach ($allowed_protocols[$protocol]["rules"] as $rule) { [$result, $message] = $rule($full_url); if (!$result) { throw new ImageException("Error loading $url: $message", E_WARNING); } } } if ($protocol === "file://") { $resolved_url = $full_url; } elseif (isset(self::$_cache[$full_url])) { $resolved_url = self::$_cache[$full_url]; } else { $tmp_dir = $options->getTempDir(); if (($resolved_url = @tempnam($tmp_dir, "ca_dompdf_img_")) === false) { throw new ImageException("Unable to create temporary image in " . $tmp_dir, E_WARNING); } $tempfile = $resolved_url; $image = null; if ($is_data_uri) { if (($parsed_data_uri = Helpers::parse_data_uri($url)) !== false) { $image = $parsed_data_uri["data"]; } } else { list($image, $http_response_header) = Helpers::getFileContent($full_url, $options->getHttpContext()); } // Image not found or invalid if ($image === null) { $msg = ($is_data_uri ? "Data-URI could not be parsed" : "Image not found"); throw new ImageException($msg, E_WARNING); } if (@file_put_contents($resolved_url, $image) === false) { throw new ImageException("Unable to create temporary image in " . $tmp_dir, E_WARNING); } self::$_cache[$full_url] = $resolved_url; } // Check if the local file is readable if (!is_readable($resolved_url) || !filesize($resolved_url)) { throw new ImageException("Image not readable or empty", E_WARNING); } list($width, $height, $type) = Helpers::dompdf_getimagesize($resolved_url, $options->getHttpContext()); if (($width && $height && in_array($type, ["gif", "png", "jpeg", "bmp", "svg","webp"], true)) === false) { throw new ImageException("Image type unknown", E_WARNING); } if ($type === "svg") { $parser = xml_parser_create("utf-8"); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false); xml_set_element_handler( $parser, function ($parser, $name, $attributes) use ($options, $parsed_url, $full_url) { if (strtolower($name) === "image") { $attributes = array_change_key_case($attributes, CASE_LOWER); $urls = []; $urls[] = $attributes["xlink:href"] ?? ""; $urls[] = $attributes["href"] ?? ""; foreach ($urls as $url) { if (!empty($url)) { $inner_full_url = Helpers::build_url($parsed_url["protocol"], $parsed_url["host"], $parsed_url["path"], $url); if ($inner_full_url === $full_url) { throw new ImageException("SVG self-reference is not allowed", E_WARNING); } [$resolved_url, $type, $message] = self::resolve_url($url, $parsed_url["protocol"], $parsed_url["host"], $parsed_url["path"], $options); if (!empty($message)) { throw new ImageException("This SVG document references a restricted resource. $message", E_WARNING); } } } } }, false ); if (($fp = fopen($resolved_url, "r")) !== false) { while ($line = fread($fp, 8192)) { xml_parse($parser, $line, false); } fclose($fp); xml_parse($parser, "", true); } xml_parser_free($parser); } } catch (ImageException $e) { if ($tempfile) { unlink($tempfile); } $resolved_url = self::$broken_image; list($width, $height, $type) = Helpers::dompdf_getimagesize($resolved_url, $options->getHttpContext()); $message = self::$error_message; Helpers::record_warnings($e->getCode(), $e->getMessage() . " \n $url", $e->getFile(), $e->getLine()); self::$_cache[$full_url] = $resolved_url; } return [$resolved_url, $type, $message]; } /** * Register a temp file for the given original image file. * * @param string $filePath The path of the original image. * @param string $tempPath The path of the temp file to register. * @param string $key An optional key to register the temp file at. */ static function addTempImage(string $filePath, string $tempPath, string $key = "default"): void { if (!isset(self::$tempImages[$filePath])) { self::$tempImages[$filePath] = []; } self::$tempImages[$filePath][$key] = $tempPath; } /** * Get the path of a temp file registered for the given original image file. * * @param string $filePath The path of the original image. * @param string $key The key the temp file is registered at. */ static function getTempImage(string $filePath, string $key = "default"): ?string { return self::$tempImages[$filePath][$key] ?? null; } /** * Unlink all cached images (i.e. temporary images either downloaded * or converted) except for the bundled "broken image" */ static function clear(bool $debugPng = false) { foreach (self::$_cache as $file) { if ($file === self::$broken_image) { continue; } if ($debugPng) { print "[clear unlink $file]"; } if (file_exists($file)) { unlink($file); } } foreach (self::$tempImages as $versions) { foreach ($versions as $file) { if ($file === self::$broken_image) { continue; } if ($debugPng) { print "[unlink temp image $file]"; } if (file_exists($file)) { unlink($file); } } } self::$_cache = []; self::$tempImages = []; } static function detect_type($file, $context = null) { list(, , $type) = Helpers::dompdf_getimagesize($file, $context); return $type; } static function is_broken($url) { return $url === self::$broken_image; } } if (file_exists(realpath(__DIR__ . "/../../lib/res/broken_image.svg"))) { Cache::$broken_image = realpath(__DIR__ . "/../../lib/res/broken_image.svg"); }