![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/magento/module-catalog/Model/Indexer/Category/Flat/Action/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Catalog\Model\Indexer\Category\Flat\Action; use Magento\Catalog\Api\CategoryRepositoryInterface; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Store\Model\Store; class Rows extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction { /** * @var CategoryRepositoryInterface */ protected $categoryRepository; /** * @param \Magento\Framework\App\ResourceConnection $resource * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param CategoryRepositoryInterface $categoryRepository */ public function __construct( \Magento\Framework\App\ResourceConnection $resource, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, CategoryRepositoryInterface $categoryRepository ) { $this->categoryRepository = $categoryRepository; parent::__construct($resource, $storeManager, $resourceHelper); } /** * Return index table name * * @param Store $store * @param bool $useTempTable * @return string */ protected function getTableNameByStore(Store $store, $useTempTable) { $tableName = $this->getMainStoreTable($store->getId()); return $useTempTable ? $this->addTemporaryTableSuffix($tableName) : $tableName; } /** * Refresh entities index * * @param int[] $entityIds * @param bool $useTempTable * @return Rows */ public function reindex(array $entityIds = [], $useTempTable = false) { $stores = $this->storeManager->getStores(); foreach ($stores as $store) { $this->reindexStore($store, $entityIds, $useTempTable); } return $this; } /** * Delete non stores categories * * @param Store $store * @param bool $useTempTable * @return void */ protected function deleteNonStoreCategories(Store $store, $useTempTable) { $rootId = \Magento\Catalog\Model\Category::TREE_ROOT_ID; $rootIdExpr = $this->connection->quote((string)$rootId); $rootCatIdExpr = $this->connection->quote("{$rootId}/{$store->getRootCategoryId()}"); $catIdExpr = $this->connection->quote("{$rootId}/{$store->getRootCategoryId()}/%"); /** @var \Magento\Framework\DB\Select $select */ $select = $this->connection->select()->from( ['cf' => $this->getTableNameByStore($store, $useTempTable)] )->where( "cf.path = {$rootIdExpr} OR cf.path = {$rootCatIdExpr} OR cf.path like {$catIdExpr}" )->where( 'cf.entity_id NOT IN (?)', new \Zend_Db_Expr( $this->connection->select()->from( ['ce' => $this->getTableName('catalog_category_entity')], ['entity_id'] ) ) ); $sql = $select->deleteFromSelect('cf'); $this->connection->query($sql); } /** * Filter category ids by store * * @param int[] $ids * @param Store $store * @return int[] */ protected function filterIdsByStore(array $ids, $store) { $rootId = \Magento\Catalog\Model\Category::TREE_ROOT_ID; $rootIdExpr = $this->connection->quote((string)$rootId); $rootCatIdExpr = $this->connection->quote("{$rootId}/{$store->getRootCategoryId()}"); $catIdExpr = $this->connection->quote("{$rootId}/{$store->getRootCategoryId()}/%"); $select = $this->connection->select()->from( $this->getTableName('catalog_category_entity'), ['entity_id'] )->where( "path = {$rootIdExpr} OR path = {$rootCatIdExpr} OR path like {$catIdExpr}" )->where( "entity_id IN (?)", $ids, \Zend_Db::INT_TYPE ); $resultIds = []; foreach ($this->connection->fetchAll($select) as $category) { $resultIds[] = $category['entity_id']; } return $resultIds; } /** * Reindex data for store * * @param Store $store * @param int[] $entityIds * @param bool $useTempTable */ private function reindexStore(Store $store, array $entityIds, $useTempTable) { $tableName = $this->getTableNameByStore($store, $useTempTable); if (!$this->connection->isTableExists($tableName)) { return; } $categoriesIdsChunks = array_chunk($entityIds, 500); foreach ($categoriesIdsChunks as $categoriesIdsChunk) { $categoriesIdsChunk = $this->filterIdsByStore($categoriesIdsChunk, $store); $attributesData = $this->getAttributeValues($categoriesIdsChunk, $store->getId()); $indexData = $this->buildIndexData($store, $categoriesIdsChunk, $attributesData); $this->updateIndexData($tableName, $indexData); } $this->deleteNonStoreCategories($store, $useTempTable); } /** * Build data for insert into index * * @param Store $store * @param int[] $categoriesIdsChunk * @param array[] $attributesData * @return array */ private function buildIndexData(Store $store, $categoriesIdsChunk, $attributesData) { $linkField = $this->categoryMetadata->getLinkField(); $data = []; foreach ($categoriesIdsChunk as $categoryId) { try { $category = $this->categoryRepository->get($categoryId); } catch (NoSuchEntityException $e) { continue; } $categoryData = $category->getData(); $linkId = $categoryData[$linkField]; $categoryAttributesData = []; if (isset($attributesData[$linkId]) && is_array($attributesData[$linkId])) { $categoryAttributesData = $attributesData[$linkId]; } $categoryIndexData = $this->buildCategoryIndexData( $store, $categoryData, $categoryAttributesData ); $data[] = $categoryIndexData; } return $data; } /** * Prepare Category data * * @param Store $store * @param array $categoryData * @param array $categoryAttributesData * @return array * @throws NoSuchEntityException */ private function buildCategoryIndexData(Store $store, array $categoryData, array $categoryAttributesData) { $data = $this->prepareValuesToInsert( array_merge( $categoryData, $categoryAttributesData, ['store_id' => $store->getId()] ) ); return $data; } /** * Insert or update index data * * @param string $tableName * @param array $data * @return void */ private function updateIndexData($tableName, $data) { foreach ($data as $row) { $updateFields = []; foreach (array_keys($row) as $key) { $updateFields[$key] = $key; } $this->connection->insertOnDuplicate($tableName, $row, $updateFields); } } }