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