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 ItemCollection extends cItemBaseAbstract {
27:
28: 29: 30: 31: 32: 33:
34: protected $objects;
35:
36: 37: 38: 39: 40:
41: protected $_driver;
42:
43: 44: 45: 46: 47:
48: protected $_collectionCache = array();
49:
50: 51: 52: 53: 54:
55: protected $_itemClass;
56:
57: 58: 59: 60: 61:
62: protected $_iteratorItem;
63:
64: 65: 66: 67: 68:
69: protected $_JoinPartners = array();
70:
71: 72: 73: 74: 75:
76: protected $_forwardJoinPartners;
77:
78: 79: 80: 81: 82:
83: protected $_whereRestriction;
84:
85: 86: 87: 88: 89:
90: protected $_innerGroupConditions = array();
91:
92: 93: 94: 95: 96:
97: protected $_groupConditions;
98:
99: 100: 101: 102: 103:
104: protected $_resultFields = array();
105:
106: 107: 108: 109: 110:
111: protected $_encoding;
112:
113: 114: 115: 116: 117:
118: protected $_itemClassInstance;
119:
120: 121: 122: 123: 124: 125:
126: protected $_aOperators;
127:
128: 129: 130: 131: 132: 133:
134: protected $_bAllMode = false;
135:
136: 137: 138: 139: 140:
141: protected $_where;
142:
143: 144: 145: 146: 147:
148: protected $_order;
149:
150: 151: 152: 153: 154:
155: protected $_limitStart;
156:
157: 158: 159: 160: 161:
162: protected $_limitCount;
163:
164: 165: 166: 167: 168:
169: protected $_lastSQL;
170:
171: 172: 173: 174: 175:
176: protected $_links;
177:
178: 179: 180: 181: 182: 183:
184: public function __construct($sTable, $sPrimaryKey) {
185: parent::__construct($sTable, $sPrimaryKey, get_parent_class($this));
186:
187: $this->resetQuery();
188:
189:
190: $this->_initializeDriver();
191:
192:
193: if (isset($GLOBALS['lang']) && isset($GLOBALS['aLanguageEncodings'])) {
194: $this->setEncoding($GLOBALS['aLanguageEncodings'][$GLOBALS['lang']]);
195: }
196:
197: $this->_aOperators = array(
198: '=',
199: '!=',
200: '<>',
201: '<',
202: '>',
203: '<=',
204: '>=',
205: 'LIKE',
206: 'DIACRITICS'
207: );
208: }
209:
210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220:
221: protected function _setJoinPartner($sForeignCollectionClass) {
222: if (class_exists($sForeignCollectionClass)) {
223:
224: if (!in_array($sForeignCollectionClass, $this->_JoinPartners)) {
225: $this->_JoinPartners[] = strtolower($sForeignCollectionClass);
226: }
227: } else {
228: $msg = "Could not instantiate class [$sForeignCollectionClass] for use " . "with _setJoinPartner in class " . get_class($this);
229: throw new cInvalidArgumentException($msg);
230: }
231: }
232:
233: 234: 235: 236: 237: 238: 239:
240: protected function _setItemClass($sClassName) {
241: if (class_exists($sClassName)) {
242: $this->_itemClass = $sClassName;
243: $this->_itemClassInstance = new $sClassName();
244:
245:
246:
247: $this->_initializeDriver();
248: $this->_driver->setItemClassInstance($this->_itemClassInstance);
249: } else {
250: $msg = "Could not instantiate class [$sClassName] for use with " . "_setItemClass in class " . get_class($this);
251: throw new cInvalidArgumentException($msg);
252: }
253: }
254:
255: 256: 257: 258: 259: 260:
261: protected function _initializeDriver($bForceInit = false) {
262: if (!is_object($this->_driver) || $bForceInit == true) {
263: $this->_driver = new cGenericDbDriverMysql();
264: }
265: }
266:
267: 268: 269: 270: 271:
272: public function setEncoding($sEncoding) {
273: $this->_encoding = $sEncoding;
274: $this->_driver->setEncoding($sEncoding);
275: }
276:
277: 278: 279: 280: 281: 282: 283:
284: public function link($sForeignClass) {
285: if (class_exists($sForeignClass)) {
286: $this->_links[$sForeignClass] = new $sForeignClass();
287: } else {
288: $msg = "Could not find class [$sForeignClass] for use with link in class " . get_class($this);
289: throw new cInvalidArgumentException($msg);
290: }
291: }
292:
293: 294: 295: 296: 297: 298:
299: public function setLimit($iRowStart, $iRowCount) {
300: $this->_limitStart = $iRowStart;
301: $this->_limitCount = $iRowCount;
302: }
303:
304: 305: 306: 307: 308: 309: 310:
311: public function setWhere($sField, $mRestriction, $sOperator = '=') {
312: $sField = strtolower($sField);
313: $this->_where['global'][$sField]['operator'] = $sOperator;
314: $this->_where['global'][$sField]['restriction'] = $mRestriction;
315: }
316:
317: 318: 319: 320: 321: 322: 323:
324: public function deleteWhere($sField, $mRestriction, $sOperator = '=') {
325: $sField = strtolower($sField);
326: if (isset($this->_where['global'][$sField]) && is_array($this->_where['global'][$sField])) {
327: if ($this->_where['global'][$sField]['operator'] == $sOperator && $this->_where['global'][$sField]['restriction'] == $mRestriction) {
328: unset($this->_where['global'][$sField]);
329: }
330: }
331: }
332:
333: 334: 335: 336: 337: 338: 339: 340:
341: public function setWhereGroup($sGroup, $sField, $mRestriction, $sOperator = '=') {
342: $sField = strtolower($sField);
343: $this->_where['groups'][$sGroup][$sField]['operator'] = $sOperator;
344: $this->_where['groups'][$sGroup][$sField]['restriction'] = $mRestriction;
345: }
346:
347: 348: 349: 350: 351: 352: 353: 354: 355:
356: public function deleteWhereGroup($sGroup, $sField, $mRestriction, $sOperator = '=') {
357: $sField = strtolower($sField);
358: if (is_array($this->_where['groups'][$sGroup]) && isset($this->_where['groups'][$sGroup][$sField]) && is_array($this->_where['groups'][$sGroup][$sField])) {
359: if ($this->_where['groups'][$sGroup][$sField]['operator'] == $sOperator && $this->_where['groups'][$sGroup][$sField]['restriction'] == $mRestriction) {
360: unset($this->_where['groups'][$sGroup][$sField]);
361: }
362: }
363: }
364:
365: 366: 367: 368: 369: 370:
371: public function setInnerGroupCondition($sGroup, $sCondition = 'AND') {
372: $this->_innerGroupConditions[$sGroup] = $sCondition;
373: }
374:
375: 376: 377: 378: 379: 380: 381:
382: public function setGroupCondition($sGroup1, $sGroup2, $sCondition = 'AND') {
383: $this->_groupConditions[$sGroup1][$sGroup2] = $sCondition;
384: }
385:
386: 387: 388: 389: 390:
391: protected function _buildGroupWhereStatements() {
392: $aWheres = array();
393: $aGroupWhere = array();
394:
395: $mLastGroup = false;
396: $sGroupWhereStatement = '';
397:
398:
399: if (count($this->_where['groups']) > 0) {
400:
401: foreach ($this->_where['groups'] as $groupname => $group) {
402: $aWheres = array();
403:
404:
405:
406:
407: foreach ($group as $field => $item) {
408: $aWheres[] = $this->_driver->buildOperator($field, $item['operator'], $item['restriction']);
409: }
410:
411:
412: $sOperator = 'AND';
413: if (isset($this->_innerGroupConditions[$groupname])) {
414: $sOperator = $this->_innerGroupConditions[$groupname];
415: }
416:
417: $aGroupWhere[$groupname] = implode(' ' . $sOperator . ' ', $aWheres);
418: }
419: }
420:
421:
422: foreach ($aGroupWhere as $groupname => $group) {
423: if ($mLastGroup != false) {
424: $sOperator = 'AND';
425:
426: if (isset($this->_groupConditions[$groupname])) {
427: if (isset($this->_groupConditions[$groupname][$mLastGroup])) {
428: $sOperator = $this->_groupConditions[$groupname][$mLastGroup];
429: }
430: }
431:
432:
433: if (isset($this->_groupConditions[$mLastGroup])) {
434: if (isset($this->_groupConditions[$mLastGroup][$groupname])) {
435: $sOperator = $this->_groupConditions[$mLastGroup][$groupname];
436: }
437: }
438:
439: $sGroupWhereStatement .= ' ' . $sOperator . ' (' . $group . ')';
440: } else {
441: $sGroupWhereStatement .= '(' . $group . ')';
442: }
443:
444: $mLastGroup = $groupname;
445: }
446:
447: return $sGroupWhereStatement;
448: }
449:
450: 451: 452: 453: 454:
455: protected function _buildWhereStatements() {
456: $aWheres = array();
457:
458:
459: foreach ($this->_where['global'] as $field => $item) {
460: $aWheres[] = $this->_driver->buildOperator($field, $item['operator'], $item['restriction']);
461: }
462:
463: return (implode(' AND ', $aWheres));
464: }
465:
466: 467: 468: 469: 470: 471: 472: 473: 474: 475: 476: 477: 478: 479: 480: 481: 482: 483: 484: 485: 486: 487:
488: protected function _fetchJoinTables() {
489: $aParameters = array();
490: $aFields = array();
491: $aTables = array();
492: $aJoins = array();
493: $aWheres = array();
494:
495:
496: foreach ($this->_links as $link => $object) {
497: $matches = $this->_findReverseJoinPartner(strtolower(get_class($this)), $link);
498: if ($matches !== false) {
499: if (isset($matches['desttable'])) {
500:
501: $aParameters[] = $this->_driver->buildJoinQuery($matches['desttable'], strtolower($matches['destclass']), $matches['key'], strtolower($matches['sourceclass']), $matches['key']);
502: } else {
503: foreach ($matches as $match) {
504: $aParameters[] = $this->_driver->buildJoinQuery($match['desttable'], strtolower($match['destclass']), $match['key'], strtolower($match['sourceclass']), $match['key']);
505: }
506: }
507: } else {
508: throw new cUnexpectedValueException("The join partner '" . get_class($this) . "' is not registered and can not be used with link().");
509: }
510: }
511:
512:
513: $aFields[] = strtolower(strtolower(get_class($this))) . '.' . $this->primaryKey;
514:
515:
516: foreach ($aParameters as $parameter) {
517: array_unshift($aFields, $parameter['field']);
518: array_unshift($aTables, $parameter['table']);
519: array_unshift($aJoins, $parameter['join']);
520: array_unshift($aWheres, $parameter['where']);
521: }
522:
523: $aFields = array_filter(array_unique($aFields));
524: $aTables = array_filter(array_unique($aTables));
525: $aJoins = array_filter(array_unique($aJoins));
526: $aWheres = array_filter(array_unique($aWheres));
527:
528: return array(
529: 'fields' => $aFields,
530: 'tables' => $aTables,
531: 'joins' => $aJoins,
532: 'wheres' => $aWheres
533: );
534: }
535:
536: 537: 538: 539: 540:
541: protected function _resolveLinks() {
542: $aResolvedLinks = array();
543: $aResolvedLinks[] = strtolower(get_class($this));
544:
545: foreach ($this->_JoinPartners as $link) {
546: $class = new $link();
547: $aResolvedLinks = array_merge($class->_resolveLinks(), $aResolvedLinks);
548: }
549: return $aResolvedLinks;
550: }
551:
552: 553: 554:
555: public function resetQuery() {
556: $this->setLimit(0, 0);
557: $this->_forwardJoinPartners = array();
558: $this->_links = array();
559: $this->_where['global'] = array();
560: $this->_where['groups'] = array();
561: $this->_groupConditions = array();
562: $this->_resultFields = array();
563: }
564:
565: 566: 567: 568: 569: 570:
571: public function query() {
572: if (!isset($this->_itemClassInstance)) {
573: throw new cException('GenericDB can\'t use query() if no item class is set via setItemClass');
574: }
575:
576: $aGroupWhereStatements = $this->_buildGroupWhereStatements();
577: $sWhereStatements = $this->_buildWhereStatements();
578: $aParameters = $this->_fetchJoinTables();
579:
580: $aStatement = array(
581: 'SELECT',
582: implode(', ', (array_merge($aParameters['fields'], $this->_resultFields))),
583: 'FROM',
584: '`' . $this->table . '` AS ' . strtolower(get_class($this))
585: );
586:
587: if (count($aParameters['tables']) > 0) {
588: $aStatement[] = implode(', ', $aParameters['tables']);
589: }
590:
591: if (count($aParameters['joins']) > 0) {
592: $aStatement[] = implode(' ', $aParameters['joins']);
593: }
594:
595: $aWheres = array();
596:
597: if (count($aParameters['wheres']) > 0) {
598: $aWheres[] = implode(', ', $aParameters['wheres']);
599: }
600:
601: if ($aGroupWhereStatements != '') {
602: $aWheres[] = $aGroupWhereStatements;
603: }
604:
605: if ($sWhereStatements != '') {
606: $aWheres[] = $sWhereStatements;
607: }
608:
609: if (count($aWheres) > 0) {
610: $aStatement[] = 'WHERE ' . implode(' AND ', $aWheres);
611: }
612:
613: if ($this->_order != '') {
614: $aStatement[] = 'ORDER BY ' . $this->_order;
615: }
616:
617: if ($this->_limitStart > 0 || $this->_limitCount > 0) {
618: $iRowStart = intval($this->_limitStart);
619: $iRowCount = intval($this->_limitCount);
620: $aStatement[] = "LIMIT $iRowStart, $iRowCount";
621: }
622:
623: $sql = implode(' ', $aStatement);
624:
625: $result = $this->db->query($sql);
626: $this->_lastSQL = $sql;
627:
628:
629:
630: $this->_bAllMode = false;
631: return ($result) ? true : false;
632: }
633:
634: 635: 636: 637: 638: 639: 640:
641: public function setOrder($order) {
642: $this->_order = strtolower($order);
643: }
644:
645: 646: 647: 648: 649:
650: public function addResultField($sField) {
651: $sField = strtolower($sField);
652: if (!in_array($sField, $this->_resultFields)) {
653: $this->_resultFields[] = $sField;
654: }
655: }
656:
657: 658: 659: 660: 661:
662: public function removeResultField($sField) {
663: $sField = strtolower($sField);
664: $key = array_search($sField, $this->_resultFields);
665: if ($key !== false) {
666: unset($this->_resultFields[$key]);
667: }
668: }
669:
670: 671: 672: 673: 674: 675: 676:
677: protected function _findReverseJoinPartner($sParentClass, $sClassName) {
678:
679: $sClassName = strtolower($sClassName);
680: $sParentClass = strtolower($sParentClass);
681:
682:
683: if (in_array($sClassName, $this->_JoinPartners)) {
684: $obj = new $sClassName();
685: return array(
686: 'desttable' => $obj->table,
687: 'destclass' => $sClassName,
688: 'sourceclass' => $sParentClass,
689: 'key' => $obj->primaryKey
690: );
691: } else {
692:
693: foreach ($this->_JoinPartners as $join => $tmpClassname) {
694: $obj = new $tmpClassname();
695: $status = $obj->_findReverseJoinPartner($tmpClassname, $sClassName);
696:
697: if (is_array($status)) {
698: $returns = array();
699:
700: if (!isset($status['desttable'])) {
701: foreach ($status as $subitem) {
702: $returns[] = $subitem;
703: }
704: } else {
705: $returns[] = $status;
706: }
707:
708: $returns[] = array(
709: 'desttable' => $obj->table,
710: 'destclass' => $tmpClassname,
711: 'sourceclass' => $sParentClass,
712: 'key' => $obj->primaryKey
713: );
714: return ($returns);
715: }
716: }
717: }
718: return false;
719: }
720:
721: 722: 723: 724: 725: 726: 727: 728: 729: 730:
731: public function select($sWhere = '', $sGroupBy = '', $sOrderBy = '', $sLimit = '') {
732: unset($this->objects);
733:
734: if ($sWhere == '') {
735: $sWhere = '';
736: } else {
737: $sWhere = ' WHERE ' . $sWhere;
738: }
739:
740: if ($sGroupBy != '') {
741: $sGroupBy = ' GROUP BY ' . $sGroupBy;
742: }
743:
744: if ($sOrderBy != '') {
745: $sOrderBy = ' ORDER BY ' . $sOrderBy;
746: }
747:
748: if ($sLimit != '') {
749: $sLimit = ' LIMIT ' . $sLimit;
750: }
751:
752: $sFields = ($this->_settings['select_all_mode']) ? '*' : $this->primaryKey;
753: $sql = 'SELECT ' . $sFields . ' FROM `' . $this->table . '`' . $sWhere . $sGroupBy . $sOrderBy . $sLimit;
754: $this->db->query($sql);
755: $this->_lastSQL = $sql;
756: $this->_bAllMode = $this->_settings['select_all_mode'];
757:
758: if ($this->db->numRows() == 0) {
759: return false;
760: } else {
761: return true;
762: }
763: }
764:
765: 766: 767: 768: 769: 770: 771: 772: 773: 774: 775: 776: 777: 778: 779:
780: public function flexSelect($sDistinct = '', $sFrom = '', $sWhere = '', $sGroupBy = '', $sOrderBy = '', $sLimit = '') {
781: unset($this->objects);
782:
783: if ($sDistinct != '') {
784: $sDistinct = 'DISTINCT ';
785: }
786:
787: if ($sFrom != '') {
788: $sFrom = ', ' . $sFrom;
789: }
790:
791: if ($sWhere != '') {
792: $sWhere = ' WHERE ' . $sWhere;
793: }
794:
795: if ($sGroupBy != '') {
796: $sGroupBy = ' GROUP BY ' . $sGroupBy;
797: }
798:
799: if ($sOrderBy != '') {
800: $sOrderBy = ' ORDER BY ' . $sOrderBy;
801: }
802:
803: if ($sLimit != '') {
804: $sLimit = ' LIMIT ' . $sLimit;
805: }
806:
807: $sql = 'SELECT ' . $sDistinct . strtolower(get_class($this)) . '.' . $this->primaryKey . ' AS ' . $this->primaryKey . ' FROM `' . $this->table . '` AS ' . strtolower(get_class($this)) . $sFrom . $sWhere . $sGroupBy . $sOrderBy . $sLimit;
808:
809: $this->db->query($sql);
810: $this->_lastSQL = $sql;
811:
812: $this->_bAllMode = false;
813:
814: if ($this->db->numRows() == 0) {
815: return false;
816: } else {
817: return true;
818: }
819: }
820:
821: 822: 823: 824: 825: 826:
827: public function exists($mId) {
828: $oDb = $this->_getSecondDBInstance();
829: $sql = "SELECT `%s` FROM %s WHERE %s='%s'";
830: $oDb->query($sql, $this->primaryKey, $this->table, $this->primaryKey, $mId);
831: return ($oDb->nextRecord()) ? true : false;
832: }
833:
834: 835: 836: 837: 838:
839: public function next() {
840: $ret = false;
841: while ($this->db->nextRecord()) {
842: if ($this->_bAllMode) {
843: $aRs = $this->db->toArray(cDb::FETCH_BOTH);
844: $ret = $this->loadItem($aRs);
845: } else {
846: $ret = $this->loadItem($this->db->f($this->primaryKey));
847: }
848:
849: if ($ret->get($this->primaryKey) == "") {
850: continue;
851: } else {
852: break;
853: }
854: }
855: return $ret;
856: }
857:
858: 859: 860: 861: 862:
863: public function fetchObject($sClassName) {
864: $sKey = strtolower($sClassName);
865:
866: if (!is_object($this->_collectionCache[$sKey])) {
867: $this->_collectionCache[$sKey] = new $sClassName();
868: }
869: $obj = $this->_collectionCache[$sKey];
870: return $obj->loadItem($this->db->f($obj->primaryKey));
871: }
872:
873: 874: 875: 876: 877: 878: 879: 880: 881: 882: 883: 884:
885: public function fetchTable(array $aFields = array(), array $aObjects = array()) {
886: $row = 1;
887: $aTable = array();
888:
889: $this->db->seek(0);
890:
891: while ($this->db->nextRecord()) {
892: foreach ($aFields as $alias => $field) {
893: if ($alias != '') {
894: $aTable[$row][$alias] = $this->db->f($field);
895: } else {
896: $aTable[$row][$field] = $this->db->f($field);
897: }
898: }
899:
900:
901: foreach ($aObjects as $alias => $object) {
902: if ($alias != '') {
903: if (isset($aTable[$row][$alias])) {
904:
905: if (is_array($aTable[$row][$alias])) {
906: $aTable[$row][$alias][] = $this->fetchObject($object);
907: } else {
908:
909: $aTable[$row][$alias] = array();
910: $aTable[$row][$alias][] = $this->fetchObject($object);
911: }
912: } else {
913: $aTable[$row][$alias] = $this->fetchObject($object);
914: }
915: } else {
916: $aTable[$row][$object] = $this->fetchObject($object);
917: }
918: }
919: $row++;
920: }
921:
922: $this->db->seek(0);
923:
924: return $aTable;
925: }
926:
927: 928: 929: 930: 931: 932:
933: public function queryAndFetchStructured(array $aObjects) {
934: $aOrder = array();
935: $aFetchObjects = array();
936: $aResult = array();
937:
938: foreach ($aObjects as $object) {
939: $x = new $object();
940: $object = strtolower($object);
941: $aOrder[] = $object . '.' . $x->primaryKey . ' ASC';
942: $aFetchObjects[] = $x;
943: }
944:
945: $this->setOrder(implode(', ', $aOrder));
946: $this->query();
947:
948: $this->db->seek(0);
949:
950: while ($this->db->nextRecord()) {
951: $aResult = $this->_recursiveStructuredFetch($aFetchObjects, $aResult);
952: }
953:
954: return $aResult;
955: }
956:
957: 958: 959: 960: 961: 962:
963: protected function _recursiveStructuredFetch(array $aObjects, array $aResult) {
964: $i = array_shift($aObjects);
965:
966: $value = $this->db->f($i->primaryKey);
967:
968: if (!is_null($value)) {
969: $aResult[$value]['class'] = strtolower(get_class($i));
970: $aResult[$value]['object'] = $i->loadItem($value);
971:
972: if (count($aObjects) > 0) {
973: $aResult[$value]['items'] = $this->_recursiveStructuredFetch($aObjects, $aResult[$value]['items']);
974: }
975: }
976:
977: return $aResult;
978: }
979:
980: 981: 982: 983: 984:
985: public function count() {
986: return ($this->db->numRows());
987: }
988:
989: 990: 991: 992: 993: 994:
995: public function fetchById($id) {
996: if (is_numeric($id)) {
997: $id = (int) $id;
998: } elseif (is_string($id)) {
999: $id = $this->escape($id);
1000: }
1001: return $this->loadItem($id);
1002: }
1003:
1004: 1005: 1006: 1007: 1008: 1009: 1010: 1011:
1012: public function loadItem($mItem) {
1013: if (empty($this->_itemClass)) {
1014: $sMsg = "ItemClass has to be set in the constructor of class " . get_class($this) . ")";
1015: throw new cException($sMsg);
1016: }
1017:
1018: if (!is_object($this->_iteratorItem)) {
1019: $this->_iteratorItem = new $this->_itemClass();
1020: }
1021: $obj = clone $this->_iteratorItem;
1022:
1023: if (is_array($mItem)) {
1024: $obj->loadByRecordSet($mItem);
1025: } else {
1026: $obj->loadByPrimaryKey($mItem);
1027: }
1028:
1029: return $obj;
1030: }
1031:
1032: 1033: 1034: 1035: 1036: 1037: 1038:
1039: public function createNewItem($data = NULL) {
1040: $this->_executeCallbacks(self::CREATE_BEFORE, get_class($this), array());
1041:
1042: $db = $this->_getSecondDBInstance();
1043:
1044: $primaryKeyValue = NULL;
1045:
1046:
1047: if (is_array($data)) {
1048: if (array_key_exists($this->primaryKey, $data)) {
1049: $primaryKeyValue = $data[$this->primaryKey];
1050: }
1051: } else {
1052:
1053: $primaryKeyValue = $data;
1054: $data = array(
1055: $this->primaryKey => $data
1056: );
1057: }
1058:
1059:
1060: $sql = $db->buildInsert($this->table, $data);
1061: $db->query($sql);
1062:
1063: if ($primaryKeyValue === NULL) {
1064: $primaryKeyValue = $db->getLastInsertedId($this->table);
1065: }
1066:
1067: if ($db->affectedRows() == 0) {
1068: $this->_executeCallbacks(self::CREATE_FAILURE, $this->_itemClass, array());
1069: } else {
1070: $this->_executeCallbacks(self::CREATE_SUCCESS, $this->_itemClass, array(
1071: $primaryKeyValue
1072: ));
1073: }
1074:
1075: return $this->loadItem($primaryKeyValue);
1076: }
1077:
1078: 1079: 1080: 1081: 1082: 1083: 1084: 1085: 1086: 1087:
1088: public function copyItem($srcItem, array $fieldsToOverwrite = array()) {
1089: if (get_class($srcItem) !== $this->_itemClass) {
1090: throw new cInvalidArgumentException("Item class doesn't match");
1091: } elseif (!$srcItem->isLoaded()) {
1092: throw new cInvalidArgumentException("Item instance has no loaded recordset");
1093: }
1094:
1095: $destItem = self::createNewItem();
1096: if (!is_object($destItem)) {
1097: return NULL;
1098: }
1099:
1100: $rs = $srcItem->toArray();
1101:
1102: foreach ($rs as $field => $value) {
1103: if (is_numeric($field)) {
1104:
1105: continue;
1106: } elseif ($field == $this->primaryKey) {
1107:
1108: continue;
1109: }
1110:
1111: if (isset($fieldsToOverwrite[$field])) {
1112: $value = $fieldsToOverwrite[$field];
1113: }
1114:
1115: $destItem->set($field, $value);
1116: }
1117:
1118: $destItem->store();
1119: return $destItem;
1120: }
1121:
1122: 1123: 1124: 1125: 1126: 1127: 1128:
1129: public function getIdsByWhereClause($sWhere) {
1130: $oDb = $this->_getSecondDBInstance();
1131:
1132: $aIds = array();
1133:
1134:
1135: $sql = 'SELECT ' . $this->primaryKey . ' AS pk FROM `' . $this->table . '` WHERE ' . $sWhere;
1136: $oDb->query($sql);
1137: while ($oDb->nextRecord()) {
1138: $aIds[] = $oDb->f('pk');
1139: }
1140:
1141: return $aIds;
1142: }
1143:
1144: 1145: 1146: 1147: 1148: 1149: 1150: 1151:
1152: public function getFieldsByWhereClause(array $aFields, $sWhere) {
1153: $oDb = $this->_getSecondDBInstance();
1154:
1155: $aEntries = array();
1156:
1157: if (count($aFields) == 0) {
1158: return $aEntries;
1159: }
1160:
1161:
1162: $aEscapedFields = array_map(array(
1163: $oDb,
1164: 'escape'
1165: ), $aFields);
1166:
1167: $fields = implode(', ', $aEscapedFields);
1168:
1169:
1170: $sql = 'SELECT ' . $fields . ' FROM `' . $this->table . '` WHERE ' . $sWhere;
1171: $oDb->query($sql);
1172: while ($oDb->nextRecord()) {
1173: $data = array();
1174: foreach ($aFields as $field) {
1175: $data[$field] = $oDb->f($field);
1176: }
1177: $aEntries[] = $data;
1178: }
1179:
1180: return $aEntries;
1181: }
1182:
1183: 1184: 1185: 1186: 1187:
1188: public function getAllIds() {
1189: $oDb = $this->_getSecondDBInstance();
1190:
1191: $aIds = array();
1192:
1193:
1194: $sql = 'SELECT ' . $this->primaryKey . ' AS pk FROM `' . $this->table . '`';
1195: $oDb->query($sql);
1196: while ($oDb->nextRecord()) {
1197: $aIds[] = $oDb->f('pk');
1198: }
1199:
1200: return $aIds;
1201: }
1202:
1203: 1204: 1205: 1206: 1207: 1208: 1209:
1210: public function delete($mId) {
1211: $result = $this->_delete($mId);
1212: return $result;
1213: }
1214:
1215: 1216: 1217: 1218: 1219: 1220: 1221: 1222:
1223: public function deleteByWhereClause($sWhere) {
1224:
1225: $aIds = $this->getIdsByWhereClause($sWhere);
1226: $numDeleted = $this->_deleteMultiple($aIds);
1227: return $numDeleted;
1228: }
1229:
1230: 1231: 1232: 1233: 1234: 1235: 1236: 1237: 1238:
1239: public function deleteBy($sField, $mValue) {
1240: $where = (is_string($mValue)) ? "`%s` = '%s'" : "`%s` = %d";
1241: $where = $this->db->prepare($where, $sField, $mValue);
1242:
1243: return $this->deleteByWhereClause($where);
1244: }
1245:
1246:
1247:
1248:
1249:
1250:
1251:
1252:
1253:
1254:
1255:
1256:
1257:
1258: 1259: 1260: 1261: 1262: 1263: 1264:
1265: protected function _delete($mId) {
1266: $this->_executeCallbacks(self::DELETE_BEFORE, $this->_itemClass, array(
1267: $mId
1268: ));
1269:
1270: $oDb = $this->_getSecondDBInstance();
1271:
1272:
1273: $sql = "DELETE FROM `%s` WHERE %s = '%s'";
1274: $oDb->query($sql, $this->table, $this->primaryKey, $mId);
1275:
1276:
1277: $this->_oCache->removeItem($mId);
1278:
1279:
1280: $oProperties = $this->_getPropertiesCollectionInstance();
1281: $oProperties->deleteProperties($this->primaryKey, $mId);
1282:
1283: if ($oDb->affectedRows() == 0) {
1284: $this->_executeCallbacks(self::DELETE_FAILURE, $this->_itemClass, array(
1285: $mId
1286: ));
1287: return false;
1288: } else {
1289: $this->_executeCallbacks(self::DELETE_SUCCESS, $this->_itemClass, array(
1290: $mId
1291: ));
1292: return true;
1293: }
1294: }
1295:
1296: 1297: 1298: 1299: 1300: 1301: 1302:
1303: protected function _deleteMultiple(array $aIds) {
1304: foreach ($aIds as $mId) {
1305: $this->_executeCallbacks(self::DELETE_BEFORE, $this->_itemClass, array(
1306: $mId
1307: ));
1308: }
1309:
1310: $oDb = $this->_getSecondDBInstance();
1311:
1312:
1313: $aEscapedIds = array_map(array(
1314: $oDb,
1315: 'escape'
1316: ), $aIds);
1317: $in = "'" . implode("', '", $aEscapedIds) . "'";
1318: $sql = "DELETE FROM `%s` WHERE %s IN (" . $in . ")";
1319: $oDb->query($sql, $this->table, $this->primaryKey);
1320: $numAffected = $oDb->affectedRows();
1321:
1322:
1323: $this->_oCache->removeItems($aIds);
1324:
1325:
1326: $oProperties = $this->_getPropertiesCollectionInstance();
1327: $oProperties->deletePropertiesMultiple($this->primaryKey, $aIds);
1328:
1329:
1330:
1331: if ($numAffected == 0) {
1332: foreach ($aIds as $mId) {
1333: $this->_executeCallbacks(self::DELETE_FAILURE, $this->_itemClass, array(
1334: $mId
1335: ));
1336: }
1337: } else {
1338: foreach ($aIds as $mId) {
1339: $this->_executeCallbacks(self::DELETE_SUCCESS, $this->_itemClass, array(
1340: $mId
1341: ));
1342: }
1343: }
1344: return $numAffected;
1345: }
1346:
1347: 1348: 1349: 1350: 1351: 1352: 1353: 1354: 1355: 1356: 1357: 1358: 1359: 1360: 1361: 1362:
1363: public function fetchArray($sKey, $mFields) {
1364: $aResult = array();
1365:
1366: while (($item = $this->next()) !== false) {
1367: if (is_array($mFields)) {
1368: foreach ($mFields as $value) {
1369: $aResult[$item->get($sKey)][$value] = $item->get($value);
1370: }
1371: } else {
1372: $aResult[$item->get($sKey)] = $item->get($mFields);
1373: }
1374: }
1375:
1376: return $aResult;
1377: }
1378: }
1379: