3

we use magento 2.1.9ce

Our products are made through an api. And they fill in the ean number at the image alt location. And unfortunatly they can't change that.

But i would like to have the products title on the img alt.

Can anyone help me with a script that copies the product title to the img alt?

7
  • 1
    Can't you just edit the PHTML file to include an alt to the images? Commented Jan 17, 2018 at 15:24
  • 1
    i would prefer a script, than i don't have to think about it when a theme updates ....
    – Ronny
    Commented Jan 17, 2018 at 17:51
  • 1
    So this needs to update the product database image alt with the Product Name? How many products? When does this need to happen is it manual like script you want to be able to fire every so often? or on addition of a product? Change of theme like suggested would be simpler. I would look at how the API is adding the products and change that after fixing current products with an import.
    – harri
    Commented Jan 18, 2018 at 13:27
  • 1
    Failing that observer on the product save event to modify the product object accordingly before save?
    – harri
    Commented Jan 18, 2018 at 13:31
  • 1
    i prefer a manually run script (which i could run with a cron). Which copies the product title to the image alt in the dbase Now its about 15K products .... but after first run we can add a line that it should start from a specific id ...
    – Ronny
    Commented Jan 18, 2018 at 13:51

2 Answers 2

4
+50

I want to add another answer and leave my existing answer as feel this one is more what you are after but like both solutions. Below creates a new cli command within Magento for updating image alt tags so you can run on demand or via cron like you have requested.

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\Framework\Console\CommandList">
                <arguments>
                        <argument name="commands" xsi:type="array">
                                <item name="update_alt" xsi:type="object">Harrigo\ProductUpdateCmd\Console\Command\UpdateAltCommand</item>
                        </argument>
                </arguments>
        </type>
</config>

etc/di.xml

This informs Magento about our new command and where to find it.

UpdateAltCommand.php

<?php
namespace Harrigo\ProductUpdateCmd\Console\Command;

use Magento\Catalog\Api\ProductManagementInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Api\FilterBuilder;
use Magento\Framework\App\Area;
use Magento\Framework\App\State;
use Magento\Framework\Registry;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class UpdateAltCommand extends Command
{

    protected $productModel;
    protected $productRepository;
    protected $productManagement;
    protected $searchCriteriaBuilder;
    protected $registry;
    protected $state;

    public function __construct(
        \Magento\Catalog\Model\Product $productModel,
        ProductRepositoryInterface $productRepositoryInterface,
        Registry $registry,
        SearchCriteriaBuilder $searchCriteriaBuilder,
        FilterBuilder $filterBuilder,
        State $state
    ) {
        $this->productModel = $productModel;
        $this->productRepository = $productRepositoryInterface;
        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
        $this->filterBuilder = $filterBuilder;
        $this->registry = $registry;
        $this->state = $state;
        parent::__construct();
    }

    protected function configure()
    {
        $this->setName('harrigo:updatealt')->setDescription('Updates Image Alt.');
        $this->addArgument('product_id', InputArgument::OPTIONAL, 'Start from Product ID');
        parent::configure();
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->registry->register('isSecureArea', true, true);
        try {
            $this->state->getAreaCode();
        }
        catch (\Exception $e) {
            $this->state->setAreaCode(Area::AREA_ADMINHTML);
        }
        if ($input->getArgument('product_id')) {
          $output->writeln('Updating Image Tags from ID: ' . $input->getArgument('product_id'));
        } else{
          $output->writeln('Updating Image Tags');
        } 
        if ($input->getArgument('product_id')) {
          $searchCriteria = $this->searchCriteriaBuilder->addFilter('entity_id', $input->getArgument('product_id'), 'gteq')->create();
          $products = $this->productRepository->getList($searchCriteria);
        } else{
          $products = $this->productRepository->getList($this->searchCriteriaBuilder->create());
        }
        if (count($products->getItems()) > 0)  {
            foreach ($products->getItems() as $product) {
                $output->writeln('Updating: ' . $product->getName());
                $title = $product->getName();
                $product = $this->productModel->load($product->getId());
                $existingMediaGalleryEntries = $product->getMediaGalleryEntries();
                if (count($existingMediaGalleryEntries) > 0) {
                    foreach ($existingMediaGalleryEntries as $key => $entry) {
                        $entry->setLabel($title);
                    }
                    $product->setMediaGalleryEntries($existingMediaGalleryEntries)->setStoreId(0)->save();
                }
            }  
        } else {
            $output->writeln('No Products Found');
        }
    }
}

Console/Command/UpdateAltCmd.php

This is the logic for our new command and is added within the Console/Command directory of the module along with the usual module files. The above tells Magento what command initiates the script and then grabs all products. This then loops through each product adding the product name to each of the image alt tags.

Usage

Once module is installed or remade on your installation run the command by using bin/magento harrigo:updatealt from Magento root. I have currently only tested this with a handful of products with Magento 2.1.8 however seems to work fine.

Run from Specific Product ID:

This command can also be run with a starting product id by adding the ID to the end of the updatealt command.

e.g:

bin/magento harrigo:updatealt 100

Download Module

Example of this module here: https://github.com/harrigo/ProductUpdateCmd

Screenshot of image update command in action

Installation

  1. Download Module
  2. Place Module Files within app/code/Harrigo/ProductUpdateCmd folder from Magento root directory.
  3. Run bin/magento setup:upgrade from Magento root
  4. Module is now installed, depending on magento mode you may need to compile and deploy static content etc.
1
  • I used the setLabel and setMediaGalleyEntries section of this answer in M2.4.6 to update the image alt text and it works nicely, but I used product repository to save the product as per 2.4 save practices.
    – Fox
    Commented Aug 10, 2023 at 0:42
1

Not entirely sure that this is what you want but I would fix all your current products with an import.

From then on in use the below observer to make sure the products are saved with your name attribute in the alt tags.

Create a Module

Create a new module with below code:

Obeserver Code

<?php
namespace Harrigo\ProductUpdate\Observer\Catalog;

class ProductSaveBefore implements \Magento\Framework\Event\ObserverInterface
{

  /**
   * Execute observer
   *
   * @param \Magento\Framework\Event\Observer $observer
   * @return void
   */
  public function execute(
      \Magento\Framework\Event\Observer $observer
  ) {
      $_product = $observer->getProduct();  // get product object
      //get title
      $title = $_product->getName();
      //get the images
      $existingMediaGalleryEntries = $_product->getMediaGalleryEntries();
      foreach ($existingMediaGalleryEntries as $key => $entry) {
          //set new title for each image
          $entry->setLabel($title);
      }
      //set the new labels for product
      $_product->setMediaGalleryEntries($existingMediaGalleryEntries);
  }
}

Harrigo/ProductUpdate/Observer/Catalog/ProductSaveBefore.php

Event

Then set this to run before product save event:

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="catalog_product_save_before">
        <observer instance="Harrigo\ProductUpdate\Observer\Catalog\ProductSaveBefore" name="harrigo_productupdate_observer_catalog_productsavebefore_catalog_product_save_before"/>
    </event>
</config>

Harrigo/ProductUpdate/etc/events.xml

This was added within app/code with all the usual module files. Harrigo was the vendor and ProductUpdate the module name here.

Update

During testing this I have noticed an issue when deleting images for a products with this will post a further update when i get a chance.

Your Answer

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

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