11

I would like to get my current product in my phtml. I saw lot of examples with registry in the Block file, but now, in M2.3, it's deprecated.

Someone have an idea how to do ?

7 Answers 7

6

My firm recently contacted Magento about this. According to them, there is no alternative way implemented yet.

5
  • Ooh.. Did they explain why ?
    – Kozame
    Commented Mar 8, 2019 at 10:10
  • Not really. I use the registry class for now until they come up with an alternative. Commented Mar 8, 2019 at 10:13
  • Seem you're right : another team say me the same thing as you.. :(
    – Kozame
    Commented Mar 8, 2019 at 10:51
  • I don't think this is the correct answer. Maybe try to read others answers. Commented Nov 10, 2020 at 8:02
  • i'm not agree with your answer. Try with catalog session please Commented Mar 9, 2021 at 7:04
6

To get the current product:

use block class: Magento\Catalog\Block\Product\View

Get product using: $block->getProduct() in your phtml or use the class and get in the block file.

Hope it Helps.Happy coding!!

2
  • This works, but is it considered a best practice?
    – Akif
    Commented Apr 24, 2021 at 20:59
  • 1
    @Akif Yes it is recommended
    – Vijay R
    Commented Apr 26, 2021 at 18:51
6

From this article: https://www.atwix.com/magento-2/alternatives-for-deprecated-registry-class-magento-2-3/

Starting from Magento 2.3 the Registry class that is (or was) used by a lot of developers and extension vendors is declared to be deprecated. In class comments it’s told to use service classes or data providers, but no examples provided.

Here an example to get the product from a phtml using a ViewModel.

<?php
declare(strict_types=1);

namespace Namespace\Module\ViewModel;

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Session as CatalogSession;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\View\Element\Block\ArgumentInterface;

class Product implements ArgumentInterface
{
    /**
     * @var CatalogSession
     */
    private $catalogSession;

    /**
     * @var ProductRepositoryInterface
     */
    private $productRepository;

    /**
     * Current Product
     *
     * @var ProductInterface
     */
    private $currentProduct;

    /**
     * @param CatalogSession $catalogSession
     * @param ProductRepositoryInterface $productRepository
     */
    public function __construct(
        CatalogSession $catalogSession,
        ProductRepositoryInterface $productRepository
    )
    {
        $this->catalogSession = $catalogSession;
        $this->productRepository = $productRepository;
    }

    /**
     * @return ProductInterface
     * @throws NoSuchEntityException
     */
    public function getProduct(): ProductInterface
    {
        if (!isset($this->currentProduct)) {
            $productId = $this->getProductId();

            if ($productId) {
                $this->currentProduct = $this->productRepository->getById($productId);
            }
        }
        return $this->currentProduct;
    }

    /**
     * @return string
     */
    public function getProductId(): string
    {
        return $this->catalogSession->getData('last_viewed_product_id');
    }
}

6

The correct way of getting the current product on PDP page without using registry class is to use Catalog Helper class.

public function __construct(    
    \Magento\Catalog\Helper\Data $catalogHelper
) {
    $this->catalogHelper = $catalogHelper;
}

public function run() {
    $this->catalogHelper->getProduct();
}

By looking at the implementation you will see that it is still using registry class under the hood, but that is okay because when core class will be refactored to not use registry class, your code will not break and you should still get your product. This is the whole purpose of the helper class, essentially you are shifting responsibility to the framework from your own implementation, which is the best you can do in this scenario.

enter image description here

3

I recently moved to Magento 2.3.2, and I had the same question

After reading this allready pointed out article (thanks https://magento.stackexchange.com/users/31910/shoaib-munir)

https://www.atwix.com/magento-2/alternatives-for-deprecated-registry-class-magento-2-3/

I found this implementation by @Vinai Kopp (https://github.com/Vinai)

https://github.com/Vinai/module-current-product-example

Basically, this trigger an observer based catalog_controller_product_init_after event for grabbing the actual displayed product and push the result into a custom registry

So after that, you can have it in your Block like the below code, or use ViewModel as suggested by @Vinai

<?php
namespace Vendor\Module\Block;

use Magento\Framework\View\Element\Template;
use Vendor\Module\Registry\CurrentProduct;

class YourBlock extends Template
{

    /**
     * @var CurrentProduct
     */
    private $_currentProduct;

    public function __construct(
        Template\Context $context,
        ...
        CurrentProduct $currentProduct,
        array $data)
    {
        $this->_currentProduct  = $currentProduct;
        parent::__construct($context, $data);
    }


    public function getCurrentProduct()
    {
            return $this->getProductId();
    }


    /**
     * @return mixed
     */
    private function getProductId()
    {
        return $this->_currentProduct->get()->getId();
    }

}

you could also return the full product, but not sure, that is really needed

    public function getCurrentProduct()
    {
            return $this->_currentProduct->get();
    }

Hope this helps,

2

try something like this:

$myBlock = \Magento\Framework\App\ObjectManager::getInstance()->get('Magento\Catalog\Model\Session')->getData('last_viewed_product_id');

I found an article for depreciated registry in Magento 2.3. It is getting category from catalog session, I don't know if my code works or not but from this you will have a path where you need to do some debugging

Reference: https://www.atwix.com/magento-2/alternatives-for-deprecated-registry-class-magento-2-3/

6
  • I try this code, but it's not work for me.. I didn't understand this part : $this->catalogSession->getData('last_viewed_product_id'); because this data is never set in my project
    – Kozame
    Commented Mar 8, 2019 at 10:10
  • Oh, sorry to hear that, I don't have magento 2.3 installed that's why didn't tried it myself Commented Mar 8, 2019 at 10:11
  • I think this is the only way of getting current product because Catalog Session stores in Magento\Catalog\Model\Session you need to do some digging on it Commented Mar 8, 2019 at 10:14
  • Thanks for the tips, I'll continue my search
    – Kozame
    Commented Mar 8, 2019 at 10:18
  • 1
    @Kozame: In that way you get only the product id of the current product, you need to load the product using that id and then you will have the object
    – HelgeB
    Commented Mar 8, 2019 at 10:33
0

Found a nice post maybe this will help you.

https://dev.to/pabodah/get-current-product-without-using-registry-magento-2-2pfl

I tried this way for a custom product collection on the product page and worked for me .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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