2 // +----------------------------------------------------------------------+
4 // +----------------------------------------------------------------------+
5 // | Copyright (c) 1997-2003 The PHP Group |
6 // +----------------------------------------------------------------------+
7 // | This source file is subject to version 2.0 of the PHP license, |
8 // | that is bundled with this package in the file LICENSE, and is |
9 // | available at through the world-wide-web at |
10 // | http://www.php.net/license/2_02.txt. |
11 // | If you did not receive a copy of the PHP license and are unable to |
12 // | obtain it through the world-wide-web, please send a note to |
13 // | license@php.net so we can mail you a copy immediately. |
14 // +----------------------------------------------------------------------+
15 // | Authors: Ulf Wendel <ulf.wendel@phpdoc.de> |
16 // +----------------------------------------------------------------------+
18 // $Id: Graphics.php 6888 2009-06-04 13:01:12Z vargenau $
20 require_once 'Cache.php';
23 * Graphics disk cache.
25 * The usual way to create images is to pass some arguments that describe the image
26 * to a script that dynamically creates an image. For every image of a page
27 * a new PHP interpreter gets started. This is a good way to kill your webserver.
29 * When dealing with dynamically generated images you should not call another script
30 * to generate the images but generate the images by the script that produces the page
31 * that contains the images. This is a major improvement but it's only half the way.
33 * There's no need to rerender an image on every request. A simple disk cache can reduce
34 * the computation time dramatically. This is what the class graphics_cache is for.
38 * // create an instance of the graphics cache
39 * $cache = new graphics_cache;
41 * $img = ImageCreate(...);
43 * // compute an ID for your image based on typical parameters
44 * $id = m5d( $size, $colors, $label);
46 * // check if it's cached
47 * if (!($link = $cache->getImageLink($id, 'gif'))) {
49 * // hmmm, it's not cached, create it
51 * // cacheImageLink() and cacheImage() make the ImageGIF() call!
52 * // cacheImage() returns the value of ImageGIF() [etc.], cacheImageLink() returns a URL
53 * $link = $cache->cacheImageLink($id, $img, 'gif');
57 * // Ok, let's build the ImageLink
58 * $size = getImageSize($link[0]);
59 * printf('<img src="%s" %s>', $link[1], $size[3]);
61 * // for cacheImage():
62 * // header('Content-type: image/gif'); print $cache->cacheImage($id, $img, 'gif');
65 * The class requires PHP 4.0.2+ [ImageType()]. Note that cacheImage() works with
66 * the output buffer. Modify it if required!
68 * @author Ulf Wendel <ulf.wendel@phpdoc.de>
69 * @version $Id: Graphics.php 6888 2009-06-04 13:01:12Z vargenau $
72 class Cache_Graphics extends Cache {
78 * Make sure that the cache URL prefix points to the $cache_dir, otherwise
79 * your links will be broken. Use setCacheURL to specify the cache_url and
80 * setCacheDir() for the cache_dir.
83 * @see setCacheURL(), setCacheDir()
88 * Directory where cached files get stored.
90 * Make sure that the cache_dir is writable and offers enough space. Check
91 * also if your cache_url points to the directory. Use setCacheDir() to set
95 * @see setCacheDir(), setCacheURL()
100 * Nameprefix of cached files.
102 * Per default the prefix "graphics_" gets used. You might use this
103 * for versioning or to ease (manual) clean ups.
107 var $cache_file_prefix = 'graphics_';
111 * Cache container group.
115 var $cache_group = 'graphics';
119 * Mapping from supported image type to a ImageType() constant.
121 * Referr to the PHP manual for more informations on ImageType()
124 * @link http://www.php.net/ImageType
126 var $imagetypes = array(
135 * Instantiates a cache file container.
138 function Cache_Graphics() {
140 $this->Cache('file', array('cache_dir' => $this->cache_dir, 'filename_prefix' => $this->cache_file_prefix));
146 * Returns the content of a cached image file.
148 * This function can be used to send the image directly to the browser.
149 * Make sure that you send a correspondending header before sending the image itself.
151 * Always try to get the image from the cache before you compute it. See
152 * the class docs for an example.
154 * @param string Image-ID
155 * @param string Image type: gif, jpg, png, wbmp
156 * @return string Image file contents if a cached file exists otherwise an empty string
159 function getImage($id, $format = 'png') {
160 $id = $this->generateID($id, $format);
162 return $this->get($id, $this->cache_group);
163 } // end func getImage
167 * Returns an array with a link to the cached image and the image file path.
169 * Always try to get the image from the cache before you compute it. See
170 * the class docs for an example.
172 * @param string Image-ID
173 * @param string Image type: gif, jpg, png, wbmp
174 * @return array [ full path to the image file, image url ]
176 * @see cacheImageLink()
178 function getImageLink($id, $format = 'png') {
179 $id = $this->generateID($id, $format);
180 if (!$this->container->idExists($id, $this->cache_group))
183 $file = $this->cache_url . $this->cache_file_prefix . $id;
185 return array($this->container->getFilename($id, $this->cache_group), $file);
186 } // end func getImageLink
190 * Create an image from the given image handler, cache it and return the file content.
192 * Always try to retrive the image from the cache before you compute it.
194 * Warning: this function uses the output buffer. If you expect collisions
197 * @param string Image-ID. Used as a part of the cache filename.
198 * Use md5() to generate a "unique" ID for your image
199 * based on characteristic values such as the color, size etc.
200 * @param string Image handler to create the image from.
201 * @param string Image type: gif, jpg, png, wbmp. Also used as filename suffix.
202 * If an unsupported type is requested the functions tries to
203 * fallback to a supported type before throwing an exeption.
204 * @return string Image content returned by ImageGIF/...
205 * @throws Cache_Error
209 function cacheImage($id, $img, $format = 'png') {
211 return new Cache_Error('You must provide an ID for and image to be cached!', __FILE__, __LINE__);
213 $id = $this->generateID($id, $format);
214 $types = ImageTypes();
216 // Check if the requested image type is supported by the GD lib.
217 // If not, try a callback to the first available image type.
218 if (!isset($this->imagetypes[$format]) || !($types & $this->imagetypes[$format])) {
219 foreach ($this->imagetypes as $supported => $bitmask) {
220 if ($types & $bitmask) {
221 new Cache_Error("The build in GD lib does not support the image type $format. Fallback to $supported.", __FILE__, __LINE__);
223 return new Cache_Error("Hmm, is your PHP build with GD support? Can't find any supported types.", __FILE__, __LINE__);
228 if ($image = $this->get($id, $this->cache_group))
231 // save the image to the output buffer, write it to disk and
236 if (strtoupper($format) == "JPG") {
239 $genFormat = strtoupper($format);
242 // generate the image
243 $func = 'Image' . $genFormat;
248 $image = ob_get_contents();
251 // save the generated image to disk
252 $this->save($id, $image, 0, $this->cache_group);
255 } // end func cacheImage
259 * Create an image from the given image handler, cache it and return a url and the file path of the image.
261 * Always try to retrive the image from the cache before you compute it.
263 * @param string Image-ID. Used as a part of the cache filename.
264 * Use md5() to generate a "unique" ID for your image
265 * based on characteristic values such as the color, size etc.
266 * @param string Image handler to create the image from.
267 * @param string Image type: gif, jpg, png, wbmp. Also used as filename suffix.
268 * If an unsupported type is requested the functions tries to
269 * fallback to a supported type before throwing an exeption.
270 * @return array [ full path to the image file, image url ]
271 * @throws Cache_Error
274 function cacheImageLink($id, &$img, $format = 'png') {
276 return new Cache_Error ('You must provide an ID for and image to be cached!', __FILE__, __LINE__);
278 $id = $this->generateID($id, $format);
279 $types = ImageTypes();
281 // Check if the requested image type is supported by the GD lib.
282 // If not, try a callback to the first available image type.
283 if (!isset($this->imagetypes[$format]) || !($types & $this->imagetypes[$format])) {
284 foreach ($this->imagetypes as $supported => $bitmask)
285 if ($types & $bitmask)
286 new Cache_Error("The build in GD lib does not support the image type $format. Fallback to $supported.", __FILE__, __LINE__);
288 return new Cache_Error("Hmm, is your PHP build with GD support? Can't find any supported types.", __FILE__, __LINE__);
291 $url = $this->cache_url . $this->cache_file_prefix . $id;
292 $ffile = $this->container->getFilename($id, $this->cache_group);
294 if ($this->isCached($id, $this->cache_group) && !isExpired($id, $this->cache_group))
295 return array($ffile, $url);
297 if (strtoupper($format) == "JPG") {
300 $genFormat = strtoupper($format);
303 $func = 'Image' . $genFormat;
308 return array($ffile, $url);
309 } // end func cacheImageLink
313 * Sets the URL prefix used when rendering HTML Tags.
315 * Make sure that the URL matches the cache directory,
316 * otherwise you'll get broken links.
322 function setCacheURL($cache_url) {
323 if ($cache_url && '/' != substr($cache_url, 1))
326 $this->cache_url = $cache_url;
328 } // end func setCacheURL
332 * Sets the directory where to cache generated Images
338 function setCacheDir($cache_dir) {
339 if ($cache_dir && '/' != substr($cache_dir, 1))
342 $this->cache_dir = $cache_dir;
343 $this->container->cache_dir = $cache_dir;
344 } // end func setCacheDir
347 function generateID($variable, $format = 'png') {
348 return md5(serialize($variable)) . '.' . $format;
349 } // end func generateID
352 } // end class Cache_Graphics