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: abstract class Mage_Eav_Model_Entity_Collection_Abstract extends Varien_Data_Collection_Db
35: {
36: 37: 38: 39: 40:
41: protected $_itemsById = array();
42:
43: 44: 45: 46: 47:
48: protected $_staticFields = array();
49:
50: 51: 52: 53: 54:
55: protected $_entity;
56:
57: 58: 59: 60: 61:
62: protected $_selectEntityTypes = array();
63:
64: 65: 66: 67: 68:
69: protected $_selectAttributes = array();
70:
71: 72: 73: 74: 75:
76: protected $_filterAttributes = array();
77:
78: 79: 80: 81: 82:
83: protected $_joinEntities = array();
84:
85: 86: 87: 88: 89:
90: protected $_joinAttributes = array();
91:
92: 93: 94: 95: 96:
97: protected $_joinFields = array();
98:
99: 100: 101: 102: 103: 104:
105: protected $_useAnalyticFunction = false;
106:
107: 108: 109: 110: 111:
112: protected $_castToIntMap = array(
113: 'validate-digits'
114: );
115:
116: 117: 118: 119: 120:
121: public function __construct($resource = null)
122: {
123: parent::__construct();
124: $this->_construct();
125: $this->setConnection($this->getEntity()->getReadConnection());
126: $this->_prepareStaticFields();
127: $this->_initSelect();
128: }
129:
130: 131: 132:
133: protected function _construct()
134: {
135:
136: }
137:
138: 139: 140: 141: 142: 143:
144: public function getTable($table)
145: {
146: return $this->getResource()->getTable($table);
147: }
148:
149: 150: 151: 152: 153:
154: protected function _prepareStaticFields()
155: {
156: foreach ($this->getEntity()->getDefaultAttributes() as $field) {
157: $this->_staticFields[$field] = $field;
158: }
159: return $this;
160: }
161:
162: 163: 164: 165: 166:
167: protected function _initSelect()
168: {
169: $this->getSelect()->from(array('e' => $this->getEntity()->getEntityTable()));
170: if ($this->getEntity()->getTypeId()) {
171: $this->addAttributeToFilter('entity_type_id', $this->getEntity()->getTypeId());
172: }
173: return $this;
174: }
175:
176: 177: 178: 179: 180: 181:
182: protected function _init($model, $entityModel = null)
183: {
184: $this->setItemObjectClass(Mage::getConfig()->getModelClassName($model));
185: if ($entityModel === null) {
186: $entityModel = $model;
187: }
188: $entity = Mage::getResourceSingleton($entityModel);
189: $this->setEntity($entity);
190:
191: return $this;
192: }
193:
194: 195: 196: 197: 198: 199: 200:
201: public function setEntity($entity)
202: {
203: if ($entity instanceof Mage_Eav_Model_Entity_Abstract) {
204: $this->_entity = $entity;
205: } elseif (is_string($entity) || $entity instanceof Mage_Core_Model_Config_Element) {
206: $this->_entity = Mage::getModel('eav/entity')->setType($entity);
207: } else {
208: throw Mage::exception('Mage_Eav', Mage::helper('eav')->__('Invalid entity supplied: %s', print_r($entity, 1)));
209: }
210: return $this;
211: }
212:
213: 214: 215: 216: 217:
218: public function getEntity()
219: {
220: if (empty($this->_entity)) {
221: throw Mage::exception('Mage_Eav', Mage::helper('eav')->__('Entity is not initialized'));
222: }
223: return $this->_entity;
224: }
225:
226: 227: 228: 229: 230:
231: public function getResource()
232: {
233: return $this->getEntity();
234: }
235:
236: 237: 238: 239: 240: 241:
242: public function setObject($object=null)
243: {
244: if (is_object($object)) {
245: $this->setItemObjectClass(get_class($object));
246: } else {
247: $this->setItemObjectClass($object);
248: }
249:
250: return $this;
251: }
252:
253:
254: 255: 256: 257: 258: 259:
260: public function addItem(Varien_Object $object)
261: {
262: if (get_class($object) !== $this->_itemObjectClass) {
263: throw Mage::exception('Mage_Eav', Mage::helper('eav')->__('Attempt to add an invalid object'));
264: }
265: return parent::addItem($object);
266: }
267:
268: 269: 270: 271: 272: 273:
274: public function getAttribute($attributeCode)
275: {
276: if (isset($this->_joinAttributes[$attributeCode])) {
277: return $this->_joinAttributes[$attributeCode]['attribute'];
278: }
279:
280: return $this->getEntity()->getAttribute($attributeCode);
281: }
282:
283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297:
298: public function addAttributeToFilter($attribute, $condition = null, $joinType = 'inner')
299: {
300: if ($attribute === null) {
301: $this->getSelect();
302: return $this;
303: }
304:
305: if (is_numeric($attribute)) {
306: $attribute = $this->getEntity()->getAttribute($attribute)->getAttributeCode();
307: } else if ($attribute instanceof Mage_Eav_Model_Entity_Attribute_Interface) {
308: $attribute = $attribute->getAttributeCode();
309: }
310:
311: if (is_array($attribute)) {
312: $sqlArr = array();
313: foreach ($attribute as $condition) {
314: $sqlArr[] = $this->_getAttributeConditionSql($condition['attribute'], $condition, $joinType);
315: }
316: $conditionSql = '('.implode(') OR (', $sqlArr).')';
317: } else if (is_string($attribute)) {
318: if ($condition === null) {
319: $condition = '';
320: }
321: $conditionSql = $this->_getAttributeConditionSql($attribute, $condition, $joinType);
322: }
323:
324: if (!empty($conditionSql)) {
325: $this->getSelect()->where($conditionSql, null, Varien_Db_Select::TYPE_CONDITION);
326: } else {
327: Mage::throwException('Invalid attribute identifier for filter ('.get_class($attribute).')');
328: }
329:
330: return $this;
331: }
332:
333: 334: 335: 336: 337: 338:
339: public function addFieldToFilter($attribute, $condition = null)
340: {
341: return $this->addAttributeToFilter($attribute, $condition);
342: }
343:
344: 345: 346: 347: 348: 349: 350:
351: public function addAttributeToSort($attribute, $dir = self::SORT_ORDER_ASC)
352: {
353: if (isset($this->_joinFields[$attribute])) {
354: $this->getSelect()->order($this->_getAttributeFieldName($attribute).' '.$dir);
355: return $this;
356: }
357: if (isset($this->_staticFields[$attribute])) {
358: $this->getSelect()->order("e.{$attribute} {$dir}");
359: return $this;
360: }
361: if (isset($this->_joinAttributes[$attribute])) {
362: $attrInstance = $this->_joinAttributes[$attribute]['attribute'];
363: $entityField = $this->_getAttributeTableAlias($attribute) . '.' . $attrInstance->getAttributeCode();
364: } else {
365: $attrInstance = $this->getEntity()->getAttribute($attribute);
366: $entityField = 'e.' . $attribute;
367: }
368:
369: if ($attrInstance) {
370: if ($attrInstance->getBackend()->isStatic()) {
371: $orderExpr = $entityField;
372: } else {
373: $this->_addAttributeJoin($attribute, 'left');
374: if (isset($this->_joinAttributes[$attribute])||isset($this->_joinFields[$attribute])) {
375: $orderExpr = $attribute;
376: } else {
377: $orderExpr = $this->_getAttributeTableAlias($attribute).'.value';
378: }
379: }
380:
381: if (in_array($attrInstance->getFrontendClass(), $this->_castToIntMap)) {
382: $orderExpr = Mage::getResourceHelper('eav')->getCastToIntExpression(
383: $this->_prepareOrderExpression($orderExpr)
384: );
385: }
386:
387: $orderExpr .= ' ' . $dir;
388: $this->getSelect()->order($orderExpr);
389: }
390: return $this;
391: }
392:
393: 394: 395: 396: 397: 398:
399: protected function _prepareOrderExpression($field)
400: {
401: foreach ($this->getSelect()->getPart(Zend_Db_Select::COLUMNS) as $columnEntry) {
402: if ($columnEntry[2] != $field) {
403: continue;
404: }
405: if ($columnEntry[1] instanceof Zend_Db_Expr) {
406: return $columnEntry[1];
407: }
408: }
409: return $field;
410: }
411:
412: 413: 414: 415: 416: 417: 418: 419: 420:
421: public function addAttributeToSelect($attribute, $joinType = false)
422: {
423: if (is_array($attribute)) {
424: Mage::getSingleton('eav/config')->loadCollectionAttributes($this->getEntity()->getType(), $attribute);
425: foreach ($attribute as $a) {
426: $this->addAttributeToSelect($a, $joinType);
427: }
428: return $this;
429: }
430: if ($joinType !== false && !$this->getEntity()->getAttribute($attribute)->isStatic()) {
431: $this->_addAttributeJoin($attribute, $joinType);
432: } elseif ('*' === $attribute) {
433: $entity = clone $this->getEntity();
434: $attributes = $entity
435: ->loadAllAttributes()
436: ->getAttributesByCode();
437: foreach ($attributes as $attrCode=>$attr) {
438: $this->_selectAttributes[$attrCode] = $attr->getId();
439: }
440: } else {
441: if (isset($this->_joinAttributes[$attribute])) {
442: $attrInstance = $this->_joinAttributes[$attribute]['attribute'];
443: } else {
444: $attrInstance = Mage::getSingleton('eav/config')
445: ->getCollectionAttribute($this->getEntity()->getType(), $attribute);
446: }
447: if (empty($attrInstance)) {
448: throw Mage::exception(
449: 'Mage_Eav',
450: Mage::helper('eav')->__('Invalid attribute requested: %s', (string)$attribute)
451: );
452: }
453: $this->_selectAttributes[$attrInstance->getAttributeCode()] = $attrInstance->getId();
454: }
455: return $this;
456: }
457:
458: public function addEntityTypeToSelect($entityType, $prefix)
459: {
460: $this->_selectEntityTypes[$entityType] = array(
461: 'prefix' => $prefix,
462: );
463: return $this;
464: }
465:
466: 467: 468: 469: 470: 471:
472: public function addStaticField($field)
473: {
474: if (!isset($this->_staticFields[$field])) {
475: $this->_staticFields[$field] = $field;
476: }
477: return $this;
478: }
479:
480: 481: 482: 483: 484: 485: 486: 487: 488: 489: 490: 491: 492:
493: public function addExpressionAttributeToSelect($alias, $expression, $attribute)
494: {
495:
496: if (isset($this->_joinFields[$alias])) {
497: throw Mage::exception(
498: 'Mage_Eav',
499: Mage::helper('eav')->__('Joint field or attribute expression with this alias is already declared')
500: );
501: }
502: if (!is_array($attribute)) {
503: $attribute = array($attribute);
504: }
505:
506: $fullExpression = $expression;
507:
508: foreach ($attribute as $attributeItem) {
509: if (isset($this->_staticFields[$attributeItem])) {
510: $attrField = sprintf('e.%s', $attributeItem);
511: } else {
512: $attributeInstance = $this->getAttribute($attributeItem);
513:
514: if ($attributeInstance->getBackend()->isStatic()) {
515: $attrField = 'e.' . $attributeItem;
516: } else {
517: $this->_addAttributeJoin($attributeItem, 'left');
518: $attrField = $this->_getAttributeFieldName($attributeItem);
519: }
520: }
521:
522: $fullExpression = str_replace('{{attribute}}', $attrField, $fullExpression);
523: $fullExpression = str_replace('{{' . $attributeItem . '}}', $attrField, $fullExpression);
524: }
525:
526: $this->getSelect()->columns(array($alias => $fullExpression));
527:
528: $this->_joinFields[$alias] = array(
529: 'table' => false,
530: 'field' => $fullExpression
531: );
532:
533: return $this;
534: }
535:
536:
537: 538: 539: 540: 541:
542: public function groupByAttribute($attribute)
543: {
544: if (is_array($attribute)) {
545: foreach ($attribute as $attributeItem) {
546: $this->groupByAttribute($attributeItem);
547: }
548: } else {
549: if (isset($this->_joinFields[$attribute])) {
550: $this->getSelect()->group($this->_getAttributeFieldName($attribute));
551: return $this;
552: }
553:
554: if (isset($this->_staticFields[$attribute])) {
555: $this->getSelect()->group(sprintf('e.%s', $attribute));
556: return $this;
557: }
558:
559: if (isset($this->_joinAttributes[$attribute])) {
560: $attrInstance = $this->_joinAttributes[$attribute]['attribute'];
561: $entityField = $this->_getAttributeTableAlias($attribute) . '.' . $attrInstance->getAttributeCode();
562: } else {
563: $attrInstance = $this->getEntity()->getAttribute($attribute);
564: $entityField = 'e.' . $attribute;
565: }
566:
567: if ($attrInstance->getBackend()->isStatic()) {
568: $this->getSelect()->group($entityField);
569: } else {
570: $this->_addAttributeJoin($attribute);
571: $this->getSelect()->group($this->_getAttributeTableAlias($attribute).'.value');
572: }
573: }
574:
575: return $this;
576: }
577:
578: 579: 580: 581: 582: 583: 584: 585: 586: 587: 588: 589: 590: 591: 592: 593: 594: 595: 596: 597: 598:
599: public function joinAttribute($alias, $attribute, $bind, $filter=null, $joinType='inner', $storeId=null)
600: {
601:
602: if (isset($this->_joinAttributes[$alias])) {
603: throw Mage::exception(
604: 'Mage_Eav',
605: Mage::helper('eav')->__('Invalid alias, already exists in joint attributes')
606: );
607: }
608:
609:
610: if (is_string($bind)) {
611: $bindAttribute = $this->getAttribute($bind);
612: }
613:
614: if (!$bindAttribute || (!$bindAttribute->isStatic() && !$bindAttribute->getId())) {
615: throw Mage::exception('Mage_Eav', Mage::helper('eav')->__('Invalid foreign key'));
616: }
617:
618:
619: if (is_string($attribute)) {
620: $attrArr = explode('/', $attribute);
621: if (isset($attrArr[1])) {
622: $entity = $attrArr[0];
623: $attribute = $attrArr[1];
624: }
625: }
626:
627:
628: if (empty($entity) && $attribute instanceof Mage_Eav_Model_Entity_Attribute_Abstract) {
629: $entity = $attribute->getEntity();
630: } elseif (is_string($entity)) {
631:
632: if (isset($this->_joinEntities[$entity])) {
633: $entity = $this->_joinEntities[$entity];
634: } else {
635: $entity = Mage::getModel('eav/entity')->setType($attrArr[0]);
636: }
637: }
638: if (!$entity || !$entity->getTypeId()) {
639: throw Mage::exception('Mage_Eav', Mage::helper('eav')->__('Invalid entity type'));
640: }
641:
642:
643: if (!isset($this->_joinEntities[$entity->getType()])) {
644: $this->_joinEntities[$entity->getType()] = $entity;
645: }
646:
647:
648: if (is_string($attribute)) {
649: $attribute = $entity->getAttribute($attribute);
650: }
651: if (!$attribute) {
652: throw Mage::exception('Mage_Eav', Mage::helper('eav')->__('Invalid attribute type'));
653: }
654:
655: if (empty($filter)) {
656: $filter = $entity->getEntityIdField();
657: }
658:
659:
660: $this->_joinAttributes[$alias] = array(
661: 'bind' => $bind,
662: 'bindAttribute' => $bindAttribute,
663: 'attribute' => $attribute,
664: 'filter' => $filter,
665: 'store_id' => $storeId,
666: );
667:
668: $this->_addAttributeJoin($alias, $joinType);
669:
670: return $this;
671: }
672:
673: 674: 675: 676: 677: 678: 679: 680: 681: 682: 683: 684: 685: 686: 687:
688: public function joinField($alias, $table, $field, $bind, $cond=null, $joinType='inner')
689: {
690:
691: if (isset($this->_joinFields[$alias])) {
692: throw Mage::exception(
693: 'Mage_Eav',
694: Mage::helper('eav')->__('Joined field with this alias is already declared')
695: );
696: }
697:
698:
699: if (strpos($table, '/')!==false) {
700: $table = Mage::getSingleton('core/resource')->getTableName($table);
701: }
702: $tableAlias = $this->_getAttributeTableAlias($alias);
703:
704:
705: list($pk, $fk) = explode('=', $bind);
706: $pk = $this->getSelect()->getAdapter()->quoteColumnAs(trim($pk), null);
707: $bindCond = $tableAlias . '.' . trim($pk) . '=' . $this->_getAttributeFieldName(trim($fk));
708:
709:
710: switch ($joinType) {
711: case 'left':
712: $joinMethod = 'joinLeft';
713: break;
714:
715: default:
716: $joinMethod = 'join';
717: }
718: $condArr = array($bindCond);
719:
720:
721: if ($cond !== null) {
722: if (is_array($cond)) {
723: foreach ($cond as $k=>$v) {
724: $condArr[] = $this->_getConditionSql($tableAlias.'.'.$k, $v);
725: }
726: } else {
727: $condArr[] = str_replace('{{table}}', $tableAlias, $cond);
728: }
729: }
730: $cond = '(' . implode(') AND (', $condArr) . ')';
731:
732:
733: $this->getSelect()
734: ->$joinMethod(array($tableAlias => $table), $cond, ($field ? array($alias=>$field) : array()));
735:
736:
737: $this->_joinFields[$alias] = array(
738: 'table' => $tableAlias,
739: 'field' => $field,
740: );
741:
742: return $this;
743: }
744:
745: 746: 747: 748: 749: 750: 751: 752: 753: 754:
755: public function joinTable($table, $bind, $fields = null, $cond = null, $joinType = 'inner')
756: {
757: $tableAlias = null;
758: if (is_array($table)) {
759: list($tableAlias, $tableName) = each($table);
760: } else {
761: $tableName = $table;
762: }
763:
764:
765: if (strpos($tableName, '/') !== false) {
766: $tableName = Mage::getSingleton('core/resource')->getTableName($tableName);
767: }
768: if (empty($tableAlias)) {
769: $tableAlias = $tableName;
770: }
771:
772:
773: if (!$fields) {
774: throw Mage::exception('Mage_Eav', Mage::helper('eav')->__('Invalid joint fields'));
775: }
776: foreach ($fields as $alias=>$field) {
777: if (isset($this->_joinFields[$alias])) {
778: throw Mage::exception(
779: 'Mage_Eav',
780: Mage::helper('eav')->__('A joint field with this alias (%s) is already declared', $alias)
781: );
782: }
783: $this->_joinFields[$alias] = array(
784: 'table' => $tableAlias,
785: 'field' => $field,
786: );
787: }
788:
789:
790: list($pk, $fk) = explode('=', $bind);
791: $bindCond = $tableAlias . '.' . $pk . '=' . $this->_getAttributeFieldName($fk);
792:
793:
794: switch ($joinType) {
795: case 'left':
796: $joinMethod = 'joinLeft';
797: break;
798:
799: default:
800: $joinMethod = 'join';
801: }
802: $condArr = array($bindCond);
803:
804:
805: if ($cond !== null) {
806: if (is_array($cond)) {
807: foreach ($cond as $k => $v) {
808: $condArr[] = $this->_getConditionSql($tableAlias.'.'.$k, $v);
809: }
810: } else {
811: $condArr[] = str_replace('{{table}}', $tableAlias, $cond);
812: }
813: }
814: $cond = '('.implode(') AND (', $condArr).')';
815:
816:
817: $this->getSelect()->$joinMethod(array($tableAlias => $tableName), $cond, $fields);
818:
819: return $this;
820: }
821:
822: 823: 824: 825: 826: 827:
828: public function removeAttributeToSelect($attribute = null)
829: {
830: if ($attribute === null) {
831: $this->_selectAttributes = array();
832: } else {
833: unset($this->_selectAttributes[$attribute]);
834: }
835: return $this;
836: }
837:
838: 839: 840: 841: 842: 843: 844:
845: public function setPage($pageNum, $pageSize)
846: {
847: $this->setCurPage($pageNum)
848: ->setPageSize($pageSize);
849: return $this;
850: }
851:
852: 853: 854: 855: 856:
857: public function load($printQuery = false, $logQuery = false)
858: {
859: if ($this->isLoaded()) {
860: return $this;
861: }
862: Varien_Profiler::start('__EAV_COLLECTION_BEFORE_LOAD__');
863: Mage::dispatchEvent('eav_collection_abstract_load_before', array('collection' => $this));
864: $this->_beforeLoad();
865: Varien_Profiler::stop('__EAV_COLLECTION_BEFORE_LOAD__');
866:
867: $this->_renderFilters();
868: $this->_renderOrders();
869:
870: Varien_Profiler::start('__EAV_COLLECTION_LOAD_ENT__');
871: $this->_loadEntities($printQuery, $logQuery);
872: Varien_Profiler::stop('__EAV_COLLECTION_LOAD_ENT__');
873: Varien_Profiler::start('__EAV_COLLECTION_LOAD_ATTR__');
874: $this->_loadAttributes($printQuery, $logQuery);
875: Varien_Profiler::stop('__EAV_COLLECTION_LOAD_ATTR__');
876:
877: Varien_Profiler::start('__EAV_COLLECTION_ORIG_DATA__');
878: foreach ($this->_items as $item) {
879: $item->setOrigData();
880: }
881: Varien_Profiler::stop('__EAV_COLLECTION_ORIG_DATA__');
882:
883: $this->_setIsLoaded();
884: Varien_Profiler::start('__EAV_COLLECTION_AFTER_LOAD__');
885: $this->_afterLoad();
886: Varien_Profiler::stop('__EAV_COLLECTION_AFTER_LOAD__');
887: return $this;
888: }
889:
890: 891: 892: 893: 894:
895: protected function _getAllIdsSelect($limit = null, $offset = null)
896: {
897: $idsSelect = clone $this->getSelect();
898: $idsSelect->reset(Zend_Db_Select::ORDER);
899: $idsSelect->reset(Zend_Db_Select::LIMIT_COUNT);
900: $idsSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
901: $idsSelect->reset(Zend_Db_Select::COLUMNS);
902: $idsSelect->columns('e.' . $this->getEntity()->getIdFieldName());
903: $idsSelect->limit($limit, $offset);
904:
905: return $idsSelect;
906: }
907:
908: 909: 910: 911: 912:
913: public function getAllIds($limit = null, $offset = null)
914: {
915: return $this->getConnection()->fetchCol($this->_getAllIdsSelect($limit, $offset), $this->_bindParams);
916: }
917:
918: 919: 920: 921: 922:
923: public function getAllIdsSql()
924: {
925: $idsSelect = clone $this->getSelect();
926: $idsSelect->reset(Zend_Db_Select::ORDER);
927: $idsSelect->reset(Zend_Db_Select::LIMIT_COUNT);
928: $idsSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
929: $idsSelect->reset(Zend_Db_Select::COLUMNS);
930: $idsSelect->reset(Zend_Db_Select::GROUP);
931: $idsSelect->columns('e.'.$this->getEntity()->getIdFieldName());
932:
933: return $idsSelect;
934: }
935:
936: 937: 938: 939: 940:
941: public function save()
942: {
943: foreach ($this->getItems() as $item) {
944: $item->save();
945: }
946: return $this;
947: }
948:
949:
950: 951: 952: 953: 954:
955: public function delete()
956: {
957: foreach ($this->getItems() as $k=>$item) {
958: $this->getEntity()->delete($item);
959: unset($this->_items[$k]);
960: }
961: return $this;
962: }
963:
964: 965: 966: 967: 968: 969: 970: 971:
972: public function importFromArray($arr)
973: {
974: $entityIdField = $this->getEntity()->getEntityIdField();
975: foreach ($arr as $row) {
976: $entityId = $row[$entityIdField];
977: if (!isset($this->_items[$entityId])) {
978: $this->_items[$entityId] = $this->getNewEmptyItem();
979: $this->_items[$entityId]->setData($row);
980: } else {
981: $this->_items[$entityId]->addData($row);
982: }
983: }
984: return $this;
985: }
986:
987: 988: 989: 990: 991:
992: public function exportToArray()
993: {
994: $result = array();
995: $entityIdField = $this->getEntity()->getEntityIdField();
996: foreach ($this->getItems() as $item) {
997: $result[$item->getData($entityIdField)] = $item->getData();
998: }
999: return $result;
1000: }
1001:
1002: 1003: 1004: 1005: 1006:
1007: public function getRowIdFieldName()
1008: {
1009: if ($this->_idFieldName === null) {
1010: $this->_setIdFieldName($this->getEntity()->getIdFieldName());
1011: }
1012: return $this->getIdFieldName();
1013: }
1014:
1015: 1016: 1017: 1018: 1019:
1020: public function setRowIdFieldName($fieldName)
1021: {
1022: return $this->_setIdFieldName($fieldName);
1023: }
1024:
1025: 1026: 1027: 1028: 1029: 1030:
1031: public function _loadEntities($printQuery = false, $logQuery = false)
1032: {
1033: $entity = $this->getEntity();
1034:
1035: if ($this->_pageSize) {
1036: $this->getSelect()->limitPage($this->getCurPage(), $this->_pageSize);
1037: }
1038:
1039: $this->printLogQuery($printQuery, $logQuery);
1040:
1041: try {
1042: 1043: 1044: 1045:
1046: $query = $this->_prepareSelect($this->getSelect());
1047: $rows = $this->_fetchAll($query);
1048: } catch (Exception $e) {
1049: Mage::printException($e, $query);
1050: $this->printLogQuery(true, true, $query);
1051: throw $e;
1052: }
1053:
1054: foreach ($rows as $v) {
1055: $object = $this->getNewEmptyItem()
1056: ->setData($v);
1057: $this->addItem($object);
1058: if (isset($this->_itemsById[$object->getId()])) {
1059: $this->_itemsById[$object->getId()][] = $object;
1060: } else {
1061: $this->_itemsById[$object->getId()] = array($object);
1062: }
1063: }
1064:
1065: return $this;
1066: }
1067:
1068: 1069: 1070: 1071: 1072: 1073:
1074: public function _loadAttributes($printQuery = false, $logQuery = false)
1075: {
1076: if (empty($this->_items) || empty($this->_itemsById) || empty($this->_selectAttributes)) {
1077: return $this;
1078: }
1079:
1080: $entity = $this->getEntity();
1081:
1082: $tableAttributes = array();
1083: $attributeTypes = array();
1084: foreach ($this->_selectAttributes as $attributeCode => $attributeId) {
1085: if (!$attributeId) {
1086: continue;
1087: }
1088: $attribute = Mage::getSingleton('eav/config')->getCollectionAttribute($entity->getType(), $attributeCode);
1089: if ($attribute && !$attribute->isStatic()) {
1090: $tableAttributes[$attribute->getBackendTable()][] = $attributeId;
1091: if (!isset($attributeTypes[$attribute->getBackendTable()])) {
1092: $attributeTypes[$attribute->getBackendTable()] = $attribute->getBackendType();
1093: }
1094: }
1095: }
1096:
1097: $selects = array();
1098: foreach ($tableAttributes as $table=>$attributes) {
1099: $select = $this->_getLoadAttributesSelect($table, $attributes);
1100: $selects[$attributeTypes[$table]][] = $this->_addLoadAttributesSelectValues(
1101: $select,
1102: $table,
1103: $attributeTypes[$table]
1104: );
1105: }
1106: $selectGroups = Mage::getResourceHelper('eav')->getLoadAttributesSelectGroups($selects);
1107: foreach ($selectGroups as $selects) {
1108: if (!empty($selects)) {
1109: try {
1110: $select = implode(' UNION ALL ', $selects);
1111: $values = $this->getConnection()->fetchAll($select);
1112: } catch (Exception $e) {
1113: Mage::printException($e, $select);
1114: $this->printLogQuery(true, true, $select);
1115: throw $e;
1116: }
1117:
1118: foreach ($values as $value) {
1119: $this->_setItemAttributeValue($value);
1120: }
1121: }
1122: }
1123:
1124: return $this;
1125: }
1126:
1127: 1128: 1129: 1130: 1131: 1132:
1133: protected function _getLoadAttributesSelect($table, $attributeIds = array())
1134: {
1135: if (empty($attributeIds)) {
1136: $attributeIds = $this->_selectAttributes;
1137: }
1138: $helper = Mage::getResourceHelper('eav');
1139: $entityIdField = $this->getEntity()->getEntityIdField();
1140: $select = $this->getConnection()->select()
1141: ->from($table, array($entityIdField, 'attribute_id'))
1142: ->where('entity_type_id =?', $this->getEntity()->getTypeId())
1143: ->where("$entityIdField IN (?)", array_keys($this->_itemsById))
1144: ->where('attribute_id IN (?)', $attributeIds);
1145: return $select;
1146: }
1147:
1148: 1149: 1150: 1151: 1152: 1153:
1154: protected function _addLoadAttributesSelectValues($select, $table, $type)
1155: {
1156: $helper = Mage::getResourceHelper('eav');
1157: $select->columns(array(
1158: 'value' => $helper->prepareEavAttributeValue($table. '.value', $type),
1159: ));
1160:
1161: return $select;
1162: }
1163:
1164: 1165: 1166: 1167: 1168: 1169: 1170: 1171: 1172:
1173: protected function _setItemAttributeValue($valueInfo)
1174: {
1175: $entityIdField = $this->getEntity()->getEntityIdField();
1176: $entityId = $valueInfo[$entityIdField];
1177: if (!isset($this->_itemsById[$entityId])) {
1178: throw Mage::exception('Mage_Eav',
1179: Mage::helper('eav')->__('Data integrity: No header row found for attribute')
1180: );
1181: }
1182: $attributeCode = array_search($valueInfo['attribute_id'], $this->_selectAttributes);
1183: if (!$attributeCode) {
1184: $attribute = Mage::getSingleton('eav/config')->getCollectionAttribute(
1185: $this->getEntity()->getType(),
1186: $valueInfo['attribute_id']
1187: );
1188: $attributeCode = $attribute->getAttributeCode();
1189: }
1190:
1191: foreach ($this->_itemsById[$entityId] as $object) {
1192: $object->setData($attributeCode, $valueInfo['value']);
1193: }
1194:
1195: return $this;
1196: }
1197:
1198: 1199: 1200: 1201: 1202: 1203:
1204: protected function _getAttributeTableAlias($attributeCode)
1205: {
1206: return 'at_' . $attributeCode;
1207: }
1208:
1209: 1210: 1211: 1212: 1213: 1214:
1215: protected function _getAttributeFieldName($attributeCode)
1216: {
1217: $attributeCode = trim($attributeCode);
1218: if (isset($this->_joinAttributes[$attributeCode]['condition_alias'])) {
1219: return $this->_joinAttributes[$attributeCode]['condition_alias'];
1220: }
1221: if (isset($this->_staticFields[$attributeCode])) {
1222: return sprintf('e.%s', $attributeCode);
1223: }
1224: if (isset($this->_joinFields[$attributeCode])) {
1225: $attr = $this->_joinFields[$attributeCode];
1226: return $attr['table'] ? $attr['table'] . '.' . $attr['field'] : $attr['field'];
1227: }
1228:
1229: $attribute = $this->getAttribute($attributeCode);
1230: if (!$attribute) {
1231: throw Mage::exception('Mage_Eav', Mage::helper('eav')->__('Invalid attribute name: %s', $attributeCode));
1232: }
1233:
1234: if ($attribute->isStatic()) {
1235: if (isset($this->_joinAttributes[$attributeCode])) {
1236: $fieldName = $this->_getAttributeTableAlias($attributeCode) . '.' . $attributeCode;
1237: } else {
1238: $fieldName = 'e.' . $attributeCode;
1239: }
1240: } else {
1241: $fieldName = $this->_getAttributeTableAlias($attributeCode) . '.value';
1242: }
1243:
1244: return $fieldName;
1245: }
1246:
1247: 1248: 1249: 1250: 1251: 1252: 1253: 1254:
1255: protected function _addAttributeJoin($attributeCode, $joinType = 'inner')
1256: {
1257: if (!empty($this->_filterAttributes[$attributeCode])) {
1258: return $this;
1259: }
1260:
1261: $adapter = $this->getConnection();
1262:
1263: $attrTable = $this->_getAttributeTableAlias($attributeCode);
1264: if (isset($this->_joinAttributes[$attributeCode])) {
1265: $attribute = $this->_joinAttributes[$attributeCode]['attribute'];
1266: $entity = $attribute->getEntity();
1267: $entityIdField = $entity->getEntityIdField();
1268: $fkName = $this->_joinAttributes[$attributeCode]['bind'];
1269: $fkAttribute = $this->_joinAttributes[$attributeCode]['bindAttribute'];
1270: $fkTable = $this->_getAttributeTableAlias($fkName);
1271:
1272: if ($fkAttribute->getBackend()->isStatic()) {
1273: if (isset($this->_joinAttributes[$fkName])) {
1274: $fk = $fkTable . '.' . $fkAttribute->getAttributeCode();
1275: } else {
1276: $fk = 'e.' . $fkAttribute->getAttributeCode();
1277: }
1278: } else {
1279: $this->_addAttributeJoin($fkAttribute->getAttributeCode(), $joinType);
1280: $fk = $fkTable . '.value';
1281: }
1282: $pk = $attrTable . '.' . $this->_joinAttributes[$attributeCode]['filter'];
1283: } else {
1284: $entity = $this->getEntity();
1285: $entityIdField = $entity->getEntityIdField();
1286: $attribute = $entity->getAttribute($attributeCode);
1287: $fk = 'e.' . $entityIdField;
1288: $pk = $attrTable . '.' . $entityIdField;
1289: }
1290:
1291: if (!$attribute) {
1292: throw Mage::exception('Mage_Eav', Mage::helper('eav')->__('Invalid attribute name: %s', $attributeCode));
1293: }
1294:
1295: if ($attribute->getBackend()->isStatic()) {
1296: $attrFieldName = $attrTable . '.' . $attribute->getAttributeCode();
1297: } else {
1298: $attrFieldName = $attrTable . '.value';
1299: }
1300:
1301: $fk = $adapter->quoteColumnAs($fk, null);
1302: $pk = $adapter->quoteColumnAs($pk, null);
1303:
1304: $condArr = array("$pk = $fk");
1305: if (!$attribute->getBackend()->isStatic()) {
1306: $condArr[] = $this->getConnection()->quoteInto(
1307: $adapter->quoteColumnAs("$attrTable.attribute_id", null) . ' = ?', $attribute->getId());
1308: }
1309:
1310: 1311: 1312:
1313: $joinMethod = ($joinType == 'left') ? 'joinLeft' : 'join';
1314:
1315: $this->_joinAttributeToSelect($joinMethod, $attribute, $attrTable, $condArr, $attributeCode, $attrFieldName);
1316:
1317: $this->removeAttributeToSelect($attributeCode);
1318: $this->_filterAttributes[$attributeCode] = $attribute->getId();
1319:
1320: 1321: 1322:
1323: $this->_joinFields[$attributeCode] = array(
1324: 'table' => '',
1325: 'field' => $attrFieldName,
1326: );
1327:
1328: return $this;
1329: }
1330:
1331: 1332: 1333: 1334: 1335: 1336: 1337: 1338: 1339: 1340: 1341:
1342: protected function _joinAttributeToSelect($method, $attribute, $tableAlias, $condition, $fieldCode, $fieldAlias)
1343: {
1344: $this->getSelect()->$method(
1345: array($tableAlias => $attribute->getBackend()->getTable()),
1346: '('.implode(') AND (', $condition).')',
1347: array($fieldCode => $fieldAlias)
1348: );
1349: return $this;
1350: }
1351:
1352: 1353: 1354: 1355: 1356: 1357: 1358: 1359: 1360:
1361: protected function _getAttributeConditionSql($attribute, $condition, $joinType = 'inner')
1362: {
1363: if (isset($this->_joinFields[$attribute])) {
1364:
1365: return $this->_getConditionSql($this->_getAttributeFieldName($attribute), $condition);
1366: }
1367: if (isset($this->_staticFields[$attribute])) {
1368: return $this->_getConditionSql($this->getConnection()->quoteIdentifier('e.' . $attribute), $condition);
1369: }
1370:
1371: if (isset($this->_joinAttributes[$attribute])) {
1372: $entity = $this->getAttribute($attribute)->getEntity();
1373: $entityTable = $entity->getEntityTable();
1374: } else {
1375: $entity = $this->getEntity();
1376: $entityTable = 'e';
1377: }
1378:
1379: if ($entity->isAttributeStatic($attribute)) {
1380: $conditionSql = $this->_getConditionSql(
1381: $this->getConnection()->quoteIdentifier('e.' . $attribute),
1382: $condition
1383: );
1384: } else {
1385: $this->_addAttributeJoin($attribute, $joinType);
1386: if (isset($this->_joinAttributes[$attribute]['condition_alias'])) {
1387: $field = $this->_joinAttributes[$attribute]['condition_alias'];
1388: } else {
1389: $field = $this->_getAttributeTableAlias($attribute) . '.value';
1390:
1391: }
1392:
1393: $conditionSql = $this->_getConditionSql($field, $condition);
1394: }
1395:
1396: return $conditionSql;
1397: }
1398:
1399: 1400: 1401: 1402: 1403: 1404: 1405: 1406: 1407:
1408: public function setOrder($attribute, $dir = self::SORT_ORDER_ASC)
1409: {
1410: if (is_array($attribute)) {
1411: foreach ($attribute as $attr) {
1412: parent::setOrder($attr, $dir);
1413: }
1414: }
1415: return parent::setOrder($attribute, $dir);
1416: }
1417:
1418: 1419: 1420: 1421: 1422: 1423:
1424: public function toArray($arrAttributes = array())
1425: {
1426: $arr = array();
1427: foreach ($this->_items as $k => $item) {
1428: $arr[$k] = $item->toArray($arrAttributes);
1429: }
1430: return $arr;
1431: }
1432:
1433: 1434: 1435: 1436: 1437:
1438: protected function _renderOrders()
1439: {
1440: if (!$this->_isOrdersRendered) {
1441: foreach ($this->_orders as $attribute => $direction) {
1442: $this->addAttributeToSort($attribute, $direction);
1443: }
1444: $this->_isOrdersRendered = true;
1445: }
1446: return $this;
1447: }
1448:
1449: 1450: 1451: 1452: 1453:
1454: protected function _afterLoad()
1455: {
1456: return $this;
1457: }
1458:
1459: 1460: 1461: 1462: 1463:
1464: protected function _reset()
1465: {
1466: parent::_reset();
1467:
1468: $this->_selectEntityTypes = array();
1469: $this->_selectAttributes = array();
1470: $this->_filterAttributes = array();
1471: $this->_joinEntities = array();
1472: $this->_joinAttributes = array();
1473: $this->_joinFields = array();
1474:
1475: return $this;
1476: }
1477:
1478: 1479: 1480: 1481: 1482:
1483: public function getLoadedIds()
1484: {
1485: return array_keys($this->_items);
1486: }
1487:
1488: 1489: 1490: 1491: 1492: 1493:
1494: public function _prepareSelect(Varien_Db_Select $select)
1495: {
1496: if ($this->_useAnalyticFunction) {
1497: $helper = Mage::getResourceHelper('core');
1498: return $helper->getQueryUsingAnalyticFunction($select);
1499: }
1500:
1501: return (string)$select;
1502: }
1503: }
1504: