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: if ($this->count() > 0) {
890:
891: $this->db->seek(0);
892:
893: while ($this->db->nextRecord()) {
894: foreach ($aFields as $alias => $field) {
895: if ($alias != '') {
896: $aTable[$row][$alias] = $this->db->f($field);
897: } else {
898: $aTable[$row][$field] = $this->db->f($field);
899: }
900: }
901:
902:
903: foreach ($aObjects as $alias => $object) {
904: if ($alias != '') {
905: if (isset($aTable[$row][$alias])) {
906:
907: if (is_array($aTable[$row][$alias])) {
908: $aTable[$row][$alias][] = $this->fetchObject($object);
909: } else {
910:
911: $aTable[$row][$alias] = array();
912: $aTable[$row][$alias][] = $this->fetchObject($object);
913: }
914: } else {
915: $aTable[$row][$alias] = $this->fetchObject($object);
916: }
917: } else {
918: $aTable[$row][$object] = $this->fetchObject($object);
919: }
920: }
921: $row++;
922: }
923:
924: $this->db->seek(0);
925:
926: }
927:
928: return $aTable;
929: }
930:
931: 932: 933: 934: 935: 936:
937: public function queryAndFetchStructured(array $aObjects) {
938: $aOrder = array();
939: $aFetchObjects = array();
940: $aResult = array();
941:
942: foreach ($aObjects as $object) {
943: $x = new $object();
944: $object = strtolower($object);
945: $aOrder[] = $object . '.' . $x->primaryKey . ' ASC';
946: $aFetchObjects[] = $x;
947: }
948:
949: $this->setOrder(implode(', ', $aOrder));
950: $this->query();
951:
952: $this->db->seek(0);
953:
954: while ($this->db->nextRecord()) {
955: $aResult = $this->_recursiveStructuredFetch($aFetchObjects, $aResult);
956: }
957:
958: return $aResult;
959: }
960:
961: 962: 963: 964: 965: 966:
967: protected function _recursiveStructuredFetch(array $aObjects, array $aResult) {
968: $i = array_shift($aObjects);
969:
970: $value = $this->db->f($i->primaryKey);
971:
972: if (!is_null($value)) {
973: $aResult[$value]['class'] = strtolower(get_class($i));
974: $aResult[$value]['object'] = $i->loadItem($value);
975:
976: if (count($aObjects) > 0) {
977: $aResult[$value]['items'] = $this->_recursiveStructuredFetch($aObjects, $aResult[$value]['items']);
978: }
979: }
980:
981: return $aResult;
982: }
983:
984: 985: 986: 987: 988:
989: public function count() {
990: return ($this->db->numRows());
991: }
992:
993: 994: 995: 996: 997: 998:
999: public function fetchById($id) {
1000: if (is_numeric($id)) {
1001: $id = (int) $id;
1002: } elseif (is_string($id)) {
1003: $id = $this->escape($id);
1004: }
1005: return $this->loadItem($id);
1006: }
1007:
1008: 1009: 1010: 1011: 1012: 1013: 1014: 1015:
1016: public function loadItem($mItem) {
1017: if (empty($this->_itemClass)) {
1018: $sMsg = "ItemClass has to be set in the constructor of class " . get_class($this) . ")";
1019: throw new cException($sMsg);
1020: }
1021:
1022: if (!is_object($this->_iteratorItem)) {
1023: $this->_iteratorItem = new $this->_itemClass();
1024: }
1025: $obj = clone $this->_iteratorItem;
1026:
1027: if (is_array($mItem)) {
1028: $obj->loadByRecordSet($mItem);
1029: } else {
1030: $obj->loadByPrimaryKey($mItem);
1031: }
1032:
1033: return $obj;
1034: }
1035:
1036: 1037: 1038: 1039: 1040: 1041: 1042:
1043: public function createNewItem($data = NULL) {
1044: $this->_executeCallbacks(self::CREATE_BEFORE, get_class($this), array());
1045:
1046: $db = $this->_getSecondDBInstance();
1047:
1048: $primaryKeyValue = NULL;
1049:
1050:
1051: if (is_array($data)) {
1052: if (array_key_exists($this->primaryKey, $data)) {
1053: $primaryKeyValue = $data[$this->primaryKey];
1054: }
1055: } else {
1056:
1057: $primaryKeyValue = $data;
1058: $data = array(
1059: $this->primaryKey => $data
1060: );
1061: }
1062:
1063:
1064: $sql = $db->buildInsert($this->table, $data);
1065: $db->query($sql);
1066:
1067: if ($primaryKeyValue === NULL) {
1068: $primaryKeyValue = $db->getLastInsertedId();
1069: }
1070:
1071: if ($db->affectedRows() == 0) {
1072: $this->_executeCallbacks(self::CREATE_FAILURE, $this->_itemClass, array());
1073: } else {
1074: $this->_executeCallbacks(self::CREATE_SUCCESS, $this->_itemClass, array(
1075: $primaryKeyValue
1076: ));
1077: }
1078:
1079: return $this->loadItem($primaryKeyValue);
1080: }
1081:
1082: 1083: 1084: 1085: 1086: 1087: 1088: 1089: 1090: 1091:
1092: public function copyItem($srcItem, array $fieldsToOverwrite = array()) {
1093: if (get_class($srcItem) !== $this->_itemClass) {
1094: throw new cInvalidArgumentException("Item class doesn't match");
1095: } elseif (!$srcItem->isLoaded()) {
1096: throw new cInvalidArgumentException("Item instance has no loaded recordset");
1097: }
1098:
1099: $destItem = self::createNewItem();
1100: if (!is_object($destItem)) {
1101: return NULL;
1102: }
1103:
1104: $rs = $srcItem->toArray();
1105:
1106: foreach ($rs as $field => $value) {
1107: if (is_numeric($field)) {
1108:
1109: continue;
1110: } elseif ($field == $this->primaryKey) {
1111:
1112: continue;
1113: }
1114:
1115: if (isset($fieldsToOverwrite[$field])) {
1116: $value = $fieldsToOverwrite[$field];
1117: }
1118:
1119: $destItem->set($field, $value);
1120: }
1121:
1122: $destItem->store();
1123: return $destItem;
1124: }
1125:
1126: 1127: 1128: 1129: 1130: 1131: 1132:
1133: public function getIdsByWhereClause($sWhere) {
1134: $oDb = $this->_getSecondDBInstance();
1135:
1136: $aIds = array();
1137:
1138:
1139: $sql = 'SELECT ' . $this->primaryKey . ' AS pk FROM `' . $this->table . '` WHERE ' . $sWhere;
1140: $oDb->query($sql);
1141: while ($oDb->nextRecord()) {
1142: $aIds[] = $oDb->f('pk');
1143: }
1144:
1145: return $aIds;
1146: }
1147:
1148: 1149: 1150: 1151: 1152: 1153: 1154: 1155:
1156: public function getFieldsByWhereClause(array $aFields, $sWhere) {
1157: $oDb = $this->_getSecondDBInstance();
1158:
1159: $aEntries = array();
1160:
1161: if (count($aFields) == 0) {
1162: return $aEntries;
1163: }
1164:
1165:
1166: $aEscapedFields = array_map(array(
1167: $oDb,
1168: 'escape'
1169: ), $aFields);
1170:
1171: $fields = implode(', ', $aEscapedFields);
1172:
1173:
1174: $sql = 'SELECT ' . $fields . ' FROM `' . $this->table . '` WHERE ' . $sWhere;
1175: $oDb->query($sql);
1176: while ($oDb->nextRecord()) {
1177: $data = array();
1178: foreach ($aFields as $field) {
1179: $data[$field] = $oDb->f($field);
1180: }
1181: $aEntries[] = $data;
1182: }
1183:
1184: return $aEntries;
1185: }
1186:
1187: 1188: 1189: 1190: 1191:
1192: public function getAllIds() {
1193: $oDb = $this->_getSecondDBInstance();
1194:
1195: $aIds = array();
1196:
1197:
1198: $sql = 'SELECT ' . $this->primaryKey . ' AS pk FROM `' . $this->table . '`';
1199: $oDb->query($sql);
1200: while ($oDb->nextRecord()) {
1201: $aIds[] = $oDb->f('pk');
1202: }
1203:
1204: return $aIds;
1205: }
1206:
1207: 1208: 1209: 1210: 1211: 1212: 1213:
1214: public function delete($mId) {
1215: $result = $this->_delete($mId);
1216: return $result;
1217: }
1218:
1219: 1220: 1221: 1222: 1223: 1224: 1225: 1226:
1227: public function deleteByWhereClause($sWhere) {
1228:
1229: $aIds = $this->getIdsByWhereClause($sWhere);
1230:
1231: if (!is_array($aIds) || 0 >= count($aIds)) {
1232: return 0;
1233: }
1234:
1235: $numDeleted = $this->_deleteMultiple($aIds);
1236: return $numDeleted;
1237: }
1238:
1239: 1240: 1241: 1242: 1243: 1244: 1245: 1246: 1247:
1248: public function deleteBy($sField, $mValue) {
1249: $where = (is_string($mValue)) ? "`%s` = '%s'" : "`%s` = %d";
1250: $where = $this->db->prepare($where, $sField, $mValue);
1251:
1252: return $this->deleteByWhereClause($where);
1253: }
1254:
1255:
1256:
1257:
1258:
1259:
1260:
1261:
1262:
1263:
1264:
1265:
1266:
1267: 1268: 1269: 1270: 1271: 1272: 1273:
1274: protected function _delete($mId) {
1275: $this->_executeCallbacks(self::DELETE_BEFORE, $this->_itemClass, array(
1276: $mId
1277: ));
1278:
1279: $oDb = $this->_getSecondDBInstance();
1280:
1281:
1282: $sql = "DELETE FROM `%s` WHERE %s = '%s'";
1283: $oDb->query($sql, $this->table, $this->primaryKey, $mId);
1284: $success = $oDb->affectedRows();
1285:
1286:
1287: $this->_oCache->removeItem($mId);
1288:
1289:
1290: $oProperties = $this->_getPropertiesCollectionInstance();
1291: $oProperties->deleteProperties($this->primaryKey, $mId);
1292:
1293: if ($success == 0) {
1294: $this->_executeCallbacks(self::DELETE_FAILURE, $this->_itemClass, array(
1295: $mId
1296: ));
1297: return false;
1298: } else {
1299: $this->_executeCallbacks(self::DELETE_SUCCESS, $this->_itemClass, array(
1300: $mId
1301: ));
1302: return true;
1303: }
1304: }
1305:
1306: 1307: 1308: 1309: 1310: 1311: 1312:
1313: protected function _deleteMultiple(array $aIds) {
1314: foreach ($aIds as $mId) {
1315: $this->_executeCallbacks(self::DELETE_BEFORE, $this->_itemClass, array(
1316: $mId
1317: ));
1318: }
1319:
1320: $oDb = $this->_getSecondDBInstance();
1321:
1322:
1323: $aEscapedIds = array_map(array(
1324: $oDb,
1325: 'escape'
1326: ), $aIds);
1327: $in = "'" . implode("', '", $aEscapedIds) . "'";
1328: $sql = "DELETE FROM `%s` WHERE %s IN (" . $in . ")";
1329: $oDb->query($sql, $this->table, $this->primaryKey);
1330: $numAffected = $oDb->affectedRows();
1331:
1332:
1333: $this->_oCache->removeItems($aIds);
1334:
1335:
1336: $oProperties = $this->_getPropertiesCollectionInstance();
1337: $oProperties->deletePropertiesMultiple($this->primaryKey, $aIds);
1338:
1339:
1340:
1341: if ($numAffected == 0) {
1342: foreach ($aIds as $mId) {
1343: $this->_executeCallbacks(self::DELETE_FAILURE, $this->_itemClass, array(
1344: $mId
1345: ));
1346: }
1347: } else {
1348: foreach ($aIds as $mId) {
1349: $this->_executeCallbacks(self::DELETE_SUCCESS, $this->_itemClass, array(
1350: $mId
1351: ));
1352: }
1353: }
1354: return $numAffected;
1355: }
1356:
1357: 1358: 1359: 1360: 1361: 1362: 1363: 1364: 1365: 1366: 1367: 1368: 1369: 1370: 1371: 1372:
1373: public function fetchArray($sKey, $mFields) {
1374: $aResult = array();
1375:
1376: while (($item = $this->next()) !== false) {
1377: if (is_array($mFields)) {
1378: foreach ($mFields as $value) {
1379: $aResult[$item->get($sKey)][$value] = $item->get($value);
1380: }
1381: } else {
1382: $aResult[$item->get($sKey)] = $item->get($mFields);
1383: }
1384: }
1385:
1386: return $aResult;
1387: }
1388: }
1389: