Advertisement
Bagosep

Cache

Jun 13th, 2021
1,130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 7.83 KB | None | 0 0
  1. <?php
  2. /**
  3.  * @package dompdf
  4.  * @link    http://dompdf.github.com/
  5.  * @author  Benj Carson <benjcarson@digitaljunkies.ca>
  6.  * @author  Helmut Tischer <htischer@weihenstephan.org>
  7.  * @author  Fabien Ménager <fabien.menager@gmail.com>
  8.  * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
  9.  */
  10. namespace Dompdf\Image;
  11.  
  12. use Dompdf\Dompdf;
  13. use Dompdf\Helpers;
  14. use Dompdf\Exception\ImageException;
  15.  
  16. /**
  17.  * Static class that resolves image urls and downloads and caches
  18.  * remote images if required.
  19.  *
  20.  * @package dompdf
  21.  */
  22. class Cache
  23. {
  24.     /**
  25.      * Array of downloaded images.  Cached so that identical images are
  26.      * not needlessly downloaded.
  27.      *
  28.      * @var array
  29.      */
  30.     protected static $_cache = [];
  31.  
  32.     /**
  33.      * The url to the "broken image" used when images can't be loaded
  34.      *
  35.      * @var string
  36.      */
  37.     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";
  38.  
  39.     public static $error_message = "Image not found or type unknown";
  40.    
  41.     /**
  42.      * Current dompdf instance
  43.      *
  44.      * @var Dompdf
  45.      */
  46.     protected static $_dompdf;
  47.  
  48.     /**
  49.      * Resolve and fetch an image for use.
  50.      *
  51.      * @param string $url       The url of the image
  52.      * @param string $protocol  Default protocol if none specified in $url
  53.      * @param string $host      Default host if none specified in $url
  54.      * @param string $base_path Default path if none specified in $url
  55.      * @param Dompdf $dompdf    The Dompdf instance
  56.      *
  57.      * @throws ImageException
  58.      * @return array             An array with two elements: The local path to the image and the image extension
  59.      */
  60.     static function resolve_url($url, $protocol, $host, $base_path, Dompdf $dompdf)
  61.     {
  62.         self::$_dompdf = $dompdf;
  63.        
  64.         $protocol = mb_strtolower($protocol);
  65.         $parsed_url = Helpers::explode_url($url);
  66.         $message = null;
  67.  
  68.         $remote = ($protocol && $protocol !== "file://") || ($parsed_url['protocol'] != "");
  69.  
  70.         $data_uri = strpos($parsed_url['protocol'], "data:") === 0;
  71.         $full_url = null;
  72.         $enable_remote = $dompdf->getOptions()->getIsRemoteEnabled();
  73.  
  74.         try {
  75.  
  76.             // Remote not allowed and is not DataURI
  77.             if (!$enable_remote && $remote && !$data_uri) {
  78.                 throw new ImageException("Remote file access is disabled.", E_WARNING);
  79.             } // Remote allowed or DataURI
  80.             else {
  81.                 if ($enable_remote && $remote || $data_uri) {
  82.                     // Download remote files to a temporary directory
  83.                     $full_url = Helpers::build_url($protocol, $host, $base_path, $url);
  84.  
  85.                     // From cache
  86.                     if (isset(self::$_cache[$full_url])) {
  87.                         $resolved_url = self::$_cache[$full_url];
  88.                     } // From remote
  89.                     else {
  90.                         $tmp_dir = $dompdf->getOptions()->getTempDir();
  91.                         if (($resolved_url = @tempnam($tmp_dir, "ca_dompdf_img_")) === false) {
  92.                             throw new ImageException("Unable to create temporary image in " . $tmp_dir, E_WARNING);
  93.                         }
  94.                         $image = "";
  95.  
  96.                         if ($data_uri) {
  97.                             if ($parsed_data_uri = Helpers::parse_data_uri($url)) {
  98.                                 $image = $parsed_data_uri['data'];
  99.                             }
  100.                         } else {
  101.                             list($image, $http_response_header) = Helpers::getFileContent($full_url, $dompdf->getHttpContext());
  102.                         }
  103.  
  104.                         // Image not found or invalid
  105.                         if (empty($image)) {
  106.                             $msg = ($data_uri ? "Data-URI could not be parsed" : "Image not found");
  107.                             throw new ImageException($msg, E_WARNING);
  108.                         } // Image found, put in cache and process
  109.                         else {
  110.                             //e.g. fetch.php?media=url.jpg&cache=1
  111.                             //- Image file name might be one of the dynamic parts of the url, don't strip off!
  112.                             //- a remote url does not need to have a file extension at all
  113.                             //- local cached file does not have a matching file extension
  114.                             //Therefore get image type from the content
  115.                             if (@file_put_contents($resolved_url, $image) === false) {
  116.                                 throw new ImageException("Unable to create temporary image in " . $tmp_dir, E_WARNING);
  117.                             }
  118.                         }
  119.                     }
  120.                 } // Not remote, local image
  121.                 else {
  122.                     $resolved_url = Helpers::build_url($protocol, $host, $base_path, $url);
  123.                 }
  124.             }
  125.  
  126.             // Check if the local file is readable
  127.             if (!is_readable($resolved_url) || !filesize($resolved_url)) {
  128.                 throw new ImageException("Image not readable or empty", E_WARNING);
  129.             } // Check is the file is an image
  130.             else {
  131.                 list($width, $height, $type) = Helpers::dompdf_getimagesize($resolved_url, $dompdf->getHttpContext());
  132.  
  133.                 // Known image type
  134.                 if ($width && $height && in_array($type, ["gif", "png", "jpeg", "bmp", "svg"])) {
  135.                     //Don't put replacement image into cache - otherwise it will be deleted on cache cleanup.
  136.                     //Only execute on successful caching of remote image.
  137.                     if ($enable_remote && $remote || $data_uri) {
  138.                         self::$_cache[$full_url] = $resolved_url;
  139.                     }
  140.                 } // Unknown image type
  141.                 else {
  142.                     throw new ImageException("Image type unknown", E_WARNING);
  143.                 }
  144.             }
  145.         } catch (ImageException $e) {
  146.             $resolved_url = self::$broken_image;
  147.             $type = "png";
  148.             $message = self::$error_message;
  149.             Helpers::record_warnings($e->getCode(), $e->getMessage() . " \n $url", $e->getFile(), $e->getLine());
  150.         }
  151.  
  152.         return [$resolved_url, $type, $message];
  153.     }
  154.  
  155.     /**
  156.      * Unlink all cached images (i.e. temporary images either downloaded
  157.      * or converted)
  158.      */
  159.     static function clear()
  160.     {
  161.         if (empty(self::$_cache) || self::$_dompdf->getOptions()->getDebugKeepTemp()) {
  162.             return;
  163.         }
  164.  
  165.         foreach (self::$_cache as $file) {
  166.             if (self::$_dompdf->getOptions()->getDebugPng()) {
  167.                 print "[clear unlink $file]";
  168.             }
  169.             unlink($file);
  170.         }
  171.  
  172.         self::$_cache = [];
  173.     }
  174.  
  175.     static function detect_type($file, $context = null)
  176.     {
  177.         list(, , $type) = Helpers::dompdf_getimagesize($file, $context);
  178.  
  179.         return $type;
  180.     }
  181.  
  182.     static function is_broken($url)
  183.     {
  184.         return $url === self::$broken_image;
  185.     }
  186. }
  187.  
  188. if (file_exists(realpath(__DIR__ . "/../../lib/res/broken_image.svg"))) {
  189.     Cache::$broken_image = realpath(__DIR__ . "/../../lib/res/broken_image.svg");
  190. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement