0

I'm trying to override the DefaultRenderer (commonly found when customer views their order in accounts) so I can do some customisations and include extra data.

I've managed to do this successfully, but when I view the order it doesn't show various bits of data which would normally appear without overriding. This includes item options, price, even SKU. It looks like this is anything with $block-> preceding it.

For example:

$block->prepareSku($block->getSku())

Gives me this error:

Invalid method Vendor\FancyOrder\Block\Item\Interceptor::prepareSku

If I remove this line, the order summary loads as expected, but with important information missing.

This is my block. I'm slowly getting used to module creation and dependency injection, so I have a feeling I've missed out some key things:

<?php
namespace Vendor\FancyOrder\Block;

use Magento\Catalog\Model\Product;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Registry;
use Magento\Framework\View\Element\Template;

class Item extends Template
{

    /**
     * @var Registry
     */
    protected $registry;
    protected $_imageBuilder;
    /**
     * @var Product
     */
    private $product;

    public function __construct(Template\Context $context,
                                Registry $registry,
                                \Magento\Catalog\Helper\Image $imageHelper,
                                \Magento\Catalog\Api\ProductRepositoryInterfaceFactory $productRepositoryFactory,
                                array $data)
    {
        $this->registry = $registry;
        $this->_imageHelper = $imageHelper;
        $this->_productRepositoryFactory = $productRepositoryFactory;

        parent::__construct($context, $data);
    }

    public function getTheImage($productID)
    {
        $product = $this->_productRepositoryFactory->create()->getById($productID);
        //return $this->_imageHelper->init($product,'thumbnail')->setImageFile($product->getThumbnail())->getUrl();

        $resized = $this->_imageHelper->init($product, 'product_small_image')
            ->constrainOnly(TRUE)
            ->keepAspectRatio(TRUE)
            ->keepTransparency(TRUE)
            ->keepFrame(FALSE)
            ->resize(200, 300);
        return $resized->getUrl();
    }
}

I have a feeling I need to declare the class in a different way, but I'm not sure how. I tried Class Item extends Magento\Sales\Block\Order\Item\Renderer but that errors.

Any information may help :)

Thank you!

1 Answer 1

1

I think I understand what you are trying to do. Have you tried to just extend the DefaultRenderer class and add any additional methods you need for your module? As long as you pass the correct parameters to the parent constructor you should be good to go. Let me provide a code sample of what I am thinking would work below (keyword "thinking", have not tested). Following the same namespace structure of mage is always nice because it makes your code is easy to follow. Here is how where I would start:

  1. Create your file FancyDefaultRenderer.php in your module folder: Vendor/FancyOrder/Block/Sales/Order/Items/Renderer/FancyDefaultRenderer.php

  2. Specify your preference for the override in you module Vendor/FancyOrder/etc/di.xml, e.g.

    <preference for="Magento\Sales\Block\Sales\Order\Items\Renderer\DefaultRenderer" type="Vendor\FancyOrder\Block\Sales\Order\Items\Renderer\FancyDefaultRenderer"/>

Contents of the FancyDefaultRenderer.php file:

<?php
namespace Vendor\FancyOrder\Block\Sales\Order\Items\Renderer;

// Any additional classes you may need to "use" can go here...

class FancyDefaultRenderer extends \Magento\Sales\Block\Order\Item\Renderer\DefaultRenderer
{
    /**
     * @var \Magento\Catalog\Block\Product\ImageBuilder
     */
    protected $_imageBuilder;

    /**
     * @var \Magento\Catalog\Api\ProductRepositoryInterface
     */
    protected $_productRepository;

    /**
     **##The first 4 params are the necessary params for our parent class
     * @param \Magento\Framework\View\Element\Template\Context $context
     * @param \Magento\Framework\Stdlib\StringUtils $string
     * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory
     * @param array $data
     **##The last params are from our class
     * @param \Magento\Catalog\Block\Product\ImageBuilder $imageBuilder
     * @param \Magento\Catalog\Api\ProductRepositoryInterface
     */
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Framework\Stdlib\StringUtils $string,
        \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory,
        array $data = [],
        \Magento\Catalog\Block\Product\ImageBuilder $imageBuilder,
        \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
    ) {
        // Here we pass the params to the parent constructor in the correct order
        parent::__construct($context, $string, $productOptionFactory, $data);
        // Setting more of our values as needed
        $this->_imageBuilder = $imageBuilder;
        $this->_productRepository = $productRepository;
    }

    public function getTheImage($productID)
    {
        $product = $this->_productRepository->create()->getById($productID);

        $resized = $this->_imageHelper->init($product, 'product_small_image')
            ->constrainOnly(TRUE)
            ->keepAspectRatio(TRUE)
            ->keepTransparency(TRUE)
            ->keepFrame(FALSE)
            ->resize(200, 300);
        return $resized->getUrl();
    }

}

I have note tested the code but I think it should work. It should also resolve your invalid prepareSku method. Might need to change my example to use ProductRepositoryInterfaceFactory instead of just ProductRepositoryInterface, not sure. Let me know if this helps. Cheers~

Your Answer

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

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