![]() 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/Console/Command/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Catalog\Console\Command; use Magento\Framework\DB\Adapter\AdapterInterface; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Magento\Catalog\Api\Data\ProductInterface; /** * Class ProductAttributesCleanUp * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class ProductAttributesCleanUp extends \Symfony\Component\Console\Command\Command { /** * @var \Magento\Catalog\Api\ProductAttributeRepositoryInterface */ protected $productAttributeRepository; /** * @var \Magento\Framework\Api\SearchCriteriaBuilder */ protected $searchCriteriaBuilder; /** * @var \Magento\Catalog\Model\ResourceModel\Attribute */ protected $attributeResource; /** * @var \Magento\Framework\App\State */ protected $appState; /** * @var \Magento\Framework\EntityManager\EntityMetadata */ protected $metadata; /** * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $productAttributeRepository * @param \Magento\Catalog\Model\ResourceModel\Attribute $attributeResource * @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder * @param \Magento\Framework\App\State $appState * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool */ public function __construct( \Magento\Catalog\Api\ProductAttributeRepositoryInterface $productAttributeRepository, \Magento\Catalog\Model\ResourceModel\Attribute $attributeResource, \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder, \Magento\Framework\App\State $appState, \Magento\Framework\EntityManager\MetadataPool $metadataPool ) { $this->productAttributeRepository = $productAttributeRepository; $this->searchCriteriaBuilder = $searchCriteriaBuilder; $this->attributeResource = $attributeResource; $this->appState = $appState; $this->metadata = $metadataPool->getMetadata(ProductInterface::class); parent::__construct(); } /** * {@inheritdoc} */ protected function configure() { $this->setName('catalog:product:attributes:cleanup'); $this->setDescription('Removes unused product attributes.'); } /** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $output->setDecorated(true); $this->appState->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL); $connection = $this->attributeResource->getConnection(); $attributeTables = $this->getAttributeTables(); $progress = new \Symfony\Component\Console\Helper\ProgressBar($output, count($attributeTables)); $progress->setFormat('<comment>%message%</comment> %current%/%max% [%bar%] %percent:3s%% %elapsed%'); $this->attributeResource->beginTransaction(); try { // Find and remove unused attributes foreach ($attributeTables as $attributeTable) { $progress->setMessage($attributeTable . ' '); $affectedIds = $this->getAffectedAttributeIds($connection, $attributeTable); if (count($affectedIds) > 0) { $connection->delete($attributeTable, ['value_id in (?)' => $affectedIds]); } $progress->advance(); } $this->attributeResource->commit(); $output->writeln(""); $output->writeln("<info>Unused product attributes successfully cleaned up:</info>"); $output->writeln("<comment> " . implode("\n ", $attributeTables) . "</comment>"); return \Magento\Framework\Console\Cli::RETURN_SUCCESS; } catch (\Exception $exception) { $this->attributeResource->rollBack(); $output->writeln(""); $output->writeln("<error>{$exception->getMessage()}</error>"); // we must have an exit code higher than zero to indicate something was wrong return \Magento\Framework\Console\Cli::RETURN_FAILURE; } } /** * @return array * @throws \Magento\Framework\Exception\LocalizedException */ private function getAttributeTables() { $searchResult = $this->productAttributeRepository->getList($this->searchCriteriaBuilder->create()); $attributeTables = []; /** @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute $productAttribute */ foreach ($searchResult->getItems() as $productAttribute) { $attributeTable = $productAttribute->getBackend()->getTable(); if (!in_array($attributeTable, $attributeTables) && $attributeTable != $this->attributeResource->getTable('catalog_product_entity') ) { $attributeTables[] = $attributeTable; } } return $attributeTables; } /** * @param AdapterInterface $connection * @param string $attributeTableName * @return array * @throws \Zend_Db_Statement_Exception */ private function getAffectedAttributeIds(AdapterInterface $connection, $attributeTableName) { $linkField = $this->metadata->getLinkField(); $select = $connection->select()->reset(); $select->from(['e' => $this->attributeResource->getTable('catalog_product_entity')], 'ei.value_id'); $select->join( ['ei' => $attributeTableName], 'ei.' . $linkField . ' = e.' . $linkField . ' AND ei.store_id != 0', '' ); $select->join(['s' => $this->attributeResource->getTable('store')], 's.store_id = ei.store_id', ''); $select->join(['sg' => $this->attributeResource->getTable('store_group')], 'sg.group_id = s.group_id', ''); $select->joinLeft( ['pw' => $this->attributeResource->getTable('catalog_product_website')], 'pw.website_id = sg.website_id AND pw.product_id = e.entity_id', '' ); $select->where('pw.product_id is null'); return $connection->fetchCol($select); } }