Базовые изображения в качестве первого изображения, массовое изменение позиций - Magento 2.3.5

Aug 17 2020

У нас есть большой каталог (125 тыс. Товаров) с большим количеством товаров, где базовое изображение расположено где-то в середине галереи.

Выбор базового изображения в порядке, это должно быть и оставаться базовым изображением, нам нужно только изменить положение этого изображения в галерее.

Мы знаем, что можем вручную изменить сортировку изображений и разместить это изображение перед галереей, но есть ли способ сделать это массово для всех продуктов?

Что-то вроде sql-запроса, который меняет положение базового изображения и помещает его впереди?

На скриншотах ниже вы видите первое, где базовое изображение находится в середине галереи, и последнее изображение, как и должно быть. Где базовое изображение размещается первым в галерее.

Перед:

После:

Ответы

1 HerveTribouilloy Aug 20 2020 at 03:02

приведенный ниже фрагмент - это шаги, которые необходимо выполнить, чтобы решить вашу проблему.

    $mainImage = $this->imageQueryResource->getProductMainImage($productId); $firstImage = $this->imageQueryResource->getFirstImages($productId);
            $output->writeln('first image' . $firstImage);
    
            if ($mainImage != $firstImage) {
                $output->writeln('fix product ' . $mainImage . ' product id: ' . $productId); $otherImages = $this->imageQueryResource->getAllImages($productId);
                foreach ($otherImages as $image) {
                    $position = 1; if ($image['value'] == $mainImage) { $this->imageQueryResource->updatePosition((int)$image['value_id'], $position);
                    }
                }
    
                reset($otherImages); foreach ($otherImages as $image) { if ($image['value'] != $mainImage) { $position++;
                        $this->imageQueryResource->updatePosition((int)$image['value_id'], $position);
                    }
                }
            }

приведенный ниже файл выполняет запрос и обновление ваших изображений.

<?php

namespace Mbs\ImageSorting\Model;

use Magento\Framework\App\ResourceConnection;

class ImageQueryResource
{
    /**
     * @var ResourceConnection
     */
    private $resourceConnection;
    /**
     * @var \Magento\Eav\Model\Config
     */
    private $config; public function __construct( ResourceConnection $resourceConnection,
        \Magento\Eav\Model\Config $config ) { $this->resourceConnection = $resourceConnection; $this->config = $config; } public function getProductMainImage(int $productId)
    {
        $mainImageAttribute = $this->config->getAttribute(\Magento\Catalog\Model\Product::ENTITY, 'image');

        $select = $this->resourceConnection->getConnection()->select();
        $select->from($this->resourceConnection->getTableName('catalog_product_entity_' . $mainImageAttribute->getBackendType())); $select->where('entity_id=?', $productId); $select->where('attribute_id=?', $mainImageAttribute->getId()); $select->reset(\Magento\Framework\DB\Select::COLUMNS);
        $select->columns(['value']); return $this->resourceConnection->getConnection()->fetchOne($select); } /** * @param int $productId
     * select * from catalog_product_entity_media_gallery_value as v
    inner join catalog_product_entity_media_gallery as g on g.value_id=v.value_id
    where entity_id=1802
    order by position
     */
    public function getAllImages(int $productId) { $select = $this->resourceConnection->getConnection()->select(); $select->from(['v' => $this->resourceConnection->getTableName('catalog_product_entity_media_gallery_value')]); $select->join(
            ['g' => 'catalog_product_entity_media_gallery'],
            'g.value_id=v.value_id',
            []
        );

        $select->where('entity_id=?', $productId);
        $select->reset(\Magento\Framework\DB\Select::COLUMNS); $select->columns(['v.value_id', 'v.position', 'g.value']);
        $select->order('v.position'); return $this->resourceConnection->getConnection()->fetchAll($select); } /** * @param int $productId
     * select * from catalog_product_entity_media_gallery_value as v
    inner join catalog_product_entity_media_gallery as g on g.value_id=v.value_id
    where entity_id=1802
    order by position
     */
    public function getFirstImages(int $productId) { $select = $this->resourceConnection->getConnection()->select(); $select->from(['v' => $this->resourceConnection->getTableName('catalog_product_entity_media_gallery_value')]); $select->join(
            ['g' => 'catalog_product_entity_media_gallery'],
            'g.value_id=v.value_id',
            []
        );

        $select->where('entity_id=?', $productId);
        $select->reset(\Magento\Framework\DB\Select::COLUMNS); $select->columns(['g.value', 'v.position']);
        $select->order('v.position'); //$select->limit(1);

        $result = $this->resourceConnection->getConnection()->fetchAll($select); $minPosition = 2000;
        $position = []; $minImage = '';
        foreach ($result as $row) {
            if ($row['position'] < $minPosition) {
                $minPosition = $row['position'];
                $minImage = $row['value'];
                $position[$row['position']] = 1;
            }
        }

        if (count($position) > 1) { return $minImage;
        }
    }

    public function updatePosition(int $valueId, int $position)
    {
        $this->resourceConnection->getConnection()->update( $this->resourceConnection->getTableName('catalog_product_entity_media_gallery_value'),
            ['position' => $position], ['value_id=?' => $valueId]
        );
    }

}