DEV Community

loading...

Get current product without using registry - Magento 2

Paboda Hettiarachchi
I'm a Magento programer. Like to travel and have work life balance so love to work remotely.
・2 min read

We have been using Magento registry method to get the current product. But registry methods are being deprecated. So the following is a workaround.

Paboda/Catalog/etc/frontend/events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="catalog_controller_product_init_after">
        <observer name="current_product"
                  instance="Paboda\Catalog\Observer\RegisterCurrentProductObserver"/>
    </event>
</config>
Enter fullscreen mode Exit fullscreen mode

Paboda/Catalog/Registry/CurrentProduct.php

<?php
namespace Paboda\Catalog\Registry;

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Api\Data\ProductInterfaceFactory;

/**
 * Class CurrentProduct
 *
 * Get current product without registry
 */
class CurrentProduct
{
    /**
     * @var ProductInterface
     */
    private $product;

    /**
     * @var ProductInterfaceFactory
     */
    private $productFactory;

    /**
     * CurrentProduct constructor.
     *
     * @param ProductInterfaceFactory $productFactory
     */
    public function __construct(
        ProductInterfaceFactory $productFactory
    ) {
        $this->productFactory = $productFactory;
    }

    /**
     * Setter
     *
     * @param ProductInterface $product
     */
    public function set(ProductInterface $product): void
    {
        $this->product = $product;
    }

    /**
     * Getter
     *
     * @return ProductInterface
     */
    public function get(): ProductInterface
    {
        return $this->product ?? $this->createProduct();
    }

    /**
     * Product factory
     *
     * @return ProductInterface
     */
    private function createProduct(): ProductInterface
    {
        return $this->productFactory->create();
    }
}
Enter fullscreen mode Exit fullscreen mode

Paboda/Catalog/Observer/RegisterCurrentProductObserver.php

<?php
namespace Paboda\Catalog\Observer;

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Framework\Event\Observer as Event;
use Magento\Framework\Event\ObserverInterface;
use Paboda/Catalog\Registry\CurrentProduct;

/**
 * Class RegisterCurrentProductObserver
 *
 * Current product observer
 */
class RegisterCurrentProductObserver implements ObserverInterface
{
    /**
     * @var CurrentProduct
     */
    private $currentProduct;

    /**
     * RegisterCurrentProductObserver constructor.
     *
     * @param CurrentProduct $currentProduct
     */
    public function __construct(
        CurrentProduct $currentProduct
    ) {
        $this->currentProduct = $currentProduct;
    }

    /**
     * Trigger event
     *
     * @param Event $event
     */
    public function execute(Event $event)
    {
        /** @var ProductInterface $product */
        $product = $event->getData('product');
        $this->currentProduct->set($product);
    }
}
Enter fullscreen mode Exit fullscreen mode

In a model or a block you can call the current product using the following method

eg block:

Paboda/Catalog/Block/Product.php

<?php
namespace Paboda\Catalog\Block;

use Magento\Framework\View\Element\Template;
use Paboda\Catalog\Registry\CurrentProduct;

class Product extends Template
{
    /**
     * @var CurrentProduct
     */
    protected $currentProduct;

    private $product;

    /**
     * Attachments constructor.
     *
     * @param Template\Context $context
     * @param CurrentProduct $currentProduct
     * @param array $data
     */
    public function __construct(
        Template\Context $context,
        CurrentProduct $currentProduct,
        array $data = []
    ) {
        $this->currentProduct = $currentProduct;
        parent::__construct($context, $data);
    }

    /**
     * Get product
     *
     * @return array
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function getCurrentProduct()
    {
        return $this->currentProduct->get();
    }
}
Enter fullscreen mode Exit fullscreen mode

Discussion (0)