root/trunk/system/libraries/Cache.php

Revision 2905, 5.0 kB (checked in by Shadowhand, 2 weeks ago)

Fixing #662, thanks HarryR!

  • Property svn:eol-style set to LF
  • Property copyright set to Copyright (c) 2007 Kohana Team
  • Property svn:keywords set to Id
Line 
1 <?php defined('SYSPATH') or die('No direct script access.');
2 /**
3  * Provides a driver-based interface for finding, creating, and deleting cached
4  * resources. Caches are identified by a unique string. Tagging of caches is
5  * also supported, and caches can be found and deleted by id or tag.
6  *
7  * $Id$
8  *
9  * @package    Cache
10  * @author     Kohana Team
11  * @copyright  (c) 2007-2008 Kohana Team
12  * @license    http://kohanaphp.com/license.html
13  */
14 class Cache_Core {
15
16     // For garbage collection
17     protected static $loaded;
18
19     // Configuration
20     protected $config;
21
22     // Driver object
23     protected $driver;
24
25     /**
26      * Returns a singleton instance of Cache.
27      *
28      * @param   array   configuration
29      * @return  Cache_Core
30      */
31     public static function instance($config = array())
32     {
33         static $obj;
34
35         // Create the Cache instance
36         ($obj === NULL) and $obj = new Cache($config);
37
38         return $obj;
39     }
40
41     /**
42      * Loads the configured driver and validates it.
43      *
44      * @param  array  custom configuration
45      * @return void
46      */
47     public function __construct($config = array())
48     {
49         if (empty($config))
50         {
51             // Load the default group
52             $config = Config::item('cache.default');
53         }
54         elseif (is_string($config))
55         {
56             $name = $config;
57
58             // Test the config group name
59             if (($config = Config::item('cache.'.$config)) === NULL)
60                 throw new Kohana_Exception('cache.undefined_group', $name);
61         }
62
63         // Load configuration
64         $this->config = (array) $config + Config::item('cache.default');
65
66         // Set driver name
67         $driver = 'Cache_'.ucfirst($this->config['driver']).'_Driver';
68
69         // Load the driver
70         if ( ! Kohana::auto_load($driver))
71             throw new Kohana_Exception('core.driver_not_found', $this->config['driver'], get_class($this));
72
73         // Initialize the driver
74         $this->driver = new $driver($this->config['params']);
75
76         // Validate the driver
77         if ( ! ($this->driver instanceof Cache_Driver))
78             throw new Kohana_Exception('core.driver_implements', $this->config['driver'], get_class($this), 'Cache_Driver');
79
80         Log::add('debug', 'Cache Library initialized');
81
82         if (self::$loaded !== TRUE)
83         {
84             $this->config['requests'] = (int) $this->config['requests'];
85
86             if ($this->config['requests'] > 0 AND mt_rand(1, $this->config['requests']) === 1)
87             {
88                 // Do garbage collection
89                 $this->driver->delete_expired();
90
91                 Log::add('debug', 'Cache: Expired caches deleted.');
92             }
93
94             // Cache has been loaded once
95             self::$loaded = TRUE;
96         }
97     }
98
99     /**
100      * Fetches a cache by id. Non-string cache items are automatically
101      * unserialized before the cache is returned. NULL is returned when
102      * a cache item is not found.
103      *
104      * @param  string  cache id
105      * @return mixed   cached data or NULL
106      */
107     public function get($id)
108     {
109         // Change slashes to colons
110         $id = str_replace(array('/', '\\'), '=', $id);
111
112         if ($data = $this->driver->get($id))
113         {
114             if (substr($data, 0, 14) === '<{serialized}>')
115             {
116                 // Data has been serialized, unserialize now
117                 $data = unserialize(substr($data, 14));
118             }
119         }
120
121         return $data;
122     }
123
124     /**
125      * Fetches all of the caches for a given tag. An empty array will be
126      * returned when no matching caches are found.
127      *
128      * @param  string  cache tag
129      * @return array   all cache items matching the tag
130      */
131     public function find($tag)
132     {
133         if ($ids = $this->driver->find($tag))
134         {
135             $data = array();
136             foreach ($ids as $id)
137             {
138                 // Load each cache item and add it to the array
139                 if (($cache = $this->get($id)) !== NULL)
140                 {
141                     $data[$id] = $cache;
142                 }
143             }
144             return $data;
145         }
146
147         return array();
148     }
149
150     /**
151      * Set a cache item by id. Tags may also be added and a custom lifetime
152      * can be set. Non-string data is automatically serialized.
153      *
154      * @param  string  unique cache id
155      * @param  mixed   data to cache
156      * @param  array   tags for this item
157      * @param  integer number of seconds until the cache expires
158      * @return bool
159      */
160     function set($id, $data, $tags = NULL, $lifetime = NULL)
161     {
162         if (is_resource($data))
163             throw new Kohana_Exception('cache.resources');
164
165         // Change slashes to colons
166         $id = str_replace(array('/', '\\'), '=', $id);
167
168         if ( ! is_string($data))
169         {
170             // Serialize all non-string data, so that types can be preserved
171             $data = '<{serialized}>'.serialize($data);
172         }
173
174         if (empty($tags))
175         {
176             $tags = array();
177         }
178         else
179         {
180             // Make sure that tags is an array
181             $tags = (array) $tags;
182         }
183
184         if ($lifetime === NULL)
185         {
186             // Get the default lifetime
187             $lifetime = $this->config['lifetime'];
188         }
189
190         return $this->driver->set($id, $data, $tags, $lifetime);
191     }
192
193     /**
194      * Delete a cache item by id.
195      *
196      * @param  string  cache id
197      * @return bool
198      */
199     public function delete($id)
200     {
201         // Change slashes to colons
202         $id = str_replace(array('/', '\\'), '=', $id);
203
204         return $this->driver->delete($id);
205     }
206
207     /**
208      * Delete all cache items with a given tag.
209      *
210      * @param  string  cache tag name
211      * @return bool
212      */
213     public function delete_tag($tag)
214     {
215         return $this->driver->delete(FALSE, $tag);
216     }
217
218     /**
219      * Delete ALL cache items items.
220      *
221      * @return bool
222      */
223     public function delete_all()
224     {
225         return $this->driver->delete(TRUE);
226     }
227
228 } // End Cache
Note: See TracBrowser for help on using the browser.