Question

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.

Était-ce utile?

La solution

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.

Autres conseils

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.

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;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à magento.stackexchange
scroll top