3

I want to change Product Images to external Image URL in Magento 2 Frontend.

  • Product Listing Page.
  • Product Details Page Gallery.
  • Related Products.
  • Upsell Products listing.
  • Cross Sell Listing.
  • All Product Widget.
  • Cart Page and Minicart as well as in checkout Page.

On admin side I want to change Product Image in grid column.

Please help me To do this.

Thank you.

5

To change All the Images to External Images Please follow below steps and create one module for that.

To change all Images in front-end you need to create four plugin for that to modify and change images with your custom external images.

First Create di.xml file

<VendorName>/<ModuleName>/etc/frontend/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">
<type name="Magento\Catalog\Block\Product\View\Gallery">
    <plugin name="add_images_to_gallery" type="<VendorName>\<ModuleName>\Plugin\AddImagesToGalleryBlock" />
</type>

<type name="Magento\Catalog\Block\Product\AbstractProduct">
    <plugin name="after_get_image_plugin" type="<VendorName>\<ModuleName>\Plugin\AfterGetImage"/>
</type>

<type name="Magento\Catalog\Block\Product\Image">
    <plugin name="after_get_image_url_plugin" type="<VendorName>\<ModuleName>\Plugin\AfterGetImageUrl"/>
</type>

<type name="Magento\Checkout\CustomerData\AbstractItem">
    <plugin name="minicart_after_get_itemdata_plugin" type="<VendorName>\<ModuleName>\Plugin\Minicart\AfterGetItemData"/>
</type>

</config>

Now You need to create a plugin files.

<VendorName>/<ModuleName>/Plugin/AddImagesToGalleryBlock.php

<?php

namespace <VendorName>\<ModuleName>\Plugin;

use Magento\Catalog\Block\Product\View\Gallery;
use Magento\Framework\Data\Collection;
use Magento\Framework\Data\CollectionFactory;
use Magento\Framework\DataObject;

class AddImagesToGalleryBlock
{
    /**
     * @var CollectionFactory
     */
    protected $dataCollectionFactory;

    /**
     * AddImagesToGalleryBlock constructor.
     *
     * @param CollectionFactory $dataCollectionFactory
     */
    public function __construct(
        CollectionFactory $dataCollectionFactory
    ) {
        $this->dataCollectionFactory = $dataCollectionFactory;
    }

    /**
     * afterGalleryImages Plugin to change images and use external images stored in custom attribute
     *
     * @param Gallery $subject
     * @param Collection|null $images
     * @return Collection|null
     */
    public function afterGetGalleryImages(Gallery $subject, $images) {
        try {
    $hasExternalImage = false;
    // logic to get your external images url
            if (!$hasExternalImage) {
                return $images;
            }
            $product = $subject->getProduct();
            $images = $this->dataCollectionFactory->create();
            $productName = $product->getName();
            $externalImages = ["https://static.integromat.com/img/packages/magento_256.png"]; // Array of images
            foreach ($externalImages as $item) {
                $imageId    = uniqid();
                $small      = $item;
                $medium     = $item;
                $large      = $item;
                $image = [
                    'file' => $large,
                    'media_type' => 'image',
                    'value_id' => $imageId, // unique value
                    'row_id' => $imageId, // unique value
                    'label' => $productName,
                    'label_default' => $productName,
                    'position' => 100,
                    'position_default' => 100,
                    'disabled' => 0,
                    'url'  => $large,
                    'path' => '',
                    'small_image_url' => $small,
                    'medium_image_url' => $medium,
                    'large_image_url' => $large
                ];
                $images->addItem(new DataObject($image));
            }

            return $images;
        } catch (\Exception $e) {
            return $images;
        }

    }
}

<VendorName>/<ModuleName>/Plugin/AfterGetImage.php

<?php

namespace <vendorName>\<ModuleName>\Plugin;

use Magento\Catalog\Block\Product\AbstractProduct;

class AfterGetImage
{
    /**
     * AfterGetImage constructor.
     */
    public function __construct()
    {
    }

    /**
     * @param AbstractProduct $subject
     * @param $result
     * @param $product
     * @param $imageId
     * @param $attributes
     * @return mixed
     */
    public function afterGetImage(AbstractProduct $subject, $result, $product, $imageId, $attributes) {
        try {
            if ($product) {
                        $image = array();
                        $image['image_url'] = "https://static.integromat.com/img/packages/magento_256.png";
                        $image['width'] = "240";
                        $image['height'] = "300";
                        $image['label'] = $product->getName();
                        $image['ratio'] = "1.25";
                        $image['custom_attributes'] = "";
                        $image['resized_image_width'] = "399";
                        $image['resized_image_height'] = "399";
                        $image['product_id'] = $product->getId();
                if ($image) {
                    $result->setData($image);
                }
            }
        } catch (\Exception $e) {
        }
        return $result;
    }
}

<VendorName>\<ModuleName>\Plugin\AfterGetImageUrl.php

<?php

namespace <venfdorName>\<moduleName>\Plugin;

use Magento\Catalog\Block\Product\Image;

class AfterGetImageUrl
{
    /**
     * AfterGetImage constructor.
     */
    public function __construct(
    )
    {
    }

    /**
     * @param Image $image
     * @param $method
     * @return array|null
     */
    public function after__call(Image $image, $result, $method)
    {
        try {
            if ($method == 'getImageUrl' && $image->getProductId() > 0) {
                $result = "https://static.integromat.com/img/packages/magento_256.png";
            }
        } catch (\Exception $e) {
        }
        return $result;
    }

}

<VendorName>\<ModuleName>\Plugin\Minicart\AfterGetItemData.php

<?php

namespace <vendorName>\<moduleName>\Plugin\Minicart;

use Magento\Checkout\CustomerData\AbstractItem;

class AfterGetItemData
{
    /**
     * AfterGetImageData constructor.
     */
    public function __construct(
    )
    {
    }

    /**
     * @param AbstractItem $item
     * @param $result
     * @return mixed
     */
    public function afterGetItemData(AbstractItem $item, $result)
    {
        try {
            if ($result['product_id'] > 0) {
                $image = "https://static.integromat.com/img/packages/magento_256.png";
                $result['product_image']['src'] = $image;
            }
        } catch (\Exception $e) {
        }

        return $result;
    }

}

Thats all changes for Change images in storefront for product on all the places.

I hope it will help you.

9
  • A great thank ful for this, Its' really working but please can you share me for admin grid section . – RAKESH ROY Apr 7 '20 at 9:27
  • I will added the answer in below comment please check. – Nirav Patel Apr 7 '20 at 9:29
  • Good descriptions. – Rakesh Jesadiya Jun 2 '20 at 11:20
  • @NiravPatel is this working for product compare and wishlist page and minicart all other pages in front end – kanidhaya Jun 18 at 8:19
  • Yes, It is working at all places. – Nirav Patel Jun 19 at 9:11
2

To add Images to Admin Grid Please follow below steps.

you need to override ui_component of listing for all product, relatedproduct, cross sale and upsale.

<vendorName>/<moduleName>/view/adminhtml/ui_component/product_listing.xml

<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <columns name="product_columns">
        <column name="thumbnail" class="<vendorName>\<moduleName>\Ui\Component\Listing\Column\Thumbnail" component="Magento_Ui/js/grid/columns/thumbnail" sortOrder="20">
            <settings>
                <altField>name</altField>
                <hasPreview>1</hasPreview>
                <addField>true</addField>
                <label translate="true">Thumbnail</label>
                <sortable>false</sortable>
            </settings>
        </column>
    </columns>
</listing>

<vendorName>/<moduleName>/view/adminhtml/ui_component/related_product_listing.xml

<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <columns name="product_columns">
        <column name="thumbnail" class="<vendorName>\<moduleName>\Ui\Component\Listing\Column\Thumbnail" component="Magento_Ui/js/grid/columns/thumbnail" sortOrder="20">
            <settings>
                <altField>name</altField>
                <hasPreview>1</hasPreview>
                <addField>true</addField>
                <label translate="true">Thumbnail</label>
                <sortable>false</sortable>
            </settings>
        </column>
    </columns>
</listing>

<vendorName>/<moduleName>/view/adminhtml/ui_component/upsell_product_listing.xml

<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <columns name="product_columns">
        <column name="thumbnail" class="<vendorName>\<moduleName>\Ui\Component\Listing\Column\Thumbnail" component="Magento_Ui/js/grid/columns/thumbnail" sortOrder="20">
            <settings>
                <altField>name</altField>
                <hasPreview>1</hasPreview>
                <addField>true</addField>
                <label translate="true">Thumbnail</label>
                <sortable>false</sortable>
            </settings>
        </column>
    </columns>
</listing>

<vendorName>/<moduleName>/view/adminhtml/ui_component/crosssell_product_listing.xml

<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <columns name="product_columns">
        <column name="thumbnail" class="<vendorName>\<moduleName>\Ui\Component\Listing\Column\Thumbnail" component="Magento_Ui/js/grid/columns/thumbnail" sortOrder="20">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="align" xsi:type="string">left</item>
                </item>
            </argument>
            <settings>
                <altField>name</altField>
                <hasPreview>1</hasPreview>
                <addField>true</addField>
                <label translate="true">Thumbnail</label>
                <sortable>false</sortable>
            </settings>
        </column>
    </columns>
</listing>

Now you need to create a UI component class file to render image content.

<vendorName>/&ltmoduleName>/Ui/Component/Listing/Column/Thumbnail.php

<?php
namespace <vendorName>\<moduleName>\Ui\Component\Listing\Column;

use Magento\Catalog\Helper\Image;
use Magento\Framework\DataObject;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Ui\Component\Listing\Columns\Column;

/**
 * Class Thumbnail
 *
 * @api
 * @since 100.0.2
 */
class Thumbnail extends Column
{
    const NAME = 'thumbnail';

    const ALT_FIELD = 'name';

    /**
     * @param ContextInterface $context
     * @param UiComponentFactory $uiComponentFactory
     * @param Image $imageHelper
     * @param \Magento\Framework\UrlInterface $urlBuilder
     * @param array $components
     * @param array $data
     */
    public function __construct(
        ContextInterface $context,
        UiComponentFactory $uiComponentFactory,
        Image $imageHelper,
        \Magento\Framework\UrlInterface $urlBuilder,
        array $components = [],
        array $data = []
    ) {
        parent::__construct($context, $uiComponentFactory, $components, $data);
        $this->imageHelper = $imageHelper;
        $this->urlBuilder = $urlBuilder;
    }

    /**
     * @param array $dataSource
     * @return array
     */
    public function prepareDataSource(array $dataSource)
    {
        try {
            if (isset($dataSource['data']['items'])) {
                $fieldName = $this->getData('name');
                foreach ($dataSource['data']['items'] as & $item) {
                    $product = new DataObject($item);
                    $imageUrl = "https://static.integromat.com/img/packages/magento_256.png";
                    if ($imageUrl != "") {
                        $item[$fieldName . '_src'] = $imageUrl;
                        $item[$fieldName . '_alt'] = $this->getAlt($item) ?: $product->getName();
                        $item[$fieldName . '_link'] = $this->urlBuilder->getUrl(
                            'catalog/product/edit',
                            ['id' => $product->getEntityId(), 'store' => $this->context->getRequestParam('store')]
                        );
                        $item[$fieldName . '_orig_src'] = $imageUrl;

                    } else {
                        $imageHelper = $this->imageHelper->init($product, 'product_listing_thumbnail');
                        $item[$fieldName . '_src'] = $imageHelper->getUrl();
                        $item[$fieldName . '_alt'] = $this->getAlt($item) ?: $imageHelper->getLabel();
                        $item[$fieldName . '_link'] = $this->urlBuilder->getUrl(
                            'catalog/product/edit',
                            ['id' => $product->getEntityId(), 'store' => $this->context->getRequestParam('store')]
                        );
                        $origImageHelper = $this->imageHelper->init($product, 'product_listing_thumbnail_preview');
                        $item[$fieldName . '_orig_src'] = $origImageHelper->getUrl();
                    }
                }
            }
        } catch (\Exception $e) {
        }

        return $dataSource;
    }

    /**
     * Get Alt
     *
     * @param array $row
     *
     * @return null|string
     */
    protected function getAlt($row)
    {
        $altField = $this->getData('config/altField') ?: self::ALT_FIELD;
        return $row[$altField] ?? null;
    }
}

This is all about to change product images in admin grid.

I hope it will work for you.

Thank you.

2
  • Thank you @NiravPatel For this wonder ful code, Its really help full for me and helping me to get api images data implementation in my project. – RAKESH ROY Apr 7 '20 at 9:32
  • You are welcome @RAKESHROY – Nirav Patel Apr 7 '20 at 9:35
0

I try to get this extension working, no error at creation and activation of the module, the extension working fine because in storefront i have the white logo https://static.integromat.com/img/packages/magento_256.png, however my external images are not found: i use the following custom attributes (as text field with urls inside):

small_image_url medium_image_url large_image_url

did i miss something?

EDIT:

i used the following method to get my url from custom attribute:

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$product = $objectManager->get('Magento\Catalog\Model\Product')->load($image->getProductId());
$result = $product->getYourCustomAtrribute();

attribute code can be: your_custom_attribute / Your_Custom_Attribute or yourcustomattribute / YourCustomAttribute.... Method will still be getYourCustomAtrribute()

hope this can help (you must integrate this in all other pages, now i steel need to construct the array for the main products pages)

full page: AfterGetImageUrl.php

/**
 * @param Image $image
 * @param $method
 * @return array|null
 */
public function after__call(Image $image, $result, $method)
{
    try {
        if ($method == 'getImageUrl' && $image->getProductId() > 0) {
            $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
            $product = $objectManager->get('Magento\Catalog\Model\Product')->load($image->getProductId());
            $result = $product->getYourCustomAtrribute();
        }
    } catch (\Exception $e) {
    }
    return $result;
}
1
  • So for beginner. i call my custom attribute with the method mentioned above – newbjs Nov 18 '20 at 1:43

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.