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