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