3

I'm trying to remove the video from the gallery in product page and I saw that the method getGalleryImages() in the Magento\Catalog\Block\Product\View\Gallery block gets all types of media (image and external-video).

So I have created my custom module where I put a block that extends Magento\Catalog\Block\Product\View\Gallery and I override getGalleryImages() method.

There wasn't any problem to get only the images, but now in my gallery I can't see the thumbnail, I get only the main gallery.

Here my code, my custom block: <Vendor>\<Module>\Block\MediaGallery:

<?php namespace <Vendor>\<Module>\Block; use Magento\Framework\Json\EncoderInterface; class MediaGallery extends \Magento\Catalog\Block\Product\View\Gallery {

public function __construct(
    \Magento\Catalog\Block\Product\Context $context,
    \Magento\Framework\Stdlib\ArrayUtils $arrayUtils,
    EncoderInterface $jsonEncoder,
    array $data = []
)
{
    parent::__construct(
        $context,
        $arrayUtils,
        $jsonEncoder,
        $data
    );
}


public function getGalleryImages()
{
    $product = $this->getProduct();
    $images = $product->getMediaGalleryImages();
    if ($images instanceof \Magento\Framework\Data\Collection) {
        foreach ($images as $key => $image) {
            /* @var \Magento\Framework\DataObject $image */
            if ($image->getMediaType() == '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()
                );
            } else {
                $images->removeItemByKey($key);                   
            }
        }
    }

    return $images;
}}

That's is what I get with my custom block: enter image description here

Setting in this way the block in layout:

 <container name="product.info.media" after="product.info.main">
                    <block class="<Vendor>\<Module>\Block\MediaGallery" name="product.info.media.image" template="Magento_Catalog::product/view/gallery.phtml"/>
                </container>

While with this configuration:

 <container name="product.info.media" after="product.info.main">
                    <block class="Magento\Catalog\Block\Product\View\Gallery" name="product.info.media.image" template="product/view/gallery.phtml"/>
                </container>

I get what I want to see: enter image description here

I don't post the phtml file, because is the same of the default module, I only copied it in my theme folder in the same position.

2 Answers 2

0

I'm not exactly sure what you're trying to do. Do you want to remove a video from the product? Or only not show it?

Here is my code to remove all product images, you can put a condition in there to remove only the video you want:

/** @var \Magento\Catalog\Model\Product $product */

$gallery = $product->getMediaGalleryEntries();
foreach ($gallery as $key => $entry) {
    $image = $entry->getFile();
    if (your condition) {
        $image = 'pub/media/catalog/product' . $image;
        // Remove entry from Media Gallery
        unset($gallery[$key]);
        // Delete file
        unlink($image);
    }
}
// Save changed media gallery to product     
$product->setMediaGalleryEntries($gallery);
// Save Product
$product = $this->productRepository->save($product);

I hope this helps.

4
  • I want to show the video in a different place of the product page, not in the gallery, so I need only not show it Nov 29, 2016 at 9:54
  • Perhaps you can write an if() condition in the template? Find a foreach in gallery.phtml where the images are loaded and write an if (this video) {continue; } or something like that
    – Jacques
    Nov 29, 2016 at 10:28
  • The gallery.phtml init mage/gallery/gallery.js and set on it the data using the method $block->getGalleryImagesJson() this method use getGalleryImages so I need to override these two method, I did it, but the thumbnail is not on the page Nov 29, 2016 at 10:48
  • I always put some mock message when overriding/testing a method before putting the custom logic in, to see if it even works. Did you edit the correct files? Display some "hello world" from the files and see if they show up. Also clear cache since you are working frontend. From what I can tell you only have to override the block method, since that's where the images are gathered from the database. However if several pages use this method and you want other pages to be unaffected you may have to put a check in the template file.
    – Jacques
    Nov 29, 2016 at 11:01
0

I know I'm a little late to the party - but I overcame this using a plugin on the getMediaGalleryImages function on the product. We were separating the images because we are using a module to zoom in on images and it didnt work well with videos.

public function aroundGetMediaGalleryImages($subject, callable $proceed){
    //let the function generate
    $returnValue = $proceed();
    //create an array
    $videoArray = array();
    //loop through whats returned
    foreach($returnValue as $key => $image){
        if($image->getMediaType() !== 'image'){
            $videoArray[] = $image;
            $returnValue->removeItemByKey($key);
        }
    }
    //set the array to return
    if(!empty($videoArray)){
        $returnValue->_video = $videoArray;
    }
    //return
    return $returnValue;
}

The videos were pulled in a custom block where the template function used is:

/**
 * Get the videos from the Media Gallery Images
 * @param $product
 * @return array/null
 */
public function getVideos($product){
    $gallery = $product->getMediaGalleryImages();
    //videos only
    if(isset($gallery->_video)){
        $videos = $gallery->_video;
    } else {
        $videos = null;
    }
    return $videos;
}

Not tested performance though.

Your Answer

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

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