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_Indexer_Eav_Source
36: extends Mage_Catalog_Model_Resource_Product_Indexer_Eav_Abstract
37: {
38: 39: 40: 41:
42: protected function _construct()
43: {
44: $this->_init('catalog/product_index_eav', 'entity_id');
45: }
46:
47: 48: 49: 50: 51: 52:
53: protected function _getIndexableAttributes($multiSelect)
54: {
55: $select = $this->_getReadAdapter()->select()
56: ->from(array('ca' => $this->getTable('catalog/eav_attribute')), 'attribute_id')
57: ->join(
58: array('ea' => $this->getTable('eav/attribute')),
59: 'ca.attribute_id = ea.attribute_id',
60: array())
61: ->where($this->_getIndexableAttributesCondition());
62:
63: if ($multiSelect == true) {
64: $select->where('ea.backend_type = ?', 'varchar')
65: ->where('ea.frontend_input = ?', 'multiselect');
66: } else {
67: $select->where('ea.backend_type = ?', 'int')
68: ->where('ea.frontend_input = ?', 'select');
69: }
70:
71: return $this->_getReadAdapter()->fetchCol($select);
72: }
73:
74: 75: 76: 77: 78: 79: 80:
81: protected function _prepareIndex($entityIds = null, $attributeId = null)
82: {
83: $this->_prepareSelectIndex($entityIds, $attributeId);
84: $this->_prepareMultiselectIndex($entityIds, $attributeId);
85:
86: return $this;
87: }
88:
89: 90: 91: 92: 93: 94: 95:
96: protected function _prepareSelectIndex($entityIds = null, $attributeId = null)
97: {
98: $adapter = $this->_getWriteAdapter();
99: $idxTable = $this->getIdxTable();
100:
101: if (is_null($attributeId)) {
102: $attrIds = $this->_getIndexableAttributes(false);
103: } else {
104: $attrIds = array($attributeId);
105: }
106:
107: if (!$attrIds) {
108: return $this;
109: }
110:
111:
112: $subSelect = $adapter->select()
113: ->from(
114: array('s' => $this->getTable('core/store')),
115: array('store_id', 'website_id')
116: )
117: ->joinLeft(
118: array('d' => $this->getValueTable('catalog/product', 'int')),
119: '1 = 1 AND d.store_id = 0',
120: array('entity_id', 'attribute_id', 'value')
121: )
122: ->where('s.store_id != 0');
123:
124: if (!is_null($entityIds)) {
125: $subSelect->where('d.entity_id IN(?)', $entityIds);
126: }
127:
128:
129: $select = $adapter->select()
130: ->from(
131: array('pid' => new Zend_Db_Expr(sprintf('(%s)',$subSelect->assemble()))),
132: array()
133: )
134: ->joinLeft(
135: array('pis' => $this->getValueTable('catalog/product', 'int')),
136: 'pis.entity_id = pid.entity_id AND pis.attribute_id = pid.attribute_id AND pis.store_id = pid.store_id',
137: array()
138: )
139: ->columns(
140: array(
141: 'pid.entity_id',
142: 'pid.attribute_id',
143: 'pid.store_id',
144: 'value' => $adapter->getIfNullSql('pis.value', 'pid.value')
145: )
146: )
147: ->where('pid.attribute_id IN(?)', $attrIds);
148:
149: $select->where(Mage::getResourceHelper('catalog')->getIsNullNotNullCondition('pis.value', 'pid.value'));
150:
151: 152: 153:
154: Mage::dispatchEvent('prepare_catalog_product_index_select', array(
155: 'select' => $select,
156: 'entity_field' => new Zend_Db_Expr('pid.entity_id'),
157: 'website_field' => new Zend_Db_Expr('pid.website_id'),
158: 'store_field' => new Zend_Db_Expr('pid.store_id')
159: ));
160:
161: $query = $select->insertFromSelect($idxTable);
162: $adapter->query($query);
163:
164: return $this;
165: }
166:
167: 168: 169: 170: 171: 172: 173:
174: protected function _prepareMultiselectIndex($entityIds = null, $attributeId = null)
175: {
176: $adapter = $this->_getWriteAdapter();
177:
178:
179: if (is_null($attributeId)) {
180: $attrIds = $this->_getIndexableAttributes(true);
181: } else {
182: $attrIds = array($attributeId);
183: }
184:
185: if (!$attrIds) {
186: return $this;
187: }
188:
189:
190: $options = array();
191: $select = $adapter->select()
192: ->from($this->getTable('eav/attribute_option'), array('attribute_id', 'option_id'))
193: ->where('attribute_id IN(?)', $attrIds);
194: $query = $select->query();
195: while ($row = $query->fetch()) {
196: $options[$row['attribute_id']][$row['option_id']] = true;
197: }
198:
199:
200: $productValueExpression = $adapter->getCheckSql('pvs.value_id > 0', 'pvs.value', 'pvd.value');
201: $select = $adapter->select()
202: ->from(
203: array('pvd' => $this->getValueTable('catalog/product', 'varchar')),
204: array('entity_id', 'attribute_id'))
205: ->join(
206: array('cs' => $this->getTable('core/store')),
207: '',
208: array('store_id'))
209: ->joinLeft(
210: array('pvs' => $this->getValueTable('catalog/product', 'varchar')),
211: 'pvs.entity_id = pvd.entity_id AND pvs.attribute_id = pvd.attribute_id'
212: . ' AND pvs.store_id=cs.store_id',
213: array('value' => $productValueExpression))
214: ->where('pvd.store_id=?', Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID)
215: ->where('cs.store_id!=?', Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID)
216: ->where('pvd.attribute_id IN(?)', $attrIds);
217:
218: $statusCond = $adapter->quoteInto('=?', Mage_Catalog_Model_Product_Status::STATUS_ENABLED);
219: $this->_addAttributeToSelect($select, 'status', 'pvd.entity_id', 'cs.store_id', $statusCond);
220:
221: if (!is_null($entityIds)) {
222: $select->where('pvd.entity_id IN(?)', $entityIds);
223: }
224:
225: 226: 227:
228: Mage::dispatchEvent('prepare_catalog_product_index_select', array(
229: 'select' => $select,
230: 'entity_field' => new Zend_Db_Expr('pvd.entity_id'),
231: 'website_field' => new Zend_Db_Expr('cs.website_id'),
232: 'store_field' => new Zend_Db_Expr('cs.store_id')
233: ));
234:
235: $i = 0;
236: $data = array();
237: $query = $select->query();
238: while ($row = $query->fetch()) {
239: $values = explode(',', $row['value']);
240: foreach ($values as $valueId) {
241: if (isset($options[$row['attribute_id']][$valueId])) {
242: $data[] = array(
243: $row['entity_id'],
244: $row['attribute_id'],
245: $row['store_id'],
246: $valueId
247: );
248: $i ++;
249: if ($i % 10000 == 0) {
250: $this->_saveIndexData($data);
251: $data = array();
252: }
253: }
254: }
255: }
256:
257: $this->_saveIndexData($data);
258: unset($options);
259: unset($data);
260:
261: return $this;
262: }
263:
264: 265: 266: 267: 268: 269:
270: protected function _saveIndexData(array $data)
271: {
272: if (!$data) {
273: return $this;
274: }
275: $adapter = $this->_getWriteAdapter();
276: $adapter->insertArray($this->getIdxTable(), array('entity_id', 'attribute_id', 'store_id', 'value'), $data);
277: return $this;
278: }
279:
280: 281: 282: 283: 284: 285:
286: public function getIdxTable($table = null)
287: {
288: if ($this->useIdxTable()) {
289: return $this->getTable('catalog/product_eav_indexer_idx');
290: }
291: return $this->getTable('catalog/product_eav_indexer_tmp');
292: }
293: }
294: