EmicoEcommerce/Magento2Tweakwise

View on GitHub
Block/Catalog/Product/ProductList/Featured.php

Summary

Maintainability
A
1 hr
Test Coverage
<?php

/**
 * Tweakwise (https://www.tweakwise.com/) - All Rights Reserved
 *
 * @copyright Copyright (c) 2017-2022 Tweakwise.com B.V. (https://www.tweakwise.com)
 * @license   Proprietary and confidential, Unauthorized copying of this file, via any medium is strictly prohibited
 */

namespace Tweakwise\Magento2Tweakwise\Block\Catalog\Product\ProductList;

use Tweakwise\Magento2Tweakwise\Exception\ApiException;
use Tweakwise\Magento2Tweakwise\MagentoCompat\PreparePostDataFactory;
use Tweakwise\Magento2Tweakwise\Model\Catalog\Product\Recommendation\Collection;
use Tweakwise\Magento2Tweakwise\Model\Catalog\Product\Recommendation\Context as RecommendationsContext;
use Tweakwise\Magento2Tweakwise\Model\Client\Request\Recommendations\FeaturedRequest;
use Tweakwise\Magento2Tweakwise\Model\Config;
use Tweakwise\Magento2Tweakwise\Model\Config\TemplateFinder;
use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Catalog\Block\Product\Context as ProductContext;
use Magento\Catalog\Block\Product\ListProduct;
use Magento\Catalog\Model\Category;
use Magento\Catalog\Model\Layer\Resolver;
use Magento\Framework\Data\Helper\PostHelper;
use Magento\Framework\Url\Helper\Data;

class Featured extends ListProduct
{
    /**
     * @var RecommendationsContext
     */
    protected $recommendationsContext;

    /**
     * @var Config
     */
    protected $config;

    /**
     * @var TemplateFinder
     */
    protected $templateFinder;

    /**
     * @var PreparePostDataFactory
     */
    protected $preparePostDataFactory;

    /**
     * Featured constructor.
     *
     * @param ProductContext $productContext
     * @param PostHelper $postDataHelper
     * @param Resolver $layerResolver
     * @param TemplateFinder $templateFinder
     * @param CategoryRepositoryInterface $categoryRepository
     * @param Data $urlHelper
     * @param RecommendationsContext $recommendationsContext
     * @param Config $config
     * @param PreparePostDataFactory $preparePostDataFactory
     * @param array $data
     * @internal param CategoryRepositoryInterface $categoryRepository
     * @internal param Data $urlHelper
     * @internal param RecommendationsContext $recommendationsContext
     * @internal param Config $config
     * @internal param array $data
     */
    public function __construct(
        ProductContext $productContext,
        PostHelper $postDataHelper,
        Resolver $layerResolver,
        TemplateFinder $templateFinder,
        CategoryRepositoryInterface $categoryRepository,
        Data $urlHelper,
        RecommendationsContext $recommendationsContext,
        Config $config,
        PreparePostDataFactory $preparePostDataFactory,
        array $data = []
    ) {
        parent::__construct(
            $productContext,
            $postDataHelper,
            $layerResolver,
            $categoryRepository,
            $urlHelper,
            $data
        );
        $this->recommendationsContext = $recommendationsContext;
        $this->config = $config;
        $this->templateFinder = $templateFinder;
        $this->preparePostDataFactory = $preparePostDataFactory;
    }

    /**
     * @return Collection
     */
    public function getProductCollection()
    {
        return $this->_getProductCollection();
    }

    /**
     * {@inheritdoc}
     */
    public function toHtml()
    {
        /*
         * Unfortunately class \Magento\Catalog\ViewModel\Product\Listing\PreparePostData
         * does not exist in magento 2.3 but is used in magento 2.4.
         * Magento_Catalog::product/list/items.phtml line 265 wants a PreparePostData from the block rendering the template
         * PreparePostDataFactory tries to get an instance of that class if it is available, if it is
         * we add it as a view model so that we remain compatible with magento 2.3 and lower.
         *
         * We dont add it if some view model is already registered
         */
        if (!$this->getData('view_model') && $this->preparePostDataFactory->getPreparePostData()) {
            $this->setData('view_model', $this->preparePostDataFactory->getPreparePostData());
        }

        try {
            $this->_getProductCollection();
        } catch (ApiException $e) {
            return '';
        }

        return parent::toHtml();
    }

    /**
     * {@inheritdoc}
     */
    protected function _getProductCollection()
    {
        if ($this->_productCollection === null) {
            if (!$this->checkRecommendationEnabled()) {
                $this->_productCollection = parent::_getProductCollection()
                    ->addFieldToFilter('entity_id', ['null' => true]);
            } else {
                $this->configureRequest($this->recommendationsContext->getRequest());
                $this->_productCollection = $this->recommendationsContext
                    ->getCollection();
            }
        }

        return $this->_productCollection;
    }

    /**
     * @return bool
     */
    protected function checkRecommendationEnabled(): bool
    {
        return $this->config->isRecommendationsEnabled(Config::RECOMMENDATION_TYPE_FEATURED);
    }

    /**
     * @param FeaturedRequest $request
     */
    protected function configureRequest(FeaturedRequest $request)
    {
        $category = $this->_coreRegistry->registry('current_category');
        if ($category instanceof Category) {
            $templateId = $this->templateFinder->forCategory($category, Config::RECOMMENDATION_TYPE_FEATURED);
            if (!$templateId) {
                $templateId = $this->config->getRecommendationsTemplate(Config::RECOMMENDATION_TYPE_FEATURED);
            }
        } else {
            $templateId = $this->config->getRecommendationsTemplate(Config::RECOMMENDATION_TYPE_FEATURED);
        }

        $request->setTemplate($templateId);
    }
}