Magento 2: práticas recomendadas para adicionar / excluir imagens de produtos programaticamente?


18

Quero fazer upload de imagens para os produtos existentes. As imagens estão em import_dir. E eles precisam ser adicionados ao produto que já existe no catálogo.

Eu poderia encontrar apenas duas maneiras de fazê-lo.
1. Maneira de "má prática" - usando o modelo do produto\Magento\Catalog\Model\Product::addImageToMediaGallery

1. Copy the images from `import_dir` to `pub/media/tmp`
2. Add the images to the product
3. Save product

Código

    /* copy files from import_dir to pub/media/tmp */

    /** @var \Magento\Catalog\Api\Data\ProductInterface $product */
    /* Init media gallery */
    $mediaGalleryEntries = $product->getMediaGalleryEntries();
    if (empty($mediaGalleryEntries) === true){
        $product->setMediaGalleryEntries([]);
    }

    /* Add an image to the product's gallery */
    $product->addImageToMediaGallery(
        $filePathFromTmpDir,
        [
          "image",
          "small_image",
          "thumbnail",
          "swatch_image" 
        ],
        $moveImage,
        $disableImage
    );

    /* Save */
    $this->_productRepository->save($product);

2. Maneira de "boas práticas" - usando API \Magento\Catalog\Api\ProductAttributeMediaGalleryManagementInterface::create

1. Create image content object via **\Magento\Framework\Api\Data\ImageContentInterfaceFactory**
2. Create image object via **\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterfaceFactory**
3. Create an image via API

Código

    $imageContent = $this->_imageContentInterfaceFactory->create()
        ->setBase64EncodedData(base64_encode(file_get_contents($filePathImportDir)))
        ->setType($this->_mime->getMimeType($filePathImportDir))
        ->setName($file_name);

    $newImage = $this->_productAttributeMediaGalleryEntryInterfaceFactory->create()
        ->setMediaType(\Magento\Catalog\Model\Product\Attribute\Backend\Media\ImageEntryConverter::MEDIA_TYPE_CODE)
        ->setFile($filePathImportDir)
        ->setDisabled($disableImage)
        ->setContent($imageContent)
        ->setLabel('label');

    $this->_productAttributeMediaGalleryManagement->create($product->getSku(), $newImage);

Preocupações:

  • Em 1 , estou recebendo um erro, problema conhecido

    Índice indefinido: media_type

  • Em 2 é muito complicado e deve ser o caminho mais fácil

Questões:

  • Existe uma maneira "recomendada" para gerenciar (adicionar, remover, substituir) imagens do produto?
  • Talvez exista uma maneira com \ Magento \ CatalogImportExport \ Model \ Import \ Product

Respostas:


3

Isso pode ser feito usando sua segunda maneira, mais ou menos assim:

<?php


namespace [vendor]\[moduleName]\Model\Adminhtml\Product\MediaGallery;

use \Magento\Catalog\Model\Product\Gallery\EntryFactory;
use \Magento\Catalog\Model\Product\Gallery\GalleryManagement;
use \Magento\Framework\Api\ImageContentFactory;

{

/**
 * @var \Magento\Catalog\Model\Product\Gallery\EntryFactory
 */
private $mediaGalleryEntryFactory;


/**
 * @var \Magento\Catalog\Model\Product\Gallery\GalleryManagement
 */
private $mediaGalleryManagement;


/**
 * @var \Magento\Framework\Api\ImageContentFactory
 */
private $imageContentFactory;


/**
 * @param \Magento\Catalog\Model\Product\Gallery\EntryFactory $mediaGalleryEntryFactory
 * @param \Magento\Catalog\Model\Product\Gallery\GalleryManagement $mediaGalleryManagement
 * @param \Magento\Framework\Api\ImageContentFactory $imageContentFactory
 */
public function __construct
(
    EntryFactory $mediaGalleryEntryFactory,
    GalleryManagement $mediaGalleryManagement,
    ImageContentFactory $imageContentFactory
)
{
    $this->mediaGalleryEntryFactory = $mediaGalleryEntryFactory;
    $this->mediaGalleryManagement = $mediaGalleryManagement;
    $this->imageContentFactory = $imageContentFactory;
}


/**
 * @param string $filePath
 * @param string $sku
 */
public function processMediaGalleryEntry($filePath, $sku)
{
    $entry = $this->mediaGalleryEntryFactory->create();

    $entry->setFile($filePath);
    $entry->setMediaType('image');
    $entry->setDisabled(false);
    $entry->setTypes(['thumbnail', 'image', 'small_image']);

    $imageContent = $this->imageContentFactory->create();
    $imageContent
        ->setType(mime_content_type($filePath))
        ->setName('test')
        ->setBase64EncodedData(base64_encode(file_get_contents($filePath)));

    $entry->setContent($imageContent);

    $this->mediaGalleryManagement->create($sku, $entry);
}

}

$filePathdeve ser um caminho absoluto - talvez você possa usar constans BP.


é triste que não haja mais boas maneiras de resolvê-lo, porque como @JakubIlczuk disse - é altamente limitado. Sobre esta $entry->setMediaType('image');linha, não tenho muita certeza, porque, até onde me lembro, me causou um erro, algo como esse: é necessário um tipo "png" ou "jpg" (por isso, no final, deve ser "image / png"). Mas, novamente, eu não tenho certeza
Olga Zhe

No magento 2.1.1, não está causando esse erro.
Bartosz Kubicki

Nenhum dos endereços de método remove ou substitui. Apenas uma observação.
precisa saber é o seguinte

0

depois de olhar para as mesmas coisas que você, aparentemente, eu estou exatamente no mesmo lugar, e não consigo encontrar uma maneira melhor do que essa 2. E essa 2 é altamente limitada. Nos testes funcionais, eles usam algo simples do produto-> save () que causa outros problemas (para mim, pessoalmente, o url_key já existe erro). Parece que apenas o segundo método pode ser usado, por mais complicado e confuso que pareça. Mas eu me pergunto se no segundo método você encontrou uma maneira de definir as imagens enviadas como miniatura ou imagem pequena?

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.