9

In Magento 1 I've always used

$_product->getMediaGallery('images')

But in the source from Magento 2 I see

$productImage = $block->getImage($_product, $image);
echo $productImage->toHtml();

It's only getting the first product image. How do I get the second or third image (not only the base one)?

GetMediaGallery function doesn't exists?

Update: $_product->getMediaGalleryImages() throws NULL in a var_dump

and

for getMediaGallery and getMediaGalleryEntries I get the same notice error:

Undefined property: Magento\Catalog\Model\Product\Interceptor::$getMediaGallery
1
  • Try to use \Magento\Catalog\Model\Product::getMediaGalleryImages() Commented Apr 25, 2016 at 11:50

8 Answers 8

12

Category loading has changed in 2.1, so this may only be relevant from 2.1 onwards:

The image gallery is added to the product via an extension interface defined via di.xml. The upshot is that we can manually create an instance of the gallery ReadHandler class and pass a product to load all its gallery images.

As usual in Magento 2 the best way to instantiate a class is via the __construct() method, so here is a stub block class:

use Magento\Catalog\Model\Product\Gallery\ReadHandler as GalleryReadHandler;

class Gallery
{
    protected $galleryReadHandler;

    public function __construct(
        GalleryReadHandler $galleryReadHandler
    )
    {
        $this->galleryReadHandler = $galleryReadHandler;
    }

    /** Add image gallery to $product */
    public function addGallery($product)
    {
        $this->galleryReadHandler->execute($product);
    }
}

In your template, assuming you have $product loaded via a product collection, you would be able to call:

$block->addGallery($product);
$images = $product->getMediaGalleryImages();
foreach ($images as $image) {
    ...
}
2
  • It is not yet possible to find out the "role" of the image (base, small, thumbnail, swatch) this way, I believe. Commented Oct 26, 2016 at 15:12
  • I think you are correct, though the order of images returned is predictable. I've used this to pick out specific roles, though this is obviously suboptimal due to coding in of assumptions that can be changed in the admin interface! Commented Oct 31, 2016 at 17:33
8

Use below code to get all gallery images on product list page:

<?php
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $product = $objectManager->create('Magento\Catalog\Model\Product')->load($_product->getId());        
    $images = $product->getMediaGalleryImages();
    foreach($images as $child){ ?>
        <img src="<?php echo $child->getUrl(); ?>" >
<?php } ?>
3
  • 7
    This does work. However, aside from the fact that using the object manager directly is an anti-pattern with regards to DI, this will require the re-loading of every product which is rather expensive. No, this is not the time to mention caching. I'll carry on looking for a less expensive solution, but thanks for giving us something to start with. Commented Jun 29, 2016 at 19:32
  • Thanks it worked! Commented May 17, 2019 at 7:26
  • Worked on 2.4.3 Commented Jan 17, 2023 at 14:59
7

There is a function available in magento Magento\Catalog\Model\ResourceModel\Product\Collection::addMediaGalleryData() which will add media gallery images to your product collection.

Just use it on your collection like,

$collection->addMediaGalleryData();

And you will be able to get media gallery images using

$_product->getMediaGalleryImages()
1
  • Thank you @JaiminSutariya, It was very helpful. :) Commented Dec 18, 2018 at 10:39
6

create helper for example :

<?php
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Ibnab\Common\Helper;
use Magento\Catalog\Model\Product\Gallery\ReadHandler as GalleryReadHandler;
class Data extends \Magento\Framework\App\Helper\AbstractHelper {
  protected $galleryReadHandler;
    /**
     * Catalog Image Helper
     *
     * @var \Magento\Catalog\Helper\Image
     */
    protected $imageHelper;
    public function __construct(
    GalleryReadHandler $galleryReadHandler,  \Magento\Framework\App\Helper\Context $context,\Magento\Catalog\Helper\Image $imageHelper)
    {
        $this->imageHelper = $imageHelper;
        $this->galleryReadHandler = $galleryReadHandler;
        parent::__construct($context);
    }
   /** Add image gallery to $product */
    public function addGallery($product) {
        $this->galleryReadHandler->execute($product);
    }
    public function getGalleryImages(\Magento\Catalog\Api\Data\ProductInterface $product)
    {
        $images = $product->getMediaGalleryImages();
        if ($images instanceof \Magento\Framework\Data\Collection) {
            foreach ($images as $image) {
                /** @var $image \Magento\Catalog\Model\Product\Image */
                $image->setData(
                    'small_image_url',
                    $this->imageHelper->init($product, 'product_page_image_small')
                        ->setImageFile($image->getFile())
                        ->getUrl()
                );
                $image->setData(
                    'medium_image_url',
                    $this->imageHelper->init($product, 'product_page_image_medium')
                        ->constrainOnly(true)->keepAspectRatio(true)->keepFrame(false)
                        ->setImageFile($image->getFile())
                        ->getUrl()
                );
                $image->setData(
                    'large_image_url',
                    $this->imageHelper->init($product, 'product_page_image_large')
                        ->constrainOnly(true)->keepAspectRatio(true)->keepFrame(false)
                        ->setImageFile($image->getFile())
                        ->getUrl()
                );
            }
        }
        return $images;
    }
}

call and use inside your list.phtml : $_helperGallery = $this->helper('Ibnab\Common\Helper\Data'); now you can use with current called product inside for each (with you technique):

  <a href="<?php echo $_product->getProductUrl() ?>">
                            <ul class="product-item-wrapper">
                                <?php
                                $_helperGallery->addGallery($_product);
                                $images = $_helperGallery->getGalleryImages($_product);
                                if ($images instanceof \Magento\Framework\Data\Collection) {
                                    $i = 1;
                                    foreach ($images as $image) {
                                        $item = $image->getData();
                                        if (isset($item['media_type']) && $item['media_type'] == 'image'):
                                            ?>
                                            <?php if ($i == 1): ?>
                                                <li class="selected">
                                                <?php else: ?>
                                                <li >
                                                <?php endif; ?>
                                                <img src="<?php echo isset($item['medium_image_url']) ? $item['medium_image_url'] : null; ?>" alt="Preview image">
                                            </li>
                                            <?php
                                            $i++;
                                        endif;
                                    }
                                }
                                ?>
                            </ul>
                        </a>

the complete source of course

2

You can use the exact same method as Magento 1:

$_product->getMediaGallery('images')

Also, Magento 2 provides a new method to get the media gallery as an array:

$_product->getMediaGalleryEntries():
1
  • I get the same notice error for getMediaGallery and getMediaGalleryEntries as well Notice: Undefined property: Magento\Catalog\Model\Product\Interceptor::$getMediaGallery
    – Xaiamedia
    Commented Apr 25, 2016 at 13:06
1
foreach ($product->getMediaGalleryImages() as $_image) {
      $array[] = $_image->getFile();
}
echo $array;
1
$product->getMediaGalleryImages()->getItems()

returns an array with the gallery images

1
  • This worked well in 2.3, thank you! Commented Jun 12, 2019 at 14:58
0

In magento 2.3.4 i get this like this. You can get all images of the product by gallery ReadHandler

 <?php
    namespace Vendor\Module\Controller\Index;
    
    class DownloadPictures extends \Magento\Framework\App\Action\Action
    {
        protected $_pageFactory;
    
        public function __construct(
            \Magento\Framework\App\Action\Context $context,
            \Magento\Framework\View\Result\PageFactory $pageFactory,
            \Magento\Catalog\Api\ProductRepositoryInterfaceFactory $productRepositoryFactory,
            \Magento\Catalog\Model\Product\Gallery\ReadHandler  $GalleryReadHandler
        )
        {
            $this->_pageFactory = $pageFactory;
            $this->_productRepositoryFactory = $productRepositoryFactory;
            $this->galleryReadHandler = $GalleryReadHandler;
            return parent::__construct($context);
        }
    
        public function execute()
        {
            $product = $this->_productRepositoryFactory->create()->getById($product_id);

            $galleryReadHandler = $this->galleryReadHandler->execute($product);
            $images = $galleryReadHandler->getMediaGalleryImages();
            foreach ($images as $image) {
               print_r($image->getUrl());
            }
    
        }
    }

Hope this helps give upvote if it helps

Your Answer

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

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