Image_Cache

Static class that resolves image urls and downloads and caches remote images if required.

Defined (1)

The class is defined in the following location(s).

/lib/dompdf/include/image_cache.cls.php  
  1. class Image_Cache { 
  2.  
  3. /** 
  4. * Array of downloaded images. Cached so that identical images are 
  5. * not needlessly downloaded. 
  6. * @var array 
  7. */ 
  8. static protected $_cache = array(); 
  9.  
  10. /** 
  11. * The url to the "broken image" used when images can't be loade 
  12. *  
  13. * @var string 
  14. */ 
  15. public static $broken_image; 
  16.  
  17. /** 
  18. * Resolve and fetch an image for use. 
  19. * @param string $url The url of the image 
  20. * @param string $protocol Default protocol if none specified in $url 
  21. * @param string $host Default host if none specified in $url 
  22. * @param string $base_path Default path if none specified in $url 
  23. * @param DOMPDF $dompdf The DOMPDF instance 
  24. * @throws DOMPDF_Image_Exception 
  25. * @return array An array with two elements: The local path to the image and the image extension 
  26. */ 
  27. static function resolve_url($url, $protocol, $host, $base_path, DOMPDF $dompdf) { 
  28. $parsed_url = explode_url($url); 
  29. $message = null; 
  30.  
  31. $remote = ($protocol && $protocol !== "file://") || ($parsed_url['protocol'] != ""); 
  32.  
  33. $data_uri = strpos($parsed_url['protocol'], "data:") === 0; 
  34. $full_url = null; 
  35. $enable_remote = $dompdf->get_option("enable_remote"); 
  36.  
  37. try { 
  38.  
  39. // Remote not allowed and is not DataURI 
  40. if ( !$enable_remote && $remote && !$data_uri ) { 
  41. throw new DOMPDF_Image_Exception("DOMPDF_ENABLE_REMOTE is set to FALSE"); 
  42. }  
  43.  
  44. // Remote allowed or DataURI 
  45. else if ( $enable_remote && $remote || $data_uri ) { 
  46. // Download remote files to a temporary directory 
  47. $full_url = build_url($protocol, $host, $base_path, $url); 
  48.  
  49. // From cache 
  50. if ( isset(self::$_cache[$full_url]) ) { 
  51. $resolved_url = self::$_cache[$full_url]; 
  52.  
  53. // From remote 
  54. else { 
  55. $tmp_dir = $dompdf->get_option("temp_dir"); 
  56. $resolved_url = tempnam($tmp_dir, "ca_dompdf_img_"); 
  57. $image = ""; 
  58.  
  59. if ($data_uri) { 
  60. if ($parsed_data_uri = parse_data_uri($url)) { 
  61. $image = $parsed_data_uri['data']; 
  62. else { 
  63. set_error_handler("record_warnings"); 
  64. $image = file_get_contents($full_url); 
  65. restore_error_handler(); 
  66.  
  67. // Image not found or invalid 
  68. if ( strlen($image) == 0 ) { 
  69. $msg = ($data_uri ? "Data-URI could not be parsed" : "Image not found"); 
  70. throw new DOMPDF_Image_Exception($msg); 
  71.  
  72. // Image found, put in cache and process 
  73. else { 
  74. //e.g. fetch.php?media=url.jpg&cache=1 
  75. //- Image file name might be one of the dynamic parts of the url, don't strip off! 
  76. //- a remote url does not need to have a file extension at all 
  77. //- local cached file does not have a matching file extension 
  78. //Therefore get image type from the content 
  79. file_put_contents($resolved_url, $image); 
  80.  
  81. // Not remote, local image 
  82. else { 
  83. $resolved_url = build_url($protocol, $host, $base_path, $url); 
  84.  
  85. // Check if the local file is readable 
  86. if ( !is_readable($resolved_url) || !filesize($resolved_url) ) { 
  87. throw new DOMPDF_Image_Exception("Image not readable or empty"); 
  88.  
  89. // Check is the file is an image 
  90. else { 
  91. list($width, $height, $type) = dompdf_getimagesize($resolved_url); 
  92.  
  93. // Known image type 
  94. if ( $width && $height && in_array($type, array(IMAGETYPE_GIF, IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_BMP)) ) { 
  95. //Don't put replacement image into cache - otherwise it will be deleted on cache cleanup. 
  96. //Only execute on successful caching of remote image. 
  97. if ( $enable_remote && $remote || $data_uri ) { 
  98. self::$_cache[$full_url] = $resolved_url; 
  99.  
  100. // Unknown image type 
  101. else { 
  102. throw new DOMPDF_Image_Exception("Image type unknown"); 
  103. catch(DOMPDF_Image_Exception $e) { 
  104. $resolved_url = self::$broken_image; 
  105. $type = IMAGETYPE_PNG; 
  106. $message = $e->getMessage()." \n $url"; 
  107.  
  108. return array($resolved_url, $type, $message); 
  109.  
  110. /** 
  111. * Unlink all cached images (i.e. temporary images either downloaded 
  112. * or converted) 
  113. */ 
  114. static function clear() { 
  115. if ( empty(self::$_cache) || DEBUGKEEPTEMP ) return; 
  116.  
  117. foreach ( self::$_cache as $file ) { 
  118. if (DEBUGPNG) print "[clear unlink $file]"; 
  119. unlink($file); 
  120.  
  121. self::$_cache = array(); 
  122.  
  123. static function detect_type($file) { 
  124. list(, , $type) = dompdf_getimagesize($file); 
  125. return $type; 
  126.  
  127. static function type_to_ext($type) { 
  128. $image_types = array( 
  129. IMAGETYPE_GIF => "gif",  
  130. IMAGETYPE_PNG => "png",  
  131. IMAGETYPE_JPEG => "jpeg",  
  132. IMAGETYPE_BMP => "bmp",  
  133. ); 
  134.  
  135. return (isset($image_types[$type]) ? $image_types[$type] : null); 
  136.  
  137. static function is_broken($url) { 
  138. return $url === self::$broken_image;