cancel
Showing results for 
Search instead for 
Did you mean: 

How to override ImageFactory in Magento 2.3.3

   Did you know you can see the translated content as per your choice?

Translation is in progress. Please check again after few minutes.

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);
    }