1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
16:
17: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
18:
19: 20: 21: 22: 23: 24: 25:
26: abstract class Item extends cItemBaseAbstract {
27:
28: 29: 30: 31:
32: public $values;
33:
34: 35: 36: 37: 38:
39: protected $modifiedValues;
40:
41: 42: 43: 44:
45: protected $oldPrimaryKey;
46:
47: 48: 49: 50:
51: protected $_arrInFilters = array('htmlspecialchars', 'addslashes');
52:
53: 54: 55: 56:
57: protected $_arrOutFilters = array('stripslashes', 'htmldecode');
58:
59: 60: 61: 62:
63: protected $_metaObject;
64:
65: 66: 67: 68:
69: protected $_lastSQL;
70:
71: 72: 73: 74: 75: 76: 77:
78: public function __construct($sTable, $sPrimaryKey) {
79: parent::__construct($sTable, $sPrimaryKey, get_parent_class($this));
80: }
81:
82: 83: 84:
85: public function Item($sTable, $sPrimaryKey, $iLifetime = 10) {
86: $this->__construct($sTable, $sPrimaryKey, $iLifetime);
87: }
88:
89: 90: 91: 92: 93: 94: 95: 96: 97:
98: public function loadBy($sField, $mValue, $bSafe = true) {
99: if ($bSafe) {
100: $mValue = $this->_inFilter($mValue);
101: }
102:
103:
104: $aRecordSet = null;
105: if ($sField === $this->primaryKey) {
106: $aRecordSet = $this->_oCache->getItem($mValue);
107: } else {
108: $aRecordSet = $this->_oCache->getItemByProperty($sField, $mValue);
109: }
110:
111: if ($aRecordSet) {
112:
113: $this->loadByRecordSet($aRecordSet);
114: return true;
115: }
116:
117:
118: $sql = "SELECT * FROM `%s` WHERE %s = '%s'";
119: $sql = $this->db->prepare($sql, $this->table, $sField, $mValue);
120:
121:
122: $this->db->query($sql);
123:
124: $this->_lastSQL = $sql;
125:
126: if ($this->db->numRows() > 1) {
127: $msg = "Tried to load a single line with field $sField and value $mValue from "
128: . $this->table . " but found more than one row";
129: throw new cException($msg);
130: }
131:
132:
133: if (!$this->db->nextRecord()) {
134: return false;
135: }
136:
137: $this->loadByRecordSet($this->db->toArray());
138: return true;
139: }
140:
141: 142: 143: 144: 145: 146: 147: 148:
149: public function loadByMany(array $aAttributes, $bSafe = true) {
150: if ($bSafe) {
151: $aAttributes = $this->_inFilter($aAttributes);
152: }
153:
154:
155: $aRecordSet = null;
156: if (count($aAttributes) == 1 && isset($aAttributes[$this->primaryKey])) {
157: $aRecordSet = $this->_oCache->getItem($aAttributes[$this->primaryKey]);
158: } else {
159: $aRecordSet = $this->_oCache->getItemByProperties($aAttributes);
160: }
161:
162: if ($aRecordSet) {
163:
164: $this->loadByRecordSet($aRecordSet);
165: return true;
166: }
167:
168:
169: $sql = 'SELECT * FROM `:mytab` WHERE';
170: foreach (array_keys($aAttributes) as $sKey) {
171:
172: if (is_string($sKey)) {
173: $sql .= " $sKey = ':$sKey' AND";
174: } else {
175: $sql .= " $sKey = :$sKey AND";
176: }
177: }
178:
179: $sql = substr($sql, 0, strlen($sql) - 4);
180: $sql = $this->db->prepare($sql, array_merge(array(
181: 'mytab' => $this->table
182: ), $aAttributes));
183:
184:
185: $this->db->query($sql);
186:
187: $this->_lastSQL = $sql;
188:
189: if ($this->db->numRows() > 1) {
190: $msg = 'Tried to load a single line with fields ' . print_r(array_keys($aAttributes), true) . ' and values ' . print_r(array_values($aAttributes), true) . ' from ' . $this->table . ' but found more than one row';
191: throw new cException($msg);
192: }
193:
194:
195: if (!$this->db->nextRecord()) {
196: return false;
197: }
198:
199: $this->loadByRecordSet($this->db->toArray());
200: return true;
201: }
202:
203: 204: 205: 206: 207: 208: 209: 210: 211: 212:
213: protected function _loadByWhereClause($sWhere) {
214:
215: $sql = "SELECT %s AS pk FROM `%s` WHERE " . (string) $sWhere;
216: $sql = $this->db->prepare($sql, $this->primaryKey, $this->table);
217:
218:
219: $this->db->query($sql);
220:
221: $this->_lastSQL = $sql;
222:
223: if ($this->db->numRows() > 1) {
224: $msg = "Tried to load a single line with where clause '" . $sWhere . "' from "
225: . $this->table . " but found more than one row";
226: throw new cException($msg);
227: }
228:
229:
230: if (!$this->db->nextRecord()) {
231: return false;
232: }
233:
234: $id = $this->db->f('pk');
235: return $this->loadByPrimaryKey($id);
236: }
237:
238: 239: 240: 241: 242: 243:
244: public function loadByPrimaryKey($mValue) {
245: $bSuccess = $this->loadBy($this->primaryKey, $mValue);
246:
247: if ($bSuccess == true && method_exists($this, '_onLoad')) {
248: $this->_onLoad();
249: }
250:
251: return $bSuccess;
252: }
253:
254: 255: 256: 257: 258:
259: public function loadByRecordSet(array $aRecordSet) {
260: $this->values = $aRecordSet;
261: $this->oldPrimaryKey = $this->values[$this->primaryKey];
262: $this->virgin = false;
263: $this->_oCache->addItem($this->oldPrimaryKey, $this->values);
264:
265: if (method_exists($this, '_onLoad')) {
266: $this->_onLoad();
267: }
268: }
269:
270: 271: 272: 273:
274: public function isLoaded() {
275: return !$this->virgin;
276: }
277:
278: 279: 280: 281: 282: 283:
284: protected function _onLoad() {
285:
286: }
287:
288: 289: 290: 291: 292: 293:
294: public function getField($sField) {
295: if ($this->virgin == true) {
296: $this->lasterror = 'No item loaded';
297: return false;
298: }
299: return $this->_outFilter($this->values[$sField]);
300: }
301:
302: 303: 304: 305: 306: 307:
308: public function get($sField) {
309: return $this->getField($sField);
310: }
311:
312: 313: 314: 315: 316: 317: 318:
319: public function setField($sField, $mValue, $bSafe = true) {
320: if ($this->virgin == true) {
321: $this->lasterror = 'No item loaded';
322: return false;
323: }
324:
325: if ($sField == $this->primaryKey) {
326: $this->oldPrimaryKey = $this->values[$sField];
327: }
328:
329:
330: if (true == $bSafe) {
331: $mValue = $this->_inFilter($mValue);
332: }
333:
334:
335: if ($this->values[$sField] != $mValue) {
336: $this->modifiedValues[$sField] = true;
337: }
338:
339:
340: $this->values[$sField] = $mValue;
341:
342: return true;
343: }
344:
345: 346: 347: 348: 349: 350: 351:
352: public function set($sField, $mValue, $bSafe = true) {
353: return $this->setField($sField, $mValue, $bSafe);
354: }
355:
356: 357: 358: 359: 360:
361: public function store() {
362: $this->_executeCallbacks(self::STORE_BEFORE, get_class($this), array($this));
363:
364: if ($this->virgin == true) {
365: $this->lasterror = 'No item loaded';
366: $this->_executeCallbacks(self::STORE_FAILURE, get_class($this), array($this));
367: return false;
368: }
369:
370: $sql = 'UPDATE `' . $this->table . '` SET ';
371: $first = true;
372:
373: if (!is_array($this->modifiedValues)) {
374: $this->_executeCallbacks(self::STORE_SUCCESS, get_class($this), array($this));
375: return true;
376: }
377:
378: foreach ($this->modifiedValues as $key => $bValue) {
379: $value = $this->values[$key];
380: if (is_string($value)) {
381: $value = $this->db->escape($value);
382: }
383:
384: if ($first == true) {
385: $sql .= "`$key` = '" . $value . "'";
386: $first = false;
387: } else {
388: $sql .= ", `$key` = '" . $value . "'";
389: }
390: }
391:
392: $sql .= " WHERE " . $this->primaryKey . " = '" . $this->oldPrimaryKey . "'";
393:
394: $this->db->query($sql);
395:
396: $this->_lastSQL = $sql;
397:
398: if ($this->db->affectedRows() > 0) {
399: $this->_oCache->addItem($this->oldPrimaryKey, $this->values);
400: $this->_executeCallbacks(self::STORE_SUCCESS, get_class($this), array($this));
401: return true;
402: }
403:
404: $this->_executeCallbacks(self::STORE_FAILURE, get_class($this), array($this));
405: return false;
406: }
407:
408: 409: 410: 411: 412:
413: public function toArray() {
414: if ($this->virgin == true) {
415: $this->lasterror = 'No item loaded';
416: return false;
417: }
418:
419: $aReturn = array();
420: foreach ($this->values as $field => $value) {
421: $aReturn[$field] = $this->getField($field);
422: }
423: return $aReturn;
424: }
425:
426: 427: 428: 429: 430:
431: public function toObject() {
432: $return = $this->toArray();
433: return (false !== $return) ? (object) $return : $return;
434: }
435:
436: 437: 438: 439: 440: 441: 442: 443: 444:
445: public function setProperty($sType, $sName, $mValue, $iClient = 0) {
446:
447: if ($this->virgin == true) {
448: $this->lasterror = 'No item loaded';
449: return false;
450: }
451:
452:
453: $oProperties = $this->_getPropertiesCollectionInstance($iClient);
454: $bResult = $oProperties->setValue(
455: $this->primaryKey, $this->get($this->primaryKey), $sType, $sName, $mValue
456: );
457: return $bResult;
458: }
459:
460: 461: 462: 463: 464: 465: 466: 467:
468: public function getProperty($sType, $sName, $iClient = 0) {
469:
470: if ($this->virgin == true) {
471: $this->lasterror = 'No item loaded';
472: return false;
473: }
474:
475:
476: $oProperties = $this->_getPropertiesCollectionInstance($iClient);
477: $mValue = $oProperties->getValue(
478: $this->primaryKey, $this->get($this->primaryKey), $sType, $sName
479: );
480: return $mValue;
481: }
482:
483: 484: 485: 486: 487: 488: 489: 490:
491: public function deleteProperty($sType, $sName, $iClient = 0) {
492:
493: if ($this->virgin == true) {
494: $this->lasterror = 'No item loaded';
495: return false;
496: }
497:
498:
499: $oProperties = $this->_getPropertiesCollectionInstance($iClient);
500: $bResult = $oProperties->deleteValue(
501: $this->primaryKey, $this->get($this->primaryKey), $sType, $sName
502: );
503: return $bResult;
504: }
505:
506: 507: 508: 509: 510: 511:
512: public function deletePropertyById($idprop) {
513: $oProperties = $this->_getPropertiesCollectionInstance();
514: return $oProperties->delete($idprop);
515: }
516:
517: 518: 519: 520: 521:
522:
523:
524:
525:
526:
527:
528: 529: 530: 531: 532: 533: 534: 535: 536: 537: 538: 539: 540:
541: public function setFilters($aInFilters = array(), $aOutFilters = array()) {
542: $this->_arrInFilters = $aInFilters;
543: $this->_arrOutFilters = $aOutFilters;
544: }
545:
546: 547: 548: 549: 550: 551: 552: 553: 554: 555:
556: public function _inFilter($mData) {
557: foreach ($this->_arrInFilters as $_function) {
558: if (function_exists($_function)) {
559: if (is_array($mData)) {
560: foreach ($mData as $key => $value) {
561: $mData[$key] = $_function($value);
562: }
563: } else {
564: $mData = $_function($mData);
565: }
566: }
567: }
568: return $mData;
569: }
570:
571: 572: 573: 574: 575: 576: 577: 578:
579: protected function _outFilter($mData) {
580: foreach ($this->_arrOutFilters as $_function) {
581: if (function_exists($_function)) {
582: if (is_array($mData)) {
583: foreach ($mData as $key => $value) {
584: $mData[$key] = $_function($value);
585: }
586: } else {
587: $mData = $_function($mData);
588: }
589: }
590: }
591: return $mData;
592: }
593:
594: protected function _setMetaObject($sObjectName) {
595: $this->_metaObject = $sObjectName;
596: }
597:
598: public function getMetaObject() {
599: global $_metaObjectCache;
600:
601: if (!is_array($_metaObjectCache)) {
602: $_metaObjectCache = array();
603: }
604:
605: $sClassName = $this->_metaObject;
606: $qclassname = strtolower($sClassName);
607:
608: if (array_key_exists($qclassname, $_metaObjectCache)) {
609: if (is_object($_metaObjectCache[$qclassname])) {
610: if (strtolower(get_class($_metaObjectCache[$qclassname])) == $qclassname) {
611: $_metaObjectCache[$qclassname]->setPayloadObject($this);
612: return $_metaObjectCache[$qclassname];
613: }
614: }
615: }
616:
617: if (class_exists($sClassName)) {
618: $_metaObjectCache[$qclassname] = new $sClassName($this);
619: return $_metaObjectCache[$qclassname];
620: }
621: }
622:
623: }
624: