Magento – Magento 2 – How to get product in a block

category-listingmagento2productregistry

I'm trying to insert a block in default.xml layout so I created my app/code/Mainf/Stickers/view/frontend/layout/default.xml file:

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
        <css src="Mainf_Stickers::css/mainf-stickers.css"/>
    </head>
    <body>
        <referenceContainer name="content">
            <block name="category.discount.sticker" class="Mainf\Stickers\Block\Discount" template="Mainf_Stickers::discount.phtml" cacheable="false" after="-" />
        </referenceContainer>
    </body>
</page>

and my block file (app/code/Mainf/Stickers/Block/Discount.php):

<?php

namespace Mainf\Stickers\Block;

class Discount extends \Magento\Framework\View\Element\Template
{
    protected $_product = null;

    protected $_coreRegistry = null;
    protected $_productFactory;

    /**
     * @param \Magento\Framework\View\Element\Template\Context $context
     * @param \Magento\Framework\Registry $registry
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Catalog\Model\ProductFactory $productFactory,
        \Magento\Framework\Registry $registry,
        array $data = []
    ) {
        $this->_productFactory = $productFactory;
        $this->_coreRegistry = $registry;
        parent::__construct($context, $data);
    }

    /**
     * @return Product
     */
    protected function _getProduct()
    {
        if (!$this->_product) {
            $this->_product = $this->_coreRegistry->registry('product');
        }

        return $this->_product;
    }

    public function isDiscounted()
    {
        $idProd = $this->_getProduct()->getData('entity_id');

        return true;
    }
}

When I call a category page, $this->_coreRegistry->registry('product') is empty, different from I call a product page.

How could I get "current product" when it loading a category page?

Is there any alternate method to get product apart from registry?

Best Answer

Try bellow code

<?php

namespace Mainf\Stickers\Block;

class Discount extends \Magento\Framework\View\Element\Template
{
    protected $_product = null;

    protected $_registry;
    protected $_productFactory;

    /**
     * @param \Magento\Framework\View\Element\Template\Context $context
     * @param \Magento\Framework\Registry $registry
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Catalog\Model\ProductFactory $productFactory,
        array $data = []
    ) {
        $this->_registry = $registry;
        $this->_productFactory = $productFactory;
        parent::__construct($context, $data);
    }

    public function getCurrentCategory()
    {       
        return $this->_registry->registry('current_category');
    }

    public function getCurrentProduct()
    {       
        return $this->_registry->registry('current_product');
    }

    public function isDiscounted()
    {
        $idProd = $this->getCurrentProduct()->getData('entity_id');

        return true;
    }
}

Display current product data in your template (custom.phtml) file

if ($currentProduct = $block->getCurrentProduct()) {
    echo $currentProduct->getName() . '<br />';
    echo $currentProduct->getSku() . '<br />';
    echo $currentProduct->getId() . '<br />';       
}
Related Topic