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