/** * Prepare temporary tables only for first call of reindex all * * @param int $storeId * @param array $changedIds * @param string $valueFieldSuffix * @return void */ public function build($storeId, $changedIds, $valueFieldSuffix) { if ($this->_isExecuted) { return; } $entityTableName = $this->_productIndexerHelper->getTable('catalog_product_entity'); $attributes = $this->_productIndexerHelper->getAttributes(); $eavAttributes = $this->_productIndexerHelper->getTablesStructure($attributes); $entityTableColumns = $eavAttributes[$entityTableName]; $temporaryEavAttributes = $eavAttributes; //add status global value to the base table /* @var $status \Magento\Eav\Model\Entity\Attribute */ $status = $this->_productIndexerHelper->getAttribute('status'); $temporaryEavAttributes[$status->getBackendTable()]['status'] = $status; //Create list of temporary tables based on available attributes attributes $valueTables = []; foreach ($temporaryEavAttributes as $tableName => $columns) { $valueTables = array_merge($valueTables, $this->_createTemporaryTable($this->_getTemporaryTableName($tableName), $columns, $valueFieldSuffix)); } //Fill "base" table which contains all available products $this->_fillTemporaryEntityTable($entityTableName, $entityTableColumns, $changedIds); //Add primary key to "base" temporary table for increase speed of joins in future $this->_addPrimaryKeyToTable($this->_getTemporaryTableName($entityTableName)); unset($temporaryEavAttributes[$entityTableName]); foreach ($temporaryEavAttributes as $tableName => $columns) { $temporaryTableName = $this->_getTemporaryTableName($tableName); //Add primary key to temporary table for increase speed of joins in future $this->_addPrimaryKeyToTable($temporaryTableName); //Create temporary table for composite attributes if (isset($valueTables[$temporaryTableName . $valueFieldSuffix])) { $this->_addPrimaryKeyToTable($temporaryTableName . $valueFieldSuffix); } //Fill temporary tables with attributes grouped by it type $this->_fillTemporaryTable($tableName, $columns, $changedIds, $valueFieldSuffix, $storeId); } $this->_isExecuted = true; }
/** * Fill temporary flat table by data from temporary flat table parts * * @param array $tables * @param int|string $storeId * @param string $valueFieldSuffix * @return void */ protected function _fillTemporaryFlatTable(array $tables, $storeId, $valueFieldSuffix) { $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); $select = $this->_connection->select(); $temporaryFlatTableName = $this->_getTemporaryTableName($this->_productIndexerHelper->getFlatTableName($storeId)); $flatColumns = $this->_productIndexerHelper->getFlatColumns(); $entityTableName = $this->_productIndexerHelper->getTable('catalog_product_entity'); $entityTemporaryTableName = $this->_getTemporaryTableName($entityTableName); $columnsList = array_keys($tables[$entityTableName]); $websiteId = (int) $this->_storeManager->getStore($storeId)->getWebsiteId(); unset($tables[$entityTableName]); $allColumns = array_merge(['entity_id', 'type_id', 'attribute_set_id'], $columnsList); /* @var $status \Magento\Eav\Model\Entity\Attribute */ $status = $this->_productIndexerHelper->getAttribute('status'); $statusTable = $this->_getTemporaryTableName($status->getBackendTable()); $statusConditions = [sprintf('e.%s = dstatus.%s', $linkField, $linkField), 'dstatus.store_id = ' . (int) $storeId, 'dstatus.attribute_id = ' . (int) $status->getId()]; $statusExpression = $this->_connection->getIfNullSql('dstatus.value', $this->_connection->quoteIdentifier("{$statusTable}.status")); $select->from(['e' => $entityTemporaryTableName], $allColumns)->joinInner(['wp' => $this->_productIndexerHelper->getTable('catalog_product_website')], 'wp.product_id = e.entity_id AND wp.website_id = ' . $websiteId, [])->joinLeft(['dstatus' => $status->getBackend()->getTable()], implode(' AND ', $statusConditions), [])->where($statusExpression . ' = ' . \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED); foreach ($tables as $tableName => $columns) { $columnValueNames = []; $temporaryTableName = $this->_getTemporaryTableName($tableName); $temporaryValueTableName = $temporaryTableName . $valueFieldSuffix; $columnsNames = array_keys($columns); $select->joinLeft($temporaryTableName, "e.{$linkField} = " . $temporaryTableName . ".{$linkField}", $columnsNames); $allColumns = array_merge($allColumns, $columnsNames); foreach ($columnsNames as $name) { $columnValueName = $name . $valueFieldSuffix; if (isset($flatColumns[$columnValueName])) { $columnValueNames[] = $columnValueName; } } if (!empty($columnValueNames)) { $select->joinLeft($temporaryValueTableName, "e.{$linkField} = " . $temporaryValueTableName . ".{$linkField}", $columnValueNames); $allColumns = array_merge($allColumns, $columnValueNames); } } $sql = $select->insertFromSelect($temporaryFlatTableName, $allColumns, false); $this->_connection->query($sql); }