extend usage of in-class cache in Tinebase_Container
[tine20] / tine20 / Tinebase / Cache / PerRequest.php
1 <?php
2 /**
3  * Tine 2.0
4  * 
5  * @package     Tinebase
6  * @subpackage  Cache
7  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
8  * @copyright   Copyright (c) 2015-2015 Metaways Infosystems GmbH (http://www.metaways.de)
9  * @author      Lars Kneschke <l.kneschke@metaways.de>
10  */
11
12 /**
13  * per request in memory cache class
14  * 
15  * a central place to manage in class caches
16  * 
17  * @package     Tinebase
18  * @subpackage  Cache
19  */
20 class Tinebase_Cache_PerRequest 
21 {
22     /**
23      * the cache
24      *
25      * @var array
26      */
27     protected $_inMemoryCache = array();
28
29     /**
30      * use Zend_Cache as fallback
31      *
32      * @var bool
33      *
34      * TODO allow to configure this
35      */
36     protected $_usePersistentCache = false;
37     
38     /**
39      * holds the instance of the singleton
40      *
41      * @var Tinebase_Cache_PerRequest
42      */
43     private static $_instance = NULL;
44     
45     /**
46      * the constructor
47      *
48      * don't use the constructor. use the singleton 
49      */
50     private function __construct()
51     {
52     }
53     
54     /**
55      * don't clone. Use the singleton.
56      *
57      */
58     private function __clone() 
59     {
60     }
61     
62     /**
63      * the singleton pattern
64      *
65      * @return Tinebase_Cache_PerRequest
66      */
67     public static function getInstance() 
68     {
69         if (self::$_instance === NULL) {
70             self::$_instance = new Tinebase_Cache_PerRequest();
71         }
72         
73         return self::$_instance;
74     }
75
76     /**
77      * set/get persistent cache usage
78      *
79      * @param  boolean optional
80      * @return boolean
81      */
82     public function usePersistentCache()
83     {
84         $value = (func_num_args() === 1) ? (bool) func_get_arg(0) : NULL;
85         $currValue = $this->_usePersistentCache;
86         if ($value !== NULL) {
87             $this->_usePersistentCache = $value;
88         }
89
90         return $currValue;
91     }
92
93     /**
94      * save entry in cache
95      * 
96      * @param string $class
97      * @param string $method
98      * @param string $cacheId
99      * @param string $value
100      * @return Tinebase_Cache_PerRequest
101      */
102     public function save($class, $method, $cacheId, $value)
103     {
104         $cacheId = sha1($cacheId);
105         
106         $this->_inMemoryCache[$class][$method][$cacheId] = $value;
107
108         if ($this->_usePersistentCache) {
109             Tinebase_Core::getCache()->save($value, $cacheId);
110         }
111         
112         return $this;
113     }
114     
115     /**
116      * load entry from cache
117      * 
118      * @param string $class
119      * @param string $method
120      * @param string $cacheId
121      * @throws Tinebase_Exception_NotFound
122      * @return mixed
123      */
124     public function load($class, $method, $cacheId)
125     {
126         $cacheId = sha1($cacheId);
127         
128         if (!isset($this->_inMemoryCache[$class]) ||
129             !isset($this->_inMemoryCache[$class][$method]) ||
130             !(isset($this->_inMemoryCache[$class][$method][$cacheId]) || array_key_exists($cacheId, $this->_inMemoryCache[$class][$method]))
131         ) {
132
133             if ($this->_usePersistentCache) {
134                 // TODO better use Tinebase_Core::getCache()->test() ?
135                 $value = Tinebase_Core::getCache()->load($cacheId);
136                 if ($value !== false) {
137                     $this->_inMemoryCache[$class][$method][$cacheId] = $value;
138                     return $value;
139                 }
140             }
141
142             throw new Tinebase_Exception_NotFound('cacheId not found');
143         };
144         
145         return $this->_inMemoryCache[$class][$method][$cacheId];
146     }
147     
148     /**
149      * reset cache
150      * 
151      * @param string $class
152      * @param string $method
153      * @param string $cacheId
154      * @return Tinebase_Cache_PerRequest
155      */
156     public function resetCache($class = null, $method = null, $cacheId = null)
157     {
158         $cacheId = $cacheId ? sha1($cacheId) : $cacheId;
159         
160         if (empty($class)) {
161             $this->_inMemoryCache = array();
162             
163             return $this;
164         }
165         
166         if (empty($method)) {
167             $this->_inMemoryCache[$class] = array();
168             
169             return $this;
170         }
171         
172         if (empty($cacheId)) {
173             $this->_inMemoryCache[$class][$method] = array();
174             
175             return $this;
176         } else if ($this->_usePersistentCache) {
177             Tinebase_Core::getCache()->remove($cacheId);
178         }
179         
180         if (isset($this->_inMemoryCache[$class]) &&
181             isset($this->_inMemoryCache[$class][$method]) &&
182             (isset($this->_inMemoryCache[$class][$method][$cacheId]) || array_key_exists($cacheId, $this->_inMemoryCache[$class][$method]))
183         ) {
184             unset($this->_inMemoryCache[$class][$method][$cacheId]);
185         };
186         
187         return $this;
188     }
189 }