1

I'm trying to add an alternative image for all config product images. To do so I extended Magento\Catalog\Block\Product\Image. For some reason $product->getMediagalleryImages() always returns the same gallery for all products in the collection though. Is this the correct way of loading a media gallery for a product in M2?

<?php                                                                               
namespace Ac\Catalog\Block\Product;                                                 

use Magento\Framework\View\Element\Template\Context;                                
use Magento\Catalog\Model\Product;                                                  
use Magento\Catalog\Model\Product\Gallery\ReadHandler;                              


class Image extends \Magento\Catalog\Block\Product\Image                            
{                                                                                   
    protected $_productModel;                                                       
    protected $_galleryReadHandler;                                                 

    public function __construct(                                                    
        Context $context,                                                           
        Product $productModel,                                                      
        ReadHandler $galleryReadHandler,                                            
        array $data = []                                                            
    ) {                                                                             
        if (isset($data['template'])) {                                             
            $this->setTemplate($data['template']);                                  
            unset($data['template']);                                               
        }                                                                           

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

        $this->_productModel = $productModel;                                       
        $this->_galleryReadHandler = $galleryReadHandler;                           
    }                                                                               

    public function getSrcAlt(): string                                             
    {                                                                               
        $product = $this->_productModel->load($this->getProductId());               
        if (strpos($product->getTypeId(), 'configurable') === false) {              
            return '';                                                              
        }                                                                           

        $i = 0;                                                                     
        $this->_galleryReadHandler->execute($product);                              
        foreach ($product->getMediaGalleryImages() as $image) {                     
            if (++$i < 2) continue;                                                 
            return sprintf('data-src-alt="%s"', $image['url']);                     
        }                                                                           

        return '';                                                                  
    }                                                                               
}    
1

I'm not sure, what the problem is, but your way to load products reuses the same product model. In that way you will have data of the previous product in cases in which the new product for example does not a have data for a specific attribute or data which is set when a getter is first called, like media gallery. That may cause such a behaviour if you reuse the same block instance for more than one product.

You should use a product factory instead for loading the product in the following way:

 protected $_productFactory;

//inject product factory
public function(
    [...]
    \Magento\Catalog\Model\ProductFactory $productFactory
    )
   {
       [...]
       $this->_productFactory = $productFactory;
   }

   [...]
   //load product
   $product = $this->_productFactory->create()->load($this->getProductId());

Or at least call reset() on your product model before loading a new product:

$product = $this->_productModel->reset()->load($this->getProductId());
  • The model load approach worked in M1. But using the factory makes much more sense here. Thanks! Much appreciated. – Michael Thessel Mar 12 at 21:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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