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