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/Category/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/corals/old/vendor/amasty/shopby/Model/Category/ExtendedCategoryCollection.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\Category;

use Amasty\Base\Model\Serializer;
use Amasty\Shopby\Helper\Category as CategoryHelper;
use Amasty\Shopby\Model\Category\CategoryDataInterfaceFactory;
use Amasty\Shopby\Model\Layer\Filter\Category;
use Amasty\ShopbyBase\Model\Category\Manager as CategoryManager;
use Exception;
use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Catalog\Model\Category as CategoryModel;
use Magento\Catalog\Model\ResourceModel\Category\Collection as CategoryCollection;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory as CategoryCollectionFactory;
use Magento\Catalog\Model\ResourceModel\Category\Flat\Collection as CategoryFlatCollection;
use Magento\Framework\App\CacheInterface;
use Magento\Framework\App\ProductMetadata;
use Magento\Framework\App\ProductMetadataInterface;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Select;
use Magento\Framework\Escaper;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\StateException;

class ExtendedCategoryCollection
{
    public const CACHE_TAG = 'amshopby_excluded_category_ids_';

    private const LIFETIME = 1800;

    /**
     * @var CategoryCollectionFactory
     */
    private $categoryCollectionFactory;

    /**
     * @var CategoryRepositoryInterface
     */
    private $categoryRepository;

    /**
     * @var CategoryManager
     */
    private $categoryManager;

    /**
     * @var CategoryHelper
     */
    private $categoryHelper;

    /**
     * @var ProductMetadataInterface
     */
    private $productMetadata;

    /**
     * @var Escaper
     */
    private $escaper;

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

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

    /**
     * @var Serializer
     */
    private $serializer;

    public function __construct(
        CategoryCollectionFactory $categoryCollectionFactory,
        CategoryRepositoryInterface $categoryRepository,
        CategoryManager $categoryManager,
        CategoryHelper $categoryHelper,
        ProductMetadataInterface $productMetadata,
        Escaper $escaper,
        ResourceConnection $resource,
        CacheInterface $cache,
        Serializer $serializer
    ) {
        $this->categoryCollectionFactory = $categoryCollectionFactory;
        $this->categoryRepository = $categoryRepository;
        $this->categoryManager = $categoryManager;
        $this->categoryHelper = $categoryHelper;
        $this->productMetadata = $productMetadata;
        $this->escaper = $escaper;
        $this->resource = $resource;
        $this->cache = $cache;
        $this->serializer = $serializer;
    }

    /**
     * @return CategoryDataInterface[]
     * @throws LocalizedException
     */
    public function getCategoryTreeData(Category $filter): array
    {
        $categories = [];
        $startCategory = $this->getStartCategory($filter);
        $startPath = $startCategory->getPath();

        $collection = $this->getExtendedCategoryCollection($filter);
        $currentCategoryParents = $filter->getLayer()->getCurrentCategory()->getParentIds();
        foreach ($collection as $category) {
            $isAllowed = $this->isAllowedOnEnterprise($category);
            if (!$isAllowed
                || (
                    !$filter->isRenderAllTree()
                    && !in_array($category->getParentId(), $currentCategoryParents)
                    && $filter->getCategoriesTreeDept() != Category::MIN_CATEGORY_DEPTH
                    && strpos($category->getPath(), $startPath) !== 0
                )
            ) {
                continue;
            }

            $categoryData = [
                CategoryDataInterface::PATH => $category->getPath(),
                CategoryDataInterface::PARENT_PATH => $category->getParentPath(),
                CategoryDataInterface::LABEL => $this->escaper->escapeHtml($category->getName()),
                CategoryDataInterface::ID => (int)$category->getId(),
                CategoryDataInterface::PERMISSIONS => $category->getPermissions() ?? []
            ];
            $categories[] = $categoryData;
        }
        $categoryTreeData = [];
        $categoryTreeData['count'] = count($categories);
        $categoryTreeData['startPath'] = $startPath;
        $categoryTreeData['categories'] = $categories;

        return $categoryTreeData;
    }

    /**
     * @param Category $filter
     *
     * @return CategoryCollection|CategoryFlatCollection
     * @throws LocalizedException
     * @throws Exception
     */
    private function getExtendedCategoryCollection(Category $filter)
    {
        $startCategory = $this->getStartCategory($filter);
        $excludedCategoryIds = $this->getExcludedCategoryIds($filter);
        if ($excludedCategoryIds && in_array($startCategory->getId(), $excludedCategoryIds)) {
            /** @var CategoryCollection $emptyCollection */
            $emptyCollection = $startCategory->getCollection();
            $emptyCollection->getSelect()->where('null');

            return $emptyCollection;
        }

        $minLevel = $startCategory->getLevel();
        $maxLevel = $minLevel + $filter->getCategoriesTreeDept();

        /** @var CategoryCollection|CategoryFlatCollection $collection */
        $collection = $startCategory->getCollection();
        $isFlat = $collection instanceof CategoryFlatCollection;
        $mainTablePrefix = $isFlat ? 'main_table.' : '';
        $collection->addAttributeToSelect('name')
            ->addAttributeToFilter($mainTablePrefix . 'is_active', 1)
            ->addFieldToFilter($mainTablePrefix . 'path', ['like' => $startCategory->getPath() . '%'])
            ->addFieldToFilter($mainTablePrefix . 'level', ['gt' => $minLevel])
            ->setOrder(
                $mainTablePrefix . 'position',
                Select::SQL_ASC
            );

        if (!empty($excludedCategoryIds)) {
            $idField = $isFlat ? 'entity_id' : $collection->getEntity()->getIdFieldName();
            $collection->addFieldToFilter($mainTablePrefix . $idField, ['nin' => $excludedCategoryIds]);
        }
        if (!$filter->isRenderAllTree()) {
            $collection->addFieldToFilter($mainTablePrefix . 'level', ['lteq' => $maxLevel]);
        }

        $mainTablePrefix = $isFlat ? 'main_table.' : 'e.';
        $collection->getSelect()->joinLeft(
            ['parent' => $collection->getMainTable()],
            $mainTablePrefix . 'parent_id = parent.entity_id',
            ['parent_path' => 'parent.path']
        );

        return $collection;
    }

    public function getExcludedCategoryIds(Category $filter): array
    {
        try {
            $rootPath = $this->categoryRepository->get($this->categoryManager->getRootCategoryId())->getPath();
            $cacheKey = $this->getCacheKey($filter, $rootPath);
            $result = $this->cache->load($cacheKey);
            if ($result) {
                return $this->serializer->unserialize($result);
            }
            $collection = $this->categoryCollectionFactory->create();
            $collection->addFieldToFilter('path', ['like' => $rootPath . '/%'])
                ->setStore($filter->getStoreId())
                ->addAttributeToFilter(Category::EXCLUDE_CATEGORY_FROM_FILTER, Category::TRUE, 'left');
            $idField = $collection->getEntity()->getIdFieldName();
            $collection->getSelect()->reset(Select::COLUMNS)->columns([$idField]);
            $categoryIds = $this->resource->getConnection()->fetchCol($collection->getSelect());
            $this->cache->save(
                $this->serializer->serialize($categoryIds),
                $cacheKey,
                [self::CACHE_TAG, CategoryModel::CACHE_TAG],
                self::LIFETIME
            );

            return $categoryIds;
        } catch (Exception $exception) {
            return [];
        }
    }

    public function getCacheKey(Category $filter, string $rootPath): string
    {
        return self::CACHE_TAG . '|s=' . $filter->getStoreId() . '|path=' . $rootPath;
    }

    /**
     * Retrieve start category for bucket prepare
     *
     * @param Category $filter
     *
     * @return CategoryModel
     */
    public function getStartCategory(Category $filter): CategoryModel
    {
        if ($filter->getCategoriesTreeDept() == Category::MIN_CATEGORY_DEPTH
            && !$filter->getLayer()->getCurrentCategory()->getChildrenCount()
            && !$filter->isRenderAllTree()
        ) {
            return $filter->getLayer()->getCurrentCategory()->getParentCategory();
        }

        return $this->categoryHelper->getStartCategory();
    }

    private function isAllowedOnEnterprise(CategoryModel $category): bool
    {
        $isAllowed = true;
        if ($this->productMetadata->getEdition() !== ProductMetadata::EDITION_NAME) {
            $permissions = $category->getPermissions();
            if (isset($permissions['grant_catalog_category_view'])) {
                $isAllowed = $permissions['grant_catalog_category_view'] !== Category::DENY_PERMISSION;
            }
        }

        return $isAllowed;
    }
}

Spamworldpro Mini