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