/** * {@inheritdoc} */ public function create($sku, ProductAttributeMediaGalleryEntryInterface $entry, $storeId = 0) { try { $this->storeManager->getStore($storeId); } catch (\Exception $exception) { throw new NoSuchEntityException(__('There is no store with provided ID.')); } /** @var $entry ProductAttributeMediaGalleryEntryInterface */ $entryContent = $entry->getContent(); if (!$this->contentValidator->isValid($entryContent)) { throw new InputException(__('The image content is not valid.')); } $product = $this->productRepository->get($sku); $existingMediaGalleryEntries = $product->getMediaGalleryEntries(); $existingEntryIds = []; if ($existingMediaGalleryEntries == null) { $existingMediaGalleryEntries = [$entry]; } else { foreach ($existingMediaGalleryEntries as $existingEntries) { $existingEntryIds[$existingEntries->getId()] = $existingEntries->getId(); } $existingMediaGalleryEntries[] = $entry; } $product->setMediaGalleryEntries($existingMediaGalleryEntries); try { $product = $this->productRepository->save($product); } catch (InputException $inputException) { throw $inputException; } catch (\Exception $e) { throw new StateException(__('Cannot save product.')); } foreach ($product->getMediaGalleryEntries() as $entry) { if (!isset($existingEntryIds[$entry->getId()])) { return $entry->getId(); } } throw new StateException(__('Failed to save new media gallery entry.')); }
/** * {@inheritdoc} */ public function create($product) { try { $this->storeManager->getStore($product->getStoreId()); } catch (\Exception $exception) { throw new NoSuchEntityException(__('There is no store with provided ID.')); } /** @var $entry ProductAttributeMediaGalleryEntryInterface */ $entry = $product->getCustomAttribute('media_gallery')->getValue(); $entryContent = $entry->getContent(); if (!$this->contentValidator->isValid($entryContent)) { throw new InputException(__('The image content is not valid.')); } $product = $this->productRepository->get($product->getSku()); $fileContent = @base64_decode($entryContent->getEntryData(), true); $mediaTmpPath = $this->mediaConfig->getBaseTmpMediaPath(); $mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); $mediaDirectory->create($mediaTmpPath); $fileName = $entryContent->getName() . '.' . $this->mimeTypeExtensionMap[$entryContent->getMimeType()]; $relativeFilePath = $mediaTmpPath . DIRECTORY_SEPARATOR . $fileName; $absoluteFilePath = $mediaDirectory->getAbsolutePath($relativeFilePath); $mediaDirectory->writeFile($relativeFilePath, $fileContent); /** @var $productMediaGallery \Magento\Catalog\Model\Product\Attribute\Backend\Media */ $productMediaGallery = $this->getGalleryAttributeBackend($product); $imageFileUri = $productMediaGallery->addImage($product, $absoluteFilePath, $entry->getTypes(), true, $entry->isDisabled()); // Update additional fields that are still empty after addImage call $productMediaGallery->updateImage($product, $imageFileUri, ['label' => $entry->getLabel(), 'position' => $entry->getPosition(), 'disabled' => $entry->isDisabled()]); try { $this->productRepository->save($product); } catch (\Exception $e) { throw new StateException(__('Cannot save product.')); } // Remove all temporary files $mediaDirectory->delete($relativeFilePath); // File could change its name during the move from tmp dir return $this->entryResolver->getEntryIdByFilePath($product, $productMediaGallery->getRenamedImage($imageFileUri)); }
/** * @param ProductInterface $product * @param array $newEntry * @return $this * @throws InputException * @throws StateException * @throws \Magento\Framework\Exception\LocalizedException */ protected function processNewMediaGalleryEntry(ProductInterface $product, array $newEntry) { /** @var ProductAttributeMediaGalleryEntryContentInterface $contentDataObject */ $contentDataObject = $newEntry['content']; if (!$this->contentValidator->isValid($contentDataObject)) { throw new InputException(__('The image content is not valid.')); } $fileContent = @base64_decode($contentDataObject->getEntryData(), true); $fileName = $contentDataObject->getName(); $mimeType = $contentDataObject->getMimeType(); /** @var \Magento\Catalog\Model\Product\Media\Config $mediaConfig */ $mediaConfig = $product->getMediaConfig(); $mediaTmpPath = $mediaConfig->getBaseTmpMediaPath(); $mediaDirectory = $this->fileSystem->getDirectoryWrite(DirectoryList::MEDIA); $mediaDirectory->create($mediaTmpPath); $fileName = $fileName . '.' . $this->mimeTypeExtensionMap->getMimeTypeExtension($mimeType); $relativeFilePath = $mediaTmpPath . DIRECTORY_SEPARATOR . $fileName; $absoluteFilePath = $mediaDirectory->getAbsolutePath($relativeFilePath); $mediaDirectory->writeFile($relativeFilePath, $fileContent); /** @var \Magento\Catalog\Model\Product\Attribute\Backend\Media $galleryAttributeBackend */ $galleryAttributeBackend = $product->getGalleryAttributeBackend(); if ($galleryAttributeBackend == null) { throw new StateException(__('Requested product does not support images.')); } $imageFileUri = $galleryAttributeBackend->addImage($product, $absoluteFilePath, isset($newEntry['types']) ? $newEntry['types'] : [], true, isset($newEntry['disabled']) ? $newEntry['disabled'] : true); // Update additional fields that are still empty after addImage call $galleryAttributeBackend->updateImage($product, $imageFileUri, ['label' => $newEntry['label'], 'position' => $newEntry['position'], 'disabled' => $newEntry['disabled']]); return $this; }
public function testSaveExistingWithNewMediaGalleryEntries() { $newEntriesData = [["label" => "label_text", 'position' => 10, 'disabled' => false, 'types' => ['image', 'small_image'], 'content' => ['name' => 'filename', 'mime_type' => 'image/jpeg', 'entry_data' => 'encoded_content']]]; $this->setupProductMocksForSave(); //media gallery data $this->productData['media_gallery_entries'] = $newEntriesData; $this->extensibleDataObjectConverterMock->expects($this->once())->method('toNestedArray')->will($this->returnValue($this->productData)); $this->initializedProductMock->setData('media_gallery', []); $this->initializedProductMock->expects($this->any())->method('getMediaAttributes')->willReturn(["image" => "imageAttribute", "small_image" => "small_image_attribute"]); //setup media attribute backend $mediaTmpPath = '/tmp'; $relativePath = $mediaTmpPath . DIRECTORY_SEPARATOR . 'filename.jpg'; $absolutePath = '/a/b/filename.jpg'; $galleryAttributeBackendMock = $this->getMockBuilder('\\Magento\\Catalog\\Model\\Product\\Attribute\\Backend\\Media')->disableOriginalConstructor()->getMock(); $galleryAttributeBackendMock->expects($this->once())->method('clearMediaAttribute')->with($this->initializedProductMock, ['image', 'small_image']); $mediaConfigMock = $this->getMockBuilder('Magento\\Catalog\\Model\\Product\\Media\\Config')->disableOriginalConstructor()->getMock(); $mediaConfigMock->expects($this->once())->method('getBaseTmpMediaPath')->willReturn($mediaTmpPath); $directoryWriteMock = $this->getMockBuilder('\\Magento\\Framework\\Filesystem\\Directory\\WriteInterface')->getMockForAbstractClass(); $this->fileSystemMock->expects($this->once())->method('getDirectoryWrite')->willReturn($directoryWriteMock); $directoryWriteMock->expects($this->once())->method('create')->with($mediaTmpPath); $this->mimeTypeExtensionMapMock->expects($this->once())->method('getMimeTypeExtension')->with('image/jpeg')->willReturn("jpg"); $directoryWriteMock->expects($this->once())->method('writeFile')->with($relativePath, false); //decoded value is false as it contains '_' $directoryWriteMock->expects($this->once())->method('getAbsolutePath')->willReturn($absolutePath); $this->initializedProductMock->expects($this->any())->method('getGalleryAttributeBackend')->willReturn($galleryAttributeBackendMock); $this->initializedProductMock->expects($this->once())->method('getMediaConfig')->willReturn($mediaConfigMock); //verify new entries $contentDataObject = $this->getMockBuilder('Magento\\Catalog\\Model\\Product\\Media\\GalleryEntryContent')->disableOriginalConstructor()->setMethods(null)->getMock(); $this->contentFactoryMock->expects($this->once())->method('create')->willReturn($contentDataObject); $this->contentValidatorMock->expects($this->once())->method('isValid')->willReturn(true); $imageFileUri = "imageFileUri"; $galleryAttributeBackendMock->expects($this->once())->method('addImage')->with($this->initializedProductMock, $absolutePath, ['image', 'small_image'], true, false)->willReturn($imageFileUri); $galleryAttributeBackendMock->expects($this->once())->method('updateImage')->with($this->initializedProductMock, $imageFileUri, ['label' => 'label_text', 'position' => 10, 'disabled' => false]); $this->model->save($this->productMock); }