root/trunk/lib/AkCache.php

Revision 1185, 11.6 kB (checked in by arnoschn, 1 week ago)

WARNING: IMPORTANT CHANGES AHEAD!

Using this version requires you do manually add/change files/folders to existing applications.

Merging Caching Branch into trunk:

New features:

1. Configuration

1.1. Yaml Configuration (see inline doc at: http://svn.akelos.org/trunk/lib/AkConfig.php)

2. Caching (see inline doc at: http://svn.akelos.org/trunk/lib/AkActionController/AkCacheHandler.php)

2.1 Memcache Cache Handler
2.2 Page Caching
2.3 Action Caching
2.4 Fragment Caching
2.5 Cache Sweepers

3. ActiveRecord?

3.1 toXml (RoR style) (see inline doc at: http://svn.akelos.org/trunk/lib/AkActiveRecord.php)
3.2 fromXml
3.3 toJson (RoR style) (see inline doc at: http://svn.akelos.org/trunk/lib/AkActiveRecord.php)
3.4 fromJson
3.5 AkDbSchemaCache?

4. ActionController?

4.1 respondToFormat (see inline doc at: http://svn.akelos.org/trunk/lib/AkActionController.php)

5. Functional Testing (AkTestApplication?) (see example usage in: http://svn.akelos.org/trunk/test/unit/lib/AkActionController/_page_caching.php)

Refactoring / Improvements:

6. Unit Testing Fixtures

class AkSomeTest? extends AkUnitTest?
{
/**

  • grabs AK_BASE_DIR/test/fixtures/data/posts.yaml and inserts the data in the db
  • example:

  • posts.yaml:
  • entry1:
  • id: 1
  • name: test1
  • entry2:
  • id: 2
  • name: test2

  • model instances are available via $this->posts['entry1] and $this->posts['entry2]
    */
    var $fixtures = 'posts';


...

}

7. AkSession?


Session handling can now be configured via config/sessions.yml.
Besides file storage you can use Memcache or Db Storage for sessions.

8. AkPluginInstaller?

Line 
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
4 // +----------------------------------------------------------------------+
5 // | Akelos Framework - http://www.akelos.org                             |
6 // +----------------------------------------------------------------------+
7 // | Copyright (c) 2002-2006, Akelos Media, S.L.  & Bermi Ferrer Martinez |
8 // | Released under the GNU Lesser General Public License, see LICENSE.txt|
9 // +----------------------------------------------------------------------+
10
11 /**
12  * @package ActiveSupport
13  * @subpackage Cache
14  * @author Bermi Ferrer <bermi a.t akelos c.om>
15  * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org
16  * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
17  */
18
19
20 // ---- Required Files ---- //
21 require_once(AK_LIB_DIR.DS.'Ak.php');
22 require_once(AK_LIB_DIR.DS.'AkObject.php');
23
24
25 /**
26 * Easy to use class for caching data using a database as
27 * container or the file system.
28 *
29 * Akelos Framework provides an easy to use functionality for
30 * caching data using a database as container or the file
31 * system.
32 *
33 * By default the cache container is defined in the following
34 * line
35 *
36 * <code>define ('AK_CACHE_HANDLER', 1);</code>
37 *
38 * in the ''config/config.php'' file
39 *
40 * Possible values are:
41 *
42 * - 0: No cache at all
43 * - 1: File based cache using the folder defined at AK_CACHE_DIR or the system /tmp dir
44 * - 2: Database based cache. This one has a performance penalty, but works on most servers
45 *
46 * Here is a small code spinet of how this works.
47 * <code>
48 * // First we include the cache class and
49 * // create a cache instance
50 * include_once(AK_LIB_DIR.'/AkCache.php');
51 * $Cache =& new AkCache();
52 *
53 * // Now we define some details for this cache
54 * $seconds = 3600; // seconds of life for this cache
55 * $cache_id = 'unique identifier for accesing this cache element';
56 *
57 * // Now we call the $Cache constructor (ALA AkFramework)
58 * $Cache->init($seconds);
59 *
60 * // If the data is not cached, we catch it now
61 * // if it was on cache, $data will hold its content
62 * if (!$data = $Cache->get($cache_id)) {
63 * $data = some_heavy_function_that_takes_too_many_time_or_resources();
64 * $Cache->save($data);
65 * }
66 *
67 * // Now you can use data no matter from where did it came from
68 * echo $data;
69 * </code>
70 *
71 * This class uses the
72 * [http://pear.php.net/manual/en/package.caching.cache-lite.php
73 * pear Cache_Lite] as driver for file based cache.
74 * In fact you can access an instance of Cache_Lite by
75 * accesing $Cache->_driverInstance.
76 *
77 * @author Bermi Ferrer <bermi at akelos dot com>
78 * @copyright Copyright (c) 2002-2005, Akelos Media, S.L. http://www.akelos.org
79 * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
80 * @since 0.1
81 * @version $Revision 0.1 $
82 */
83 class AkCache extends AkObject
84 {
85
86     /**
87     * Handles an instance of current Cache driver
88     *
89     * @access private
90     * @var object $_driverInstance
91     */
92     var $_driverInstance = NULL;
93
94     /**
95     * Ecnables / Disables caching
96     *
97     * @access public
98     * @var boolean true
99     */
100     var $cache_enabled = true;
101     
102     
103     /**
104      * Instantiates and configures the AkCache store.
105      *
106      * If $options == NULL the configuration will be taken from the constants:
107      *
108      * AK_CACHE_HANDLER and AK_CACHE_OPTIONS
109      *
110      * if $options is of type string/int the $options parameter will be considered
111      * as the AK_CACHE_HANDLER_* Type (AK_CACHE_HANDLER_PEAR,AK_CACHE_HANDLER_ADODB,AK_CACHE_HANDLER_MEMCACHE)
112      *
113      * if $options is an array of format:
114      *
115      *   array('file'=>array('cacheDir'=>'/tmp'))
116      *   
117      *   or
118      *
119      *   array(AK_CACHE_HANDLER_PEAR=>array('cacheDir'=>'/tmp'))
120      *
121      *  the first key will be used as the AK_CACHE_HANDLER_* Type
122      *  and the array as the config options
123      *
124      * Default behaviour is calling the method with the $options == null parameter:
125      *
126      * AkCache::lookupStore()
127      *
128      * Calling it with:
129      *
130      * AkCache::lookupStore(true)
131      *
132      * will return the configured $cache_store
133      *
134      * @param mixed $options
135      * @return mixed   false if no cache could be configured or AkCache instance
136      */
137     function &lookupStore($options = null)
138     {
139         static $cache_store;
140         $false = false;
141         if ($options === true && !empty($cache_store)) {
142             return $cache_store;
143         } else if (is_array($options) &&
144                    isset($options['enabled']) && $options['enabled']==true &&
145                    isset($options['handler']) &&
146                    isset($options['handler']['type'])) {
147             $type = $options['handler']['type'];
148             $options = isset($options['handler']['options'])?$options['handler']['options']:array();
149         } else if (is_string($options) || is_int($options)) {
150             $type = $options;
151             $options = array();
152         } else {
153             return $false;
154         }
155         $cache_store = new AkCache();
156         $cache_store->init($options,$type);
157         if ($cache_store->cache_enabled) {
158             return $cache_store;
159         }
160         return $false;
161     }
162     
163     function expandCacheKey($key, $namespace = null)
164     {
165         $expanded_cache_key = $namespace != null? $namespace : '';
166         if (isset($_ENV['AK_CACHE_ID'])) {
167             $expanded_cache_key .= DS . $_ENV['AK_CACHE_ID'];
168         } else if (isset($_ENV['AK_APP_VERSION'])) {
169             $expanded_cache_key .= DS . $_ENV['AK_APP_VERSION'];
170         }
171         
172         if (is_object($key) && method_exists($key,'cacheKey')) {
173             $expanded_cache_key .= DS . $key->cacheKey();
174         } else if (is_array($key)) {
175             foreach ($key as $idx => $v) {
176                 $expanded_cache_key .= DS . $idx.'='.$v;
177             }
178         } else {
179             $expanded_cache_key .= DS . $key;
180         }
181         $regex = '|'.DS.'+|';
182         $expanded_cache_key = preg_replace($regex,DS, $expanded_cache_key);
183         $expanded_cache_key = rtrim($expanded_cache_key,DS);
184         return $expanded_cache_key;
185     }
186     
187     /**
188     * Class constructor (ALA Akelos Framework)
189     *
190     * This method loads an instance of selected driver in order to
191     * use it class wide.
192     *
193     * @access public
194     * @param    mixed    $options    You can pass a number specifying the second for
195     * the cache to expire or an array with the
196     * following options:
197     *
198     * <code>
199     * $options = array(
200     * //This options are valid for both cache contains (database and file based)
201     * 'lifeTime' => cache lifetime in seconds
202     * (int),
203     * 'memoryCaching' => enable / disable memory caching (boolean),
204     * 'automaticSerialization' => enable / disable automatic serialization (boolean)
205     *
206     * //This options are for file based cache
207     * 'cacheDir' => directory where to put the cache files (string),
208     * 'caching' => enable / disable caching (boolean),
209     * 'fileLocking' => enable / disable fileLocking (boolean),
210     * 'writeControl' => enable / disable write control (boolean),
211     * 'readControl' => enable / disable read control (boolean),
212     * 'readControlType' => type of read control
213     * 'crc32', 'md5', 'strlen' (string),
214     * 'pearErrorMode' => pear error mode (when raiseError is called) (cf PEAR doc) (int),
215     * 'onlyMemoryCaching' => enable / disable only memory caching (boolean),
216     * 'memoryCachingLimit' => max nbr of records to store into memory caching (int),
217     * 'fileNameProtection' => enable / disable automatic file name protection (boolean),
218     * 'automaticCleaningFactor' => distable / tune automatic cleaning process (int)
219     * 'hashedDirectoryLevel' => level of the hashed directory system (int)
220     * );
221     * </code>
222     * @param    integer    $cache_type    The default value is set by defining the constant AK_CACHE_HANDLER in the following line
223     *
224     * <code>define ('AK_CACHE_HANDLER', 1);</code>
225     *
226     * in the ''config/config.php'' file
227     *
228     * Possible values are:
229     *
230     * - 0: No cache at all
231     * - 1: File based cache using the folder defined at AK_CACHE_DIR or the system /tmp dir
232     * - 2: Database based cache. This one has a performance penalty, but works on most servers
233     * - 3: Memcached - The fastest option
234     * @return void
235     */
236     function init($options = null, $cache_type = null)
237     {
238         $options = is_int($options) ? array('lifeTime'=>$options) : (is_array($options) ? $options : array());
239
240         switch ($cache_type) {
241             case 1:
242                 $this->cache_enabled = true;
243                 if(!class_exists('Cache_Lite')){
244                     require_once(AK_CONTRIB_DIR.'/pear/Cache_Lite/Lite.php');
245                 }
246                 if(!isset($options['cacheDir'])){
247                     $options['cacheDir'] = AK_CACHE_DIR.DS;
248                 } else {
249                     $options['cacheDir'].=DS;
250                 }
251                  if(!is_dir($options['cacheDir'])){
252                     Ak::make_dir($options['cacheDir'], array('base_path'=>dirname($options['cacheDir'])));
253                 }
254                 $this->_driverInstance =& new Cache_Lite($options);
255                 break;
256             case 2:
257                 require_once(AK_LIB_DIR.'/AkCache/AkAdodbCache.php');
258                 $this->_driverInstance =& new AkAdodbCache();
259                 $res = $this->_driverInstance->init($options);
260                 $this->cache_enabled = $res;
261                 break;
262             case 3:
263                 require_once(AK_LIB_DIR.'/AkCache/AkMemcache.php');
264                 $this->_driverInstance =& new AkMemcache();
265                 $res = $this->_driverInstance->init($options);
266                 $this->cache_enabled = $res;
267                 break;
268             default:
269                 $this->cache_enabled = false;
270                 break;
271         }
272     }
273
274
275     /**
276     * Test if a cache is available and (if yes) return it
277     *
278     * @access public
279     * @param    string    $id    Cache id
280     * @param    string    $group    Name of the cache group.
281     * @return mixed Data of the cache (or false if no cache available)
282     */
283     function get($id, $group = 'default')
284     {
285         return $this->cache_enabled ? $this->_driverInstance->get($id, $group) : false;
286     }
287
288
289     /**
290     * Save some data in the cache
291     *
292     * @access public
293     * @param    string    $data    Data to put in cache
294     * @param    string    $id    Cache id
295     * @param    string    $group    Name of the cache group
296     * @return boolean True if no problem
297     */
298     function save($data, $id = null, $group = 'default')
299     {
300         return $this->cache_enabled ? $this->_driverInstance->save($data, $id, $group) : true;
301     }
302
303
304     /**
305     * Remove a cache item
306     *
307     * @access public
308     * @param    string    $id    Cache id
309     * @param    string    $group    Name of the cache group
310     * @return boolean True if no problem
311     */
312     function remove($id, $group = 'default')
313     {
314         return $this->cache_enabled ? $this->_driverInstance->remove($id, $group) : true;
315     }
316
317
318     /**
319     * Clean the cache
320     *
321     * If no group is specified all cache items will be destroyed
322     * else only cache items of the specified group will be
323     * destroyed
324     *
325     * @access public
326     * @param    string    $group    Name of the cache group.
327     * If no group is specified all cache items will be
328     * destroyed else only cache items of the specified
329     * group will be destroyed
330     * @param    string    $mode    Flush cache mode. Options are:
331     *
332     * - old
333     * - ingroup
334     * - notingroup
335     * @return boolean True if no problem
336     */
337     function clean($group = false, $mode = 'ingroup')
338     {
339         return $this->cache_enabled ? $this->_driverInstance->clean($group, $mode) : true;
340     }
341
342 }
343
344 ?>
345
Note: See TracBrowser for help on using the browser.