Spamworldpro Mini Shell
Spamworldpro


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/cartforge.co/app/code/Amasty/Label/Model/Indexer/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/corals/cartforge.co/app/code/Amasty/Label/Model/Indexer/IndexBuilder.php
<?php
/**
 * @author Amasty Team
 * @copyright Copyright (c) Amasty (https://www.amasty.com)
 * @package Product Labels for Magento 2
 */

namespace Amasty\Label\Model\Indexer;

use Amasty\Label\Api\Data\LabelInterface;
use Amasty\Label\Model\Label;
use Amasty\Label\Model\Label\GetMatchedProductIdsInterface;
use Amasty\Label\Model\ResourceModel\Indexer\ProductTypeDataProvider;
use Amasty\Label\Model\ResourceModel\Label\Collection as LabelCollection;
use Amasty\Label\Model\ResourceModel\Label\CollectionFactory;
use Amasty\Label\Setup\Uninstall;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ProductRepository;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollectionFactory;
use Magento\CatalogRule\Model\Indexer\IndexerTableSwapperInterface as TableSwapper;
use Magento\Framework\App\CacheInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\DB\Select;
use Magento\Framework\Event\ManagerInterface;
use Magento\Framework\Exception\LocalizedException;
use Psr\Log\LoggerInterface;

/**
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 * @SuppressWarnings(PHPMD.ExcessiveParameterList)
 */
class IndexBuilder
{
    public const PRODUCT_ID = 'product_id';
    public const STORE_ID = 'store_id';

    /**
     * @var bool
     */
    private $isFullIndexRunning = false;

    /**
     * @var LabelCollection|null
     */
    private $fullLabelCollection = null;

    /**
     * @var ResourceConnection
     */
    private $resource;

    /**
     * @var LoggerInterface
     */
    private $logger;

    /**
     * @var AdapterInterface
     */
    private $connection;

    /**
     * @var CollectionFactory
     */
    private $collectionFactory;

    /**
     * @var ProductRepository
     */
    private $productRepository;

    /**
     * @var int
     */
    private $batchCount;

    /**
     * @var ProductCollectionFactory
     */
    private $productCollectionFactory;

    /**
     * @var CacheContext
     */
    private $cacheContext;

    /**
     * @var ManagerInterface
     */
    private $eventManager;

    /**
     * @var int
     */
    private $batchCacheCount;

    /**
     * @var GetMatchedProductIdsInterface
     */
    private $getMatchedProductIds;

    /**
     * @var ProductTypeDataProvider
     */
    private $productTypeDataProvider;

    /**
     * @var TableSwapper
     */
    private $tableSwapper;

    /**
     * @var CacheInterface
     */
    private $cache;

    public function __construct(
        ResourceConnection $resource,
        LoggerInterface $logger,
        CollectionFactory $collectionFactory,
        ProductRepository $productRepository,
        ProductCollectionFactory $productCollectionFactory,
        CacheContext $cacheContext,
        ManagerInterface $eventManager,
        GetMatchedProductIdsInterface $getMatchedProductIds,
        ProductTypeDataProvider $productTypeDataProvider,
        $batchCount = 1000,
        $batchCacheCount = 100,
        TableSwapper $tableSwapper = null, // TODO move to not optional
        CacheInterface $cache = null // TODO move to not optional
    ) {
        $this->resource = $resource;
        $this->connection = $resource->getConnection();
        $this->logger = $logger;
        $this->collectionFactory = $collectionFactory;
        $this->productRepository = $productRepository;
        $this->batchCount = $batchCount;
        $this->productCollectionFactory = $productCollectionFactory;
        $this->cacheContext = $cacheContext;
        $this->eventManager = $eventManager;
        $this->batchCacheCount = $batchCacheCount;
        $this->getMatchedProductIds = $getMatchedProductIds;
        $this->productTypeDataProvider = $productTypeDataProvider;
        $this->tableSwapper = $tableSwapper ?? ObjectManager::getInstance()->get(TableSwapper::class);
        $this->cache = $cache ?? ObjectManager::getInstance()->get(CacheInterface::class);
    }

    /**
     * Reindex by ids
     *
     * @param array $ids
     * @return void
     * @throws LocalizedException
     * @api
     */
    public function reindexByProductIds(array $ids)
    {
        $connection = $this->resource->getConnection();
        $connection->beginTransaction();
        try {
            $this->cleanByProductIds($ids);
            $this->doReindexByProductIds($ids);
            $connection->commit();
        } catch (\Exception $e) {
            $connection->rollBack();
            $this->logger->critical($e);
            throw new LocalizedException(
                __("Amasty label indexing failed. See details in exception log.")
            );
        }
    }

    /**
     * Reindex by label ids
     *
     * @param array $ids
     * @return void
     * @throws LocalizedException
     * @api
     */
    public function reindexByLabelIds($ids)
    {
        $connection = $this->resource->getConnection();
        $connection->beginTransaction();

        try {
            $this->cleanByLabelIds($ids);
            $this->doReindexByLabelIds($ids);
            $connection->commit();
        } catch (\Exception $e) {
            $connection->rollBack();
            $this->logger->critical($e);
            throw new LocalizedException(
                __("Amasty label indexing failed. See details in exception log.")
            );
        }
    }

    /**
     * @param $id
     * @throws LocalizedException
     */
    public function reindexByProductId($id)
    {
        $this->reindexByProductIds((array) $id);
    }

    /**
     * @param $id
     * @throws LocalizedException
     */
    public function reindexByLabelId($id)
    {
        $this->reindexByLabelIds([$id]);
    }

    /**
     * @param int[] $productIds
     */
    private function cleanByProductIds(array $productIds)
    {
        if (!empty($productIds)) {
            $connection = $this->resource->getConnection();
            $connection->delete(
                $this->getIndexTable(),
                $connection->prepareSqlCondition(self::PRODUCT_ID, ['in' => $productIds])
            );
        }
    }

    private function getMainTable(): string
    {
        return $this->resource->getTableName(Uninstall::AMASTY_LABEL_INDEX_TABLE);
    }

    private function getTmpTable(): string
    {
        return $this->tableSwapper->getWorkingTableName(
            $this->resource->getTableName(Uninstall::AMASTY_LABEL_INDEX_TABLE)
        );
    }

    private function getIndexTable(): string
    {
        return $this->isFullIndexRunning ? $this->getTmpTable() : $this->getMainTable();
    }

    /**
     * @param int[] $labelIds
     */
    private function cleanByLabelIds(array $labelIds)
    {
        if (!empty($labelIds)) {
            $connection = $this->resource->getConnection();
            $connection->delete(
                $this->getIndexTable(),
                $connection->prepareSqlCondition(LabelInterface::LABEL_ID, ['in' => $labelIds])
            );
        }
    }

    /**
     * @param array $ids
     * @return $this
     */
    private function doReindexByProductIds($ids)
    {
        $labels = $this->getFullLabelCollection()->getItems();

        /** @var Label $label **/
        foreach ($labels as $label) {
            $this->reindexByLabelAndProductIds($label, $ids);
        }

        $this->renderChildrenLabelsOnParent($labels, $ids);

        return $this;
    }

    /**
     * @param array $ids
     * @return $this
     */
    private function doReindexByLabelIds($ids)
    {
        $labels = $this->getLabelCollection($ids)->getItems();

        /** @var Label $label **/
        foreach ($labels as $label) {
            $this->reindexByLabelAndProductIds($label);
        }
        $this->cacheContext->registerEntities(Label::CACHE_TAG, $ids);
        $this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]);
        $this->cache->clean($this->cacheContext->getIdentities());
        $this->cacheContext->flush();

        $this->renderChildrenLabelsOnParent($labels);

        return $this;
    }

    /**
     * @param Label $label
     * @param $ids
     * @return $this
     */
    private function reindexByLabelAndProductIds(Label $label, $ids = null)
    {
        $matchedProductIds = $this->getMatchedProductIds->executeWrapper($label, $ids);
        $this->insertMatchedData($label, $matchedProductIds);

        return $this;
    }

    /**
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     *
     * @param LabelInterface $label
     * @param array $matchedProductIds
     */
    private function insertMatchedData(
        LabelInterface $label,
        array $matchedProductIds
    ): void {
        $rows = [];
        $productIds = [];
        $count = 0;

        if (!empty($matchedProductIds)) {
            /** @var int[] $matchedStores **/
            foreach ($matchedProductIds as $productId => $matchedStores) {
                $stores = array_keys($matchedStores);

                foreach ($stores as $storeId) {
                    $rows[] = [
                        self::PRODUCT_ID => (int) $productId,
                        LabelInterface::LABEL_ID => $label->getLabelId(),
                        self::STORE_ID => $storeId
                    ];
                    $count++;
                }

                $productIds[] = (int) $productId;

                if ($count >= $this->batchCount) {
                    $this->insertData($rows);
                    $rows = [];
                    $count = 0;
                }

                if (count($productIds) > $this->batchCacheCount) {
                    $this->cacheContext->registerEntities(Product::CACHE_TAG, $productIds);
                    $this->eventManager->dispatch(
                        'clean_cache_by_tags',
                        ['object' => $this->cacheContext]
                    );
                    $this->cache->clean($this->cacheContext->getIdentities());
                    $this->cacheContext->flush();

                    $productIds = [];
                }
            }
        }

        if (!empty($rows)) {
            $this->insertData($rows);
        }

        if (!empty($productIds)) {
            $this->cacheContext->registerEntities(Product::CACHE_TAG, $productIds);
            $this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]);
            $this->cache->clean($this->cacheContext->getIdentities());
            $this->cacheContext->flush();
        }
    }

    private function insertData(array $data): void
    {
        $this->resource->getConnection()->insertOnDuplicate($this->getIndexTable(), $data);
    }

    /**
     * @api
     *
     * Full reindex
     *
     * @return void
     * @throws LocalizedException
     */
    public function reindexFull()
    {
        $this->getTmpTable();
        $connection = $this->resource->getConnection();
        $connection->beginTransaction();

        try {
            $this->isFullIndexRunning = true;
            $this->doReindexFull();
            $this->isFullIndexRunning = false;
            $connection->commit();
            $this->tableSwapper->swapIndexTables([$this->getMainTable()]);
        } catch (\Exception $e) {
            $connection->rollBack();
            $this->logger->critical($e->getMessage());
            throw new LocalizedException(__($e->getMessage()), $e);
        }
    }

    /**
     * @param null $labelIds
     * @return mixed
     */
    private function getLabelCollection($labelIds = null): LabelCollection
    {
        $collection = $this->collectionFactory->create();
        $collection->addActiveFilter();

        if ($labelIds) {
            $collection->addFieldToFilter(LabelInterface::LABEL_ID, ['in' => $labelIds]);
        }

        return $collection;
    }

    private function getFullLabelCollection(): LabelCollection
    {
        if ($this->fullLabelCollection === null) {
            $this->fullLabelCollection = $this->collectionFactory->create();
            $this->fullLabelCollection->addActiveFilter();
        }

        return $this->fullLabelCollection;
    }

    /**
     * @return $this
     */
    private function doReindexFull()
    {
        $labels = $this->getFullLabelCollection()->getItems();

        /** @var Label $label **/
        foreach ($labels as $label) {
            $this->reindexByLabelAndProductIds($label);
        }

        $this->renderChildrenLabelsOnParent($labels);

        return $this;
    }

    private function renderChildrenLabelsOnParent(array $labels, ?array $productIds = null): void
    {
        $labelIds = array_reduce($labels, function (array $carry, LabelInterface $label): array {
            if ($label->getUseForParent()) {
                $carry[] = $label->getLabelId();
            }

            return $carry;
        }, []);

        if (!empty($labelIds)) {
            /** @var array $stores * */
            foreach ($this->productTypeDataProvider->getProductChildrenIds($productIds) as $productId => $childrenIds) {
                $this->addChildLabelsToParent($labelIds, $productId, $childrenIds);
            }
        }
    }

    private function addChildLabelsToParent(array $labelIds, int $productId, array $childIds): void
    {
        $connection = $this->resource->getConnection();
        $select = $connection->select();
        $select->from($this->getIndexTable());
        $select->where($connection->prepareSqlCondition(LabelInterface::LABEL_ID, ['in' => $labelIds]));
        $select->where($connection->prepareSqlCondition(self::PRODUCT_ID, ['in' => $childIds]));
        $select->reset(Select::COLUMNS);
        $select->columns([
            LabelInterface::LABEL_ID,
            self::PRODUCT_ID => new \Zend_Db_Expr($productId),
            self::STORE_ID
        ]);
        $query = $connection->insertFromSelect(
            $select,
            $this->getIndexTable(),
            [LabelInterface::LABEL_ID, self::PRODUCT_ID, self::STORE_ID],
            AdapterInterface::INSERT_ON_DUPLICATE
        );
        $connection->query($query);
    }
}

Spamworldpro Mini