Magento 2 ada cara yang lebih cepat untuk mengubah entri galeri media produk secara terprogram

8

Saya perlu melakukan pembaruan besar-besaran terhadap data produk tetapi apa yang harus saya lakukan tidak dapat dicapai dengan impor produk. Sebagai contoh, saya perlu memperbarui galeri media dan kategori untuk produk yang diberikan, tetapi solusi yang saya buat terlalu lama.

Rekap kecil: Saya menambahkan perintah ke Magento 2 CLI yang, diberikan file konfigurasi json, menghapus, menambah, memperbarui atau mengurutkan entri galeri media untuk produk yang diberikan seperti ini. Di sini saya menempelkan kutipan kode:

/* $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();

Karena ini merupakan pembaruan besar-besaran, baris "$ product-> save ()" dipanggil berkali-kali dan selalu memakan waktu 2 hingga 4 detik. Karena saya perlu meluncurkan kode untuk ribuan produk, saya perlu cara yang lebih cepat untuk melakukannya.

Saya mencoba

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

dan

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

tapi itu tidak berfungsi untuk galeri media (saya pikir hanya berfungsi untuk eav).

Apakah ada cara untuk menyimpan hanya galeri media dan mempertahankan perubahan ini lebih cepat?

(Apa yang saya cari adalah sesuatu seperti Magento\Catalog\Api\CategoryLinkManagementInterface::assignProductToCategoriesmetode yang menyimpan asosiasi kategori / produk lebih cepat daripada menyimpan produk lengkap)

CaNNaDaRk
sumber

Jawaban:

0

Saya pikir Anda berada di jalur yang benar: menyimpan produk butuh waktu lama dan harus pergi ..

Sekarang, dengan pembaruan gambar, itu bisa sangat rumit. Tapi saya ingin berpikir itu mungkin jalan ke depan untuk memisahkan masalah:

  • Dugaan saya adalah Anda membutuhkan data media untuk disimpan dalam database dan itu dapat dilakukan dengan menggunakan metode Anda saveAttribute .. (sangat cepat). Namun, Anda mungkin ingin menambahkan beberapa atribut dalam skrip pembaruan Anda: lihat atribut 'gambar, small_image, thumbnail' (lihat di database select * from eav_attribute where ((attribute_code like '%image%') or (attribute_code='thumbnail')) and entity_type_id=4))

  • sekarang yang lebih kompleks tetapi saya mungkin punya beberapa ide, adalah untuk berurusan dengan gambar yang berbicara secara fisik dan kemungkinan data media tambahan (judul tag gambar, posisi dan sebagainya)

-> untuk poin kedua ini: Saya akan melihat kelas Magento \ Katalog \ Model \ Produk \ Galeri \ CreateHandler karena akan menunjukkan kepada Anda bagaimana Magento membuat semuanya bekerja mengenai data media.

Herve Tribouilloy
sumber
0

Sejauh yang saya tahu tidak ada cara untuk menyimpan entri media tanpa menyimpan produk. tetapi produk simpanan seharusnya tidak membutuhkan waktu lama dengan productRepositoryInterface.

Saya membuat modul serupa dan saya tidak memiliki masalah yang sama dengan media save.

Inilah solusi saya untuk menghemat 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;
    }

Saya kemudian menyimpan produk dengan 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()));
    }

Menghemat cukup cepat. Saya dapat menjalankan 10.000 produk dalam beberapa menit. Itu termasuk pencarian untuk media yang bernama {sku} .jpg dan semua yang dimasukkan dalam satu folder.

Djfordz
sumber
apakah mungkin untuk hanya mengatur peran gambar yaitu -> setTypes (['thumbnail', 'small_image', 'image']) tanpa mengganti seluruh gambar?
paj