Пример #1
0
 /**
  * Prepare temporary flat tables
  *
  * @param int|string $storeId
  * @param array $changedIds
  * @param string $valueFieldSuffix
  * @param string $tableDropSuffix
  * @param bool $fillTmpTables
  * @return void
  */
 public function build($storeId, $changedIds, $valueFieldSuffix, $tableDropSuffix, $fillTmpTables)
 {
     $attributes = $this->_productIndexerHelper->getAttributes();
     $eavAttributes = $this->_productIndexerHelper->getTablesStructure($attributes);
     $this->_createTemporaryFlatTable($storeId);
     if ($fillTmpTables) {
         $this->_fillTemporaryFlatTable($eavAttributes, $storeId, $valueFieldSuffix);
         //Update zero based attributes by values from current store
         $this->_updateTemporaryTableByStoreValues($eavAttributes, $changedIds, $storeId, $valueFieldSuffix);
     }
     $flatTable = $this->_productIndexerHelper->getFlatTableName($storeId);
     $flatDropName = $flatTable . $tableDropSuffix;
     $temporaryFlatTableName = $this->_getTemporaryTableName($this->_productIndexerHelper->getFlatTableName($storeId));
     $this->_tableData->move($flatTable, $flatDropName, $temporaryFlatTableName);
 }
Пример #2
0
 /**
  * Rebuild catalog flat index from scratch
  *
  * @param int $storeId
  * @param array $changedIds
  * @return void
  * @throws \Exception
  */
 protected function _reindex($storeId, array $changedIds = [])
 {
     try {
         $this->_tableBuilder->build($storeId, $changedIds, $this->_valueFieldSuffix);
         $this->_flatTableBuilder->build($storeId, $changedIds, $this->_valueFieldSuffix, $this->_tableDropSuffix, true);
         $this->_updateRelationProducts($storeId, $changedIds);
         $this->_cleanRelationProducts($storeId);
     } catch (\Exception $e) {
         $attributes = $this->_productIndexerHelper->getAttributes();
         $eavAttributes = $this->_productIndexerHelper->getTablesStructure($attributes);
         $this->_cleanOnFailure($eavAttributes, $storeId);
         throw $e;
     }
 }
Пример #3
0
 /**
  * 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;
 }
Пример #4
0
 /**
  * Write single product into flat product table
  *
  * @param int $storeId
  * @param int $productId
  * @param string $valueFieldSuffix
  * @return \Magento\Catalog\Model\Indexer\Product\Flat
  */
 public function write($storeId, $productId, $valueFieldSuffix = '')
 {
     $flatTable = $this->_productIndexerHelper->getFlatTableName($storeId);
     $attributes = $this->_productIndexerHelper->getAttributes();
     $eavAttributes = $this->_productIndexerHelper->getTablesStructure($attributes);
     $updateData = array();
     $describe = $this->_connection->describeTable($flatTable);
     foreach ($eavAttributes as $tableName => $tableColumns) {
         $columnsChunks = array_chunk($tableColumns, self::ATTRIBUTES_CHUNK_SIZE, true);
         foreach ($columnsChunks as $columns) {
             $select = $this->_connection->select();
             $selectValue = $this->_connection->select();
             $keyColumns = array('entity_id' => 'e.entity_id', 'attribute_id' => 't.attribute_id', 'value' => $this->_connection->getIfNullSql('`t2`.`value`', '`t`.`value`'));
             if ($tableName != $this->_productIndexerHelper->getTable('catalog_product_entity')) {
                 $valueColumns = array();
                 $ids = array();
                 $select->from(array('e' => $this->_productIndexerHelper->getTable('catalog_product_entity')), $keyColumns);
                 $selectValue->from(array('e' => $this->_productIndexerHelper->getTable('catalog_product_entity')), $keyColumns);
                 /** @var $attribute \Magento\Catalog\Model\Resource\Eav\Attribute */
                 foreach ($columns as $columnName => $attribute) {
                     if (isset($describe[$columnName])) {
                         $ids[$attribute->getId()] = $columnName;
                     }
                 }
                 $select->joinLeft(array('t' => $tableName), 'e.entity_id = t.entity_id ' . $this->_connection->quoteInto(' AND t.attribute_id IN (?)', array_keys($ids)) . ' AND t.store_id = 0', array())->joinLeft(array('t2' => $tableName), 't.entity_id = t2.entity_id ' . ' AND t.attribute_id = t2.attribute_id  ' . $this->_connection->quoteInto(' AND t2.store_id = ?', $storeId), array())->where('e.entity_id = ' . $productId)->where('t.attribute_id IS NOT NULL');
                 $cursor = $this->_connection->query($select);
                 while ($row = $cursor->fetch(\Zend_Db::FETCH_ASSOC)) {
                     $updateData[$ids[$row['attribute_id']]] = $row['value'];
                     $valueColumnName = $ids[$row['attribute_id']] . $valueFieldSuffix;
                     if (isset($describe[$valueColumnName])) {
                         $valueColumns[$row['value']] = $valueColumnName;
                     }
                 }
                 //Update not simple attributes (eg. dropdown)
                 if (!empty($valueColumns)) {
                     $valueIds = array_keys($valueColumns);
                     $select = $this->_connection->select()->from(array('t' => $this->_productIndexerHelper->getTable('eav_attribute_option_value')), array('t.option_id', 't.value'))->where($this->_connection->quoteInto('t.option_id IN (?)', $valueIds));
                     $cursor = $this->_connection->query($select);
                     while ($row = $cursor->fetch(\Zend_Db::FETCH_ASSOC)) {
                         $valueColumnName = $valueColumns[$row['option_id']];
                         if (isset($describe[$valueColumnName])) {
                             $updateData[$valueColumnName] = $row['value'];
                         }
                     }
                 }
             } else {
                 $columnNames = array_keys($columns);
                 $columnNames[] = 'attribute_set_id';
                 $columnNames[] = 'type_id';
                 $select->from(array('e' => $this->_productIndexerHelper->getTable('catalog_product_entity')), $columnNames)->where('e.entity_id = ' . $productId);
                 $cursor = $this->_connection->query($select);
                 $row = $cursor->fetch(\Zend_Db::FETCH_ASSOC);
                 if (!empty($row)) {
                     foreach ($row as $columnName => $value) {
                         $updateData[$columnName] = $value;
                     }
                 }
             }
         }
     }
     if (!empty($updateData)) {
         $updateData += array('entity_id' => $productId);
         $updateFields = array();
         foreach ($updateData as $key => $value) {
             $updateFields[$key] = $key;
         }
         $this->_connection->insertOnDuplicate($flatTable, $updateData, $updateFields);
     }
     return $this;
 }