Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
DefaultStock.php
Go to the documentation of this file.
1 <?php
8 
15 
27 {
33  protected $_typeId;
34 
40  protected $_isComposite = false;
41 
47  protected $_scopeConfig;
48 
52  private $queryProcessorComposite;
53 
59 
65  private $actionType;
66 
76  public function __construct(
77  \Magento\Framework\Model\ResourceModel\Db\Context $context,
78  \Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy,
79  \Magento\Eav\Model\Config $eavConfig,
80  \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
81  $connectionName = null
82  ) {
83  $this->_scopeConfig = $scopeConfig;
84  parent::__construct($context, $tableStrategy, $eavConfig, $connectionName);
85  }
86 
92  protected function _construct()
93  {
94  $this->_init('cataloginventory_stock_status', 'product_id');
95  }
96 
103  public function reindexAll()
104  {
105  $this->tableStrategy->setUseIdxTable(true);
106  $this->beginTransaction();
107  try {
108  $this->_prepareIndexTable();
109  $this->commit();
110  } catch (\Exception $e) {
111  $this->rollBack();
112  throw $e;
113  }
114  return $this;
115  }
116 
123  public function reindexEntity($entityIds)
124  {
125  if ($this->getActionType() === Full::ACTION_TYPE) {
126  $this->tableStrategy->setUseIdxTable(false);
127  $this->_prepareIndexTable($entityIds);
128  return $this;
129  }
130 
131  $this->_updateIndex($entityIds);
132  return $this;
133  }
134 
141  public function getActionType()
142  {
143  return $this->actionType;
144  }
145 
153  public function setActionType($type)
154  {
155  $this->actionType = $type;
156  return $this;
157  }
158 
165  public function setTypeId($typeId)
166  {
167  $this->_typeId = $typeId;
168  return $this;
169  }
170 
177  public function getTypeId()
178  {
179  if ($this->_typeId === null) {
180  throw new \Magento\Framework\Exception\LocalizedException(__('Undefined product type'));
181  }
182  return $this->_typeId;
183  }
184 
191  public function setIsComposite($flag)
192  {
193  $this->_isComposite = (bool) $flag;
194  return $this;
195  }
196 
203  public function getIsComposite()
204  {
205  return $this->_isComposite;
206  }
207 
213  protected function _isManageStock()
214  {
215  return $this->_scopeConfig->isSetFlag(
216  \Magento\CatalogInventory\Model\Configuration::XML_PATH_MANAGE_STOCK,
218  );
219  }
220 
229  protected function _getStockStatusSelect($entityIds = null, $usePrimaryTable = false)
230  {
231  $connection = $this->getConnection();
232  $qtyExpr = $connection->getCheckSql('cisi.qty > 0', 'cisi.qty', 0);
233  $metadata = $this->getMetadataPool()->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class);
234  $linkField = $metadata->getLinkField();
235 
236  $select = $connection->select()->from(
237  ['e' => $this->getTable('catalog_product_entity')],
238  ['entity_id']
239  );
240  $select->join(
241  ['cis' => $this->getTable('cataloginventory_stock')],
242  '',
243  ['website_id', 'stock_id']
244  )->joinInner(
245  ['cisi' => $this->getTable('cataloginventory_stock_item')],
246  'cisi.stock_id = cis.stock_id AND cisi.product_id = e.entity_id',
247  []
248  )->joinInner(
249  ['mcpei' => $this->getTable('catalog_product_entity_int')],
250  'e.' . $linkField . ' = mcpei.' . $linkField
251  . ' AND mcpei.attribute_id = ' . $this->_getAttribute('status')->getId()
252  . ' AND mcpei.value = ' . ProductStatus::STATUS_ENABLED,
253  []
254  )->columns(
255  ['qty' => $qtyExpr]
256  )->where(
257  'cis.website_id = ?',
258  $this->getStockConfiguration()->getDefaultScopeId()
259  )->where('e.type_id = ?', $this->getTypeId())
260  ->group(['e.entity_id', 'cis.website_id', 'cis.stock_id']);
261 
262  $select->columns(['status' => $this->getStatusExpression($connection, true)]);
263  if ($entityIds !== null) {
264  $select->where('e.entity_id IN(?)', $entityIds);
265  }
266 
267  return $select;
268  }
269 
276  protected function _prepareIndexTable($entityIds = null)
277  {
278  $connection = $this->getConnection();
279  $select = $this->_getStockStatusSelect($entityIds, true);
280  $select = $this->getQueryProcessorComposite()->processQuery($select, $entityIds);
281  $query = $select->insertFromSelect($this->getIdxTable());
282  $connection->query($query);
283 
284  return $this;
285  }
286 
293  protected function _updateIndex($entityIds)
294  {
295  $connection = $this->getConnection();
296  $select = $this->_getStockStatusSelect($entityIds, true);
297  $select = $this->getQueryProcessorComposite()->processQuery($select, $entityIds, true);
298  $query = $connection->query($select);
299 
300  $i = 0;
301  $data = [];
302  while ($row = $query->fetch(\PDO::FETCH_ASSOC)) {
303  $i++;
304  $data[] = [
305  'product_id' => (int)$row['entity_id'],
306  'website_id' => (int)$row['website_id'],
307  'stock_id' => Stock::DEFAULT_STOCK_ID,
308  'qty' => (double)$row['qty'],
309  'stock_status' => (int)$row['status'],
310  ];
311  if ($i % 1000 == 0) {
312  $this->_updateIndexTable($data);
313  $data = [];
314  }
315  }
316 
317  $this->deleteOldRecords($entityIds);
318  $this->_updateIndexTable($data);
319 
320  return $this;
321  }
322 
331  private function deleteOldRecords(array $ids)
332  {
333  if (count($ids) !== 0) {
334  $this->getConnection()->delete($this->getMainTable(), ['product_id in (?)' => $ids]);
335  }
336  }
337 
344  protected function _updateIndexTable($data)
345  {
346  if (empty($data)) {
347  return $this;
348  }
349 
350  $connection = $this->getConnection();
351  $connection->insertOnDuplicate($this->getMainTable(), $data, ['qty', 'stock_status']);
352 
353  return $this;
354  }
355 
363  public function getIdxTable($table = null)
364  {
365  return $this->tableStrategy->getTableName('cataloginventory_stock_status');
366  }
367 
374  protected function getStatusExpression(AdapterInterface $connection, $isAggregate = false)
375  {
376  $isInStockExpression = $isAggregate ? 'MAX(cisi.is_in_stock)' : 'cisi.is_in_stock';
377  if ($this->_isManageStock()) {
378  $statusExpr = $connection->getCheckSql(
379  'cisi.use_config_manage_stock = 0 AND cisi.manage_stock = 0',
380  1,
381  $isInStockExpression
382  );
383  } else {
384  $statusExpr = $connection->getCheckSql(
385  'cisi.use_config_manage_stock = 0 AND cisi.manage_stock = 1',
386  $isInStockExpression,
387  1
388  );
389  }
390  return $statusExpr;
391  }
392 
399  protected function getStockConfiguration()
400  {
401  if ($this->stockConfiguration === null) {
402  $this->stockConfiguration = \Magento\Framework\App\ObjectManager::getInstance()
403  ->get(\Magento\CatalogInventory\Api\StockConfigurationInterface::class);
404  }
406  }
407 
411  private function getQueryProcessorComposite()
412  {
413  if (null === $this->queryProcessorComposite) {
414  $this->queryProcessorComposite = \Magento\Framework\App\ObjectManager::getInstance()
415  ->get(\Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\QueryProcessorComposite::class);
416  }
417  return $this->queryProcessorComposite;
418  }
419 }
getStatusExpression(AdapterInterface $connection, $isAggregate=false)
__()
Definition: __.php:13
$type
Definition: item.phtml:13
$connection
Definition: bulk.php:13
$table
Definition: trigger.php:14
__construct(\Magento\Framework\Model\ResourceModel\Db\Context $context, \Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy, \Magento\Eav\Model\Config $eavConfig, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, $connectionName=null)
$i
Definition: gallery.phtml:31