PageRenderTime 26ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/magento/module-catalog/Model/Indexer/Product/Flat/AbstractAction.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 317 lines | 175 code | 30 blank | 112 comment | 18 complexity | 747aecc1236e61f273166855211dcb1a MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Catalog\Model\Indexer\Product\Flat;
  7. use Magento\Framework\App\ResourceConnection;
  8. /**
  9. * Abstract action reindex class
  10. *
  11. */
  12. abstract class AbstractAction
  13. {
  14. /**
  15. * Suffix for value field on composite attributes
  16. *
  17. * @var string
  18. */
  19. protected $_valueFieldSuffix = '_value';
  20. /**
  21. * Suffix for drop table (uses on flat table rename)
  22. *
  23. * @var string
  24. */
  25. protected $_tableDropSuffix = '_drop_indexer';
  26. /**
  27. * @var \Magento\Store\Model\StoreManagerInterface
  28. */
  29. protected $_storeManager;
  30. /**
  31. * @var \Magento\Catalog\Helper\Product\Flat\Indexer
  32. */
  33. protected $_productIndexerHelper;
  34. /**
  35. * @var \Magento\Framework\DB\Adapter\AdapterInterface
  36. */
  37. protected $_connection;
  38. /**
  39. * @var \Magento\Catalog\Model\Product\Type
  40. */
  41. protected $_productType;
  42. /**
  43. * Existing flat tables flags pool
  44. *
  45. * @var array
  46. */
  47. protected $_flatTablesExist = [];
  48. /**
  49. * List of product types available in installation
  50. *
  51. * @var array
  52. */
  53. protected $_productTypes = [];
  54. /**
  55. * @var TableBuilder
  56. */
  57. protected $_tableBuilder;
  58. /**
  59. * @var FlatTableBuilder
  60. */
  61. protected $_flatTableBuilder;
  62. /**
  63. * @param \Magento\Framework\App\ResourceConnection $resource
  64. * @param \Magento\Store\Model\StoreManagerInterface $storeManager
  65. * @param \Magento\Catalog\Helper\Product\Flat\Indexer $productHelper
  66. * @param \Magento\Catalog\Model\Product\Type $productType
  67. * @param TableBuilder $tableBuilder
  68. * @param FlatTableBuilder $flatTableBuilder
  69. */
  70. public function __construct(
  71. \Magento\Framework\App\ResourceConnection $resource,
  72. \Magento\Store\Model\StoreManagerInterface $storeManager,
  73. \Magento\Catalog\Helper\Product\Flat\Indexer $productHelper,
  74. \Magento\Catalog\Model\Product\Type $productType,
  75. TableBuilder $tableBuilder,
  76. FlatTableBuilder $flatTableBuilder
  77. ) {
  78. $this->_storeManager = $storeManager;
  79. $this->_productIndexerHelper = $productHelper;
  80. $this->_productType = $productType;
  81. $this->_connection = $resource->getConnection();
  82. $this->_tableBuilder = $tableBuilder;
  83. $this->_flatTableBuilder = $flatTableBuilder;
  84. }
  85. /**
  86. * Execute action for given ids
  87. *
  88. * @param array|int $ids
  89. * @return \Magento\Catalog\Model\Indexer\Product\Flat\AbstractAction
  90. */
  91. abstract public function execute($ids);
  92. /**
  93. * Return temporary table name by regular table name
  94. *
  95. * @param string $tableName
  96. * @return string
  97. */
  98. protected function _getTemporaryTableName($tableName)
  99. {
  100. return sprintf('%s_tmp_indexer', $tableName);
  101. }
  102. /**
  103. * Drop temporary tables created by reindex process
  104. *
  105. * @param array $tablesList
  106. * @param int|string $storeId
  107. * @return void
  108. * @SuppressWarnings(PHPMD.UnusedLocalVariable)
  109. */
  110. protected function _cleanOnFailure(array $tablesList, $storeId)
  111. {
  112. foreach ($tablesList as $table => $columns) {
  113. $this->_connection->dropTemporaryTable($table);
  114. }
  115. $tableName = $this->_getTemporaryTableName($this->_productIndexerHelper->getFlatTableName($storeId));
  116. $this->_connection->dropTable($tableName);
  117. }
  118. /**
  119. * Rebuild catalog flat index from scratch
  120. *
  121. * @param int $storeId
  122. * @param array $changedIds
  123. * @return void
  124. * @throws \Exception
  125. */
  126. protected function _reindex($storeId, array $changedIds = [])
  127. {
  128. try {
  129. $this->_tableBuilder->build($storeId, $changedIds, $this->_valueFieldSuffix);
  130. $this->_flatTableBuilder->build(
  131. $storeId,
  132. $changedIds,
  133. $this->_valueFieldSuffix,
  134. $this->_tableDropSuffix,
  135. true
  136. );
  137. $this->_updateRelationProducts($storeId, $changedIds);
  138. $this->_cleanRelationProducts($storeId);
  139. } catch (\Exception $e) {
  140. $attributes = $this->_productIndexerHelper->getAttributes();
  141. $eavAttributes = $this->_productIndexerHelper->getTablesStructure($attributes);
  142. $this->_cleanOnFailure($eavAttributes, $storeId);
  143. throw $e;
  144. }
  145. }
  146. /**
  147. * Retrieve Product Type Instances
  148. * as key - type code, value - instance model
  149. *
  150. * @return array
  151. */
  152. protected function _getProductTypeInstances()
  153. {
  154. if ($this->_productTypes === null) {
  155. $this->_productTypes = [];
  156. $productEmulator = new \Magento\Framework\DataObject();
  157. foreach (array_keys($this->_productType->getTypes()) as $typeId) {
  158. $productEmulator->setTypeId($typeId);
  159. $this->_productTypes[$typeId] = $this->_productType->factory($productEmulator);
  160. }
  161. }
  162. return $this->_productTypes;
  163. }
  164. /**
  165. * Update relation products
  166. *
  167. * @param int $storeId
  168. * @param int|array $productIds Update child product(s) only
  169. * @return \Magento\Catalog\Model\Indexer\Product\Flat\AbstractAction
  170. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  171. */
  172. protected function _updateRelationProducts($storeId, $productIds = null)
  173. {
  174. if (!$this->_productIndexerHelper->isAddChildData() || !$this->_isFlatTableExists($storeId)) {
  175. return $this;
  176. }
  177. foreach ($this->_getProductTypeInstances() as $typeInstance) {
  178. /** @var $typeInstance \Magento\Catalog\Model\Product\Type\AbstractType */
  179. if (!$typeInstance->isComposite(null)) {
  180. continue;
  181. }
  182. $relation = $typeInstance->getRelationInfo();
  183. if ($relation && $relation->getTable() && $relation->getParentFieldName() && $relation->getChildFieldName()
  184. ) {
  185. $columns = $this->_productIndexerHelper->getFlatColumns();
  186. $fieldList = array_keys($columns);
  187. unset($columns['entity_id']);
  188. unset($columns['child_id']);
  189. unset($columns['is_child']);
  190. /** @var $select \Magento\Framework\DB\Select */
  191. $select = $this->_connection->select()->from(
  192. ['t' => $this->_productIndexerHelper->getTable($relation->getTable())],
  193. [$relation->getParentFieldName(), $relation->getChildFieldName(), new \Zend_Db_Expr('1')]
  194. )->join(
  195. ['e' => $this->_productIndexerHelper->getFlatTableName($storeId)],
  196. "e.entity_id = t.{$relation->getChildFieldName()}",
  197. array_keys($columns)
  198. );
  199. if ($relation->getWhere() !== null) {
  200. $select->where($relation->getWhere());
  201. }
  202. if ($productIds !== null) {
  203. $cond = [
  204. $this->_connection->quoteInto("{$relation->getChildFieldName()} IN(?)", $productIds),
  205. $this->_connection->quoteInto("{$relation->getParentFieldName()} IN(?)", $productIds),
  206. ];
  207. $select->where(implode(' OR ', $cond));
  208. }
  209. $sql = $select->insertFromSelect($this->_productIndexerHelper->getFlatTableName($storeId), $fieldList);
  210. $this->_connection->query($sql);
  211. }
  212. }
  213. return $this;
  214. }
  215. /**
  216. * Clean unused relation products
  217. *
  218. * @param int $storeId
  219. * @return \Magento\Catalog\Model\Indexer\Product\Flat\AbstractAction
  220. */
  221. protected function _cleanRelationProducts($storeId)
  222. {
  223. if (!$this->_productIndexerHelper->isAddChildData()) {
  224. return $this;
  225. }
  226. foreach ($this->_getProductTypeInstances() as $typeInstance) {
  227. /** @var $typeInstance \Magento\Catalog\Model\Product\Type\AbstractType */
  228. if (!$typeInstance->isComposite(null)) {
  229. continue;
  230. }
  231. $relation = $typeInstance->getRelationInfo();
  232. if ($relation && $relation->getTable() && $relation->getParentFieldName() && $relation->getChildFieldName()
  233. ) {
  234. $select = $this->_connection->select()->distinct(
  235. true
  236. )->from(
  237. $this->_productIndexerHelper->getTable($relation->getTable()),
  238. "{$relation->getParentFieldName()}"
  239. );
  240. $joinLeftCond = [
  241. "e.entity_id = t.{$relation->getParentFieldName()}",
  242. "e.child_id = t.{$relation->getChildFieldName()}",
  243. ];
  244. if ($relation->getWhere() !== null) {
  245. $select->where($relation->getWhere());
  246. $joinLeftCond[] = $relation->getWhere();
  247. }
  248. $entitySelect = new \Zend_Db_Expr($select->__toString());
  249. /** @var $select \Magento\Framework\DB\Select */
  250. $select = $this->_connection->select()->from(
  251. ['e' => $this->_productIndexerHelper->getFlatTableName($storeId)],
  252. null
  253. )->joinLeft(
  254. ['t' => $this->_productIndexerHelper->getTable($relation->getTable())],
  255. implode(' AND ', $joinLeftCond),
  256. []
  257. )->where(
  258. 'e.is_child = ?',
  259. 1
  260. )->where(
  261. 'e.entity_id IN(?)',
  262. $entitySelect
  263. )->where(
  264. "t.{$relation->getChildFieldName()} IS NULL"
  265. );
  266. $sql = $select->deleteFromSelect('e');
  267. $this->_connection->query($sql);
  268. }
  269. }
  270. return $this;
  271. }
  272. /**
  273. * Check is flat table for store exists
  274. *
  275. * @param int $storeId
  276. * @return bool
  277. */
  278. protected function _isFlatTableExists($storeId)
  279. {
  280. if (!isset($this->_flatTablesExist[$storeId])) {
  281. $tableName = $this->_productIndexerHelper->getFlatTableName($storeId);
  282. $isTableExists = $this->_connection->isTableExists($tableName);
  283. $this->_flatTablesExist[$storeId] = $isTableExists ? true : false;
  284. }
  285. return $this->_flatTablesExist[$storeId];
  286. }
  287. }