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:
27:
28: 29: 30: 31: 32: 33: 34:
35: abstract class Mage_Core_Model_Resource_Db_Collection_Abstract extends Varien_Data_Collection_Db
36: {
37: const CACHE_TAG = 'COLLECTION_DATA';
38:
39: 40: 41: 42: 43:
44: protected $_model;
45:
46: 47: 48: 49: 50:
51: protected $_resourceModel;
52:
53: 54: 55: 56: 57:
58: protected $_resource;
59:
60: 61: 62: 63: 64:
65: protected $_fieldsToSelect = null;
66:
67: 68: 69: 70: 71:
72: protected $_initialFieldsToSelect = null;
73:
74: 75: 76: 77: 78:
79: protected $_fieldsToSelectChanged = false;
80:
81: 82: 83: 84: 85:
86: protected $_joinedTables = array();
87:
88: 89: 90: 91: 92:
93: protected $_mainTable = null;
94:
95: 96: 97: 98: 99:
100: protected $_resetItemsDataChanged = false;
101:
102: 103: 104: 105: 106:
107: protected $_eventPrefix = '';
108:
109: 110: 111: 112: 113:
114: protected $_eventObject = '';
115:
116: 117: 118: 119: 120: 121:
122: protected $_useAnalyticFunction = false;
123:
124: 125: 126: 127: 128:
129: public function __construct($resource = null)
130: {
131: parent::__construct();
132: $this->_construct();
133: $this->_resource = $resource;
134: $this->setConnection($this->getResource()->getReadConnection());
135: $this->_initSelect();
136: }
137:
138: 139: 140: 141:
142: protected function _construct()
143: {
144:
145: }
146:
147: 148: 149: 150: 151:
152: public function getMainTable()
153: {
154: if ($this->_mainTable === null) {
155: $this->setMainTable($this->getResource()->getMainTable());
156: }
157:
158: return $this->_mainTable;
159: }
160:
161: 162: 163: 164: 165: 166:
167: public function setMainTable($table)
168: {
169: if (strpos($table, '/') !== false) {
170: $table = $this->getTable($table);
171: }
172:
173: if ($this->_mainTable !== null && $table !== $this->_mainTable && $this->getSelect() !== null) {
174: $from = $this->getSelect()->getPart(Zend_Db_Select::FROM);
175: if (isset($from['main_table'])) {
176: $from['main_table']['tableName'] = $table;
177: }
178: $this->getSelect()->setPart(Zend_Db_Select::FROM, $from);
179: }
180:
181: $this->_mainTable = $table;
182: return $this;
183: }
184:
185: 186: 187: 188: 189:
190: protected function _initSelect()
191: {
192: $this->getSelect()->from(array('main_table' => $this->getMainTable()));
193: return $this;
194: }
195:
196: 197: 198: 199: 200:
201: public function getSelect()
202: {
203: if ($this->_select && $this->_fieldsToSelectChanged) {
204: $this->_fieldsToSelectChanged = false;
205: $this->_initSelectFields();
206: }
207: return parent::getSelect();
208: }
209:
210: 211: 212: 213: 214:
215: protected function _initSelectFields()
216: {
217: $columns = $this->_select->getPart(Zend_Db_Select::COLUMNS);
218: $columnsToSelect = array();
219: foreach ($columns as $columnEntry) {
220: list($correlationName, $column, $alias) = $columnEntry;
221: if ($correlationName !== 'main_table') {
222: if ($column instanceof Zend_Db_Expr) {
223: $column = $column->__toString();
224: }
225: $key = ($alias !== null ? $alias : $column);
226: $columnsToSelect[$key] = $columnEntry;
227: }
228: }
229:
230: $columns = $columnsToSelect;
231:
232: $columnsToSelect = array_keys($columnsToSelect);
233:
234: if ($this->_fieldsToSelect !== null) {
235: $insertIndex = 0;
236: foreach ($this->_fieldsToSelect as $alias => $field) {
237: if (!is_string($alias)) {
238: $alias = null;
239: }
240:
241: if ($field instanceof Zend_Db_Expr) {
242: $column = $field->__toString();
243: } else {
244: $column = $field;
245: }
246:
247: if (($alias !== null && in_array($alias, $columnsToSelect)) ||
248:
249: ($alias === null && isset($alias, $columnsToSelect))) {
250: continue;
251: }
252:
253: $columnEntry = array('main_table', $field, $alias);
254: array_splice($columns, $insertIndex, 0, array($columnEntry));
255: $insertIndex ++;
256:
257: }
258: } else {
259: array_unshift($columns, array('main_table', '*', null));
260: }
261:
262: $this->_select->setPart(Zend_Db_Select::COLUMNS, $columns);
263:
264: return $this;
265: }
266:
267: 268: 269: 270: 271:
272: protected function _getInitialFieldsToSelect()
273: {
274: if ($this->_initialFieldsToSelect === null) {
275: $this->_initialFieldsToSelect = array();
276: $this->_initInitialFieldsToSelect();
277: }
278:
279: return $this->_initialFieldsToSelect;
280: }
281:
282: 283: 284: 285: 286:
287: protected function _initInitialFieldsToSelect()
288: {
289: $idFieldName = $this->getResource()->getIdFieldName();
290: if ($idFieldName) {
291: $this->_initialFieldsToSelect[] = $idFieldName;
292: }
293: return $this;
294: }
295:
296: 297: 298: 299: 300: 301: 302:
303: public function addFieldToSelect($field, $alias = null)
304: {
305: if ($field === '*') {
306: $this->_fieldsToSelect = null;
307: $this->_fieldsToSelectChanged = true;
308: return $this;
309: }
310:
311: if (is_array($field)) {
312: if ($this->_fieldsToSelect === null) {
313: $this->_fieldsToSelect = $this->_getInitialFieldsToSelect();
314: }
315:
316: foreach ($field as $key => $value) {
317: $this->addFieldToSelect(
318: $value,
319: (is_string($key) ? $key : null),
320: false
321: );
322: }
323:
324: $this->_fieldsToSelectChanged = true;
325: return $this;
326: }
327:
328: if ($alias === null) {
329: $this->_fieldsToSelect[] = $field;
330: } else {
331: $this->_fieldsToSelect[$alias] = $field;
332: }
333:
334: $this->_fieldsToSelectChanged = true;
335: return $this;
336: }
337:
338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348:
349: public function addExpressionFieldToSelect($alias, $expression, $fields)
350: {
351:
352: if (!is_array($fields)) {
353: $fields = array($fields=>$fields);
354: }
355:
356: $fullExpression = $expression;
357: foreach ($fields as $fieldKey=>$fieldItem) {
358: $fullExpression = str_replace('{{' . $fieldKey . '}}', $fieldItem, $fullExpression);
359: }
360:
361: $this->getSelect()->columns(array($alias=>$fullExpression));
362:
363: return $this;
364: }
365:
366: 367: 368: 369: 370: 371: 372:
373: public function removeFieldFromSelect($field, $isAlias = false)
374: {
375: if ($isAlias) {
376: if (isset($this->_fieldsToSelect[$field])) {
377: unset($this->_fieldsToSelect[$field]);
378: }
379: } else {
380: foreach ($this->_fieldsToSelect as $key => $value) {
381: if ($value === $field) {
382: unset($this->_fieldsToSelect[$key]);
383: break;
384: }
385: }
386: }
387:
388: $this->_fieldsToSelectChanged = true;
389: return $this;
390: }
391:
392: 393: 394: 395: 396:
397: public function removeAllFieldsFromSelect()
398: {
399: $this->_fieldsToSelect = $this->_getInitialFieldsToSelect();
400: $this->_fieldsToSelectChanged = true;
401: return $this;
402: }
403:
404: 405: 406: 407: 408: 409: 410:
411: protected function _init($model, $resourceModel = null)
412: {
413: $this->setModel($model);
414: if (is_null($resourceModel)) {
415: $resourceModel = $model;
416: }
417: $this->setResourceModel($resourceModel);
418: return $this;
419: }
420:
421: 422: 423: 424: 425: 426:
427: public function setModel($model)
428: {
429: if (is_string($model)) {
430: $this->_model = $model;
431: $this->setItemObjectClass(Mage::getConfig()->getModelClassName($model));
432: }
433: return $this;
434: }
435:
436: 437: 438: 439: 440: 441:
442: public function getModelName($args = array())
443: {
444: return $this->_model;
445: }
446:
447: 448: 449: 450: 451:
452: public function setResourceModel($model)
453: {
454: $this->_resourceModel = $model;
455: }
456:
457: 458: 459: 460: 461:
462: public function getResourceModelName()
463: {
464: return $this->_resourceModel;
465: }
466:
467: 468: 469: 470: 471:
472: public function getResource()
473: {
474: if (empty($this->_resource)) {
475: $this->_resource = Mage::getResourceModel($this->getResourceModelName());
476: }
477: return $this->_resource;
478: }
479:
480: 481: 482: 483: 484: 485:
486: public function getTable($table)
487: {
488: return $this->getResource()->getTable($table);
489: }
490:
491: 492: 493: 494: 495:
496: public function getAllIds()
497: {
498: $idsSelect = clone $this->getSelect();
499: $idsSelect->reset(Zend_Db_Select::ORDER);
500: $idsSelect->reset(Zend_Db_Select::LIMIT_COUNT);
501: $idsSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
502: $idsSelect->reset(Zend_Db_Select::COLUMNS);
503:
504: $idsSelect->columns($this->getResource()->getIdFieldName(), 'main_table');
505: return $this->getConnection()->fetchCol($idsSelect);
506: }
507:
508: public function getData()
509: {
510: if ($this->_data === null) {
511:
512:
513: $this->_renderFilters()
514: ->_renderOrders()
515: ->_renderLimit();
516: 517: 518: 519:
520: $query = $this->_prepareSelect($this->getSelect());
521: $this->_data = $this->_fetchAll($query, $this->_bindParams);
522: $this->_afterLoadData();
523: }
524: return $this->_data;
525: }
526:
527: 528: 529: 530: 531:
532: protected function _prepareSelect(Varien_Db_Select $select)
533: {
534: $helper = Mage::getResourceHelper('core');
535:
536: $unionParts = $select->getPart(Zend_Db_Select::UNION);
537: if (!empty($unionParts)) {
538: $select = $helper->limitUnion($select);
539: }
540:
541: if ($this->_useAnalyticFunction) {
542: return $helper->getQueryUsingAnalyticFunction($select);
543: }
544:
545: return (string)$select;
546: }
547: 548: 549: 550: 551: 552: 553: 554:
555: public function join($table, $cond, $cols = '*')
556: {
557: if (is_array($table)) {
558: foreach ($table as $k => $v) {
559: $alias = $k;
560: $table = $v;
561: break;
562: }
563: } else {
564: $alias = $table;
565: }
566:
567: if (!isset($this->_joinedTables[$table])) {
568: $this->getSelect()->join(
569: array($alias => $this->getTable($table)),
570: $cond,
571: $cols
572: );
573: $this->_joinedTables[$alias] = true;
574: }
575: return $this;
576: }
577:
578: 579: 580: 581: 582:
583: protected function _beforeLoad()
584: {
585: parent::_beforeLoad();
586: Mage::dispatchEvent('core_collection_abstract_load_before', array('collection' => $this));
587: if ($this->_eventPrefix && $this->_eventObject) {
588: Mage::dispatchEvent($this->_eventPrefix.'_load_before', array(
589: $this->_eventObject => $this
590: ));
591: }
592: return $this;
593: }
594:
595: 596: 597: 598: 599: 600:
601: public function setResetItemsDataChanged($flag)
602: {
603: $this->_resetItemsDataChanged = (bool)$flag;
604: return $this;
605: }
606:
607: 608: 609: 610: 611:
612: public function resetItemsDataChanged()
613: {
614: foreach ($this->_items as $item) {
615: $item->setDataChanges(false);
616: }
617:
618: return $this;
619: }
620:
621: 622: 623: 624: 625:
626: protected function _afterLoad()
627: {
628: parent::_afterLoad();
629: foreach ($this->_items as $item) {
630: $item->setOrigData();
631: if ($this->_resetItemsDataChanged) {
632: $item->setDataChanges(false);
633: }
634: }
635: Mage::dispatchEvent('core_collection_abstract_load_after', array('collection' => $this));
636: if ($this->_eventPrefix && $this->_eventObject) {
637: Mage::dispatchEvent($this->_eventPrefix.'_load_after', array(
638: $this->_eventObject => $this
639: ));
640: }
641: return $this;
642: }
643:
644: 645: 646: 647: 648:
649: public function save()
650: {
651: foreach ($this->getItems() as $item) {
652: $item->save();
653: }
654: return $this;
655: }
656:
657: 658: 659: 660: 661:
662: protected function _canUseCache()
663: {
664: return Mage::app()->useCache('collections') && !empty($this->_cacheConf);
665: }
666:
667: 668: 669: 670: 671: 672:
673: protected function _loadCache($select)
674: {
675: $data = Mage::app()->loadCache($this->_getSelectCacheId($select));
676: return $data;
677: }
678:
679: 680: 681: 682: 683: 684: 685:
686: protected function _saveCache($data, $select)
687: {
688: Mage::app()->saveCache(serialize($data), $this->_getSelectCacheId($select), $this->_getCacheTags());
689: return $this;
690: }
691:
692: 693: 694: 695: 696:
697: protected function _getCacheTags()
698: {
699: $tags = parent::_getCacheTags();
700: $tags[] = Mage_Core_Model_App::CACHE_TAG;
701: $tags[] = self::CACHE_TAG;
702: return $tags;
703: }
704:
705: 706: 707: 708: 709: 710: 711:
712: public function formatDate($date, $includeTime = true)
713: {
714: return Varien_Date::formatDate($date, $includeTime);
715: }
716:
717:
718:
719: }
720: