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
I have the same problem, did you find a fix?
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); }