1: <?php
2: /**
3: * Magento
4: *
5: * NOTICE OF LICENSE
6: *
7: * This source file is subject to the Open Software License (OSL 3.0)
8: * that is bundled with this package in the file LICENSE.txt.
9: * It is also available through the world-wide-web at this URL:
10: * http://opensource.org/licenses/osl-3.0.php
11: * If you did not receive a copy of the license and are unable to
12: * obtain it through the world-wide-web, please send an email
13: * to license@magentocommerce.com so we can send you a copy immediately.
14: *
15: * DISCLAIMER
16: *
17: * Do not edit or add to this file if you wish to upgrade Magento to newer
18: * versions in the future. If you wish to customize Magento for your
19: * needs please refer to http://www.magentocommerce.com for more information.
20: *
21: * @category Mage
22: * @package Mage_Catalog
23: * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
24: * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25: */
26:
27:
28: /**
29: * Catalog product linked products collection
30: *
31: * @category Mage
32: * @package Mage_Catalog
33: * @author Magento Core Team <core@magentocommerce.com>
34: */
35: class Mage_Catalog_Model_Resource_Product_Link_Product_Collection extends Mage_Catalog_Model_Resource_Product_Collection
36: {
37: /**
38: * Store product model
39: *
40: * @var Mage_Catalog_Model_Product
41: */
42: protected $_product;
43:
44: /**
45: * Store product link model
46: *
47: * @var Mage_Catalog_Model_Product_Link
48: */
49: protected $_linkModel;
50:
51: /**
52: * Store link type id
53: *
54: * @var int
55: */
56: protected $_linkTypeId;
57:
58: /**
59: * Store strong mode flag that determine if needed for inner join or left join of linked products
60: *
61: * @var bool
62: */
63: protected $_isStrongMode;
64:
65: /**
66: * Store flag that determine if product filter was enabled
67: *
68: * @var bool
69: */
70: protected $_hasLinkFilter = false;
71:
72: /**
73: * Declare link model and initialize type attributes join
74: *
75: * @param Mage_Catalog_Model_Product_Link $linkModel
76: * @return Mage_Catalog_Model_Resource_Product_Link_Product_Collection
77: */
78: public function setLinkModel(Mage_Catalog_Model_Product_Link $linkModel)
79: {
80: $this->_linkModel = $linkModel;
81: if ($linkModel->getLinkTypeId()) {
82: $this->_linkTypeId = $linkModel->getLinkTypeId();
83: }
84: return $this;
85: }
86:
87: /**
88: * Enable strong mode for inner join of linked products
89: *
90: * @return Mage_Catalog_Model_Resource_Product_Link_Product_Collection
91: */
92: public function setIsStrongMode()
93: {
94: $this->_isStrongMode = true;
95: return $this;
96: }
97:
98: /**
99: * Retrieve collection link model
100: *
101: * @return Mage_Catalog_Model_Product_Link
102: */
103: public function getLinkModel()
104: {
105: return $this->_linkModel;
106: }
107:
108: /**
109: * Initialize collection parent product and add limitation join
110: *
111: * @param Mage_Catalog_Model_Product $product
112: * @return Mage_Catalog_Model_Resource_Product_Link_Product_Collection
113: */
114: public function setProduct(Mage_Catalog_Model_Product $product)
115: {
116: $this->_product = $product;
117: if ($product && $product->getId()) {
118: $this->_hasLinkFilter = true;
119: }
120: return $this;
121: }
122:
123: /**
124: * Retrieve collection base product object
125: *
126: * @return Mage_Catalog_Model_Product
127: */
128: public function getProduct()
129: {
130: return $this->_product;
131: }
132:
133: /**
134: * Exclude products from filter
135: *
136: * @param array $products
137: * @return Mage_Catalog_Model_Resource_Product_Link_Product_Collection
138: */
139: public function addExcludeProductFilter($products)
140: {
141: if (!empty($products)) {
142: if (!is_array($products)) {
143: $products = array($products);
144: }
145: $this->_hasLinkFilter = true;
146: $this->getSelect()->where('links.linked_product_id NOT IN (?)', $products);
147: }
148: return $this;
149: }
150:
151: /**
152: * Add products to filter
153: *
154: * @param array|int|string $products
155: * @return Mage_Catalog_Model_Resource_Product_Link_Product_Collection
156: */
157: public function addProductFilter($products)
158: {
159: if (!empty($products)) {
160: if (!is_array($products)) {
161: $products = array($products);
162: }
163: $this->getSelect()->where('links.product_id IN (?)', $products);
164: $this->_hasLinkFilter = true;
165: }
166:
167: return $this;
168: }
169:
170: /**
171: * Add random sorting order
172: *
173: * @return Mage_Catalog_Model_Resource_Product_Link_Product_Collection
174: */
175: public function setRandomOrder()
176: {
177: $this->getSelect()->orderRand('main_table.entity_id');
178: return $this;
179: }
180:
181: /**
182: * Setting group by to exclude duplications in collection
183: *
184: * @param string $groupBy
185: * @return Mage_Catalog_Model_Resource_Product_Link_Product_Collection
186: */
187: public function setGroupBy($groupBy = 'e.entity_id')
188: {
189: $this->getSelect()->group($groupBy);
190:
191: /*
192: * Allow Analytic functions usage
193: */
194: $this->_useAnalyticFunction = true;
195:
196: return $this;
197: }
198:
199: /**
200: * Join linked products when specified link model
201: *
202: * @return Mage_Catalog_Model_Resource_Product_Link_Product_Collection
203: */
204: protected function _beforeLoad()
205: {
206: if ($this->getLinkModel()) {
207: $this->_joinLinks();
208: }
209: return parent::_beforeLoad();
210: }
211:
212: /**
213: * Join linked products and their attributes
214: *
215: * @return Mage_Catalog_Model_Resource_Product_Link_Product_Collection
216: */
217: protected function _joinLinks()
218: {
219: $select = $this->getSelect();
220: $adapter = $select->getAdapter();
221:
222: $joinCondition = array(
223: 'links.linked_product_id = e.entity_id',
224: $adapter->quoteInto('links.link_type_id = ?', $this->_linkTypeId)
225: );
226: $joinType = 'join';
227: if ($this->getProduct() && $this->getProduct()->getId()) {
228: $productId = $this->getProduct()->getId();
229: if ($this->_isStrongMode) {
230: $this->getSelect()->where('links.product_id = ?', (int)$productId);
231: } else {
232: $joinType = 'joinLeft';
233: $joinCondition[] = $adapter->quoteInto('links.product_id = ?', $productId);
234: }
235: $this->addFieldToFilter('entity_id', array('neq' => $productId));
236: } else if ($this->_isStrongMode) {
237: $this->addFieldToFilter('entity_id', array('eq' => -1));
238: }
239: if($this->_hasLinkFilter) {
240: $select->$joinType(
241: array('links' => $this->getTable('catalog/product_link')),
242: implode(' AND ', $joinCondition),
243: array('link_id')
244: );
245: $this->joinAttributes();
246: }
247: return $this;
248: }
249:
250:
251:
252: /**
253: * Enable sorting products by its position
254: *
255: * @param string $dir sort type asc|desc
256: * @return Mage_Catalog_Model_Resource_Product_Link_Product_Collection
257: */
258: public function setPositionOrder($dir = self::SORT_ORDER_ASC)
259: {
260: if ($this->_hasLinkFilter) {
261: $this->getSelect()->order('position ' . $dir);
262: }
263: return $this;
264: }
265:
266: /**
267: * Enable sorting products by its attribute set name
268: *
269: * @param string $dir sort type asc|desc
270: * @return Mage_Catalog_Model_Resource_Product_Link_Product_Collection
271: */
272: public function setAttributeSetIdOrder($dir = self::SORT_ORDER_ASC)
273: {
274: $this->getSelect()
275: ->joinLeft(
276: array('set' => $this->getTable('eav/attribute_set')),
277: 'e.attribute_set_id = set.attribute_set_id',
278: array('attribute_set_name')
279: )
280: ->order('set.attribute_set_name ' . $dir);
281: return $this;
282: }
283:
284: /**
285: * Join attributes
286: *
287: * @return Mage_Catalog_Model_Resource_Product_Link_Product_Collection
288: */
289: public function joinAttributes()
290: {
291: if (!$this->getLinkModel()) {
292: return $this;
293: }
294: $attributes = $this->getLinkModel()->getAttributes();
295:
296: $attributesByType = array();
297: foreach ($attributes as $attribute) {
298: $table = $this->getLinkModel()->getAttributeTypeTable($attribute['type']);
299: $alias = sprintf('link_attribute_%s_%s', $attribute['code'], $attribute['type']);
300:
301: $joinCondiotion = array(
302: "{$alias}.link_id = links.link_id",
303: $this->getSelect()->getAdapter()->quoteInto("{$alias}.product_link_attribute_id = ?", $attribute['id'])
304: );
305: $this->getSelect()->joinLeft(
306: array($alias => $table),
307: implode(' AND ', $joinCondiotion),
308: array($attribute['code'] => 'value')
309: );
310: }
311:
312: return $this;
313: }
314:
315: /**
316: * Set sorting order
317: *
318: * $attribute can also be an array of attributes
319: *
320: * @param string|array $attribute
321: * @param string $dir
322: * @return Mage_Catalog_Model_Resource_Product_Link_Product_Collection
323: */
324: public function setOrder($attribute, $dir = self::SORT_ORDER_ASC)
325: {
326: if ($attribute == 'position') {
327: return $this->setPositionOrder($dir);
328: } elseif ($attribute == 'attribute_set_id') {
329: return $this->setAttributeSetIdOrder($dir);
330: }
331: return parent::setOrder($attribute, $dir);
332: }
333: }
334: