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/old/vendor/amasty/shopby/Model/CatalogSearch/Indexer/Fulltext/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/corals/old/vendor/amasty/shopby/Model/CatalogSearch/Indexer/Fulltext/DataProvider.php
<?php

declare(strict_types=1);

/**
 * @author Amasty Team
 * @copyright Copyright (c) Amasty (https://www.amasty.com)
 * @package Improved Layered Navigation Base for Magento 2
 */

namespace Amasty\Shopby\Model\CatalogSearch\Indexer\Fulltext;

use Amasty\ShopbyBase\Model\Di\Wrapper;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Model\Product\Attribute\Source\Status;
use Magento\Catalog\Model\Product\Visibility;
use Magento\Eav\Model\Config;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\DB\Select;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Framework\Event\ManagerInterface;
use Magento\Store\Model\Store;
use Magento\Store\Model\StoreManagerInterface;

class DataProvider
{
    public const TYPE_WEBSITE = 'website';

    /**
     * @var ScopeConfigInterface
     */
    private $config;

    /**
     * @var Config
     */
    private $eavConfig;

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

    /**
     * @var StoreManagerInterface
     */
    private $storeManager;

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

    /**
     * @var \Magento\Framework\EntityManager\EntityMetadata
     */
    private $metadata;

    /**
     * @var \Magento\InventorySalesApi\Api\StockResolverInterface
     */
    private $stockResolver;

    /**
     * @var \Magento\InventoryCatalogApi\Api\DefaultStockProviderInterface
     */
    private $defaultStockProvider;

    /**
     * @var \Magento\InventoryIndexer\Model\StockIndexTableNameResolverInterface
     */
    private $stockIndexTableNameResolver;

    /**
     * @var int
     */
    private $antiGapMultiplier = 5;

    /**
     * @var int[]
     */
    private $productVisibility;

    public function __construct(
        ResourceConnection $resource,
        ScopeConfigInterface $config,
        Config $eavConfig,
        Visibility $productVisibility,
        ManagerInterface $eventManager,
        StoreManagerInterface $storeManager,
        MetadataPool $metadataPool,
        Wrapper $stockResolver,
        Wrapper $defaultStockProvider,
        Wrapper $stockIndexTableNameResolver
    ) {
        $this->resource = $resource;
        $this->config = $config;
        $this->eavConfig = $eavConfig;
        $this->eventManager = $eventManager;
        $this->storeManager = $storeManager;
        $this->productVisibility = $productVisibility->getVisibleInSiteIds();
        $this->metadata = $metadataPool->getMetadata(ProductInterface::class);
        $this->stockResolver = $stockResolver;
        $this->defaultStockProvider = $defaultStockProvider;
        $this->stockIndexTableNameResolver = $stockIndexTableNameResolver;
    }

    private function getTable(string $table): string
    {
        return $this->resource->getTableName($table);
    }

    private function getConnection(): AdapterInterface
    {
        return $this->resource->getConnection();
    }

    public function getAttributeByCode(string $attribute)
    {
        return $this->eavConfig->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $attribute);
    }

    public function getSearchableProducts(
        int $storeId,
        array $staticFields,
        ?array $productIds = null,
        int $lastProductId = 0,
        int $batch = 100
    ): array {

        $select = $this->getSelectForSearchableProducts($storeId, $staticFields, $productIds, $lastProductId, $batch);
        if ($productIds === null) {
            $select->where(
                'e.entity_id < ?',
                $lastProductId ? $this->antiGapMultiplier * $batch + $lastProductId + 1 : $batch + 1
            );
        }
        $products = $this->getConnection()->fetchAll($select);
        if ($productIds === null && !$products) {
            // try to search without limit entity_id by batch size for cover case with a big gap between entity ids
            $products = $this->getConnection()->fetchAll(
                $this->getSelectForSearchableProducts($storeId, $staticFields, $productIds, $lastProductId, $batch)
            );
        }

        return $products;
    }

    private function getSelectForSearchableProducts(
        int $storeId,
        array $staticFields,
        ?array $productIds,
        int $lastProductId,
        int $batch
    ): Select {
        $websiteId = (int)$this->storeManager->getStore($storeId)->getWebsiteId();
        $connection = $this->getConnection();

        $select = $connection->select()
            ->useStraightJoin(true)
            ->from(
                ['e' => $this->getTable('catalog_product_entity')],
                array_merge(['entity_id', 'type_id'], $staticFields)
            )
            ->join(
                ['website' => $this->getTable('catalog_product_website')],
                $connection->quoteInto('website.product_id = e.entity_id AND website.website_id = ?', $websiteId),
                []
            );

        $stockId = $this->getStockId($storeId);
        $displayOutOfStock = (bool) $this->config->getValue('cataloginventory/options/show_out_of_stock');

        if ($stockId === null || $stockId === $this->defaultStockProvider->getId()) {
            $this->addDefaultStockFilter($select, $displayOutOfStock);
        } else {
            $this->addMsiStockFilter($select, $stockId, $displayOutOfStock);
        }

        $this->joinAttribute($select, 'visibility', $storeId, $this->productVisibility);
        $this->joinAttribute($select, 'status', $storeId, [Status::STATUS_ENABLED]);

        if ($productIds !== null) {
            $select->where('e.entity_id IN (?)', $productIds);
        }
        $select->where('e.entity_id > ?', $lastProductId);
        $select->order('e.entity_id');
        $select->limit($batch);

        return $select;
    }

    private function joinAttribute(Select $select, string $attributeCode, int $storeId, array $whereValue): void
    {
        $field = $this->metadata->getLinkField();
        $attribute = $this->getAttributeByCode($attributeCode);
        $attributeTable = $this->getTable('catalog_product_entity_' . $attribute->getBackendType());
        $alias = $attributeCode . '_default';
        $storeAlias = $attributeCode . '_store';

        $whereCondition = $this->getConnection()->getCheckSql(
            $storeAlias . '.value_id > 0',
            $storeAlias . '.value',
            $alias . '.value'
        );

        $select->join(
            [$alias => $attributeTable],
            $this->getConnection()->quoteInto(
                $alias . '.' . $field . '= e.' . $field . ' AND ' . $alias . '.attribute_id = ?',
                $attribute->getAttributeId()
            ) . $this->getConnection()->quoteInto(
                ' AND ' . $alias . '.store_id = ?',
                Store::DEFAULT_STORE_ID
            ),
            []
        )->joinLeft(
            [$storeAlias => $attributeTable],
            $this->getConnection()->quoteInto(
                $storeAlias . '.' . $field . '= e.' . $field . ' AND ' . $storeAlias . '.attribute_id = ?',
                $attribute->getAttributeId()
            ) . $this->getConnection()->quoteInto(
                ' AND ' . $storeAlias . '.store_id = ?',
                $storeId
            ),
            []
        )->where(
            $whereCondition . ' IN (?)',
            $whereValue
        );
    }

    public function getStockId(int $storeId): ?int
    {
        $websiteId = $this->storeManager->getStore($storeId)->getWebsiteId();
        $websiteCode = $this->storeManager->getWebsite($websiteId)->getCode();
        $stock = $this->stockResolver->execute(self::TYPE_WEBSITE, $websiteCode);
        return $stock ? $stock->getStockId() : null;
    }

    public function addDefaultStockFilter(Select $select, bool $displayOutOfStock = false): void
    {
        $stockStatusTable = $this->resource->getTableName('cataloginventory_stock_status');
        $select->joinInner(
            ['stock_index' => $stockStatusTable],
            'stock_index.product_id = e.entity_id',
            []
        );

        if (!$displayOutOfStock) {
            $select->where('stock_index.stock_status = 1');
        }
    }

    public function addMsiStockFilter(Select $select, int $stockId, bool $displayOutOfStock = false): void
    {
        $stockIndexTableName = $this->stockIndexTableNameResolver->execute((int)$stockId);
        if (!$stockIndexTableName) {
            $this->addDefaultStockFilter($select, $displayOutOfStock);
        } else {
            $select->joinInner(['stock_index' => $stockIndexTableName], 'e.sku = stock_index.sku', []);

            if (!$displayOutOfStock) {
                $select->where('stock_index.is_salable = 1');
            }
        }
    }
}

Spamworldpro Mini