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