cancel
Showing results for 
Search instead for 
Did you mean: 

How to override ImageFactory in Magento 2.3.3

How to override ImageFactory in Magento 2.3.3

i have my module which is overriding product in images in product list page (it is loading product images from custom attribute).

In Magento 2.2.x there was file vendor/magento/module-catalog/Block/Product/ImageBuilder.php

which you can override and then use your own product image, in my case loaded from custom attribute.

class ImageBuilder extends \Magento\Catalog\Block\Product\ImageBuilder
{

    public function create()
    {

        /** @var \Magento\Catalog\Helper\Image $helper */
        $helper = $this->helperFactory->create()
            ->init($this->product, $this->imageId);

        $template = $helper->getFrame()
            ? 'Magento_Catalog::product/image.phtml'
            : 'Magento_Catalog::product/image_with_borders.phtml';

        $imagesize = $helper->getResizedImageInfo();

        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $product = $objectManager->create('Magento\Catalog\Model\Product')->load($this->product->getId());
        $url = $product->getData('MY_OWN_ATTRIBUTE');
        if (trim($url) == '')
        {
            $url = $helper->getUrl();
        }

        $data = [
            'data' => [
                'template' => $template,
                'image_url' => $url,
                'width' => $helper->getWidth(),
                'height' => $helper->getHeight(),
                'label' => $helper->getLabel(),
                'ratio' =>  $this->getRatio($helper),
                'custom_attributes' => $this->getCustomAttributes(),
                'resized_image_width' => !empty($imagesize[0]) ? $imagesize[0] : $helper->getWidth(),
                'resized_image_height' => !empty($imagesize[1]) ? $imagesize[1] : $helper->getHeight()
            ],
        ];

        return $this->imageFactory->create($data);
    }
}

 

In Magento 2.3.3 this code was moved into vendor/magento/module-catalog/Block/Product/ImageFactory.php Even if i copy whole file and overrride it under my module (without any changes), product list page wont load and i dont see any errors. It just look like this:

 

This is how look ImageFactory.php under my module:

 

<?php
namespace MY_COMPANY\MY_MODULE\Block\Product;
use Magento\Catalog\Block\Product\Image as ImageBlock;
use Magento\Catalog\Model\View\Asset\ImageFactory as AssetImageFactory;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\Image\ParamsBuilder;
use Magento\Catalog\Model\View\Asset\PlaceholderFactory;
use Magento\Framework\ObjectManagerInterface;
use Magento\Framework\View\ConfigInterface;
use Magento\Catalog\Helper\Image as ImageHelper;

class ImageFactory extends \Magento\Catalog\Block\Product\ImageFactory
{
    /**
     * @var ConfigInterface
     */
    private $presentationConfig;

    /**
     * @var AssetImageFactory
     */
    private $viewAssetImageFactory;

    /**
     * @var ParamsBuilder
     */
    private $imageParamsBuilder;

    /**
     * @var ObjectManagerInterface
     */
    private $objectManager;

    /**
     * @var PlaceholderFactory
     */
    private $viewAssetPlaceholderFactory;

    /**
     * @param ObjectManagerInterface $objectManager
     * @param ConfigInterface $presentationConfig
     * @param AssetImageFactory $viewAssetImageFactory
     * @param PlaceholderFactory $viewAssetPlaceholderFactory
     * @param ParamsBuilder $imageParamsBuilder
     */
    public function __construct(
        ObjectManagerInterface $objectManager,
        ConfigInterface $presentationConfig,
        AssetImageFactory $viewAssetImageFactory,
        PlaceholderFactory $viewAssetPlaceholderFactory,
        ParamsBuilder $imageParamsBuilder
    ) {
        $this->objectManager = $objectManager;
        $this->presentationConfig = $presentationConfig;
        $this->viewAssetPlaceholderFactory = $viewAssetPlaceholderFactory;
        $this->viewAssetImageFactory = $viewAssetImageFactory;
        $this->imageParamsBuilder = $imageParamsBuilder;
    }

    public function create(Product $product, string $imageId, array $attributes = null): ImageBlock
    {
        $viewImageConfig = $this->presentationConfig->getViewConfig()->getMediaAttributes(
            'Magento_Catalog',
            ImageHelper::MEDIA_TYPE_CONFIG_NODE,
            $imageId
        );

        $imageMiscParams = $this->imageParamsBuilder->build($viewImageConfig);
        $originalFilePath = $product->getData($imageMiscParams['image_type']);

        if ($originalFilePath === null || $originalFilePath === 'no_selection') {
            $imageAsset = $this->viewAssetPlaceholderFactory->create(
                [
                    'type' => $imageMiscParams['image_type']
                ]
            );
        } else {
            $imageAsset = $this->viewAssetImageFactory->create(
                [
                    'miscParams' => $imageMiscParams,
                    'filePath' => $originalFilePath,
                ]
            );
        }

        $data = [
            'data' => [
                'template' => 'Magento_Catalog::product/image_with_borders.phtml',
                'image_url' => $imageAsset->getUrl(),
                'width' => $imageMiscParams['image_width'],
                'height' => $imageMiscParams['image_height'],
                'label' => $this->getLabel($product, $imageMiscParams['image_type']),
                'ratio' => $this->getRatio($imageMiscParams['image_width'], $imageMiscParams['image_height']),
                'custom_attributes' => $this->getStringCustomAttributes($attributes),
                'class' => $this->getClass($attributes),
                'product_id' => $product->getId()
            ],
        ];

        return $this->objectManager->create(ImageBlock::class, $data);
    }

}

Of course i have defined override in di.xml.

Question is: how can i override ImageFactory.php in my module ?

 

If i cant override ImageFactory.php, what solution should i use ?

 

thanks

2 REPLIES 2

Re: How to override ImageFactory in Magento 2.3.3

I have the same problem, did you find a fix?

Re: How to override ImageFactory in Magento 2.3.3

Looks like you can do this (tested with Magento 2.3.4, but it should be similar):

 

 

    public function create(\Magento\Catalog\Model\Product $product = null, string $imageId = null, array $attributes = null)
    {
        /** @var \MGS\Mpanel\Helper\Data $themeHelper */
        $themeHelper =  \Magento\Framework\App\ObjectManager::getInstance()->get('MGS\Mpanel\Helper\Data');
        $imageSize = $themeHelper->getImageMinSize();
        
        /** @var \Magento\Catalog\Helper\Image $helper */
        $helper = $this->helperFactory->create()
            ->init($this->product, $this->imageId)->resize($imageSize['width'], $imageSize['height']);

        $template = $helper->getFrame()
            ? 'Magento_Catalog::product/image.phtml'
            : 'Magento_Catalog::product/image_with_borders.phtml';
        
        $data = [
            'data' => [
                'template' => $template,
                'image_url' => $helper->getUrl(),
                'width' => $imageSize['width'],
                'height' => $imageSize['height'],
                'label' => $helper->getLabel(),
                'ratio' =>  $this->getRatio($helper),
                'custom_attributes' => $this->getCustomAttributes(),
                'resized_image_width' => $imageSize['width'],
                'resized_image_height' => $imageSize['height'],
                'class' => $this->getClass($attributes),
                'product_id' => $this->product->getId()
            ],
        ];

        //return $this->imageFactory->create($data);
        return $this->objectManager->create(ImageBlock::class, $data);
    }