1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
22:
23: 24: 25:
26: require_once 'Zend/Db.php';
27:
28: 29: 30: 31: 32: 33: 34:
35: abstract class Zend_Db_Table_Row_Abstract implements ArrayAccess, IteratorAggregate
36: {
37:
38: 39: 40: 41: 42: 43: 44:
45: protected $_data = array();
46:
47: 48: 49: 50: 51: 52: 53:
54: protected $_cleanData = array();
55:
56: 57: 58: 59: 60: 61:
62: protected $_modifiedFields = array();
63:
64: 65: 66: 67: 68:
69: protected $_table = null;
70:
71: 72: 73: 74: 75: 76: 77:
78: protected $_connected = true;
79:
80: 81: 82: 83: 84: 85: 86:
87: protected $_readOnly = false;
88:
89: 90: 91: 92: 93:
94: protected $_tableClass = null;
95:
96: 97: 98: 99: 100:
101: protected $_primary;
102:
103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113:
114: public function __construct(array $config = array())
115: {
116: if (isset($config['table']) && $config['table'] instanceof Zend_Db_Table_Abstract) {
117: $this->_table = $config['table'];
118: $this->_tableClass = get_class($this->_table);
119: } elseif ($this->_tableClass !== null) {
120: $this->_table = $this->_getTableFromString($this->_tableClass);
121: }
122:
123: if (isset($config['data'])) {
124: if (!is_array($config['data'])) {
125: require_once 'Zend/Db/Table/Row/Exception.php';
126: throw new Zend_Db_Table_Row_Exception('Data must be an array');
127: }
128: $this->_data = $config['data'];
129: }
130: if (isset($config['stored']) && $config['stored'] === true) {
131: $this->_cleanData = $this->_data;
132: }
133:
134: if (isset($config['readOnly']) && $config['readOnly'] === true) {
135: $this->setReadOnly(true);
136: }
137:
138:
139: if (($table = $this->_getTable())) {
140: $info = $table->info();
141: $this->_primary = (array) $info['primary'];
142: }
143:
144: $this->init();
145: }
146:
147: 148: 149: 150: 151: 152: 153: 154: 155: 156:
157: protected function _transformColumn($columnName)
158: {
159: if (!is_string($columnName)) {
160: require_once 'Zend/Db/Table/Row/Exception.php';
161: throw new Zend_Db_Table_Row_Exception('Specified column is not a string');
162: }
163:
164: return $columnName;
165: }
166:
167: 168: 169: 170: 171: 172: 173:
174: public function __get($columnName)
175: {
176: $columnName = $this->_transformColumn($columnName);
177: if (!array_key_exists($columnName, $this->_data)) {
178: require_once 'Zend/Db/Table/Row/Exception.php';
179: throw new Zend_Db_Table_Row_Exception("Specified column \"$columnName\" is not in the row");
180: }
181: return $this->_data[$columnName];
182: }
183:
184: 185: 186: 187: 188: 189: 190: 191:
192: public function __set($columnName, $value)
193: {
194: $columnName = $this->_transformColumn($columnName);
195: if (!array_key_exists($columnName, $this->_data)) {
196: require_once 'Zend/Db/Table/Row/Exception.php';
197: throw new Zend_Db_Table_Row_Exception("Specified column \"$columnName\" is not in the row");
198: }
199: $this->_data[$columnName] = $value;
200: $this->_modifiedFields[$columnName] = true;
201: }
202:
203: 204: 205: 206: 207: 208: 209:
210: public function __unset($columnName)
211: {
212: $columnName = $this->_transformColumn($columnName);
213: if (!array_key_exists($columnName, $this->_data)) {
214: require_once 'Zend/Db/Table/Row/Exception.php';
215: throw new Zend_Db_Table_Row_Exception("Specified column \"$columnName\" is not in the row");
216: }
217: if ($this->isConnected() && in_array($columnName, $this->_table->info('primary'))) {
218: require_once 'Zend/Db/Table/Row/Exception.php';
219: throw new Zend_Db_Table_Row_Exception("Specified column \"$columnName\" is a primary key and should not be unset");
220: }
221: unset($this->_data[$columnName]);
222: return $this;
223: }
224:
225: 226: 227: 228: 229: 230:
231: public function __isset($columnName)
232: {
233: $columnName = $this->_transformColumn($columnName);
234: return array_key_exists($columnName, $this->_data);
235: }
236:
237: 238: 239: 240: 241:
242: public function __sleep()
243: {
244: return array('_tableClass', '_primary', '_data', '_cleanData', '_readOnly' ,'_modifiedFields');
245: }
246:
247: 248: 249: 250: 251: 252: 253:
254: public function __wakeup()
255: {
256: $this->_connected = false;
257: }
258:
259: 260: 261: 262: 263: 264: 265:
266: public function offsetExists($offset)
267: {
268: return $this->__isset($offset);
269: }
270:
271: 272: 273: 274: 275: 276: 277:
278: public function offsetGet($offset)
279: {
280: return $this->__get($offset);
281: }
282:
283: 284: 285: 286: 287: 288: 289:
290: public function offsetSet($offset, $value)
291: {
292: $this->__set($offset, $value);
293: }
294:
295: 296: 297: 298: 299: 300:
301: public function offsetUnset($offset)
302: {
303: return $this->__unset($offset);
304: }
305:
306: 307: 308: 309: 310: 311: 312:
313: public function init()
314: {
315: }
316:
317: 318: 319: 320: 321:
322: public function getTable()
323: {
324: return $this->_table;
325: }
326:
327: 328: 329: 330: 331: 332: 333: 334:
335: public function setTable(Zend_Db_Table_Abstract $table = null)
336: {
337: if ($table == null) {
338: $this->_table = null;
339: $this->_connected = false;
340: return false;
341: }
342:
343: $tableClass = get_class($table);
344: if (! $table instanceof $this->_tableClass) {
345: require_once 'Zend/Db/Table/Row/Exception.php';
346: throw new Zend_Db_Table_Row_Exception("The specified Table is of class $tableClass, expecting class to be instance of $this->_tableClass");
347: }
348:
349: $this->_table = $table;
350: $this->_tableClass = $tableClass;
351:
352: $info = $this->_table->info();
353:
354: if ($info['cols'] != array_keys($this->_data)) {
355: require_once 'Zend/Db/Table/Row/Exception.php';
356: throw new Zend_Db_Table_Row_Exception('The specified Table does not have the same columns as the Row');
357: }
358:
359: if (! array_intersect((array) $this->_primary, $info['primary']) == (array) $this->_primary) {
360:
361: require_once 'Zend/Db/Table/Row/Exception.php';
362: throw new Zend_Db_Table_Row_Exception("The specified Table '$tableClass' does not have the same primary key as the Row");
363: }
364:
365: $this->_connected = true;
366: return true;
367: }
368:
369: 370: 371: 372: 373: 374:
375: public function getTableClass()
376: {
377: return $this->_tableClass;
378: }
379:
380: 381: 382: 383: 384:
385: public function isConnected()
386: {
387: return $this->_connected;
388: }
389:
390: 391: 392: 393: 394:
395: public function isReadOnly()
396: {
397: return $this->_readOnly;
398: }
399:
400: 401: 402: 403: 404: 405:
406: public function setReadOnly($flag)
407: {
408: $this->_readOnly = (bool) $flag;
409: }
410:
411: 412: 413: 414: 415:
416: public function select()
417: {
418: return $this->getTable()->select();
419: }
420:
421: 422: 423: 424: 425: 426: 427: 428: 429:
430: public function save()
431: {
432: 433: 434: 435: 436:
437: if (empty($this->_cleanData)) {
438: return $this->_doInsert();
439: } else {
440: return $this->_doUpdate();
441: }
442: }
443:
444: 445: 446: 447:
448: protected function _doInsert()
449: {
450: 451: 452:
453: if ($this->_readOnly === true) {
454: require_once 'Zend/Db/Table/Row/Exception.php';
455: throw new Zend_Db_Table_Row_Exception('This row has been marked read-only');
456: }
457:
458: 459: 460:
461: $this->_insert();
462:
463: 464: 465:
466: $data = array_intersect_key($this->_data, $this->_modifiedFields);
467: $primaryKey = $this->_getTable()->insert($data);
468:
469: 470: 471: 472:
473: if (is_array($primaryKey)) {
474: $newPrimaryKey = $primaryKey;
475: } else {
476:
477: $tempPrimaryKey = (array) $this->_primary;
478: $newPrimaryKey = array(current($tempPrimaryKey) => $primaryKey);
479: }
480:
481: 482: 483: 484: 485: 486:
487: $this->_data = array_merge($this->_data, $newPrimaryKey);
488:
489: 490: 491:
492: $this->_postInsert();
493:
494: 495: 496:
497: $this->_refresh();
498:
499: return $primaryKey;
500: }
501:
502: 503: 504: 505:
506: protected function _doUpdate()
507: {
508: 509: 510:
511: if ($this->_readOnly === true) {
512: require_once 'Zend/Db/Table/Row/Exception.php';
513: throw new Zend_Db_Table_Row_Exception('This row has been marked read-only');
514: }
515:
516: 517: 518: 519:
520: $where = $this->_getWhereQuery(false);
521:
522: 523: 524:
525: $this->_update();
526:
527: 528: 529: 530:
531: $diffData = array_intersect_key($this->_data, $this->_modifiedFields);
532:
533: 534: 535:
536: $pkDiffData = array_intersect_key($diffData, array_flip((array)$this->_primary));
537:
538: 539: 540: 541:
542: if (count($pkDiffData) > 0) {
543: $depTables = $this->_getTable()->getDependentTables();
544: if (!empty($depTables)) {
545: $pkNew = $this->_getPrimaryKey(true);
546: $pkOld = $this->_getPrimaryKey(false);
547: foreach ($depTables as $tableClass) {
548: $t = $this->_getTableFromString($tableClass);
549: $t->_cascadeUpdate($this->getTableClass(), $pkOld, $pkNew);
550: }
551: }
552: }
553:
554: 555: 556: 557: 558: 559:
560: if (count($diffData) > 0) {
561: $this->_getTable()->update($diffData, $where);
562: }
563:
564: 565: 566: 567: 568:
569: $this->_postUpdate();
570:
571: 572: 573: 574:
575: $this->_refresh();
576:
577: 578: 579: 580: 581:
582: $primaryKey = $this->_getPrimaryKey(true);
583: if (count($primaryKey) == 1) {
584: return current($primaryKey);
585: }
586:
587: return $primaryKey;
588: }
589:
590: 591: 592: 593: 594:
595: public function delete()
596: {
597: 598: 599:
600: if ($this->_readOnly === true) {
601: require_once 'Zend/Db/Table/Row/Exception.php';
602: throw new Zend_Db_Table_Row_Exception('This row has been marked read-only');
603: }
604:
605: $where = $this->_getWhereQuery();
606:
607: 608: 609:
610: $this->_delete();
611:
612: 613: 614:
615: $depTables = $this->_getTable()->getDependentTables();
616: if (!empty($depTables)) {
617: $pk = $this->_getPrimaryKey();
618: foreach ($depTables as $tableClass) {
619: $t = $this->_getTableFromString($tableClass);
620: $t->_cascadeDelete($this->getTableClass(), $pk);
621: }
622: }
623:
624: 625: 626:
627: $result = $this->_getTable()->delete($where);
628:
629: 630: 631:
632: $this->_postDelete();
633:
634: 635: 636:
637: $this->_data = array_combine(
638: array_keys($this->_data),
639: array_fill(0, count($this->_data), null)
640: );
641:
642: return $result;
643: }
644:
645: public function getIterator()
646: {
647: return new ArrayIterator((array) $this->_data);
648: }
649:
650: 651: 652: 653: 654:
655: public function toArray()
656: {
657: return (array)$this->_data;
658: }
659:
660: 661: 662: 663: 664: 665:
666: public function setFromArray(array $data)
667: {
668: $data = array_intersect_key($data, $this->_data);
669:
670: foreach ($data as $columnName => $value) {
671: $this->__set($columnName, $value);
672: }
673:
674: return $this;
675: }
676:
677: 678: 679: 680: 681:
682: public function refresh()
683: {
684: return $this->_refresh();
685: }
686:
687: 688: 689: 690: 691:
692: protected function _getTable()
693: {
694: if (!$this->_connected) {
695: require_once 'Zend/Db/Table/Row/Exception.php';
696: throw new Zend_Db_Table_Row_Exception('Cannot save a Row unless it is connected');
697: }
698: return $this->_table;
699: }
700:
701: 702: 703: 704: 705: 706:
707: protected function _getPrimaryKey($useDirty = true)
708: {
709: if (!is_array($this->_primary)) {
710: require_once 'Zend/Db/Table/Row/Exception.php';
711: throw new Zend_Db_Table_Row_Exception("The primary key must be set as an array");
712: }
713:
714: $primary = array_flip($this->_primary);
715: if ($useDirty) {
716: $array = array_intersect_key($this->_data, $primary);
717: } else {
718: $array = array_intersect_key($this->_cleanData, $primary);
719: }
720: if (count($primary) != count($array)) {
721: require_once 'Zend/Db/Table/Row/Exception.php';
722: throw new Zend_Db_Table_Row_Exception("The specified Table '$this->_tableClass' does not have the same primary key as the Row");
723: }
724: return $array;
725: }
726:
727: 728: 729: 730: 731: 732:
733: protected function _getWhereQuery($useDirty = true)
734: {
735: $where = array();
736: $db = $this->_getTable()->getAdapter();
737: $primaryKey = $this->_getPrimaryKey($useDirty);
738: $info = $this->_getTable()->info();
739: $metadata = $info[Zend_Db_Table_Abstract::METADATA];
740:
741:
742: $where = array();
743: foreach ($primaryKey as $column => $value) {
744: $tableName = $db->quoteIdentifier($info[Zend_Db_Table_Abstract::NAME], true);
745: $type = $metadata[$column]['DATA_TYPE'];
746: $columnName = $db->quoteIdentifier($column, true);
747: $where[] = $db->quoteInto("{$tableName}.{$columnName} = ?", $value, $type);
748: }
749: return $where;
750: }
751:
752: 753: 754: 755: 756:
757: protected function _refresh()
758: {
759: $where = $this->_getWhereQuery();
760: $row = $this->_getTable()->fetchRow($where);
761:
762: if (null === $row) {
763: require_once 'Zend/Db/Table/Row/Exception.php';
764: throw new Zend_Db_Table_Row_Exception('Cannot refresh row as parent is missing');
765: }
766:
767: $this->_data = $row->toArray();
768: $this->_cleanData = $this->_data;
769: $this->_modifiedFields = array();
770: }
771:
772: 773: 774: 775: 776: 777:
778: protected function _insert()
779: {
780: }
781:
782: 783: 784: 785: 786: 787:
788: protected function _postInsert()
789: {
790: }
791:
792: 793: 794: 795: 796: 797:
798: protected function _update()
799: {
800: }
801:
802: 803: 804: 805: 806: 807:
808: protected function _postUpdate()
809: {
810: }
811:
812: 813: 814: 815: 816: 817:
818: protected function _delete()
819: {
820: }
821:
822: 823: 824: 825: 826: 827:
828: protected function _postDelete()
829: {
830: }
831:
832: 833: 834: 835: 836: 837: 838: 839: 840: 841:
842: protected function _prepareReference(Zend_Db_Table_Abstract $dependentTable, Zend_Db_Table_Abstract $parentTable, $ruleKey)
843: {
844: $parentTableName = (get_class($parentTable) === 'Zend_Db_Table') ? $parentTable->getDefinitionConfigName() : get_class($parentTable);
845: $map = $dependentTable->getReference($parentTableName, $ruleKey);
846:
847: if (!isset($map[Zend_Db_Table_Abstract::REF_COLUMNS])) {
848: $parentInfo = $parentTable->info();
849: $map[Zend_Db_Table_Abstract::REF_COLUMNS] = array_values((array) $parentInfo['primary']);
850: }
851:
852: $map[Zend_Db_Table_Abstract::COLUMNS] = (array) $map[Zend_Db_Table_Abstract::COLUMNS];
853: $map[Zend_Db_Table_Abstract::REF_COLUMNS] = (array) $map[Zend_Db_Table_Abstract::REF_COLUMNS];
854:
855: return $map;
856: }
857:
858: 859: 860: 861: 862: 863: 864: 865: 866:
867: public function findDependentRowset($dependentTable, $ruleKey = null, Zend_Db_Table_Select $select = null)
868: {
869: $db = $this->_getTable()->getAdapter();
870:
871: if (is_string($dependentTable)) {
872: $dependentTable = $this->_getTableFromString($dependentTable);
873: }
874:
875: if (!$dependentTable instanceof Zend_Db_Table_Abstract) {
876: $type = gettype($dependentTable);
877: if ($type == 'object') {
878: $type = get_class($dependentTable);
879: }
880: require_once 'Zend/Db/Table/Row/Exception.php';
881: throw new Zend_Db_Table_Row_Exception("Dependent table must be a Zend_Db_Table_Abstract, but it is $type");
882: }
883:
884:
885:
886: if (($tableDefinition = $this->_table->getDefinition()) !== null
887: && ($dependentTable->getDefinition() == null)) {
888: $dependentTable->setOptions(array(Zend_Db_Table_Abstract::DEFINITION => $tableDefinition));
889: }
890:
891: if ($select === null) {
892: $select = $dependentTable->select();
893: } else {
894: $select->setTable($dependentTable);
895: }
896:
897: $map = $this->_prepareReference($dependentTable, $this->_getTable(), $ruleKey);
898:
899: for ($i = 0; $i < count($map[Zend_Db_Table_Abstract::COLUMNS]); ++$i) {
900: $parentColumnName = $db->foldCase($map[Zend_Db_Table_Abstract::REF_COLUMNS][$i]);
901: $value = $this->_data[$parentColumnName];
902:
903: $dependentDb = $dependentTable->getAdapter();
904: $dependentColumnName = $dependentDb->foldCase($map[Zend_Db_Table_Abstract::COLUMNS][$i]);
905: $dependentColumn = $dependentDb->quoteIdentifier($dependentColumnName, true);
906: $dependentInfo = $dependentTable->info();
907: $type = $dependentInfo[Zend_Db_Table_Abstract::METADATA][$dependentColumnName]['DATA_TYPE'];
908: $select->where("$dependentColumn = ?", $value, $type);
909: }
910:
911: return $dependentTable->fetchAll($select);
912: }
913:
914: 915: 916: 917: 918: 919: 920: 921: 922:
923: public function findParentRow($parentTable, $ruleKey = null, Zend_Db_Table_Select $select = null)
924: {
925: $db = $this->_getTable()->getAdapter();
926:
927: if (is_string($parentTable)) {
928: $parentTable = $this->_getTableFromString($parentTable);
929: }
930:
931: if (!$parentTable instanceof Zend_Db_Table_Abstract) {
932: $type = gettype($parentTable);
933: if ($type == 'object') {
934: $type = get_class($parentTable);
935: }
936: require_once 'Zend/Db/Table/Row/Exception.php';
937: throw new Zend_Db_Table_Row_Exception("Parent table must be a Zend_Db_Table_Abstract, but it is $type");
938: }
939:
940:
941:
942: if (($tableDefinition = $this->_table->getDefinition()) !== null
943: && ($parentTable->getDefinition() == null)) {
944: $parentTable->setOptions(array(Zend_Db_Table_Abstract::DEFINITION => $tableDefinition));
945: }
946:
947: if ($select === null) {
948: $select = $parentTable->select();
949: } else {
950: $select->setTable($parentTable);
951: }
952:
953: $map = $this->_prepareReference($this->_getTable(), $parentTable, $ruleKey);
954:
955:
956: for ($i = 0; $i < count($map[Zend_Db_Table_Abstract::COLUMNS]); ++$i) {
957: $dependentColumnName = $db->foldCase($map[Zend_Db_Table_Abstract::COLUMNS][$i]);
958: $value = $this->_data[$dependentColumnName];
959:
960: $parentDb = $parentTable->getAdapter();
961: $parentColumnName = $parentDb->foldCase($map[Zend_Db_Table_Abstract::REF_COLUMNS][$i]);
962: $parentColumn = $parentDb->quoteIdentifier($parentColumnName, true);
963: $parentInfo = $parentTable->info();
964:
965:
966: $type = $parentInfo[Zend_Db_Table_Abstract::METADATA][$parentColumnName]['DATA_TYPE'];
967: $nullable = $parentInfo[Zend_Db_Table_Abstract::METADATA][$parentColumnName]['NULLABLE'];
968: if ($value === null && $nullable == true) {
969: $select->where("$parentColumn IS NULL");
970: } elseif ($value === null && $nullable == false) {
971: return null;
972: } else {
973: $select->where("$parentColumn = ?", $value, $type);
974: }
975:
976: }
977:
978: return $parentTable->fetchRow($select);
979: }
980:
981: 982: 983: 984: 985: 986: 987: 988: 989:
990: public function findManyToManyRowset($matchTable, $intersectionTable, $callerRefRule = null,
991: $matchRefRule = null, Zend_Db_Table_Select $select = null)
992: {
993: $db = $this->_getTable()->getAdapter();
994:
995: if (is_string($intersectionTable)) {
996: $intersectionTable = $this->_getTableFromString($intersectionTable);
997: }
998:
999: if (!$intersectionTable instanceof Zend_Db_Table_Abstract) {
1000: $type = gettype($intersectionTable);
1001: if ($type == 'object') {
1002: $type = get_class($intersectionTable);
1003: }
1004: require_once 'Zend/Db/Table/Row/Exception.php';
1005: throw new Zend_Db_Table_Row_Exception("Intersection table must be a Zend_Db_Table_Abstract, but it is $type");
1006: }
1007:
1008:
1009:
1010: if (($tableDefinition = $this->_table->getDefinition()) !== null
1011: && ($intersectionTable->getDefinition() == null)) {
1012: $intersectionTable->setOptions(array(Zend_Db_Table_Abstract::DEFINITION => $tableDefinition));
1013: }
1014:
1015: if (is_string($matchTable)) {
1016: $matchTable = $this->_getTableFromString($matchTable);
1017: }
1018:
1019: if (! $matchTable instanceof Zend_Db_Table_Abstract) {
1020: $type = gettype($matchTable);
1021: if ($type == 'object') {
1022: $type = get_class($matchTable);
1023: }
1024: require_once 'Zend/Db/Table/Row/Exception.php';
1025: throw new Zend_Db_Table_Row_Exception("Match table must be a Zend_Db_Table_Abstract, but it is $type");
1026: }
1027:
1028:
1029:
1030: if (($tableDefinition = $this->_table->getDefinition()) !== null
1031: && ($matchTable->getDefinition() == null)) {
1032: $matchTable->setOptions(array(Zend_Db_Table_Abstract::DEFINITION => $tableDefinition));
1033: }
1034:
1035: if ($select === null) {
1036: $select = $matchTable->select();
1037: } else {
1038: $select->setTable($matchTable);
1039: }
1040:
1041:
1042: $interInfo = $intersectionTable->info();
1043: $interDb = $intersectionTable->getAdapter();
1044: $interName = $interInfo['name'];
1045: $interSchema = isset($interInfo['schema']) ? $interInfo['schema'] : null;
1046: $matchInfo = $matchTable->info();
1047: $matchName = $matchInfo['name'];
1048: $matchSchema = isset($matchInfo['schema']) ? $matchInfo['schema'] : null;
1049:
1050: $matchMap = $this->_prepareReference($intersectionTable, $matchTable, $matchRefRule);
1051:
1052: for ($i = 0; $i < count($matchMap[Zend_Db_Table_Abstract::COLUMNS]); ++$i) {
1053: $interCol = $interDb->quoteIdentifier('i' . '.' . $matchMap[Zend_Db_Table_Abstract::COLUMNS][$i], true);
1054: $matchCol = $interDb->quoteIdentifier('m' . '.' . $matchMap[Zend_Db_Table_Abstract::REF_COLUMNS][$i], true);
1055: $joinCond[] = "$interCol = $matchCol";
1056: }
1057: $joinCond = implode(' AND ', $joinCond);
1058:
1059: $select->from(array('i' => $interName), array(), $interSchema)
1060: ->joinInner(array('m' => $matchName), $joinCond, Zend_Db_Select::SQL_WILDCARD, $matchSchema)
1061: ->setIntegrityCheck(false);
1062:
1063: $callerMap = $this->_prepareReference($intersectionTable, $this->_getTable(), $callerRefRule);
1064:
1065: for ($i = 0; $i < count($callerMap[Zend_Db_Table_Abstract::COLUMNS]); ++$i) {
1066: $callerColumnName = $db->foldCase($callerMap[Zend_Db_Table_Abstract::REF_COLUMNS][$i]);
1067: $value = $this->_data[$callerColumnName];
1068: $interColumnName = $interDb->foldCase($callerMap[Zend_Db_Table_Abstract::COLUMNS][$i]);
1069: $interCol = $interDb->quoteIdentifier("i.$interColumnName", true);
1070: $interInfo = $intersectionTable->info();
1071: $type = $interInfo[Zend_Db_Table_Abstract::METADATA][$interColumnName]['DATA_TYPE'];
1072: $select->where($interDb->quoteInto("$interCol = ?", $value, $type));
1073: }
1074:
1075: $stmt = $select->query();
1076:
1077: $config = array(
1078: 'table' => $matchTable,
1079: 'data' => $stmt->fetchAll(Zend_Db::FETCH_ASSOC),
1080: 'rowClass' => $matchTable->getRowClass(),
1081: 'readOnly' => false,
1082: 'stored' => true
1083: );
1084:
1085: $rowsetClass = $matchTable->getRowsetClass();
1086: if (!class_exists($rowsetClass)) {
1087: try {
1088: require_once 'Zend/Loader.php';
1089: Zend_Loader::loadClass($rowsetClass);
1090: } catch (Zend_Exception $e) {
1091: require_once 'Zend/Db/Table/Row/Exception.php';
1092: throw new Zend_Db_Table_Row_Exception($e->getMessage(), $e->getCode(), $e);
1093: }
1094: }
1095: $rowset = new $rowsetClass($config);
1096: return $rowset;
1097: }
1098:
1099: 1100: 1101: 1102: 1103: 1104: 1105: 1106: 1107:
1108: public function __call($method, array $args)
1109: {
1110: $matches = array();
1111:
1112: if (count($args) && $args[0] instanceof Zend_Db_Table_Select) {
1113: $select = $args[0];
1114: } else {
1115: $select = null;
1116: }
1117:
1118: 1119: 1120: 1121: 1122: 1123:
1124: if (preg_match('/^findParent(\w+?)(?:By(\w+))?$/', $method, $matches)) {
1125: $class = $matches[1];
1126: $ruleKey1 = isset($matches[2]) ? $matches[2] : null;
1127: return $this->findParentRow($class, $ruleKey1, $select);
1128: }
1129:
1130: 1131: 1132: 1133: 1134: 1135: 1136:
1137: if (preg_match('/^find(\w+?)Via(\w+?)(?:By(\w+?)(?:And(\w+))?)?$/', $method, $matches)) {
1138: $class = $matches[1];
1139: $viaClass = $matches[2];
1140: $ruleKey1 = isset($matches[3]) ? $matches[3] : null;
1141: $ruleKey2 = isset($matches[4]) ? $matches[4] : null;
1142: return $this->findManyToManyRowset($class, $viaClass, $ruleKey1, $ruleKey2, $select);
1143: }
1144:
1145: 1146: 1147: 1148: 1149: 1150:
1151: if (preg_match('/^find(\w+?)(?:By(\w+))?$/', $method, $matches)) {
1152: $class = $matches[1];
1153: $ruleKey1 = isset($matches[2]) ? $matches[2] : null;
1154: return $this->findDependentRowset($class, $ruleKey1, $select);
1155: }
1156:
1157: require_once 'Zend/Db/Table/Row/Exception.php';
1158: throw new Zend_Db_Table_Row_Exception("Unrecognized method '$method()'");
1159: }
1160:
1161:
1162: 1163: 1164: 1165: 1166: 1167:
1168: protected function _getTableFromString($tableName)
1169: {
1170:
1171: if ($this->_table instanceof Zend_Db_Table_Abstract) {
1172: $tableDefinition = $this->_table->getDefinition();
1173:
1174: if ($tableDefinition !== null && $tableDefinition->hasTableConfig($tableName)) {
1175: return new Zend_Db_Table($tableName, $tableDefinition);
1176: }
1177: }
1178:
1179:
1180: if (!class_exists($tableName)) {
1181: try {
1182: require_once 'Zend/Loader.php';
1183: Zend_Loader::loadClass($tableName);
1184: } catch (Zend_Exception $e) {
1185: require_once 'Zend/Db/Table/Row/Exception.php';
1186: throw new Zend_Db_Table_Row_Exception($e->getMessage(), $e->getCode(), $e);
1187: }
1188: }
1189:
1190: $options = array();
1191:
1192: if (($table = $this->_getTable())) {
1193: $options['db'] = $table->getAdapter();
1194: }
1195:
1196: if (isset($tableDefinition) && $tableDefinition !== null) {
1197: $options[Zend_Db_Table_Abstract::DEFINITION] = $tableDefinition;
1198: }
1199:
1200: return new $tableName($options);
1201: }
1202:
1203: }
1204: