image_cache.cls.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. <?php
  2. /**
  3. * DOMPDF - PHP5 HTML to PDF renderer
  4. *
  5. * File: $RCSfile: image_cache.cls.php,v $
  6. * Created on: 2004-08-08
  7. *
  8. * Copyright (c) 2004 - Benj Carson <benjcarson@digitaljunkies.ca>
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation; either
  13. * version 2.1 of the License, or (at your option) any later version.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public License
  21. * along with this library in the file LICENSE.LGPL; if not, write to the
  22. * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  23. * 02111-1307 USA
  24. *
  25. * Alternatively, you may distribute this software under the terms of the
  26. * PHP License, version 3.0 or later. A copy of this license should have
  27. * been distributed with this file in the file LICENSE.PHP . If this is not
  28. * the case, you can obtain a copy at http://www.php.net/license/3_0.txt.
  29. *
  30. * The latest version of DOMPDF might be available at:
  31. * http://www.dompdf.com/
  32. *
  33. * @link http://www.dompdf.com/
  34. * @copyright 2004 Benj Carson
  35. * @author Benj Carson <benjcarson@digitaljunkies.ca>
  36. * @contributor Helmut Tischer <htischer@weihenstephan.org>
  37. * @package dompdf
  38. *
  39. * Changes
  40. * @contributor Helmut Tischer <htischer@weihenstephan.org>
  41. * @version 0.5.1.htischer.20090507
  42. * - On getting type of images don't require any file endings
  43. * and don't strip off url parameters,
  44. * to allowing dynamically generated sites with image id
  45. * in url parameters and not at end of url or missing file extension
  46. * @contributor Helmut Tischer <htischer@weihenstephan.org>
  47. * @version dompdf_trunk_with_helmut_mods.20090524
  48. * - Made debug messages more individually configurable
  49. * @version 20090622
  50. * - don't cache broken image, but refer to original broken image replacement
  51. */
  52. /* $Id: image_cache.cls.php 216 2010-03-11 22:49:18Z ryan.masten $ */
  53. /**
  54. * Static class that resolves image urls and downloads and caches
  55. * remote images if required.
  56. *
  57. * @access private
  58. * @package dompdf
  59. */
  60. class Image_Cache {
  61. /**
  62. * Array of downloaded images. Cached so that identical images are
  63. * not needlessly downloaded.
  64. *
  65. * @var array
  66. */
  67. static protected $_cache = array();
  68. /**
  69. * Resolve and fetch an image for use.
  70. *
  71. * @param string $url The url of the image
  72. * @param string $proto Default protocol if none specified in $url
  73. * @param string $host Default host if none specified in $url
  74. * @param string $base_path Default path if none specified in $url
  75. * @return array An array with two elements: The local path to the image and the image extension
  76. */
  77. static function resolve_url($url, $proto, $host, $base_path) {
  78. global $_dompdf_warnings;
  79. $parsed_url = explode_url($url);
  80. $DEBUGPNG=DEBUGPNG; //=DEBUGPNG; Allow override of global setting for ad hoc debug
  81. $full_url_dbg = '';
  82. //debugpng
  83. if ($DEBUGPNG) print 'resolve_url('.$url.','.$proto.','.$host.','.$base_path.')('.$parsed_url['protocol'].')';
  84. $remote = ($proto != "" && $proto !== "file://");
  85. $remote = $remote || ($parsed_url['protocol'] != "");
  86. if ( !DOMPDF_ENABLE_REMOTE && $remote ) {
  87. $resolved_url = DOMPDF_LIB_DIR . "/res/broken_image.png";
  88. $ext = "png";
  89. //debugpng
  90. if ($DEBUGPNG) $full_url_dbg = '(blockedremote)';
  91. } else if ( DOMPDF_ENABLE_REMOTE && $remote ) {
  92. // Download remote files to a temporary directory
  93. $full_url = build_url($proto, $host, $base_path, $url);
  94. if ( isset(self::$_cache[$full_url]) ) {
  95. list($resolved_url,$ext) = self::$_cache[$full_url];
  96. //debugpng
  97. if ($DEBUGPNG) $full_url_dbg = $full_url.'(cache)';
  98. } else {
  99. $resolved_url = tempnam(DOMPDF_TEMP_DIR, "ca_dompdf_img_");
  100. //debugpng
  101. if ($DEBUGPNG) echo $resolved_url . "\n";
  102. $old_err = set_error_handler("record_warnings");
  103. $image = file_get_contents($full_url);
  104. restore_error_handler();
  105. if ( strlen($image) == 0 ) {
  106. //target image not found
  107. $resolved_url = DOMPDF_LIB_DIR . "/res/broken_image.png";
  108. $ext = "png";
  109. //debugpng
  110. if ($DEBUGPNG) $full_url_dbg = $full_url.'(missing)';
  111. } else {
  112. file_put_contents($resolved_url, $image);
  113. //e.g. fetch.php?media=url.jpg&cache=1
  114. //- Image file name might be one of the dynamic parts of the url, don't strip off!
  115. // if ( preg_match("/.*\.(\w+)/",$url,$match) ) $ext = $match[1];
  116. //- a remote url does not need to have a file extension at all
  117. //- local cached file does not have a matching file extension
  118. //Therefore get image type from the content
  119. $imagedim = getimagesize($resolved_url);
  120. if( $imagedim[2] >= 1 && $imagedim[2] <=3 && $imagedim[0] && $imagedim[1] ) {
  121. //target image is valid
  122. $imagetypes = array('','gif','jpeg','png','swf');
  123. $ext = $imagetypes[$imagedim[2]];
  124. if ( rename($resolved_url,$resolved_url.'.'.$ext) ) {
  125. $resolved_url .= '.'.$ext;
  126. }
  127. //Don't put replacement image into cache - otherwise it will be deleted on cache cleanup.
  128. //Only execute on successfull caching of remote image.
  129. self::$_cache[$full_url] = array($resolved_url,$ext);
  130. } else {
  131. //target image is not valid.
  132. unlink($resolved_url);
  133. $resolved_url = DOMPDF_LIB_DIR . "/res/broken_image.png";
  134. $ext = "png";
  135. }
  136. }
  137. }
  138. } else {
  139. $resolved_url = build_url($proto, $host, $base_path, $url);
  140. if ($DEBUGPNG) print 'build_url('.$proto.','.$host.','.$base_path.','.$url.')('.$resolved_url.')';
  141. if ( !preg_match("/.*\.(\w+)/",$url,$match) ) {
  142. //debugpng
  143. if ($DEBUGPNG) print '[resolve_url exception '.$url.']';
  144. throw new DOMPDF_Exception("Unknown image type: $url.");
  145. }
  146. $ext = $match[1];
  147. //debugpng
  148. if ($DEBUGPNG) $full_url_dbg = '(local)';
  149. }
  150. if ( !is_readable($resolved_url) || !filesize($resolved_url) ) {
  151. //debugpng
  152. if ($DEBUGPNG) $full_url_dbg .= '(nocache'.$resolved_url.')';
  153. $_dompdf_warnings[] = "File " .$resolved_url . " is not readable or is an empty file.\n";
  154. $resolved_url = DOMPDF_LIB_DIR . "/res/broken_image.png";
  155. $ext = "png";
  156. }
  157. //debugpng
  158. if ($DEBUGPNG) print '[resolve_url '.$url.'|'.$full_url_dbg.'|'.$resolved_url.'|'.$ext.']';
  159. return array($resolved_url, $ext);
  160. }
  161. /**
  162. * Unlink all cached images (i.e. temporary images either downloaded
  163. * or converted)
  164. */
  165. static function clear() {
  166. if ( count(self::$_cache) ) {
  167. while ($entry = array_shift(self::$_cache)) {
  168. list($file, $ext) = $entry;
  169. //debugpng
  170. if (DEBUGPNG) print '[clear unlink '.$file.']';
  171. if (!DEBUGKEEPTEMP)
  172. //XXX: Should we have some kind of fallback or warning if unlink() fails?
  173. unlink($file);
  174. }
  175. }
  176. }
  177. }