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();
}
}
Top comments (0)