Magento 2: Best Practice zum programmgesteuerten Hinzufügen / Löschen von Produktbildern?

18

Ich möchte Bilder zu den vorhandenen Produkten hochladen. Die Bilder sind in import_dir. Und sie müssen zu dem Produkt hinzugefügt werden, das bereits im Katalog vorhanden ist.

Ich konnte nur 2 Wege finden, wie es geht.
1. "Bad Practice" -Methode - Verwendung des Produktmodells\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. "Good Practice" -Methode - Verwendung der 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);

Bedenken:

  • Bei 1 erhalte ich einen Fehler, der ein bekanntes Problem darstellt

    Undefinierter Index: Medientyp

  • In 2 ist es viel zu kompliziert und es sollte der einfachere Weg sein

Fragen:

  • Gibt es eine bewährte Methode zum Verwalten (Hinzufügen, Entfernen, Ersetzen) von Produktbildern?
  • Möglicherweise gibt es einen Weg mit \ Magento \ CatalogImportExport \ Model \ Import \ Product
Olga Zhe
quelle

Antworten:

3

Dies kann auf Ihre zweite Art mehr oder weniger so gemacht werden:

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

}

$filePathsollte ein absoluter Pfad sein - vielleicht können Sie Konstanten verwenden BP.

Bartosz Kubicki
quelle
Es ist traurig, dass es keine guten Möglichkeiten mehr gibt, es zu lösen, denn wie @JakubIlczuk sagte - es ist sehr begrenzt. Über diese $entry->setMediaType('image');Zeile bin ich nicht ganz sicher, denn soweit ich mich erinnere, verursachte es mir einen Fehler, dass es einen Typ "png" oder "jpg" braucht (also sollte es am Ende "image / png" sein). Aber auch hier bin ich mir nicht sicher
Olga Zhe
In Magento 2.1.1 verursacht es keinen solchen Fehler.
Bartosz Kubicki
Weder Methodenadressen entfernen noch ersetzen. Nur eine Beobachtung.
Rooster242
0

Nachdem ich die gleichen Dinge wie Sie angeschaut habe, bin ich anscheinend genau am gleichen Ort und kann keinen besseren Weg finden als diese 2. Und diese 2 sind sehr begrenzt. In Funktionstests verwenden sie einfache product-> save () Dinge, die andere Probleme verursachen (für mich persönlich ist url_key bereits ein Fehler). Es scheint, dass nur die 2. Methode verwendet werden kann, wie kompliziert und verwirrend es auch sein mag. Aber ich frage mich, ob Sie bei der zweiten Methode eine Möglichkeit gefunden haben, die hochgeladenen Bilder als Miniaturbild oder kleines Bild festzulegen.

Jakub Ilczuk
quelle