0

I seem to be unable to create a plugin for the named class.

The plugin is executed, but then the static files on product pages do not get deployed in developer mode and I get an error in the system.log file saying that a less mixin could not be found. The exception.log does not show anything.
The same happens when I create a preference for that class.

Funny enough, if I add my code changes (replace getById() with a collection, see below) directly into the core file, everything works fine.

Using version 2.1.8.

Here is my code:

etc/frontend/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <type name="Magento\Catalog\Helper\Product">
        <plugin name="Namespace_Module" type="Namespace\Module\Helper\Catalog\ProductPlugin" />
    </type>
</config>

Helper/Catalog/ProductPlugin.php

<?php
namespace Namespace\Module\Helper\Catalog;

use Magento\Catalog\Helper\Product as OriginalProduct;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Product as ModelProduct;
use Magento\Store\Model\Store;
use Magento\Framework\EntityManager\EventManager;

class ProductPlugin
{

    /**
     *
     * @var \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory
     */
    protected $_collectionFactory;

    public function __construct(EventManager $eventManager, \Psr\Log\LoggerInterface $logger, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Catalog\Model\Session $catalogSession, \Magento\Framework\Registry $coreRegistry, CategoryRepositoryInterface $categoryRepository, \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $collectionFactory)
    {
        $this->_collectionFactory = $collectionFactory;
        $this->_eventManager = $eventManager;
        $this->_storeManager = $storeManager;
        $this->_catalogSession = $catalogSession;
        $this->categoryRepository = $categoryRepository;
        $this->_coreRegistry = $coreRegistry;
        $this->_logger = $logger;
    }

    /**
     * replace getbyId() with product collection for better performance
     *
     * @param OriginalProduct $subject
     * @param callable $proceed
     * @param mixed $productId
     * @param \Magento\Catalog\Controller\Product\View $controller
     * @param mixed $params
     * @throws NoSuchEntityException
     * @return boolean|\Magento\Framework\DataObject
     */
    public function aroundInitProduct(OriginalProduct $subject, callable $proceed, $productId, $controller, $params = null)
    {
        // Prepare data for routine
        if (! $params) {
            $params = new \Magento\Framework\DataObject();
        }

        // Init and load product
        $this->_eventManager->dispatch('catalog_controller_product_init_before', [
            'controller_action' => $controller,
            'params' => $params
        ]);

        if (! $productId) {
            return false;
        }

        try {
            /* @var $collection \Magento\Catalog\Model\ResourceModel\Product\Collection */
            $collection = $this->_collectionFactory->create()
                ->addAttributeToSelect('*')
                ->addFieldToFilter('entity_id', $productId)
                ->addMediaGalleryData()
                ->addOptionsToResult()
                ->setStore($this->_storeManager->getStore());
            if (! $collection->count()) {
                throw new NoSuchEntityException(__('Product not found with id $1', $productId));
            }
            $product = $collection->getFirstItem();
        } catch (NoSuchEntityException $e) {
            return false;
        }

        if (! $subject->canShow($product)) {
            return false;
        }
        if (! in_array($this->_storeManager->getStore()->getWebsiteId(), $product->getWebsiteIds())) {
            return false;
        }

        // Load product current category
        $categoryId = $params->getCategoryId();
        if (! $categoryId && $categoryId !== false) {
            $lastId = $this->_catalogSession->getLastVisitedCategoryId();
            if ($product->canBeShowInCategory($lastId)) {
                $categoryId = $lastId;
            }
        } elseif (! $product->canBeShowInCategory($categoryId)) {
            $categoryId = null;
        }

        if ($categoryId) {
            try {
                $category = $this->categoryRepository->get($categoryId);
            } catch (NoSuchEntityException $e) {
                $category = null;
            }
            if ($category) {
                $product->setCategory($category);
                $this->_coreRegistry->register('current_category', $category);
            }
        }

        // Register current data and dispatch final events
        $this->_coreRegistry->register('current_product', $product);
        $this->_coreRegistry->register('product', $product);

        try {
            $this->_eventManager->dispatch('catalog_controller_product_init_after', [
                'product' => $product,
                'controller_action' => $controller
            ]);
        } catch (\Magento\Framework\Exception\LocalizedException $e) {
            $this->_logger->critical($e);
            return false;
        }

        return $product;
    }
}
0

One issue I see, and it MIGHT be the cause of your problem and it might not be, is still a problem in and of itself.

In your "around" observer, you never call $proceed($productId, $controller, $params). By never making this call, you prevent all other plugins on this method from firing. It's a possible cause to your issue but you'll have to test.

To test, comment out the content of your function and simply do return $proceed($productId, $controller, $params);, flush cache, and see if the problem goes away. If that doesn't pan out, then it's something else.

| improve this answer | |
  • Thanks for the answer. I actually tested with proceed, and it still did not work. I went for another way. I accept this answer tho as it's a valid point. – simonthesorcerer Jun 29 '18 at 11:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.