Get current product without using registry - Magento 2
Tags: magento2
Published: 2021-05-22 04:59:05

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>
```

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();
    }
}
```

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);
    }
}
```

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();
    }
}
```