Magento 2: meilleure pratique pour ajouter / supprimer des images de produit par programmation?

18

Je souhaite télécharger des images vers les produits existants. Les images sont là import_dir. Et ils doivent être ajoutés au produit qui existe déjà dans le catalogue.

Je n'ai pu trouver que 2 façons de le faire.
1. Manière de "mauvaise pratique" - en utilisant le modèle de produit\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

Code

    /* 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. Méthode "bonne pratique" - utilisation de l'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

Code

    $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);

Préoccupations:

  • Dans 1, je reçois une erreur, qui est un problème connu

    Index non défini: media_type

  • En 2, c'est trop compliqué et ça devrait être le moyen le plus simple

Des questions:

  • Existe-t-il un moyen de "meilleure pratique" pour gérer (ajouter, supprimer, remplacer) les images du produit?
  • Peut-être existe-t-il un moyen avec \ Magento \ CatalogImportExport \ Model \ Import \ Product
Olga Zhe
la source

Réponses:

3

Cela peut être fait en utilisant votre deuxième méthode, plus ou moins comme ceci:

<?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);
}

}

$filePathdevrait être un chemin absolu - vous pouvez peut-être utiliser des constans BP.

Bartosz Kubicki
la source
c'est triste qu'il n'y ait plus de bonnes façons de le résoudre, comme l'a dit @JakubIlczuk - c'est très limité. À propos de cette $entry->setMediaType('image');ligne, je ne suis pas sûr, pour autant que je m'en souvienne, cela m'a causé une erreur quelque chose comme ça, il faut un type "png" ou "jpg" (donc à la fin ce devrait être "image / png"). Mais encore une fois, je ne suis pas sûr
Olga Zhe
Dans magento 2.1.1, il ne provoque pas une telle erreur.
Bartosz Kubicki
Aucune des deux méthodes ne supprime ou remplace. Juste une observation.
Rooster242
0

après avoir regardé les mêmes choses que vous, apparemment, je suis exactement au même endroit, et je ne peux pas trouver de meilleur moyen que ce 2. Et ces 2 sont très limités. Dans les tests fonctionnels, ils utilisent un simple produit-> save () qui provoque d'autres problèmes (pour moi personnellement, url_key existe déjà une erreur). Il semble que seule la 2ème méthode puisse être utilisée, aussi compliquée et déroutante que cela puisse paraître. Mais je me demande si dans la 2e méthode, vous avez trouvé un moyen de définir les images téléchargées comme vignette ou petite image?

Jakub Ilczuk
la source