1: <?php
2: /**
3: * This file contains the generic db item cache class.
4: *
5: * @package Core
6: * @subpackage GenericDB
7: * @version SVN Revision $Rev:$
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: * @var array
33: */
34: protected static $_oInstances = array();
35:
36: /**
37: * Assoziative cache array
38: * @var array
39: */
40: protected $_aItemsCache = array();
41:
42: /**
43: * Table name for current instance
44: * @var string
45: */
46: protected $_sTable = '';
47:
48: /**
49: * Max number of items to cache
50: * @var int
51: */
52: protected $_iMaxItemsToCache = 10;
53:
54: /**
55: * Enable caching
56: * @var bool
57: */
58: protected $_bEnable = false;
59:
60: /**
61: * Contructor of cItemCache
62: * @param string $sTable Table name
63: * @param array $aOptions Options array as follows:
64: * - $aOptions['max_items_to_cache'] = (int) Number of items to cache
65: * - $aOptions['enable'] = (bool) Flag to enable caching
66: */
67: protected function __construct($sTable, array $aOptions = array()) {
68: $this->_sTable = $sTable;
69: if (isset($aOptions['max_items_to_cache']) && (int) $aOptions['max_items_to_cache'] > 0) {
70: $this->_iMaxItemsToCache = (int) $aOptions['max_items_to_cache'];
71: }
72: if (isset($aOptions['enable']) && is_bool($aOptions['enable'])) {
73: $this->_bEnable = (bool) $aOptions['enable'];
74: }
75: }
76:
77: /**
78: * Prevent cloning
79: */
80: protected function __clone() {
81:
82: }
83:
84: /**
85: * Returns item cache instance, creates it, if not done before.
86: * Works as a singleton for one specific table.
87: *
88: * @param string $sTable Table name
89: * @param array $aOptions Options array as follows:
90: * - $aOptions['max_items_to_cache'] = (int) Number of items to cache
91: * - $aOptions['enable'] = (bool) Flag to enable caching
92: */
93: public static function getInstance($sTable, array $aOptions = array()) {
94: if (!isset(self::$_oInstances[$sTable])) {
95: self::$_oInstances[$sTable] = new self($sTable, $aOptions);
96: }
97: return self::$_oInstances[$sTable];
98: }
99:
100: /**
101: * Returns items cache list.
102: *
103: * @return array
104: */
105: public function getItemsCache() {
106: return $this->_aItemsCache;
107: }
108:
109: /**
110: * Returns existing entry from cache by it's id.
111: *
112: * @param mixed $mId
113: * @return array|null
114: */
115: public function getItem($mId) {
116: if (!$this->_bEnable) {
117: return null;
118: }
119:
120: if (isset($this->_aItemsCache[$mId])) {
121: return $this->_aItemsCache[$mId];
122: } else {
123: return null;
124: }
125: }
126:
127: /**
128: * Returns existing entry from cache by matching propery value.
129: *
130: * @param mixed $mProperty
131: * @param mixed $mValue
132: * @return array|null
133: */
134: public function getItemByProperty($mProperty, $mValue) {
135: if (!$this->_bEnable) {
136: return null;
137: }
138:
139: // loop thru all cached entries and try to find a entry by it's property
140: foreach ($this->_aItemsCache as $id => $aEntry) {
141: if (isset($aEntry[$mProperty]) && $aEntry[$mProperty] == $mValue) {
142: return $aEntry;
143: }
144: }
145: return null;
146: }
147:
148: /**
149: * Returns existing entry from cache by matching properties and their values.
150: *
151: * @param array $aProperties Assoziative key value pairs
152: * @return array|null
153: */
154: public function getItemByProperties(array $aProperties) {
155: if (!$this->_bEnable) {
156: return null;
157: }
158:
159: // loop thru all cached entries and try to find a entry by it's property
160: foreach ($this->_aItemsCache as $id => $aEntry) {
161: $mFound = null;
162: foreach ($aProperties as $key => $value) {
163: if (isset($aEntry[$key]) && $aEntry[$key] == $value) {
164: if (null === $mFound) {
165: $mFound = true;
166: }
167: } else {
168: $mFound = false;
169: break;
170: }
171: }
172: if (true === $mFound) {
173: return $aEntry;
174: }
175: }
176: return null;
177: }
178:
179: /**
180: * Adds passed item data to internal cache
181: *
182: * @param mixed $mId
183: * @param array $aData Usually the recordset
184: */
185: public function addItem($mId, array $aData) {
186: if (!$this->_bEnable) {
187: return null;
188: }
189:
190: if ($this->_iMaxItemsToCache == count($this->_aItemsCache)) {
191: // we have reached the maximum number of cached items, remove first entry
192: $keys = array_keys($this->_aItemsCache);
193: $firstEntryKey = array_shift($keys);
194: unset($this->_aItemsCache[$firstEntryKey]);
195: }
196:
197: // add entry
198: $this->_aItemsCache[$mId] = $aData;
199: }
200:
201: /**
202: * Removes existing cache entry by it's key
203: *
204: * @param mixed $mId
205: */
206: public function removeItem($mId) {
207: if (!$this->_bEnable) {
208: return null;
209: }
210:
211: // remove entry
212: if (isset($this->_aItemsCache[$mId])) {
213: unset($this->_aItemsCache[$mId]);
214: }
215: }
216:
217: /**
218: * Removes multiple existing cache entries by their keys
219: *
220: * @param array $aIds
221: */
222: public function removeItems(array $aIds) {
223: if (!$this->_bEnable) {
224: return null;
225: }
226:
227: // remove entries
228: foreach ($aIds as $mId) {
229: if (isset($this->_aItemsCache[$mId])) {
230: unset($this->_aItemsCache[$mId]);
231: }
232: }
233: }
234:
235: }
236:
237: ?>