8

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
  • Try to use \Magento\Catalog\Model\Product::getMediaGalleryImages() – Siarhey Uchukhlebau Apr 25 '16 at 11:50
9

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) {
    ...
}
| improve this answer | |
  • It is not yet possible to find out the "role" of the image (base, small, thumbnail, swatch) this way, I believe. – Patrick van Bergen Oct 26 '16 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! – Robert Egginton Oct 31 '16 at 17:33
5

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 } ?>
| improve this answer | |
  • 6
    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. – Robert Egginton Jun 29 '16 at 19:32
  • Thanks it worked! – Amrit Pal Singh May 17 '19 at 7:26
4

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

| improve this answer | |
3

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()
| improve this answer | |
  • Thank you @JaiminSutariya, It was very helpful. :) – Aditya Shah Dec 18 '18 at 10:39
1

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():
| improve this answer | |
  • I get the same notice error for getMediaGallery and getMediaGalleryEntries as well Notice: Undefined property: Magento\Catalog\Model\Product\Interceptor::$getMediaGallery – Xaiamedia Apr 25 '16 at 13:06
1
$product->getMediaGalleryImages()->getItems()

returns an array with the gallery images

| improve this answer | |
  • This worked well in 2.3, thank you! – Raphael Parent Jun 12 '19 at 14:58
0
foreach ($product->getMediaGalleryImages() as $_image) {
      $array[] = $_image->getFile();
}
echo $array;
| improve this answer | |

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.