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: class Mage_Catalog_Model_Resource_Product_Collection extends Mage_Catalog_Model_Resource_Collection_Abstract
36: {
37: 38: 39:
40: const INDEX_TABLE_ALIAS = 'price_index';
41:
42: 43: 44:
45: const MAIN_TABLE_ALIAS = 'e';
46:
47: 48: 49: 50: 51:
52: protected $_flatEnabled = array();
53:
54: 55: 56: 57: 58:
59: protected $_productWebsiteTable;
60:
61: 62: 63: 64: 65:
66: protected $_productCategoryTable;
67:
68: 69: 70: 71: 72:
73: protected $_addUrlRewrite = false;
74:
75: 76: 77: 78: 79:
80: protected $_urlRewriteCategory = '';
81:
82: 83: 84: 85: 86:
87: protected $_addMinimalPrice = false;
88:
89: 90: 91: 92: 93:
94: protected $_addFinalPrice = false;
95:
96: 97: 98: 99: 100:
101: protected $_allIdsCache = null;
102:
103: 104: 105: 106: 107:
108: protected $_addTaxPercents = false;
109:
110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124:
125: protected $_productLimitationFilters = array();
126:
127: 128: 129: 130: 131:
132: protected $_productCountSelect = null;
133:
134: 135: 136: 137: 138:
139: protected $_isWebsiteFilter = false;
140:
141: 142: 143: 144: 145:
146: protected $_priceDataFieldFilters = array();
147:
148: 149: 150: 151: 152:
153: protected $_map = array('fields' => array(
154: 'price' => 'price_index.price',
155: 'final_price' => 'price_index.final_price',
156: 'min_price' => 'price_index.min_price',
157: 'max_price' => 'price_index.max_price',
158: 'tier_price' => 'price_index.tier_price',
159: 'special_price' => 'price_index.special_price',
160: ));
161:
162: 163: 164: 165: 166:
167: protected $_priceExpression;
168:
169: 170: 171: 172: 173:
174: protected $_additionalPriceExpression;
175:
176: 177: 178: 179: 180:
181: protected $_maxPrice;
182:
183: 184: 185: 186: 187:
188: protected $_minPrice;
189:
190: 191: 192: 193: 194:
195: protected $_priceStandardDeviation;
196:
197: 198: 199: 200: 201:
202: protected $_pricesCount = null;
203:
204: 205: 206: 207: 208:
209: protected $_catalogPreparePriceSelect = null;
210:
211: 212: 213: 214: 215:
216: public function getCatalogPreparedSelect()
217: {
218: return $this->_catalogPreparePriceSelect;
219: }
220:
221: 222: 223: 224: 225: 226:
227: protected function _preparePriceExpressionParameters($select)
228: {
229:
230: $response = new Varien_Object();
231: $response->setAdditionalCalculations(array());
232: $tableAliases = array_keys($select->getPart(Zend_Db_Select::FROM));
233: if (in_array(self::INDEX_TABLE_ALIAS, $tableAliases)) {
234: $table = self::INDEX_TABLE_ALIAS;
235: } else {
236: $table = reset($tableAliases);
237: }
238:
239:
240: $eventArgs = array(
241: 'select' => $select,
242: 'table' => $table,
243: 'store_id' => $this->getStoreId(),
244: 'response_object' => $response
245: );
246:
247: Mage::dispatchEvent('catalog_prepare_price_select', $eventArgs);
248:
249: $additional = join('', $response->getAdditionalCalculations());
250: $this->_priceExpression = $table . '.min_price';
251: $this->_additionalPriceExpression = $additional;
252: $this->_catalogPreparePriceSelect = clone $select;
253:
254: return $this;
255: }
256:
257: 258: 259: 260: 261: 262:
263: public function getPriceExpression($select)
264: {
265: if (is_null($this->_priceExpression)) {
266: $this->_preparePriceExpressionParameters($select);
267: }
268: return $this->_priceExpression;
269: }
270:
271: 272: 273: 274: 275: 276:
277: public function getAdditionalPriceExpression($select)
278: {
279: if (is_null($this->_additionalPriceExpression)) {
280: $this->_preparePriceExpressionParameters($select);
281: }
282: return $this->_additionalPriceExpression;
283: }
284:
285: 286: 287: 288: 289:
290: public function getCurrencyRate()
291: {
292: return Mage::app()->getStore($this->getStoreId())->getCurrentCurrencyRate();
293: }
294:
295: 296: 297: 298: 299:
300: public function getFlatHelper()
301: {
302: return Mage::helper('catalog/product_flat');
303: }
304:
305: 306: 307: 308: 309: 310:
311: public function isEnabledFlat()
312: {
313: if (Mage::app()->getStore()->isAdmin()) {
314: return false;
315: }
316: if (!isset($this->_flatEnabled[$this->getStoreId()])) {
317: $this->_flatEnabled[$this->getStoreId()] = $this->getFlatHelper()
318: ->isEnabled($this->getStoreId());
319: }
320: return $this->_flatEnabled[$this->getStoreId()];
321: }
322:
323: 324: 325: 326:
327: protected function _construct()
328: {
329: if ($this->isEnabledFlat()) {
330: $this->_init('catalog/product', 'catalog/product_flat');
331: }
332: else {
333: $this->_init('catalog/product');
334: }
335: $this->_initTables();
336: }
337:
338: 339: 340: 341:
342: protected function _initTables()
343: {
344: $this->_productWebsiteTable = $this->getResource()->getTable('catalog/product_website');
345: $this->_productCategoryTable= $this->getResource()->getTable('catalog/category_product');
346: }
347:
348: 349: 350: 351: 352: 353: 354:
355: protected function _init($model, $entityModel = null)
356: {
357: if ($this->isEnabledFlat()) {
358: $entityModel = 'catalog/product_flat';
359: }
360:
361: return parent::_init($model, $entityModel);
362: }
363:
364: 365: 366: 367: 368:
369: protected function _prepareStaticFields()
370: {
371: if ($this->isEnabledFlat()) {
372: return $this;
373: }
374: return parent::_prepareStaticFields();
375: }
376:
377: 378: 379: 380: 381: 382:
383: public function getNewEmptyItem()
384: {
385: $object = parent::getNewEmptyItem();
386: if ($this->isEnabledFlat()) {
387: $object->setIdFieldName($this->getEntity()->getIdFieldName());
388: }
389: return $object;
390: }
391:
392: 393: 394: 395: 396: 397:
398: public function setEntity($entity)
399: {
400: if ($this->isEnabledFlat() && ($entity instanceof Mage_Core_Model_Resource_Db_Abstract)) {
401: $this->_entity = $entity;
402: return $this;
403: }
404: return parent::setEntity($entity);
405: }
406:
407: 408: 409: 410: 411: 412:
413: public function setStore($store)
414: {
415: parent::setStore($store);
416: if ($this->isEnabledFlat()) {
417: $this->getEntity()->setStoreId($this->getStoreId());
418: }
419: return $this;
420: }
421:
422: 423: 424: 425: 426: 427: 428:
429: protected function _initSelect()
430: {
431: if ($this->isEnabledFlat()) {
432: $this->getSelect()
433: ->from(array(self::MAIN_TABLE_ALIAS => $this->getEntity()->getFlatTableName()), null)
434: ->columns(array('status' => new Zend_Db_Expr(Mage_Catalog_Model_Product_Status::STATUS_ENABLED)));
435: $this->addAttributeToSelect(array('entity_id', 'type_id', 'attribute_set_id'));
436: if ($this->getFlatHelper()->isAddChildData()) {
437: $this->getSelect()
438: ->where('e.is_child=?', 0);
439: $this->addAttributeToSelect(array('child_id', 'is_child'));
440: }
441: } else {
442: $this->getSelect()->from(array(self::MAIN_TABLE_ALIAS => $this->getEntity()->getEntityTable()));
443: }
444: return $this;
445: }
446:
447: 448: 449: 450: 451: 452: 453:
454: public function _loadAttributes($printQuery = false, $logQuery = false)
455: {
456: if ($this->isEnabledFlat()) {
457: return $this;
458: }
459: return parent::_loadAttributes($printQuery, $logQuery);
460: }
461:
462: 463: 464: 465: 466: 467: 468: 469:
470: public function addAttributeToSelect($attribute, $joinType = false)
471: {
472: if ($this->isEnabledFlat()) {
473: if (!is_array($attribute)) {
474: $attribute = array($attribute);
475: }
476: foreach ($attribute as $attributeCode) {
477: if ($attributeCode == '*') {
478: foreach ($this->getEntity()->getAllTableColumns() as $column) {
479: $this->getSelect()->columns('e.' . $column);
480: $this->_selectAttributes[$column] = $column;
481: $this->_staticFields[$column] = $column;
482: }
483: } else {
484: $columns = $this->getEntity()->getAttributeForSelect($attributeCode);
485: if ($columns) {
486: foreach ($columns as $alias => $column) {
487: $this->getSelect()->columns(array($alias => 'e.' . $column));
488: $this->_selectAttributes[$column] = $column;
489: $this->_staticFields[$column] = $column;
490: }
491: }
492: }
493: }
494: return $this;
495: }
496: return parent::addAttributeToSelect($attribute, $joinType);
497: }
498:
499: 500: 501: 502: 503:
504: protected function _beforeLoad()
505: {
506: Mage::dispatchEvent('catalog_product_collection_load_before', array('collection' => $this));
507:
508: return parent::_beforeLoad();
509: }
510:
511: 512: 513: 514: 515: 516:
517: protected function _afterLoad()
518: {
519: if ($this->_addUrlRewrite) {
520: $this->_addUrlRewrite($this->_urlRewriteCategory);
521: }
522:
523: $this->_prepareUrlDataObject();
524:
525: if (count($this) > 0) {
526: Mage::dispatchEvent('catalog_product_collection_load_after', array('collection' => $this));
527: }
528:
529: foreach ($this as $product) {
530: if ($product->isRecurring() && $profile = $product->getRecurringProfile()) {
531: $product->setRecurringProfile(unserialize($profile));
532: }
533: }
534:
535: return $this;
536: }
537:
538: 539: 540: 541: 542:
543: protected function _prepareUrlDataObject()
544: {
545: $objects = array();
546:
547: foreach ($this->_items as $item) {
548: if ($this->getFlag('do_not_use_category_id')) {
549: $item->setDoNotUseCategoryId(true);
550: }
551: if (!$item->isVisibleInSiteVisibility() && $item->getItemStoreId()) {
552: $objects[$item->getEntityId()] = $item->getItemStoreId();
553: }
554: }
555:
556: if ($objects && $this->hasFlag('url_data_object')) {
557: $objects = Mage::getResourceSingleton('catalog/url')
558: ->getRewriteByProductStore($objects);
559: foreach ($this->_items as $item) {
560: if (isset($objects[$item->getEntityId()])) {
561: $object = new Varien_Object($objects[$item->getEntityId()]);
562: $item->setUrlDataObject($object);
563: }
564: }
565: }
566:
567: return $this;
568: }
569:
570: 571: 572: 573: 574: 575: 576:
577: public function addIdFilter($productId, $exclude = false)
578: {
579: if (empty($productId)) {
580: $this->_setIsLoaded(true);
581: return $this;
582: }
583: if (is_array($productId)) {
584: if (!empty($productId)) {
585: if ($exclude) {
586: $condition = array('nin' => $productId);
587: } else {
588: $condition = array('in' => $productId);
589: }
590: } else {
591: $condition = '';
592: }
593: } else {
594: if ($exclude) {
595: $condition = array('neq' => $productId);
596: } else {
597: $condition = $productId;
598: }
599: }
600: $this->addFieldToFilter('entity_id', $condition);
601: return $this;
602: }
603:
604: 605: 606: 607: 608: 609:
610: public function addWebsiteNamesToResult()
611: {
612: $productWebsites = array();
613: foreach ($this as $product) {
614: $productWebsites[$product->getId()] = array();
615: }
616:
617: if (!empty($productWebsites)) {
618: $select = $this->getConnection()->select()
619: ->from(array('product_website' => $this->_productWebsiteTable))
620: ->join(
621: array('website' => $this->getResource()->getTable('core/website')),
622: 'website.website_id = product_website.website_id',
623: array('name'))
624: ->where('product_website.product_id IN (?)', array_keys($productWebsites))
625: ->where('website.website_id > ?', 0);
626:
627: $data = $this->getConnection()->fetchAll($select);
628: foreach ($data as $row) {
629: $productWebsites[$row['product_id']][] = $row['website_id'];
630: }
631: }
632:
633: foreach ($this as $product) {
634: if (isset($productWebsites[$product->getId()])) {
635: $product->setData('websites', $productWebsites[$product->getId()]);
636: }
637: }
638: return $this;
639: }
640:
641: 642: 643: 644: 645: 646: 647:
648: public function addStoreFilter($store = null)
649: {
650: if ($store === null) {
651: $store = $this->getStoreId();
652: }
653: $store = Mage::app()->getStore($store);
654:
655: if (!$store->isAdmin()) {
656: $this->setStoreId($store);
657: $this->_productLimitationFilters['store_id'] = $store->getId();
658: $this->_applyProductLimitations();
659: }
660:
661: return $this;
662: }
663:
664: 665: 666: 667: 668: 669:
670: public function addWebsiteFilter($websites = null)
671: {
672: if (!is_array($websites)) {
673: $websites = array(Mage::app()->getWebsite($websites)->getId());
674: }
675:
676: $this->_productLimitationFilters['website_ids'] = $websites;
677: $this->_applyProductLimitations();
678:
679: return $this;
680: }
681:
682: 683: 684: 685: 686:
687: public function getLimitationFilters()
688: {
689: return $this->_productLimitationFilters;
690: }
691:
692: 693: 694: 695: 696: 697:
698: public function addCategoryFilter(Mage_Catalog_Model_Category $category)
699: {
700: $this->_productLimitationFilters['category_id'] = $category->getId();
701: if ($category->getIsAnchor()) {
702: unset($this->_productLimitationFilters['category_is_anchor']);
703: } else {
704: $this->_productLimitationFilters['category_is_anchor'] = 1;
705: }
706:
707: if ($this->getStoreId() == Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID) {
708: $this->_applyZeroStoreProductLimitations();
709: } else {
710: $this->_applyProductLimitations();
711: }
712:
713: return $this;
714: }
715:
716: 717: 718: 719: 720:
721: public function joinMinimalPrice()
722: {
723: $this->addAttributeToSelect('price')
724: ->addAttributeToSelect('minimal_price');
725: return $this;
726: }
727:
728: 729: 730: 731: 732: 733:
734: public function getMaxAttributeValue($attribute)
735: {
736: $select = clone $this->getSelect();
737: $attribute = $this->getEntity()->getAttribute($attribute);
738: $attributeCode = $attribute->getAttributeCode();
739: $tableAlias = $attributeCode . '_max_value';
740: $fieldAlias = 'max_' . $attributeCode;
741: $condition = 'e.entity_id = ' . $tableAlias . '.entity_id
742: AND '.$this->_getConditionSql($tableAlias . '.attribute_id', $attribute->getId());
743:
744: $select->join(
745: array($tableAlias => $attribute->getBackend()->getTable()),
746: $condition,
747: array($fieldAlias => new Zend_Db_Expr('MAX('.$tableAlias.'.value)'))
748: )
749: ->group('e.entity_type_id');
750:
751: $data = $this->getConnection()->fetchRow($select);
752: if (isset($data[$fieldAlias])) {
753: return $data[$fieldAlias];
754: }
755:
756: return null;
757: }
758:
759: 760: 761: 762: 763: 764: 765:
766: public function getAttributeValueCountByRange($attribute, $range)
767: {
768: $select = clone $this->getSelect();
769: $attribute = $this->getEntity()->getAttribute($attribute);
770: $attributeCode = $attribute->getAttributeCode();
771: $tableAlias = $attributeCode . '_range_count_value';
772:
773: $condition = 'e.entity_id = ' . $tableAlias . '.entity_id
774: AND ' . $this->_getConditionSql($tableAlias . '.attribute_id', $attribute->getId());
775:
776: $select->reset(Zend_Db_Select::GROUP);
777: $select->join(
778: array($tableAlias => $attribute->getBackend()->getTable()),
779: $condition,
780: array(
781: 'count_' . $attributeCode => new Zend_Db_Expr('COUNT(DISTINCT e.entity_id)'),
782: 'range_' . $attributeCode => new Zend_Db_Expr(
783: 'CEIL((' . $tableAlias . '.value+0.01)/' . $range . ')')
784: )
785: )
786: ->group('range_' . $attributeCode);
787:
788: $data = $this->getConnection()->fetchAll($select);
789: $res = array();
790:
791: foreach ($data as $row) {
792: $res[$row['range_' . $attributeCode]] = $row['count_' . $attributeCode];
793: }
794: return $res;
795: }
796:
797: 798: 799: 800: 801: 802:
803: public function getAttributeValueCount($attribute)
804: {
805: $select = clone $this->getSelect();
806: $attribute = $this->getEntity()->getAttribute($attribute);
807: $attributeCode = $attribute->getAttributeCode();
808: $tableAlias = $attributeCode . '_value_count';
809:
810: $select->reset(Zend_Db_Select::GROUP);
811: $condition = 'e.entity_id=' . $tableAlias . '.entity_id
812: AND '.$this->_getConditionSql($tableAlias . '.attribute_id', $attribute->getId());
813:
814: $select->join(
815: array($tableAlias => $attribute->getBackend()->getTable()),
816: $condition,
817: array(
818: 'count_' . $attributeCode => new Zend_Db_Expr('COUNT(DISTINCT e.entity_id)'),
819: 'value_' . $attributeCode => new Zend_Db_Expr($tableAlias . '.value')
820: )
821: )
822: ->group('value_' . $attributeCode);
823:
824: $data = $this->getConnection()->fetchAll($select);
825: $res = array();
826:
827: foreach ($data as $row) {
828: $res[$row['value_' . $attributeCode]] = $row['count_' . $attributeCode];
829: }
830: return $res;
831: }
832:
833: 834: 835: 836: 837: 838: 839: 840: 841: 842: 843: 844: 845: 846: 847:
848: public function getAllAttributeValues($attribute)
849: {
850:
851: $select = clone $this->getSelect();
852: $attribute = $this->getEntity()->getAttribute($attribute);
853:
854: $select->reset()
855: ->from($attribute->getBackend()->getTable(), array('entity_id', 'store_id', 'value'))
856: ->where('attribute_id = ?', (int)$attribute->getId());
857:
858: $data = $this->getConnection()->fetchAll($select);
859: $res = array();
860:
861: foreach ($data as $row) {
862: $res[$row['entity_id']][$row['store_id']] = $row['value'];
863: }
864:
865: return $res;
866: }
867:
868: 869: 870: 871: 872:
873: public function getSelectCountSql()
874: {
875: return $this->_getSelectCountSql();
876: }
877:
878: 879: 880: 881: 882: 883:
884: protected function _getSelectCountSql($select = null, $resetLeftJoins = true)
885: {
886: $this->_renderFilters();
887: $countSelect = (is_null($select)) ?
888: $this->_getClearSelect() :
889: $this->_buildClearSelect($select);
890: $countSelect->columns('COUNT(DISTINCT e.entity_id)');
891: if ($resetLeftJoins) {
892: $countSelect->resetJoinLeft();
893: }
894: return $countSelect;
895: }
896:
897: 898: 899: 900: 901:
902: protected function _prepareStatisticsData()
903: {
904: $select = clone $this->getSelect();
905: $priceExpression = $this->getPriceExpression($select) . ' ' . $this->getAdditionalPriceExpression($select);
906: $sqlEndPart = ') * ' . $this->getCurrencyRate() . ', 2)';
907: $select = $this->_getSelectCountSql($select, false);
908: $select->columns('ROUND(MAX(' . $priceExpression . $sqlEndPart);
909: $select->columns('ROUND(MIN(' . $priceExpression . $sqlEndPart);
910: $select->columns($this->getConnection()->getStandardDeviationSql('ROUND((' . $priceExpression . $sqlEndPart));
911: $select->where($this->getPriceExpression($select) . ' IS NOT NULL');
912: $row = $this->getConnection()->fetchRow($select, $this->_bindParams, Zend_Db::FETCH_NUM);
913: $this->_pricesCount = (int)$row[0];
914: $this->_maxPrice = (float)$row[1];
915: $this->_minPrice = (float)$row[2];
916: $this->_priceStandardDeviation = (float)$row[3];
917:
918: return $this;
919: }
920:
921: 922: 923: 924: 925:
926: protected function _getClearSelect()
927: {
928: return $this->_buildClearSelect();
929: }
930:
931: 932: 933: 934: 935: 936:
937: protected function _buildClearSelect($select = null)
938: {
939: if (is_null($select)) {
940: $select = clone $this->getSelect();
941: }
942: $select->reset(Zend_Db_Select::ORDER);
943: $select->reset(Zend_Db_Select::LIMIT_COUNT);
944: $select->reset(Zend_Db_Select::LIMIT_OFFSET);
945: $select->reset(Zend_Db_Select::COLUMNS);
946:
947: return $select;
948: }
949:
950: 951: 952: 953: 954: 955: 956:
957: public function getAllIds($limit = null, $offset = null)
958: {
959: $idsSelect = $this->_getClearSelect();
960: $idsSelect->columns('e.' . $this->getEntity()->getIdFieldName());
961: $idsSelect->limit($limit, $offset);
962: $idsSelect->resetJoinLeft();
963:
964: return $this->getConnection()->fetchCol($idsSelect, $this->_bindParams);
965: }
966:
967: 968: 969: 970: 971:
972: public function getProductCountSelect()
973: {
974: if ($this->_productCountSelect === null) {
975: $this->_productCountSelect = clone $this->getSelect();
976: $this->_productCountSelect->reset(Zend_Db_Select::COLUMNS)
977: ->reset(Zend_Db_Select::GROUP)
978: ->reset(Zend_Db_Select::ORDER)
979: ->distinct(false)
980: ->join(array('count_table' => $this->getTable('catalog/category_product_index')),
981: 'count_table.product_id = e.entity_id',
982: array(
983: 'count_table.category_id',
984: 'product_count' => new Zend_Db_Expr('COUNT(DISTINCT count_table.product_id)')
985: )
986: )
987: ->where('count_table.store_id = ?', $this->getStoreId())
988: ->group('count_table.category_id');
989: }
990:
991: return $this->_productCountSelect;
992: }
993:
994: 995: 996: 997: 998:
999: public function unsProductCountSelect()
1000: {
1001: $this->_productCountSelect = null;
1002: return $this;
1003: }
1004:
1005: 1006: 1007: 1008: 1009: 1010:
1011: public function addCountToCategories($categoryCollection)
1012: {
1013: $isAnchor = array();
1014: $isNotAnchor = array();
1015: foreach ($categoryCollection as $category) {
1016: if ($category->getIsAnchor()) {
1017: $isAnchor[] = $category->getId();
1018: } else {
1019: $isNotAnchor[] = $category->getId();
1020: }
1021: }
1022: $productCounts = array();
1023: if ($isAnchor || $isNotAnchor) {
1024: $select = $this->getProductCountSelect();
1025:
1026: Mage::dispatchEvent(
1027: 'catalog_product_collection_before_add_count_to_categories',
1028: array('collection' => $this)
1029: );
1030:
1031: if ($isAnchor) {
1032: $anchorStmt = clone $select;
1033: $anchorStmt->limit();
1034: $anchorStmt->where('count_table.category_id IN (?)', $isAnchor);
1035: $productCounts += $this->getConnection()->fetchPairs($anchorStmt);
1036: $anchorStmt = null;
1037: }
1038: if ($isNotAnchor) {
1039: $notAnchorStmt = clone $select;
1040: $notAnchorStmt->limit();
1041: $notAnchorStmt->where('count_table.category_id IN (?)', $isNotAnchor);
1042: $notAnchorStmt->where('count_table.is_parent = 1');
1043: $productCounts += $this->getConnection()->fetchPairs($notAnchorStmt);
1044: $notAnchorStmt = null;
1045: }
1046: $select = null;
1047: $this->unsProductCountSelect();
1048: }
1049:
1050: foreach ($categoryCollection as $category) {
1051: $_count = 0;
1052: if (isset($productCounts[$category->getId()])) {
1053: $_count = $productCounts[$category->getId()];
1054: }
1055: $category->setProductCount($_count);
1056: }
1057:
1058: return $this;
1059: }
1060:
1061: 1062: 1063: 1064: 1065:
1066: public function getSetIds()
1067: {
1068: $select = clone $this->getSelect();
1069:
1070: $select->reset(Zend_Db_Select::COLUMNS);
1071: $select->distinct(true);
1072: $select->columns('attribute_set_id');
1073: return $this->getConnection()->fetchCol($select);
1074: }
1075:
1076: 1077: 1078: 1079: 1080:
1081: public function getProductTypeIds()
1082: {
1083: $select = clone $this->getSelect();
1084:
1085: $select->reset(Zend_Db_Select::COLUMNS);
1086: $select->distinct(true);
1087: $select->columns('type_id');
1088: return $this->getConnection()->fetchCol($select);
1089: }
1090:
1091: 1092: 1093: 1094: 1095:
1096: public function joinUrlRewrite()
1097: {
1098: $this->joinTable(
1099: 'core/url_rewrite',
1100: 'entity_id=entity_id',
1101: array('request_path'),
1102: '{{table}}.type = ' . Mage_Core_Model_Url_Rewrite::TYPE_PRODUCT,
1103: 'left'
1104: );
1105:
1106: return $this;
1107: }
1108:
1109: 1110: 1111: 1112: 1113: 1114: 1115:
1116: public function addUrlRewrite($categoryId = '')
1117: {
1118: $this->_addUrlRewrite = true;
1119: if (Mage::getStoreConfig(Mage_Catalog_Helper_Product::XML_PATH_PRODUCT_URL_USE_CATEGORY, $this->getStoreId())) {
1120: $this->_urlRewriteCategory = $categoryId;
1121: } else {
1122: $this->_urlRewriteCategory = 0;
1123: }
1124:
1125: if ($this->isLoaded()) {
1126: $this->_addUrlRewrite();
1127: }
1128:
1129: return $this;
1130: }
1131:
1132: 1133: 1134: 1135:
1136: protected function _addUrlRewrite()
1137: {
1138: $urlRewrites = null;
1139: if ($this->_cacheConf) {
1140: if (!($urlRewrites = Mage::app()->loadCache($this->_cacheConf['prefix'] . 'urlrewrite'))) {
1141: $urlRewrites = null;
1142: } else {
1143: $urlRewrites = unserialize($urlRewrites);
1144: }
1145: }
1146:
1147: if (!$urlRewrites) {
1148: $productIds = array();
1149: foreach($this->getItems() as $item) {
1150: $productIds[] = $item->getEntityId();
1151: }
1152: if (!count($productIds)) {
1153: return;
1154: }
1155:
1156: $select = $this->getConnection()->select()
1157: ->from($this->getTable('core/url_rewrite'), array('product_id', 'request_path'))
1158: ->where('store_id = ?', Mage::app()->getStore()->getId())
1159: ->where('is_system = ?', 1)
1160: ->where('category_id = ? OR category_id IS NULL', $this->_urlRewriteCategory)
1161: ->where('product_id IN(?)', $productIds)
1162: ->order('category_id ' . self::SORT_ORDER_DESC);
1163: $urlRewrites = array();
1164:
1165: foreach ($this->getConnection()->fetchAll($select) as $row) {
1166: if (!isset($urlRewrites[$row['product_id']])) {
1167: $urlRewrites[$row['product_id']] = $row['request_path'];
1168: }
1169: }
1170:
1171: if ($this->_cacheConf) {
1172: Mage::app()->saveCache(
1173: serialize($urlRewrites),
1174: $this->_cacheConf['prefix'] . 'urlrewrite',
1175: array_merge($this->_cacheConf['tags'], array(Mage_Catalog_Model_Product_Url::CACHE_TAG)),
1176: $this->_cacheLifetime
1177: );
1178: }
1179: }
1180:
1181: foreach($this->getItems() as $item) {
1182: if (isset($urlRewrites[$item->getEntityId()])) {
1183: $item->setData('request_path', $urlRewrites[$item->getEntityId()]);
1184: } else {
1185: $item->setData('request_path', false);
1186: }
1187: }
1188: }
1189:
1190: 1191: 1192: 1193: 1194:
1195: public function addMinimalPrice()
1196: {
1197: return $this->addPriceData();
1198: }
1199:
1200: 1201: 1202: 1203: 1204: 1205: 1206: 1207:
1208: protected function _addMinimalPrice()
1209: {
1210: return $this;
1211: }
1212:
1213: 1214: 1215: 1216: 1217:
1218: public function addFinalPrice()
1219: {
1220: return $this->addPriceData();
1221: }
1222:
1223: 1224: 1225: 1226: 1227:
1228: protected function _joinPriceRules()
1229: {
1230: if ($this->isEnabledFlat()) {
1231: $customerGroup = Mage::getSingleton('customer/session')->getCustomerGroupId();
1232: $priceColumn = 'e.display_price_group_' . $customerGroup;
1233: $this->getSelect()->columns(array('_rule_price' => $priceColumn));
1234:
1235: return $this;
1236: }
1237: if (!Mage::helper('catalog')->isModuleEnabled('Mage_CatalogRule')) {
1238: return $this;
1239: }
1240: $wId = Mage::app()->getWebsite()->getId();
1241: $gId = Mage::getSingleton('customer/session')->getCustomerGroupId();
1242:
1243: $storeDate = Mage::app()->getLocale()->storeTimeStamp($this->getStoreId());
1244: $conditions = 'price_rule.product_id = e.entity_id AND ';
1245: $conditions .= "price_rule.rule_date = '".$this->getResource()->formatDate($storeDate, false)."' AND ";
1246: $conditions .= $this->getConnection()->quoteInto('price_rule.website_id = ? AND', $wId);
1247: $conditions .= $this->getConnection()->quoteInto('price_rule.customer_group_id = ?', $gId);
1248:
1249: $this->getSelect()->joinLeft(
1250: array('price_rule' => $this->getTable('catalogrule/rule_product_price')),
1251: $conditions,
1252: array('rule_price' => 'rule_price')
1253: );
1254: return $this;
1255: }
1256:
1257: 1258: 1259: 1260: 1261:
1262: protected function _addFinalPrice()
1263: {
1264: foreach ($this->_items as $product) {
1265: $basePrice = $product->getPrice();
1266: $specialPrice = $product->getSpecialPrice();
1267: $specialPriceFrom = $product->getSpecialFromDate();
1268: $specialPriceTo = $product->getSpecialToDate();
1269: if ($this->isEnabledFlat()) {
1270: $rulePrice = null;
1271: if ($product->getData('_rule_price') != $basePrice) {
1272: $rulePrice = $product->getData('_rule_price');
1273: }
1274: } else {
1275: $rulePrice = $product->getData('_rule_price');
1276: }
1277:
1278: $finalPrice = $product->getPriceModel()->calculatePrice(
1279: $basePrice,
1280: $specialPrice,
1281: $specialPriceFrom,
1282: $specialPriceTo,
1283: $rulePrice,
1284: null,
1285: null,
1286: $product->getId()
1287: );
1288:
1289: $product->setCalculatedFinalPrice($finalPrice);
1290: }
1291:
1292: return $this;
1293: }
1294:
1295: 1296: 1297: 1298: 1299: 1300:
1301: public function getAllIdsCache($resetCache = false)
1302: {
1303: $ids = null;
1304: if (!$resetCache) {
1305: $ids = $this->_allIdsCache;
1306: }
1307:
1308: if (is_null($ids)) {
1309: $ids = $this->getAllIds();
1310: $this->setAllIdsCache($ids);
1311: }
1312:
1313: return $ids;
1314: }
1315:
1316: 1317: 1318: 1319: 1320: 1321:
1322: public function setAllIdsCache($value)
1323: {
1324: $this->_allIdsCache = $value;
1325: return $this;
1326: }
1327:
1328: 1329: 1330: 1331: 1332: 1333: 1334:
1335: public function addPriceData($customerGroupId = null, $websiteId = null)
1336: {
1337: $this->_productLimitationFilters['use_price_index'] = true;
1338:
1339: if (!isset($this->_productLimitationFilters['customer_group_id']) && is_null($customerGroupId)) {
1340: $customerGroupId = Mage::getSingleton('customer/session')->getCustomerGroupId();
1341: }
1342: if (!isset($this->_productLimitationFilters['website_id']) && is_null($websiteId)) {
1343: $websiteId = Mage::app()->getStore($this->getStoreId())->getWebsiteId();
1344: }
1345:
1346: if (!is_null($customerGroupId)) {
1347: $this->_productLimitationFilters['customer_group_id'] = $customerGroupId;
1348: }
1349: if (!is_null($websiteId)) {
1350: $this->_productLimitationFilters['website_id'] = $websiteId;
1351: }
1352:
1353: $this->_applyProductLimitations();
1354:
1355: return $this;
1356: }
1357:
1358: 1359: 1360: 1361: 1362: 1363: 1364: 1365:
1366: public function addAttributeToFilter($attribute, $condition = null, $joinType = 'inner')
1367: {
1368: if ($this->isEnabledFlat()) {
1369: if ($attribute instanceof Mage_Eav_Model_Entity_Attribute_Abstract) {
1370: $attribute = $attribute->getAttributeCode();
1371: }
1372:
1373: if (is_array($attribute)) {
1374: $sqlArr = array();
1375: foreach ($attribute as $condition) {
1376: $sqlArr[] = $this->_getAttributeConditionSql($condition['attribute'], $condition, $joinType);
1377: }
1378: $conditionSql = '('.join(') OR (', $sqlArr).')';
1379: $this->getSelect()->where($conditionSql);
1380: return $this;
1381: }
1382:
1383: if (!isset($this->_selectAttributes[$attribute])) {
1384: $this->addAttributeToSelect($attribute);
1385: }
1386:
1387: if (isset($this->_selectAttributes[$attribute])) {
1388: $this->getSelect()->where($this->_getConditionSql('e.' . $attribute, $condition));
1389: }
1390:
1391: return $this;
1392: }
1393:
1394: $this->_allIdsCache = null;
1395:
1396: if (is_string($attribute) && $attribute == 'is_saleable') {
1397: $columns = $this->getSelect()->getPart(Zend_Db_Select::COLUMNS);
1398: foreach ($columns as $columnEntry) {
1399: list($correlationName, $column, $alias) = $columnEntry;
1400: if ($alias == 'is_saleable') {
1401: if ($column instanceof Zend_Db_Expr) {
1402: $field = $column;
1403: } else {
1404: $adapter = $this->getSelect()->getAdapter();
1405: if (empty($correlationName)) {
1406: $field = $adapter->quoteColumnAs($column, $alias, true);
1407: } else {
1408: $field = $adapter->quoteColumnAs(array($correlationName, $column), $alias, true);
1409: }
1410: }
1411: $this->getSelect()->where("{$field} = ?", $condition);
1412: break;
1413: }
1414: }
1415:
1416: return $this;
1417: } else {
1418: return parent::addAttributeToFilter($attribute, $condition, $joinType);
1419: }
1420: }
1421:
1422: 1423: 1424: 1425: 1426:
1427: public function addTaxPercents()
1428: {
1429: $this->_addTaxPercents = true;
1430: return $this;
1431: }
1432:
1433: 1434: 1435: 1436: 1437:
1438: public function requireTaxPercent()
1439: {
1440: return $this->_addTaxPercents;
1441: }
1442:
1443: 1444: 1445: 1446: 1447: 1448:
1449: protected function _addTaxPercents()
1450: {
1451: $classToRate = array();
1452: $request = Mage::getSingleton('tax/calculation')->getRateRequest();
1453: foreach ($this as &$item) {
1454: if (null === $item->getTaxClassId()) {
1455: $item->setTaxClassId($item->getMinimalTaxClassId());
1456: }
1457: if (!isset($classToRate[$item->getTaxClassId()])) {
1458: $request->setProductClassId($item->getTaxClassId());
1459: $classToRate[$item->getTaxClassId()] = Mage::getSingleton('tax/calculation')->getRate($request);
1460: }
1461: $item->setTaxPercent($classToRate[$item->getTaxClassId()]);
1462: }
1463: }
1464:
1465: 1466: 1467: 1468: 1469:
1470: public function addOptionsToResult()
1471: {
1472: $productIds = array();
1473: foreach ($this as $product) {
1474: $productIds[] = $product->getId();
1475: }
1476: if (!empty($productIds)) {
1477: $options = Mage::getModel('catalog/product_option')
1478: ->getCollection()
1479: ->addTitleToResult(Mage::app()->getStore()->getId())
1480: ->addPriceToResult(Mage::app()->getStore()->getId())
1481: ->addProductToFilter($productIds)
1482: ->addValuesToResult();
1483:
1484: foreach ($options as $option) {
1485: if($this->getItemById($option->getProductId())) {
1486: $this->getItemById($option->getProductId())->addOption($option);
1487: }
1488: }
1489: }
1490:
1491: return $this;
1492: }
1493:
1494: 1495: 1496: 1497: 1498:
1499: public function addFilterByRequiredOptions()
1500: {
1501: $this->addAttributeToFilter('required_options', array(array('neq' => '1'), array('null' => true)), 'left');
1502: return $this;
1503: }
1504:
1505: 1506: 1507: 1508: 1509: 1510:
1511: public function setVisibility($visibility)
1512: {
1513: $this->_productLimitationFilters['visibility'] = $visibility;
1514: $this->_applyProductLimitations();
1515:
1516: return $this;
1517: }
1518:
1519: 1520: 1521: 1522: 1523: 1524: 1525:
1526: public function addAttributeToSort($attribute, $dir = self::SORT_ORDER_ASC)
1527: {
1528: if ($attribute == 'position') {
1529: if (isset($this->_joinFields[$attribute])) {
1530: $this->getSelect()->order($this->_getAttributeFieldName($attribute) . ' ' . $dir);
1531: return $this;
1532: }
1533: if ($this->isEnabledFlat()) {
1534: $this->getSelect()->order("cat_index_position {$dir}");
1535: }
1536:
1537: $filters = $this->_productLimitationFilters;
1538: if (isset($filters['category_id']) || isset($filters['visibility'])) {
1539: $this->getSelect()->order('cat_index.position ' . $dir);
1540: } else {
1541: $this->getSelect()->order('e.entity_id ' . $dir);
1542: }
1543:
1544: return $this;
1545: } elseif($attribute == 'is_saleable'){
1546: $this->getSelect()->order("is_saleable " . $dir);
1547: return $this;
1548: }
1549:
1550: $storeId = $this->getStoreId();
1551: if ($attribute == 'price' && $storeId != 0) {
1552: $this->addPriceData();
1553: $this->getSelect()->order("price_index.min_price {$dir}");
1554:
1555: return $this;
1556: }
1557:
1558: if ($this->isEnabledFlat()) {
1559: $column = $this->getEntity()->getAttributeSortColumn($attribute);
1560:
1561: if ($column) {
1562: $this->getSelect()->order("e.{$column} {$dir}");
1563: }
1564: else if (isset($this->_joinFields[$attribute])) {
1565: $this->getSelect()->order($this->_getAttributeFieldName($attribute) . ' ' . $dir);
1566: }
1567:
1568: return $this;
1569: } else {
1570: $attrInstance = $this->getEntity()->getAttribute($attribute);
1571: if ($attrInstance && $attrInstance->usesSource()) {
1572: $attrInstance->getSource()
1573: ->addValueSortToCollection($this, $dir);
1574: return $this;
1575: }
1576: }
1577:
1578: return parent::addAttributeToSort($attribute, $dir);
1579: }
1580:
1581: 1582: 1583: 1584: 1585:
1586: protected function _prepareProductLimitationFilters()
1587: {
1588: if (isset($this->_productLimitationFilters['visibility'])
1589: && !isset($this->_productLimitationFilters['store_id'])
1590: ) {
1591: $this->_productLimitationFilters['store_id'] = $this->getStoreId();
1592: }
1593: if (isset($this->_productLimitationFilters['category_id'])
1594: && !isset($this->_productLimitationFilters['store_id'])
1595: ) {
1596: $this->_productLimitationFilters['store_id'] = $this->getStoreId();
1597: }
1598: if (isset($this->_productLimitationFilters['store_id'])
1599: && isset($this->_productLimitationFilters['visibility'])
1600: && !isset($this->_productLimitationFilters['category_id'])
1601: ) {
1602: $this->_productLimitationFilters['category_id'] = Mage::app()
1603: ->getStore($this->_productLimitationFilters['store_id'])
1604: ->getRootCategoryId();
1605: }
1606:
1607: return $this;
1608: }
1609:
1610: 1611: 1612: 1613: 1614:
1615: protected function _productLimitationJoinWebsite()
1616: {
1617: $joinWebsite = false;
1618: $filters = $this->_productLimitationFilters;
1619: $conditions = array('product_website.product_id = e.entity_id');
1620:
1621: if (isset($filters['website_ids'])) {
1622: $joinWebsite = true;
1623: if (count($filters['website_ids']) > 1) {
1624: $this->getSelect()->distinct(true);
1625: }
1626: $conditions[] = $this->getConnection()
1627: ->quoteInto('product_website.website_id IN(?)', $filters['website_ids']);
1628: } elseif (isset($filters['store_id'])
1629: && (!isset($filters['visibility']) && !isset($filters['category_id']))
1630: && !$this->isEnabledFlat()
1631: ) {
1632: $joinWebsite = true;
1633: $websiteId = Mage::app()->getStore($filters['store_id'])->getWebsiteId();
1634: $conditions[] = $this->getConnection()
1635: ->quoteInto('product_website.website_id = ?', $websiteId);
1636: }
1637:
1638: $fromPart = $this->getSelect()->getPart(Zend_Db_Select::FROM);
1639: if (isset($fromPart['product_website'])) {
1640: if (!$joinWebsite) {
1641: unset($fromPart['product_website']);
1642: } else {
1643: $fromPart['product_website']['joinCondition'] = join(' AND ', $conditions);
1644: }
1645: $this->getSelect()->setPart(Zend_Db_Select::FROM, $fromPart);
1646: } elseif ($joinWebsite) {
1647: $this->getSelect()->join(
1648: array('product_website' => $this->getTable('catalog/product_website')),
1649: join(' AND ', $conditions),
1650: array()
1651: );
1652: }
1653:
1654: return $this;
1655: }
1656:
1657: 1658: 1659: 1660: 1661:
1662: protected function _productLimitationJoinStore()
1663: {
1664: $filters = $this->_productLimitationFilters;
1665: if (!isset($filters['store_table'])) {
1666: return $this;
1667: }
1668:
1669: $hasColumn = false;
1670: foreach ($this->getSelect()->getPart(Zend_Db_Select::COLUMNS) as $columnEntry) {
1671: list(,,$alias) = $columnEntry;
1672: if ($alias == 'visibility') {
1673: $hasColumn = true;
1674: }
1675: }
1676: if (!$hasColumn) {
1677: $this->getSelect()->columns('visibility', 'cat_index');
1678: }
1679:
1680: $fromPart = $this->getSelect()->getPart(Zend_Db_Select::FROM);
1681: if (!isset($fromPart['store_index'])) {
1682: $this->getSelect()->joinLeft(
1683: array('store_index' => $this->getTable('core/store')),
1684: 'store_index.store_id = ' . $filters['store_table'] . '.store_id',
1685: array()
1686: );
1687: }
1688: if (!isset($fromPart['store_group_index'])) {
1689: $this->getSelect()->joinLeft(
1690: array('store_group_index' => $this->getTable('core/store_group')),
1691: 'store_index.group_id = store_group_index.group_id',
1692: array()
1693: );
1694: }
1695: if (!isset($fromPart['store_cat_index'])) {
1696: $this->getSelect()->joinLeft(
1697: array('store_cat_index' => $this->getTable('catalog/category_product_index')),
1698: join(' AND ', array(
1699: 'store_cat_index.product_id = e.entity_id',
1700: 'store_cat_index.store_id = ' . $filters['store_table'] . '.store_id',
1701: 'store_cat_index.category_id=store_group_index.root_category_id'
1702: )),
1703: array('store_visibility' => 'visibility')
1704: );
1705: }
1706:
1707: Mage::getResourceHelper('core')->prepareColumnsList($this->getSelect());
1708:
1709: $whereCond = join(' OR ', array(
1710: $this->getConnection()->quoteInto('cat_index.visibility IN(?)', $filters['visibility']),
1711: $this->getConnection()->quoteInto('store_cat_index.visibility IN(?)', $filters['visibility'])
1712: ));
1713:
1714: $wherePart = $this->getSelect()->getPart(Zend_Db_Select::WHERE);
1715: $hasCond = false;
1716: foreach ($wherePart as $cond) {
1717: if ($cond == '(' . $whereCond . ')') {
1718: $hasCond = true;
1719: }
1720: }
1721:
1722: if (!$hasCond) {
1723: $this->getSelect()->where($whereCond);
1724: }
1725:
1726: return $this;
1727: }
1728:
1729: 1730: 1731: 1732: 1733:
1734: protected function _productLimitationJoinPrice()
1735: {
1736: return $this->_productLimitationPrice();
1737: }
1738:
1739: 1740: 1741: 1742: 1743: 1744:
1745: protected function _productLimitationPrice($joinLeft = false)
1746: {
1747: $filters = $this->_productLimitationFilters;
1748: if (empty($filters['use_price_index'])) {
1749: return $this;
1750: }
1751:
1752: $helper = Mage::getResourceHelper('core');
1753: $connection = $this->getConnection();
1754: $select = $this->getSelect();
1755: $joinCond = join(' AND ', array(
1756: 'price_index.entity_id = e.entity_id',
1757: $connection->quoteInto('price_index.website_id = ?', $filters['website_id']),
1758: $connection->quoteInto('price_index.customer_group_id = ?', $filters['customer_group_id'])
1759: ));
1760:
1761: $fromPart = $select->getPart(Zend_Db_Select::FROM);
1762: if (!isset($fromPart['price_index'])) {
1763: $least = $connection->getLeastSql(array('price_index.min_price', 'price_index.tier_price'));
1764: $minimalExpr = $connection->getCheckSql('price_index.tier_price IS NOT NULL',
1765: $least, 'price_index.min_price');
1766: $colls = array('price', 'tax_class_id', 'final_price',
1767: 'minimal_price' => $minimalExpr , 'min_price', 'max_price', 'tier_price');
1768: $tableName = array('price_index' => $this->getTable('catalog/product_index_price'));
1769: if ($joinLeft) {
1770: $select->joinLeft($tableName, $joinCond, $colls);
1771: } else {
1772: $select->join($tableName, $joinCond, $colls);
1773: }
1774:
1775: foreach ($this->_priceDataFieldFilters as $filterData) {
1776: $select->where(call_user_func_array('sprintf', $filterData));
1777: }
1778: } else {
1779: $fromPart['price_index']['joinCondition'] = $joinCond;
1780: $select->setPart(Zend_Db_Select::FROM, $fromPart);
1781: }
1782:
1783: $helper->prepareColumnsList($select);
1784:
1785:
1786: return $this;
1787: }
1788:
1789: 1790: 1791: 1792: 1793:
1794: public function applyFrontendPriceLimitations()
1795: {
1796: $this->_productLimitationFilters['use_price_index'] = true;
1797: if (!isset($this->_productLimitationFilters['customer_group_id'])) {
1798: $customerGroupId = Mage::getSingleton('customer/session')->getCustomerGroupId();
1799: $this->_productLimitationFilters['customer_group_id'] = $customerGroupId;
1800: }
1801: if (!isset($this->_productLimitationFilters['website_id'])) {
1802: $websiteId = Mage::app()->getStore($this->getStoreId())->getWebsiteId();
1803: $this->_productLimitationFilters['website_id'] = $websiteId;
1804: }
1805: $this->_applyProductLimitations();
1806: return $this;
1807: }
1808:
1809: 1810: 1811: 1812: 1813: 1814: 1815: 1816:
1817: protected function _applyProductLimitations()
1818: {
1819: $this->_prepareProductLimitationFilters();
1820: $this->_productLimitationJoinWebsite();
1821: $this->_productLimitationJoinPrice();
1822: $filters = $this->_productLimitationFilters;
1823:
1824: if (!isset($filters['category_id']) && !isset($filters['visibility'])) {
1825: return $this;
1826: }
1827:
1828: $conditions = array(
1829: 'cat_index.product_id=e.entity_id',
1830: $this->getConnection()->quoteInto('cat_index.store_id=?', $filters['store_id'])
1831: );
1832: if (isset($filters['visibility']) && !isset($filters['store_table'])) {
1833: $conditions[] = $this->getConnection()
1834: ->quoteInto('cat_index.visibility IN(?)', $filters['visibility']);
1835: }
1836: $conditions[] = $this->getConnection()
1837: ->quoteInto('cat_index.category_id=?', $filters['category_id']);
1838: if (isset($filters['category_is_anchor'])) {
1839: $conditions[] = $this->getConnection()
1840: ->quoteInto('cat_index.is_parent=?', $filters['category_is_anchor']);
1841: }
1842:
1843: $joinCond = join(' AND ', $conditions);
1844: $fromPart = $this->getSelect()->getPart(Zend_Db_Select::FROM);
1845: if (isset($fromPart['cat_index'])) {
1846: $fromPart['cat_index']['joinCondition'] = $joinCond;
1847: $this->getSelect()->setPart(Zend_Db_Select::FROM, $fromPart);
1848: }
1849: else {
1850: $this->getSelect()->join(
1851: array('cat_index' => $this->getTable('catalog/category_product_index')),
1852: $joinCond,
1853: array('cat_index_position' => 'position')
1854: );
1855: }
1856:
1857: $this->_productLimitationJoinStore();
1858:
1859: Mage::dispatchEvent('catalog_product_collection_apply_limitations_after', array(
1860: 'collection' => $this
1861: ));
1862:
1863: return $this;
1864: }
1865:
1866: 1867: 1868: 1869: 1870: 1871: 1872:
1873: protected function _applyZeroStoreProductLimitations()
1874: {
1875: $filters = $this->_productLimitationFilters;
1876:
1877: $conditions = array(
1878: 'cat_pro.product_id=e.entity_id',
1879: $this->getConnection()->quoteInto('cat_pro.category_id=?', $filters['category_id'])
1880: );
1881: $joinCond = join(' AND ', $conditions);
1882:
1883: $fromPart = $this->getSelect()->getPart(Zend_Db_Select::FROM);
1884: if (isset($fromPart['cat_pro'])) {
1885: $fromPart['cat_pro']['joinCondition'] = $joinCond;
1886: $this->getSelect()->setPart(Zend_Db_Select::FROM, $fromPart);
1887: }
1888: else {
1889: $this->getSelect()->join(
1890: array('cat_pro' => $this->getTable('catalog/category_product')),
1891: $joinCond,
1892: array('cat_index_position' => 'position')
1893: );
1894: }
1895: $this->_joinFields['position'] = array(
1896: 'table' => 'cat_pro',
1897: 'field' => 'position',
1898: );
1899:
1900: return $this;
1901: }
1902:
1903: 1904: 1905: 1906: 1907:
1908: public function addCategoryIds()
1909: {
1910: if ($this->getFlag('category_ids_added')) {
1911: return $this;
1912: }
1913: $ids = array_keys($this->_items);
1914: if (empty($ids)) {
1915: return $this;
1916: }
1917:
1918: $select = $this->getConnection()->select();
1919:
1920: $select->from($this->_productCategoryTable, array('product_id', 'category_id'));
1921: $select->where('product_id IN (?)', $ids);
1922:
1923: $data = $this->getConnection()->fetchAll($select);
1924:
1925: $categoryIds = array();
1926: foreach ($data as $info) {
1927: if (isset($categoryIds[$info['product_id']])) {
1928: $categoryIds[$info['product_id']][] = $info['category_id'];
1929: } else {
1930: $categoryIds[$info['product_id']] = array($info['category_id']);
1931: }
1932: }
1933:
1934:
1935: foreach ($this->getItems() as $item) {
1936: $productId = $item->getId();
1937: if (isset($categoryIds[$productId])) {
1938: $item->setCategoryIds($categoryIds[$productId]);
1939: } else {
1940: $item->setCategoryIds(array());
1941: }
1942: }
1943:
1944: $this->setFlag('category_ids_added', true);
1945: return $this;
1946: }
1947:
1948: 1949: 1950: 1951: 1952:
1953: public function addTierPriceData()
1954: {
1955: if ($this->getFlag('tier_price_added')) {
1956: return $this;
1957: }
1958:
1959: $tierPrices = array();
1960: $productIds = array();
1961: foreach ($this->getItems() as $item) {
1962: $productIds[] = $item->getId();
1963: $tierPrices[$item->getId()] = array();
1964: }
1965: if (!$productIds) {
1966: return $this;
1967: }
1968:
1969:
1970: $attribute = $this->getAttribute('tier_price');
1971: if ($attribute->isScopeGlobal()) {
1972: $websiteId = 0;
1973: } else if ($this->getStoreId()) {
1974: $websiteId = Mage::app()->getStore($this->getStoreId())->getWebsiteId();
1975: }
1976:
1977: $adapter = $this->getConnection();
1978: $columns = array(
1979: 'price_id' => 'value_id',
1980: 'website_id' => 'website_id',
1981: 'all_groups' => 'all_groups',
1982: 'cust_group' => 'customer_group_id',
1983: 'price_qty' => 'qty',
1984: 'price' => 'value',
1985: 'product_id' => 'entity_id'
1986: );
1987: $select = $adapter->select()
1988: ->from($this->getTable('catalog/product_attribute_tier_price'), $columns)
1989: ->where('entity_id IN(?)', $productIds)
1990: ->order(array('entity_id','qty'));
1991:
1992: if ($websiteId == '0') {
1993: $select->where('website_id = ?', $websiteId);
1994: } else {
1995: $select->where('website_id IN(?)', array('0', $websiteId));
1996: }
1997:
1998: foreach ($adapter->fetchAll($select) as $row) {
1999: $tierPrices[$row['product_id']][] = array(
2000: 'website_id' => $row['website_id'],
2001: 'cust_group' => $row['all_groups'] ? Mage_Customer_Model_Group::CUST_GROUP_ALL : $row['cust_group'],
2002: 'price_qty' => $row['price_qty'],
2003: 'price' => $row['price'],
2004: 'website_price' => $row['price'],
2005:
2006: );
2007: }
2008:
2009:
2010: $backend = $attribute->getBackend();
2011:
2012: foreach ($this->getItems() as $item) {
2013: $data = $tierPrices[$item->getId()];
2014: if (!empty($data) && $websiteId) {
2015: $data = $backend->preparePriceData($data, $item->getTypeId(), $websiteId);
2016: }
2017: $item->setData('tier_price', $data);
2018: }
2019:
2020: $this->setFlag('tier_price_added', true);
2021: return $this;
2022: }
2023:
2024: 2025: 2026: 2027: 2028: 2029: 2030: 2031:
2032: public function addPriceDataFieldFilter($comparisonFormat, $fields)
2033: {
2034: if (!preg_match('/^%s( (<|>|=|<=|>=|<>) %s)*$/', $comparisonFormat)) {
2035: throw new Exception('Invalid comparison format.');
2036: }
2037:
2038: if (!is_array($fields)) {
2039: $fields = array($fields);
2040: }
2041: foreach ($fields as $key => $field) {
2042: $fields[$key] = $this->_getMappedField($field);
2043: }
2044:
2045: $this->_priceDataFieldFilters[] = array_merge(array($comparisonFormat), $fields);
2046: return $this;
2047: }
2048:
2049: 2050: 2051: 2052: 2053:
2054: public function clear()
2055: {
2056: foreach ($this->_items as $i => $item) {
2057: if ($item->hasStockItem()) {
2058: $item->unsStockItem();
2059: }
2060: $item = $this->_items[$i] = null;
2061: }
2062:
2063: foreach ($this->_itemsById as $i => $item) {
2064: $item = $this->_itemsById[$i] = null;
2065: }
2066:
2067: unset($this->_items, $this->_data, $this->_itemsById);
2068: $this->_data = array();
2069: $this->_itemsById = array();
2070: return parent::clear();
2071: }
2072:
2073: 2074: 2075: 2076: 2077: 2078: 2079:
2080: public function setOrder($attribute, $dir = 'desc')
2081: {
2082: if ($attribute == 'price') {
2083: $this->addAttributeToSort($attribute, $dir);
2084: } else {
2085: parent::setOrder($attribute, $dir);
2086: }
2087: return $this;
2088: }
2089:
2090: 2091: 2092: 2093: 2094:
2095: public function getMaxPrice()
2096: {
2097: if (is_null($this->_maxPrice)) {
2098: $this->_prepareStatisticsData();
2099: }
2100:
2101: return $this->_maxPrice;
2102: }
2103:
2104: 2105: 2106: 2107: 2108:
2109: public function getMinPrice()
2110: {
2111: if (is_null($this->_minPrice)) {
2112: $this->_prepareStatisticsData();
2113: }
2114:
2115: return $this->_minPrice;
2116: }
2117:
2118: 2119: 2120: 2121: 2122:
2123: public function getPriceStandardDeviation()
2124: {
2125: if (is_null($this->_priceStandardDeviation)) {
2126: $this->_prepareStatisticsData();
2127: }
2128:
2129: return $this->_priceStandardDeviation;
2130: }
2131:
2132:
2133: 2134: 2135: 2136: 2137:
2138: public function getPricesCount()
2139: {
2140: if (is_null($this->_pricesCount)) {
2141: $this->_prepareStatisticsData();
2142: }
2143:
2144: return $this->_pricesCount;
2145: }
2146: }
2147: