Magento 2.1 – Override Magento\Catalog\Block\Product\View\Gallery Using Preference Not Working

magento-2.1magento2

I am trying to override the getGalleryImagesJson() method of Class Magento\Catalog\Block\Product\View\Gallery but I am unable to do so.

Below are my codes:

di.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Block\Product\View\Gallery" type="Custom\Catalogoverride\Block\Product\View\Gallery" />
</config>

My overriden file

<?php 
namespace Custom\Catalogoverride\Block\Product\View;


    class Gallery extends \Magento\Catalog\Block\Product\View\Gallery
        {
            /**
     * Retrieve product images in JSON format
     *
     * @return string
     */
    public function getGalleryImagesJson()
    {
        die('here');
        //var_dump('here');die();
        $imagesItems = [];
        foreach ($this->getGalleryImages() as $image) {
            $imagesItems[] = [
                'thumb' => $image->getData('small_image_url'),
                'img' => $image->getData('medium_image_url'),
                'full' => $image->getData('large_image_url'),
                'caption' => $image->getLabel(),
                'position' => $image->getPosition(),
                'isMain' => $this->isMainImage($image),
            ];
        }
        if (empty($imagesItems)) {
            $imagesItems[] = [
                'thumb' => $this->_imageHelper->getDefaultPlaceholderUrl('thumbnail'),
                'img' => $this->_imageHelper->getDefaultPlaceholderUrl('image'),
                'full' => $this->_imageHelper->getDefaultPlaceholderUrl('image'),
                'caption' => '',
                'position' => '0',
                'isMain' => true,
            ];
        }
        return json_encode($imagesItems);
    }
        }
?>

I am not getting up this file. I have tried same way to override other methods of checkout module which worked but not this time.

I have found similar question here but it followed the approach of plugin but I need to do it using preference.

Can anyone suggest why it is not working from this method.

Thanks in advance.

Best Answer

I am posting my fix so that it could help others. As the preference didn't work for me I used plugin to get it done.

My di.xml file looks like this.

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Catalog\Block\Product\View\Gallery">
        <plugin disabled="false" name="Custom_Catalogoverride_Plugin_Magento_Catalog_Block_Product_View_Gallery" sortOrder="10" type="Custom\Catalogoverride\Plugin\Magento\Catalog\Block\Product\View\Gallery"/>
    </type>
</config>

Create a class named gallery on the above mentioned file. It looks like this.

<?php 
namespace Custom\Catalogoverride\Plugin\Magento\Catalog\Block\Product\View;

class Gallery
{

    public function afterGetGalleryImagesJson(
        \Magento\Catalog\Block\Product\View\Gallery $subject,
        $result
    ) {
        //your code here
    }
}

Now if you dump $result you will get the data returned by GetGalleryImagesJson() method.I created my own result and returned that. Also I needed the product data in this file to have some condition so what i did was i get the product from the registry. here is what i did.

<?php


namespace Custom\Catalogoverride\Plugin\Magento\Catalog\Block\Product\View;

class Gallery
{

    public function afterGetGalleryImagesJson(
        \Magento\Catalog\Block\Product\View\Gallery $subject,
        $result
    ) {
        //your code here
        $om = \Magento\Framework\App\ObjectManager::getInstance();
        $registry = $om->get('Magento\Framework\Registry');
        $product = $registry->registry('product');  
        //now use this product object to get product info if you need to do some processing
        //let's say i need to check the product id and return the default place holder image url
        $id = $product->getId();
        if($id=="something"){
            //get the placeholder image url
            $scopeconfig = $om->get('Magento\Framework\App\Config\ScopeConfigInterface');
            $storeManager = $om->get('Magento\Store\Model\StoreManager');
            //get media url
            $mediaUrl = $storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA );
            //create full placeholder image url
            $placeholderUrl = $mediaUrl.'catalog/product/placeholder/'.$scopeconfig->getValue('catalog/placeholder/image_placeholder');

        $imagesItems[] = [                
                'thumb' => $placeholderUrl,
                'img' => $placeholderUrl,
                'full' => $placeholderUrl,
                'caption' => '',
                'position' => '0',
                'isMain' => true,
            ];
            $result = json_encode($imagesItems);
        }   
        return $result;
    }
}

Check the comments to get broad idea what I did. Also if if you want further information on Plugins check here.

Note: I used objectmanager to create the object it is not the proper way the best way is to do with dependency injection but for now i couldn't implement that here so i used the quick fix. if you can use it please let me know.

Hope it will help.