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_CatalogInventory_Model_Resource_Indexer_Stock_Default
36: extends Mage_Catalog_Model_Resource_Product_Indexer_Abstract
37: implements Mage_CatalogInventory_Model_Resource_Indexer_Stock_Interface
38: {
39: 40: 41: 42: 43:
44: protected $_typeId;
45:
46: 47: 48: 49: 50:
51: protected $_isComposite = false;
52:
53: 54: 55: 56:
57: protected function _construct()
58: {
59: $this->_init('cataloginventory/stock_status', 'product_id');
60: }
61:
62: 63: 64: 65: 66:
67: public function reindexAll()
68: {
69: $this->useIdxTable(true);
70: $this->beginTransaction();
71: try {
72: $this->_prepareIndexTable();
73: $this->commit();
74: } catch (Exception $e) {
75: $this->rollBack();
76: throw $e;
77: }
78: return $this;
79: }
80:
81: 82: 83: 84: 85: 86:
87: public function reindexEntity($entityIds)
88: {
89: $this->_updateIndex($entityIds);
90: return $this;
91: }
92:
93: 94: 95: 96: 97: 98:
99: public function setTypeId($typeId)
100: {
101: $this->_typeId = $typeId;
102: return $this;
103: }
104:
105: 106: 107: 108: 109: 110: 111:
112: public function getTypeId()
113: {
114: if (is_null($this->_typeId)) {
115: Mage::throwException(Mage::helper('cataloginventory')->__('Undefined product type.'));
116: }
117: return $this->_typeId;
118: }
119:
120: 121: 122: 123: 124: 125:
126: public function setIsComposite($flag)
127: {
128: $this->_isComposite = (bool)$flag;
129: return $this;
130: }
131:
132: 133: 134: 135: 136:
137: public function getIsComposite()
138: {
139: return $this->_isComposite;
140: }
141:
142: 143: 144: 145: 146:
147: protected function _isManageStock()
148: {
149: return Mage::getStoreConfigFlag(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_MANAGE_STOCK);
150: }
151:
152: 153: 154: 155: 156: 157: 158:
159: protected function _getStockStatusSelect($entityIds = null, $usePrimaryTable = false)
160: {
161: $adapter = $this->_getWriteAdapter();
162: $qtyExpr = $adapter->getCheckSql('cisi.qty > 0', 'cisi.qty', 0);
163: $select = $adapter->select()
164: ->from(array('e' => $this->getTable('catalog/product')), array('entity_id'));
165: $this->_addWebsiteJoinToSelect($select, true);
166: $this->_addProductWebsiteJoinToSelect($select, 'cw.website_id', 'e.entity_id');
167: $select->columns('cw.website_id')
168: ->join(
169: array('cis' => $this->getTable('cataloginventory/stock')),
170: '',
171: array('stock_id'))
172: ->joinLeft(
173: array('cisi' => $this->getTable('cataloginventory/stock_item')),
174: 'cisi.stock_id = cis.stock_id AND cisi.product_id = e.entity_id',
175: array())
176: ->columns(array('qty' => $qtyExpr))
177: ->where('cw.website_id != 0')
178: ->where('e.type_id = ?', $this->getTypeId());
179:
180:
181: $condition = $adapter->quoteInto('=?', Mage_Catalog_Model_Product_Status::STATUS_ENABLED);
182: $this->_addAttributeToSelect($select, 'status', 'e.entity_id', 'cs.store_id', $condition);
183:
184: if ($this->_isManageStock()) {
185: $statusExpr = $adapter->getCheckSql('cisi.use_config_manage_stock = 0 AND cisi.manage_stock = 0',
186: 1, 'cisi.is_in_stock');
187: } else {
188: $statusExpr = $adapter->getCheckSql('cisi.use_config_manage_stock = 0 AND cisi.manage_stock = 1',
189: 'cisi.is_in_stock', 1);
190: }
191:
192: $select->columns(array('status' => $statusExpr));
193:
194: if (!is_null($entityIds)) {
195: $select->where('e.entity_id IN(?)', $entityIds);
196: }
197:
198: return $select;
199: }
200:
201: 202: 203: 204: 205: 206:
207: protected function _prepareIndexTable($entityIds = null)
208: {
209: $adapter = $this->_getWriteAdapter();
210: $select = $this->_getStockStatusSelect($entityIds);
211: $query = $select->insertFromSelect($this->getIdxTable());
212: $adapter->query($query);
213:
214: return $this;
215: }
216:
217: 218: 219: 220: 221: 222:
223: protected function _updateIndex($entityIds)
224: {
225: $adapter = $this->_getWriteAdapter();
226: $select = $this->_getStockStatusSelect($entityIds, true);
227: $query = $adapter->query($select);
228:
229: $i = 0;
230: $data = array();
231: while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
232: $i ++;
233: $data[] = array(
234: 'product_id' => (int)$row['entity_id'],
235: 'website_id' => (int)$row['website_id'],
236: 'stock_id' => (int)$row['stock_id'],
237: 'qty' => (float)$row['qty'],
238: 'stock_status' => (int)$row['status'],
239: );
240: if (($i % 1000) == 0) {
241: $this->_updateIndexTable($data);
242: $data = array();
243: }
244: }
245: $this->_updateIndexTable($data);
246:
247: return $this;
248: }
249:
250: 251: 252: 253: 254: 255:
256: protected function _updateIndexTable($data)
257: {
258: if (empty($data)) {
259: return $this;
260: }
261:
262: $adapter = $this->_getWriteAdapter();
263: $adapter->insertOnDuplicate($this->getMainTable(), $data, array('qty', 'stock_status'));
264:
265: return $this;
266: }
267:
268: 269: 270: 271: 272: 273:
274: public function getIdxTable($table = null)
275: {
276: if ($this->useIdxTable()) {
277: return $this->getTable('cataloginventory/stock_status_indexer_idx');
278: }
279: return $this->getTable('cataloginventory/stock_status_indexer_tmp');
280: }
281: }
282: