Magento 2 offre un modo più rapido per modificare le voci della galleria multimediale dei prodotti a livello di codice


8

Devo fare un aggiornamento massiccio dei dati del prodotto, ma ciò che devo fare non può essere raggiunto con l'importazione del prodotto. Ad esempio, devo aggiornare la galleria multimediale e le categorie per determinati prodotti, ma la soluzione con cui sono uscito richiede troppo tempo.

Un piccolo riassunto: ho aggiunto un comando alla CLI di Magento 2 che, dato un file di configurazione json, rimuove, aggiunge, aggiorna o ordina le voci della galleria multimediale per un determinato prodotto come questo. Qui incollo un estratto del codice:

/* $product is of type Magento\Catalog\Model\Product */

//get existing media gallery
$existingMediaGallery = $product->getMediaGallery();

/* 
   do stuff with media gallery (alter $existingMediaGallery)
   (add, remove, sort, ...)
*/

//set media gallery again
$product->setMediaGallery($existingMediaGallery);

//process media gallery
$mediaGalleryEntries = $product->getMediaGalleryEntries();
$this->getMediaGalleryProcessor()->clearMediaAttribute($product, array_keys($product->getMediaAttributes()));
if ($mediaGalleryEntries) {
  foreach ($mediaGalleryEntries as $k => $entry) {
    if (!isset($entry['removed']) && !empty($entry['types'])) {
      $this->getMediaGalleryProcessor()->setMediaAttribute($product, $entry['types'], $entry['file']);
    }
  }
}

//save product
$product->save();

Poiché si tratta di un aggiornamento massiccio, la riga "$ product-> save ()" viene chiamata molte volte e richiede sempre da 2 a 4 secondi. Dato che devo lanciare il codice per migliaia di prodotti, ho bisogno di un modo più rapido per farlo.

Ci ho provato

$product->getResource()->saveAttribute($product, 'media_gallery');

e

$product->addAttributeUpdate('media_gallery', $mediaGallery, $storeId);

ma questo non funziona per la galleria multimediale (funziona solo per eav credo).

C'è un modo per salvare solo la galleria multimediale e persistere più rapidamente queste modifiche?

(Quello che cerco è qualcosa di simile al Magento\Catalog\Api\CategoryLinkManagementInterface::assignProductToCategoriesmetodo che salva l'associazione categoria / prodotto più velocemente di un salvataggio completo del prodotto)

Risposte:


0

Penso che tu sia sulla buona strada: il prodotto di salvataggio sta impiegando molto tempo e deve andare ..

Ora, con l'aggiornamento delle immagini, può essere davvero complicato. Ma mi piacerebbe pensare che potrebbe essere un modo per separare il problema:

  • suppongo che sia necessario che i dati multimediali siano archiviati nel database e ciò può essere fatto utilizzando il metodo saveAttribute .. (molto veloce). Tuttavia, potresti voler aggiungere alcuni attributi nel tuo script di aggiornamento: vedi gli attributi 'image, small_image, thumbnail' (vedi nel database select * from eav_attribute where ((attribute_code like '%image%') or (attribute_code='thumbnail')) and entity_type_id=4))

  • ora il più complesso, ma potrei avere alcune idee, è di trattare l'immagine fisicamente parlando e possibili dati multimediali aggiuntivi (titolo tag immagine, posizione e così via)

-> per questo secondo punto: darei un'occhiata alla classe Magento \ Catalog \ Model \ Product \ Gallery \ CreateHandler in quanto ti mostrerà come Magento mantiene tutto funzionante per quanto riguarda i dati multimediali.


0

Per quanto ne so non esiste un modo per salvare le voci multimediali senza salvare il prodotto. ma il prodotto di salvataggio non dovrebbe impiegare molto tempo con l'interfaccia ProductRepository.

Ho creato un modulo simile e non ho lo stesso problema con il salvataggio multimediale.

Ecco la mia soluzione per salvare i media:

 /**
     * Add Product media from folder.
     * @param $product
     * @param $productData
     * @return mixed
     */
    protected function setProductMedia($product, $productData)
    {
        $medias = [];
        $files = scandir(self::MEDIA_PATH);
        $mediaPath = '';
        foreach ($files as $file) {
            if ($file !== '.' && $file !== '..') {
                $path = realpath(self::MEDIA_PATH . $file);
                if ($path) {
                    if (basename($path, '.jpg') == trim($productData['productCode'])) {
                        $mediaPath = self::MEDIA_PATH . $file;
                        break;
                    }
                }
            }
        }

        if ((bool)$mediaPath) {
            $image = $this->_imageContent
               ->setBase64EncodedData(base64_encode(file_get_contents($mediaPath)))
               ->setType(image_type_to_mime_type(exif_imagetype($mediaPath)))
               ->setName(basename($mediaPath));

            $media = $this->_productAttributeMediaGalleryEntry
               ->setFile($mediaPath)
               ->setTypes(['thumbnail', 'small_image', 'image'])
               ->setLabel($productData['description'])
               ->setPosition(0)
               ->setMediaType('image')
               ->setContent($image)
               ->setDisabled(false)
               ->setPosition(0);

            $medias[] = $media;
            $product->setMediaGalleryEntries($medias);
       }

        return $product;
    }

Quindi salvo il prodotto con productRepositoryInterface.

   try {
        $product = $this->_productRepository->get($productData['productCode']);
    } catch (NoSuchEntityException $e) {
        throw new NoSuchEntityException(__('Could Not Update Product Error: %1', $e->getMessage()));
    }

    $product = $this->setProductMedia($product, $productData);

    try {
       $this->_productRepository->save($product);
    } catch (InputException $exception) {
       $this->_logger->critical(__("Could not save product Error: %1", $exception->getMessage()));
    } catch (StateException $exception) {
       $this->_logger->critical(__("Could not save product, Error: %1",$exception->getMessage()));
    } catch (CouldNotSaveException $exception) {
       $this->_logger->critical(__('Could Not Save Product Error: %1' ,$exception->getMessage()));
    }

Salva abbastanza rapidamente. Posso eseguire 10.000 prodotti in pochi minuti. Ciò include la ricerca del supporto che è chiamato {sku} .jpg e tutto in una singola cartella.


è possibile semplicemente impostare i ruoli dell'immagine, ad es. -> setTypes (['thumbnail', 'small_image', 'image']) senza sostituire l'intera immagine?
paj
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.