![]() 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/Helper/Product/Flat/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Catalog\Helper\Product\Flat; use Magento\Framework\App\ResourceConnection; /** * Catalog Product Flat Indexer Helper * * @api * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @since 100.0.2 */ class Indexer extends \Magento\Framework\App\Helper\AbstractHelper { /** * Path to list of attributes used for flat indexer */ const XML_NODE_ATTRIBUTE_NODES = 'global/catalog/product/flat/attribute_groups'; /** * Size of ids batch for reindex */ const BATCH_SIZE = 500; /** * Resource instance * * @var \Magento\Framework\App\ResourceConnection */ protected $_resource; /** * @var array */ protected $_columns; /** * List of indexes uses in flat product table * * @var null|array */ protected $_indexes; /** * Retrieve catalog product flat columns array in old format (used before MMDB support) * * @return array */ protected $_attributes; /** * Required system attributes for preload * * @var array */ protected $_systemAttributes = ['status', 'required_options', 'tax_class_id', 'weight']; /** * EAV Config instance * * @var \Magento\Eav\Model\Config */ protected $_eavConfig; /** * @var \Magento\Catalog\Model\Attribute\Config */ protected $_attributeConfig; /** * @var array */ protected $_attributeCodes; /** * @var int */ protected $_entityTypeId; /** * @var \Magento\Catalog\Model\ResourceModel\Config */ protected $_catalogConfig; /** * @var array */ protected $_flatAttributeGroups = []; /** * Config factory * * @var \Magento\Catalog\Model\ResourceModel\ConfigFactory */ protected $_configFactory; /** * @var \Magento\Eav\Model\Entity\AttributeFactory */ protected $_attributeFactory; /** * @var \Magento\Store\Model\StoreManagerInterface */ protected $_storeManager; /** * @var bool */ protected $_addFilterableAttrs; /** * @var bool */ protected $_addChildData; /** * @var \Magento\Framework\Mview\View\Changelog */ protected $_changelog; /** * @param \Magento\Framework\App\Helper\Context $context * @param \Magento\Framework\App\ResourceConnection $resource * @param \Magento\Eav\Model\Config $eavConfig * @param \Magento\Catalog\Model\Attribute\Config $attributeConfig * @param \Magento\Catalog\Model\ResourceModel\ConfigFactory $configFactory * @param \Magento\Eav\Model\Entity\AttributeFactory $attributeFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\Mview\View\Changelog $changelog * @param bool $addFilterableAttrs * @param bool $addChildData * @param array $flatAttributeGroups * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( \Magento\Framework\App\Helper\Context $context, \Magento\Framework\App\ResourceConnection $resource, \Magento\Eav\Model\Config $eavConfig, \Magento\Catalog\Model\Attribute\Config $attributeConfig, \Magento\Catalog\Model\ResourceModel\ConfigFactory $configFactory, \Magento\Eav\Model\Entity\AttributeFactory $attributeFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\Mview\View\Changelog $changelog, $addFilterableAttrs = false, $addChildData = false, $flatAttributeGroups = [] ) { $this->_configFactory = $configFactory; $this->_resource = $resource; $this->_eavConfig = $eavConfig; $this->_attributeConfig = $attributeConfig; $this->_attributeFactory = $attributeFactory; $this->_flatAttributeGroups = $flatAttributeGroups; $this->_storeManager = $storeManager; $this->_changelog = $changelog; $this->_addFilterableAttrs = $addFilterableAttrs; $this->_addChildData = $addChildData; parent::__construct($context); } /** * Retrieve catalog product flat columns array in DDL format * * @return array */ public function getFlatColumnsDdlDefinition() { $columns = []; $columns['entity_id'] = [ 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, 'length' => null, 'unsigned' => true, 'nullable' => false, 'default' => false, 'primary' => true, 'comment' => 'Entity Id', ]; if ($this->isAddChildData()) { $columns['child_id'] = [ 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, 'length' => null, 'unsigned' => true, 'nullable' => true, 'default' => null, 'primary' => true, 'comment' => 'Child Id', ]; $columns['is_child'] = [ 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT, 'length' => 1, 'unsigned' => true, 'nullable' => false, 'default' => '0', 'comment' => 'Checks If Entity Is Child', ]; } $columns['attribute_set_id'] = [ 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT, 'length' => 5, 'unsigned' => true, 'nullable' => false, 'default' => '0', 'comment' => 'Attribute Set ID', ]; $columns['type_id'] = [ 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, 'length' => 32, 'unsigned' => false, 'nullable' => false, 'default' => \Magento\Catalog\Model\Product\Type::DEFAULT_TYPE, 'comment' => 'Type Id', ]; return $columns; } /** * Check whether filterable attributes should be added * * @return bool */ public function isAddFilterableAttributes() { return $this->_addFilterableAttrs; } /** * Check whether child data should be added * * @return bool */ public function isAddChildData() { return $this->_addChildData; } /** * Retrieve catalog product flat table columns array * * @return array */ public function getFlatColumns() { if ($this->_columns === null) { $this->_columns = $this->getFlatColumnsDdlDefinition(); foreach ($this->getAttributes() as $attribute) { /** @var $attribute \Magento\Eav\Model\Entity\Attribute\AbstractAttribute */ $columns = $attribute->setFlatAddFilterableAttributes( $this->isAddFilterableAttributes() )->setFlatAddChildData( $this->isAddChildData() )->getFlatColumns(); if ($columns !== null) { $this->_columns = array_merge($this->_columns, $columns); } } } return $this->_columns; } /** * Retrieve entity type * * @return string */ public function getEntityType() { return \Magento\Catalog\Model\Product::ENTITY; } /** * Retrieve Catalog Entity Type Id * * @return int */ public function getEntityTypeId() { if ($this->_entityTypeId === null) { $this->_entityTypeId = $this->_configFactory->create()->getEntityTypeId(); } return $this->_entityTypeId; } /** * Retrieve attribute objects for flat * * @return array */ public function getAttributes() { if ($this->_attributes === null) { $this->_attributes = []; $attributeCodes = $this->getAttributeCodes(); $entity = $this->_eavConfig->getEntityType($this->getEntityType())->getEntity(); foreach ($attributeCodes as $attributeCode) { $attribute = $this->_eavConfig->getAttribute( $this->getEntityType(), $attributeCode )->setEntity( $entity ); try { // check if exists source and backend model. // To prevent exception when some module was disabled $attribute->usesSource() && $attribute->getSource(); $attribute->getBackend(); $this->_attributes[$attributeCode] = $attribute; } catch (\Exception $e) { $this->_logger->critical($e); } } } return $this->_attributes; } /** * Retrieve attribute codes using for flat * * @return array */ public function getAttributeCodes() { if ($this->_attributeCodes === null) { $connection = $this->_resource->getConnection(); $this->_attributeCodes = []; foreach ($this->_flatAttributeGroups as $attributeGroupName) { $attributes = $this->_attributeConfig->getAttributeNames($attributeGroupName); $this->_systemAttributes = array_unique(array_merge($attributes, $this->_systemAttributes)); } $bind = [ 'backend_type' => \Magento\Eav\Model\Entity\Attribute\AbstractAttribute::TYPE_STATIC, 'entity_type_id' => $this->getEntityTypeId(), ]; $select = $connection->select()->from( ['main_table' => $this->getTable('eav_attribute')] )->join( ['additional_table' => $this->getTable('catalog_eav_attribute')], 'additional_table.attribute_id = main_table.attribute_id' )->where( 'main_table.entity_type_id = :entity_type_id' ); $whereCondition = [ 'main_table.backend_type = :backend_type', $connection->quoteInto('additional_table.is_used_for_promo_rules = ?', 1), $connection->quoteInto('additional_table.used_in_product_listing = ?', 1), $connection->quoteInto('additional_table.used_for_sort_by = ?', 1), $connection->quoteInto('main_table.attribute_code IN(?)', $this->_systemAttributes), ]; if ($this->isAddFilterableAttributes()) { $whereCondition[] = $connection->quoteInto('additional_table.is_filterable > ?', 0); } $select->where(implode(' OR ', $whereCondition)); $attributesData = $connection->fetchAll($select, $bind); $this->_eavConfig->importAttributesData($this->getEntityType(), $attributesData); foreach ($attributesData as $data) { $this->_attributeCodes[$data['attribute_id']] = $data['attribute_code']; } unset($attributesData); } return $this->_attributeCodes; } /** * Retrieve catalog product flat table indexes array * * @return array */ public function getFlatIndexes() { if ($this->_indexes === null) { $this->_indexes = []; if ($this->isAddChildData()) { $this->_indexes['PRIMARY'] = [ 'type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_PRIMARY, 'fields' => ['entity_id', 'child_id'], ]; $this->_indexes['IDX_CHILD'] = [ 'type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_INDEX, 'fields' => ['child_id'], ]; $this->_indexes['IDX_IS_CHILD'] = [ 'type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_INDEX, 'fields' => ['entity_id', 'is_child'], ]; } else { $this->_indexes['PRIMARY'] = [ 'type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_PRIMARY, 'fields' => ['entity_id'], ]; } $this->_indexes['IDX_TYPE_ID'] = [ 'type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_INDEX, 'fields' => ['type_id'], ]; $this->_indexes['IDX_ATTRIBUTE_SET'] = [ 'type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_INDEX, 'fields' => ['attribute_set_id'], ]; foreach ($this->getAttributes() as $attribute) { /** @var $attribute \Magento\Eav\Model\Entity\Attribute */ $indexes = $attribute->setFlatAddFilterableAttributes( $this->isAddFilterableAttributes() )->setFlatAddChildData( $this->isAddChildData() )->getFlatIndexes(); if ($indexes !== null) { $this->_indexes = array_merge($this->_indexes, $indexes); } } } return $this->_indexes; } /** * Get table structure for temporary eav tables * * @param array $attributes * @return array */ public function getTablesStructure(array $attributes) { $eavAttributes = []; $flatColumnsList = $this->getFlatColumns(); /** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */ foreach ($attributes as $attribute) { $eavTable = $attribute->getBackend()->getTable(); $attributeCode = $attribute->getAttributeCode(); if (isset($flatColumnsList[$attributeCode])) { $eavAttributes[$eavTable][$attributeCode] = $attribute; } } return $eavAttributes; } /** * Returns table name * * @param string|array $name * @return string */ public function getTable($name) { return $this->_resource->getTableName($name); } /** * Retrieve Catalog Product Flat Table name * * @param int $storeId * @return string */ public function getFlatTableName($storeId) { return sprintf('%s_%s', $this->getTable('catalog_product_flat'), $storeId); } /** * Retrieve loaded attribute by code * * @param string $attributeCode * @throws \Magento\Framework\Exception\LocalizedException * @return \Magento\Eav\Model\Entity\Attribute */ public function getAttribute($attributeCode) { $attributes = $this->getAttributes(); if (!isset($attributes[$attributeCode])) { $attribute = $this->_attributeFactory->create(); $attribute->loadByCode($this->getEntityTypeId(), $attributeCode); if (!$attribute->getId()) { throw new \Magento\Framework\Exception\LocalizedException(__('Invalid attribute %1', $attributeCode)); } $entity = $this->_eavConfig->getEntityType($this->getEntityType())->getEntity(); $attribute->setEntity($entity); return $attribute; } return $attributes[$attributeCode]; } /** * Delete all product flat tables for not existing stores * * @return void */ public function deleteAbandonedStoreFlatTables() { $connection = $this->_resource->getConnection(); $existentTables = $connection->getTables($connection->getTableName('catalog_product_flat_%')); $this->_changelog->setViewId('catalog_product_flat'); foreach ($existentTables as $key => $tableName) { if ($this->_changelog->getName() == $tableName) { unset($existentTables[$key]); } } $actualStoreTables = []; foreach ($this->_storeManager->getStores() as $store) { $actualStoreTables[] = $this->getFlatTableName($store->getId()); } $tablesToDelete = array_diff($existentTables, $actualStoreTables); foreach ($tablesToDelete as $table) { $connection->dropTable($table); } } }