]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/pear/Cache/Graphics.php
Remove svn:keywords
[SourceForge/phpwiki.git] / lib / pear / Cache / Graphics.php
1 <?php
2 // +----------------------------------------------------------------------+
3 // | PEAR :: Cache                                                        |
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 // +----------------------------------------------------------------------+
17
18 require_once 'Cache.php';
19
20 /**
21 * Graphics disk cache.
22 *
23 * The usual way to create images is to pass some arguments that describe the image
24 * to a script that dynamically creates an image. For every image of a page
25 * a new PHP interpreter gets started. This is a good way to kill your webserver.
26 *
27 * When dealing with dynamically generated images you should not call another script
28 * to generate the images but generate the images by the script that produces the page
29 * that contains the images. This is a major improvement but it's only half the way.
30 *
31 * There's no need to rerender an image on every request. A simple disk cache can reduce
32 * the computation time dramatically. This is what the class graphics_cache is for.
33 *
34 * Usage:
35 *
36 * // create an instance of the graphics cache
37 * $cache = new graphics_cache;
38 *
39 * $img = ImageCreate(...);
40 *
41 * // compute an ID for your image based on typical parameters
42 * $id = m5d( $size, $colors, $label);
43 *
44 * // check if it's cached
45 * if (!($link = $cache->getImageLink($id, 'gif'))) {
46 *
47 *   // hmmm, it's not cached, create it
48 *   ...
49 *   // cacheImageLink() and cacheImage() make the ImageGIF() call!
50 *   // cacheImage() returns the value of ImageGIF() [etc.], cacheImageLink() returns a URL
51 *   $link = $cache->cacheImageLink($id, $img, 'gif');
52 *
53 * }
54 *
55 * // Ok, let's build the ImageLink
56 * $size = getImageSize($link[0]);
57 * printf('<img src="%s" %s>', $link[1], $size[3]);
58 *
59 * // for cacheImage():
60 * // header('Content-type: image/gif'); print $cache->cacheImage($id, $img, 'gif');
61 *
62 *
63 * The class requires PHP 4.0.2+ [ImageType()]. Note that cacheImage() works with
64 * the output buffer. Modify it if required!
65 *
66 * @author   Ulf Wendel <ulf.wendel@phpdoc.de>
67 * @version  
68 * @package  Cache
69 */
70 class Cache_Graphics extends Cache {
71
72
73     /**
74     * Cache URL prefix.
75     *
76     * Make sure that the cache URL prefix points to the $cache_dir, otherwise
77     * your links will be broken. Use setCacheURL to specify the cache_url and
78     * setCacheDir() for the cache_dir.
79     *
80     * @var  string
81     * @see  setCacheURL(), setCacheDir()
82     */
83     var $cache_url = '';
84
85     /**
86     * Directory where cached files get stored.
87     * s
88     * Make sure that the cache_dir is writable and offers enough space. Check
89     * also if your cache_url points to the directory. Use setCacheDir() to set
90     * the variable.
91     *
92     * @var  string
93     * @see  setCacheDir(), setCacheURL()
94     */
95     var $cache_dir = '';
96
97     /**
98     * Nameprefix of cached files.
99     *
100     * Per default the prefix "graphics_" gets used. You might use this
101     * for versioning or to ease (manual) clean ups.
102     *
103     * @var      string
104     */
105     var $cache_file_prefix = 'graphics_';
106
107
108     /**
109     * Cache container group.
110     *
111     * @var      string
112     */
113     var $cache_group = 'graphics';
114
115
116     /**
117     * Mapping from supported image type to a ImageType() constant.
118     *
119     * Referr to the PHP manual for more informations on ImageType()
120     *
121     * @var  array
122     * @link http://www.php.net/ImageType
123     */
124     var $imagetypes = array(
125                                 'gif'   => IMG_GIF,
126                                 'jpg'   => IMG_JPG,
127                                 'png'   => IMG_PNG,
128                                 'wbmp'  => IMG_WBMP
129                             );
130
131
132     /**
133     * Instantiates a cache file container.
134     *
135     */
136     function Cache_Graphics() {
137
138         $this->Cache('file', array('cache_dir' => $this->cache_dir, 'filename_prefix' => $this->cache_file_prefix));
139
140     } // end constructor
141
142
143     /**
144     * Returns the content of a cached image file.
145     *
146     * This function can be used to send the image directly to the browser.
147     * Make sure that you send a correspondending header before sending the image itself.
148     *
149     * Always try to get the image from the cache before you compute it. See
150     * the class docs for an example.
151     *
152     * @param    string  Image-ID
153     * @param    string  Image type: gif, jpg, png, wbmp
154     * @return   string  Image file contents if a cached file exists otherwise an empty string
155     * @see      cacheImage()
156     */
157     function getImage($id, $format = 'png') {
158         $id = $this->generateID($id, $format);
159
160         return $this->get($id, $this->cache_group);
161     } // end func getImage
162
163
164     /**
165     * Returns an array with a link to the cached image and the image file path.
166     *
167     * Always try to get the image from the cache before you compute it. See
168     * the class docs for an example.
169     *
170     * @param    string  Image-ID
171     * @param    string  Image type: gif, jpg, png, wbmp
172     * @return   array   [ full path to the image file, image url ]
173     * @throw    Cache_Error
174     * @see      cacheImageLink()
175     */
176     function getImageLink($id, $format = 'png') {
177         $id = $this->generateID($id, $format);
178         if (!$this->container->idExists($id, $this->cache_group))
179             return array();
180
181         $file = $this->cache_url . $this->cache_file_prefix . $id;
182
183         return array($this->container->getFilename($id, $this->cache_group), $file);
184     } // end func getImageLink
185
186
187     /**
188     * Create an image from the given image handler, cache it and return the file content.
189     *
190     * Always try to retrive the image from the cache before you compute it.
191     *
192     * Warning: this function uses the output buffer. If you expect collisions
193     * modify the code.
194     *
195     * @param    string  Image-ID. Used as a part of the cache filename.
196     *                   Use md5() to generate a "unique" ID for your image
197     *                   based on characteristic values such as the color, size etc.
198     * @param    string  Image handler to create the image from.
199     * @param    string  Image type: gif, jpg, png, wbmp. Also used as filename suffix.
200     *                   If an unsupported type is requested the functions tries to
201     *                   fallback to a supported type before throwing an exeption.
202     * @return   string  Image content returned by ImageGIF/...
203     * @throws   Cache_Error
204     * @access   public
205     * @see      getImage()
206     */
207     function cacheImage($id, $img, $format = 'png') {
208         if (!$id)
209             return new Cache_Error('You must provide an ID for and image to be cached!', __FILE__, __LINE__);
210
211         $id = $this->generateID($id, $format);
212         $types = ImageTypes();
213
214         // Check if the requested image type is supported by the GD lib.
215         // If not, try a callback to the first available image type.
216         if (!isset($this->imagetypes[$format]) || !($types & $this->imagetypes[$format])) {
217             foreach ($this->imagetypes as $supported => $bitmask) {
218                 if ($types & $bitmask) {
219                     new Cache_Error("The build in GD lib does not support the image type $format. Fallback to $supported.", __FILE__, __LINE__);
220                 } else {
221                     return new Cache_Error("Hmm, is your PHP build with GD support? Can't find any supported types.", __FILE__, __LINE__);
222                 }
223             }
224         }
225
226         if ($image = $this->get($id, $this->cache_group))
227             return $image;
228
229         // save the image to the output buffer, write it to disk and
230         // return the image.
231         ob_end_clean();
232         ob_start();
233
234         if (strtoupper($format) == "JPG") {
235             $genFormat = "JPEG";
236         } else {
237             $genFormat = strtoupper($format);
238         }
239
240         // generate the image
241         $func = 'Image' . $genFormat;
242         $func($img);
243         ImageDestroy($img);
244
245         ob_end();
246         $image = ob_get_contents();
247         ob_end_clean();
248
249         // save the generated image to disk
250         $this->save($id, $image, 0, $this->cache_group);
251
252         return $image;
253     } // end func cacheImage
254
255
256     /**
257     * Create an image from the given image handler, cache it and return a url and the file path of the image.
258     *
259     * Always try to retrive the image from the cache before you compute it.
260     *
261     * @param    string  Image-ID. Used as a part of the cache filename.
262     *                   Use md5() to generate a "unique" ID for your image
263     *                   based on characteristic values such as the color, size etc.
264     * @param    string  Image handler to create the image from.
265     * @param    string  Image type: gif, jpg, png, wbmp. Also used as filename suffix.
266     *                   If an unsupported type is requested the functions tries to
267     *                   fallback to a supported type before throwing an exeption.
268     * @return   array  [ full path to the image file, image url ]
269     * @throws   Cache_Error
270     * @access   public
271     */
272     function cacheImageLink($id, &$img, $format = 'png') {
273         if (!$id)
274             return new Cache_Error ('You must provide an ID for and image to be cached!', __FILE__, __LINE__);
275
276         $id = $this->generateID($id, $format);
277         $types = ImageTypes();
278
279         // Check if the requested image type is supported by the GD lib.
280         // If not, try a callback to the first available image type.
281         if (!isset($this->imagetypes[$format]) || !($types & $this->imagetypes[$format])) {
282             foreach ($this->imagetypes as $supported => $bitmask)
283                 if ($types & $bitmask)
284                     new Cache_Error("The build in GD lib does not support the image type $format. Fallback to $supported.", __FILE__, __LINE__);
285                 else
286                     return new Cache_Error("Hmm, is your PHP build with GD support? Can't find any supported types.", __FILE__, __LINE__);
287         }
288
289         $url = $this->cache_url . $this->cache_file_prefix . $id;
290         $ffile = $this->container->getFilename($id, $this->cache_group);
291
292         if ($this->isCached($id, $this->cache_group) && !isExpired($id, $this->cache_group))
293             return array($ffile, $url);
294
295         if (strtoupper($format) == "JPG") {
296             $genFormat = "JPEG";
297         } else {
298             $genFormat = strtoupper($format);
299         }
300
301         $func = 'Image' . $genFormat;
302         $func($img, $ffile);
303
304         ImageDestroy($img);
305
306         return array($ffile, $url);
307     } // end func cacheImageLink
308
309
310     /**
311     * Sets the URL prefix used when rendering HTML Tags.
312     *
313     * Make sure that the URL matches the cache directory,
314     * otherwise you'll get broken links.
315     *
316     * @param    string
317     * @access   public
318     * @see      setCacheDir()
319     */
320     function setCacheURL($cache_url) {
321         if ($cache_url && '/' != substr($cache_url, 1))
322             $cache_url .= '/';
323
324         $this->cache_url = $cache_url;
325
326     } // end func setCacheURL
327
328     /**
329     * Sets the directory where to cache generated Images
330     *
331     * @param    string
332     * @access   public
333     * @see      setCacheURL()
334     */
335     function setCacheDir($cache_dir) {
336         if ($cache_dir && '/' != substr($cache_dir, 1))
337             $cache_dir .= '/';
338
339         $this->cache_dir = $cache_dir;
340         $this->container->cache_dir = $cache_dir;
341     } // end func setCacheDir
342
343     function generateID($variable, $format = 'png') {
344       return md5(serialize($variable)) . '.' . $format;
345     } // end func generateID
346
347 } // end class Cache_Graphics
348 ?>