1: <?php
2:
3: /**
4: * This file contains the generic db item cache class.
5: *
6: * @package Core
7: * @subpackage GenericDB
8: * @version SVN Revision $Rev:$
9: *
10: * @author Murat Purc <murat@purc.de>
11: * @copyright four for business AG <www.4fb.de>
12: * @license http://www.contenido.org/license/LIZENZ.txt
13: * @link http://www.4fb.de
14: * @link http://www.contenido.org
15: */
16:
17: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
18:
19: /**
20: * Class cItemCache.
21: *
22: * Implements features to cache entries, usually result sets of Item classes.
23: * Contains a list of self instances, where each instance contains cached Items
24: * fore one specific table.
25: *
26: * @package Core
27: * @subpackage GenericDB
28: */
29: class cItemCache {
30:
31: /**
32: * List of self instances (cItemCache)
33: *
34: * @var array
35: */
36: protected static $_oInstances = array();
37:
38: /**
39: * Assoziative cache array
40: *
41: * @var array
42: */
43: protected $_aItemsCache = array();
44:
45: /**
46: * Table name for current instance
47: *
48: * @var string
49: */
50: protected $_sTable = '';
51:
52: /**
53: * Max number of items to cache
54: *
55: * @var int
56: */
57: protected $_iMaxItemsToCache = 10;
58:
59: /**
60: * Enable caching
61: *
62: * @var bool
63: */
64: protected $_bEnable = false;
65:
66: /**
67: * Contructor of cItemCache
68: *
69: * @param string $sTable
70: * Table name
71: * @param array $aOptions [optional]
72: * Options array as follows:
73: * - $aOptions['max_items_to_cache'] = (int) Number of items to cache
74: * - $aOptions['enable'] = (bool) Flag to enable caching
75: */
76: protected function __construct($sTable, array $aOptions = array()) {
77: $this->_sTable = $sTable;
78: if (isset($aOptions['max_items_to_cache']) && (int) $aOptions['max_items_to_cache'] > 0) {
79: $this->_iMaxItemsToCache = (int) $aOptions['max_items_to_cache'];
80: }
81: if (isset($aOptions['enable']) && is_bool($aOptions['enable'])) {
82: $this->_bEnable = (bool) $aOptions['enable'];
83: }
84: }
85:
86: /**
87: * Prevent cloning
88: */
89: protected function __clone() {
90: }
91:
92: /**
93: * Returns item cache instance, creates it, if not done before.
94: * Works as a singleton for one specific table.
95: *
96: * @param string $sTable
97: * Table name
98: * @param array $aOptions [optional]
99: * Options array as follows:
100: * - $aOptions['max_items_to_cache'] = (int) Number of items to cache
101: * - $aOptions['enable'] = (bool) Flag to enable caching
102: * @return cItemCache
103: */
104: public static function getInstance($sTable, array $aOptions = array()) {
105: if (!isset(self::$_oInstances[$sTable])) {
106: self::$_oInstances[$sTable] = new self($sTable, $aOptions);
107: }
108: return self::$_oInstances[$sTable];
109: }
110:
111: /**
112: * Returns items cache list.
113: *
114: * @return array
115: */
116: public function getItemsCache() {
117: return $this->_aItemsCache;
118: }
119:
120: /**
121: * Returns existing entry from cache by it's id.
122: *
123: * @param mixed $mId
124: * @return array|NULL
125: */
126: public function getItem($mId) {
127: if (!$this->_bEnable) {
128: return NULL;
129: }
130:
131: if (isset($this->_aItemsCache[$mId])) {
132: return $this->_aItemsCache[$mId];
133: } else {
134: return NULL;
135: }
136: }
137:
138: /**
139: * Returns existing entry from cache by matching propery value.
140: *
141: * @param mixed $mProperty
142: * @param mixed $mValue
143: * @return array|NULL
144: */
145: public function getItemByProperty($mProperty, $mValue) {
146: if (!$this->_bEnable) {
147: return NULL;
148: }
149:
150: // loop thru all cached entries and try to find a entry by it's property
151: foreach ($this->_aItemsCache as $id => $aEntry) {
152: if (isset($aEntry[$mProperty]) && $aEntry[$mProperty] == $mValue) {
153: return $aEntry;
154: }
155: }
156: return NULL;
157: }
158:
159: /**
160: * Returns existing entry from cache by matching properties and their
161: * values.
162: *
163: * @param array $aProperties
164: * Assoziative key value pairs
165: * @return array|NULL
166: */
167: public function getItemByProperties(array $aProperties) {
168: if (!$this->_bEnable) {
169: return NULL;
170: }
171:
172: // loop thru all cached entries and try to find a entry by it's property
173: foreach ($this->_aItemsCache as $id => $aEntry) {
174: $mFound = NULL;
175: foreach ($aProperties as $key => $value) {
176: if (isset($aEntry[$key]) && $aEntry[$key] == $value) {
177: if (NULL === $mFound) {
178: $mFound = true;
179: }
180: } else {
181: $mFound = false;
182: break;
183: }
184: }
185: if (true === $mFound) {
186: return $aEntry;
187: }
188: }
189: return NULL;
190: }
191:
192: /**
193: * Adds passed item data to internal cache
194: *
195: * @todo check if null should be returned
196: * @param mixed $mId
197: * @param array $aData
198: * Usually the recordset
199: * @return void|null
200: */
201: public function addItem($mId, array $aData) {
202: if (!$this->_bEnable) {
203: return NULL;
204: }
205:
206: if ($this->_iMaxItemsToCache == count($this->_aItemsCache)) {
207: // we have reached the maximum number of cached items, remove first
208: // entry
209: $keys = array_keys($this->_aItemsCache);
210: $firstEntryKey = array_shift($keys);
211: unset($this->_aItemsCache[$firstEntryKey]);
212: }
213:
214: // add entry
215: $this->_aItemsCache[$mId] = $aData;
216: }
217:
218: /**
219: * Removes existing cache entry by it's key
220: *
221: * @todo check if null should be returned
222: * @param mixed $mId
223: * @return void|null
224: */
225: public function removeItem($mId) {
226: if (!$this->_bEnable) {
227: return NULL;
228: }
229:
230: // remove entry
231: if (isset($this->_aItemsCache[$mId])) {
232: unset($this->_aItemsCache[$mId]);
233: }
234: }
235:
236: /**
237: * Removes multiple existing cache entries by their keys
238: *
239: * @todo check if null should be returned
240: * @param array $aIds
241: * @return void|null
242: */
243: public function removeItems(array $aIds) {
244: if (!$this->_bEnable) {
245: return NULL;
246: }
247:
248: // remove entries
249: foreach ($aIds as $mId) {
250: if (isset($this->_aItemsCache[$mId])) {
251: unset($this->_aItemsCache[$mId]);
252: }
253: }
254: }
255:
256: }
257: