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