From 152b0924d652de96bb49a93959bb3b304e2601ba Mon Sep 17 00:00:00 2001 From: Yevhenii Dumskyi Date: Tue, 30 Oct 2018 16:34:52 +0200 Subject: [PATCH 1/5] Fix Notice and Exception while adding image to product programmatically --- .../Model/Product/Gallery/Processor.php | 24 +++++++++++++++---- composer.json | 1 + 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php index c6c7fbda7e9ec..225c502830695 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php @@ -6,6 +6,7 @@ namespace Magento\Catalog\Model\Product\Gallery; +use Magento\Framework\Api\Data\ImageContentInterface; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Filesystem\DriverInterface; @@ -183,6 +184,13 @@ public function addImage( $attrCode = $this->getAttribute()->getAttributeCode(); $mediaGalleryData = $product->getData($attrCode); $position = 0; + + $absoluteFilePath = $this->mediaDirectory->getAbsolutePath($file); + $imageMimeType = mime_content_type($absoluteFilePath); + $imageContent = file_get_contents($absoluteFilePath); + $imageBase64 = base64_encode($imageContent); + $imageName = pathinfo($destinationFile, PATHINFO_FILENAME); + if (!is_array($mediaGalleryData)) { $mediaGalleryData = ['images' => []]; } @@ -195,11 +203,19 @@ public function addImage( $position++; $mediaGalleryData['images'][] = [ - 'file' => $fileName, - 'position' => $position, + 'file' => $fileName, + 'position' => $position, + 'label' => '', + 'disabled' => (int)$exclude, 'media_type' => 'image', - 'label' => '', - 'disabled' => (int)$exclude, + 'types' => $mediaAttribute, + 'content' => [ + 'data' => [ + ImageContentInterface::NAME => $imageName, + ImageContentInterface::BASE64_ENCODED_DATA => $imageBase64, + ImageContentInterface::TYPE => $imageMimeType, + ] + ] ]; $product->setData($attrCode, $mediaGalleryData); diff --git a/composer.json b/composer.json index e2a646275d98b..68bf1f1d8a8b0 100644 --- a/composer.json +++ b/composer.json @@ -29,6 +29,7 @@ "ext-xsl": "*", "ext-zip": "*", "lib-libxml": "*", + "ext-fileinfo": "*", "braintree/braintree_php": "3.35.0", "colinmollenhour/cache-backend-file": "~1.4.1", "colinmollenhour/cache-backend-redis": "1.10.5", From 7fd52e7ea8f7c7f77702d1b7a4665e715eee1ac3 Mon Sep 17 00:00:00 2001 From: Yevhenii Dumskyi Date: Wed, 31 Oct 2018 11:31:19 +0200 Subject: [PATCH 2/5] Remove all possible native php functions & use framework components --- .../Model/Product/Gallery/Processor.php | 33 ++++++++++++------- composer.json | 1 - 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php index 225c502830695..048ad55985b72 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php @@ -57,25 +57,34 @@ class Processor */ protected $resourceModel; + /** + * @var \Magento\Framework\File\Mime + */ + protected $mime; + /** * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository * @param \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDb * @param \Magento\Catalog\Model\Product\Media\Config $mediaConfig * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel + * @param \Magento\Framework\File\Mime $mime + * @throws \Magento\Framework\Exception\FileSystemException */ public function __construct( \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository, \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDb, \Magento\Catalog\Model\Product\Media\Config $mediaConfig, \Magento\Framework\Filesystem $filesystem, - \Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel + \Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel, + \Magento\Framework\File\Mime $mime ) { $this->attributeRepository = $attributeRepository; $this->fileStorageDb = $fileStorageDb; $this->mediaConfig = $mediaConfig; $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); $this->resourceModel = $resourceModel; + $this->mime = $mime; } /** @@ -186,10 +195,10 @@ public function addImage( $position = 0; $absoluteFilePath = $this->mediaDirectory->getAbsolutePath($file); - $imageMimeType = mime_content_type($absoluteFilePath); - $imageContent = file_get_contents($absoluteFilePath); + $imageMimeType = $this->mime->getMimeType($absoluteFilePath); + $imageContent = $this->mediaDirectory->readFile($absoluteFilePath); $imageBase64 = base64_encode($imageContent); - $imageName = pathinfo($destinationFile, PATHINFO_FILENAME); + $imageName = $pathinfo['filename']; if (!is_array($mediaGalleryData)) { $mediaGalleryData = ['images' => []]; @@ -203,17 +212,17 @@ public function addImage( $position++; $mediaGalleryData['images'][] = [ - 'file' => $fileName, - 'position' => $position, - 'label' => '', - 'disabled' => (int)$exclude, + 'file' => $fileName, + 'position' => $position, + 'label' => '', + 'disabled' => (int)$exclude, 'media_type' => 'image', - 'types' => $mediaAttribute, - 'content' => [ + 'types' => $mediaAttribute, + 'content' => [ 'data' => [ - ImageContentInterface::NAME => $imageName, + ImageContentInterface::NAME => $imageName, ImageContentInterface::BASE64_ENCODED_DATA => $imageBase64, - ImageContentInterface::TYPE => $imageMimeType, + ImageContentInterface::TYPE => $imageMimeType, ] ] ]; diff --git a/composer.json b/composer.json index 68bf1f1d8a8b0..e2a646275d98b 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,6 @@ "ext-xsl": "*", "ext-zip": "*", "lib-libxml": "*", - "ext-fileinfo": "*", "braintree/braintree_php": "3.35.0", "colinmollenhour/cache-backend-file": "~1.4.1", "colinmollenhour/cache-backend-redis": "1.10.5", From 71983df468f7d5a9ff35e915c59d56c4d33a414b Mon Sep 17 00:00:00 2001 From: Yevhenii Dumskyi Date: Thu, 1 Nov 2018 10:50:59 +0200 Subject: [PATCH 3/5] Fix backward incompatibility --- .../Catalog/Model/Product/Gallery/Processor.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php index 048ad55985b72..9cd5073f4357c 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php @@ -9,7 +9,7 @@ use Magento\Framework\Api\Data\ImageContentInterface; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\Filesystem\DriverInterface; +use Magento\Framework\App\ObjectManager; /** * Catalog product Media Gallery attribute processor. @@ -60,7 +60,7 @@ class Processor /** * @var \Magento\Framework\File\Mime */ - protected $mime; + private $mime; /** * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository @@ -68,7 +68,7 @@ class Processor * @param \Magento\Catalog\Model\Product\Media\Config $mediaConfig * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel - * @param \Magento\Framework\File\Mime $mime + * @param \Magento\Framework\File\Mime|null $mime * @throws \Magento\Framework\Exception\FileSystemException */ public function __construct( @@ -77,14 +77,14 @@ public function __construct( \Magento\Catalog\Model\Product\Media\Config $mediaConfig, \Magento\Framework\Filesystem $filesystem, \Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel, - \Magento\Framework\File\Mime $mime + \Magento\Framework\File\Mime $mime = null ) { $this->attributeRepository = $attributeRepository; $this->fileStorageDb = $fileStorageDb; $this->mediaConfig = $mediaConfig; $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); $this->resourceModel = $resourceModel; - $this->mime = $mime; + $this->mime = $mime ?: ObjectManager::getInstance()->get(\Magento\Framework\File\Mime::class); } /** From 10e64f25fc69c35010a74cb5628e67a64e6f9256 Mon Sep 17 00:00:00 2001 From: Yevhenii Dumskyi Date: Fri, 9 Nov 2018 12:16:37 +0200 Subject: [PATCH 4/5] Add save product with image integration test scenario --- .../Catalog/Model/ProductRepositoryTest.php | 48 +++++++++++++++++++ .../_files/product_simple_with_image.php | 45 +++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_image.php diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php index 39752460a1cd7..d4016b2bfa8d4 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php @@ -90,4 +90,52 @@ public function skuDataProvider(): array ['sku' => 'simple '], ]; } + + /** + * Test save product with gallery image + * + * @magentoDataFixture Magento/Catalog/_files/product_simple_with_image.php + * + * @throws \Magento\Framework\Exception\CouldNotSaveException + * @throws \Magento\Framework\Exception\InputException + * @throws \Magento\Framework\Exception\StateException + */ + public function testSaveProductWithGalleryImage(): void + { + /** @var $mediaConfig \Magento\Catalog\Model\Product\Media\Config */ + $mediaConfig = Bootstrap::getObjectManager() + ->get(\Magento\Catalog\Model\Product\Media\Config::class); + + /** @var $mediaDirectory \Magento\Framework\Filesystem\Directory\WriteInterface */ + $mediaDirectory = Bootstrap::getObjectManager() + ->get(\Magento\Framework\Filesystem::class) + ->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA); + + $product = Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); + $product->load(1); + + $path = $mediaConfig->getBaseMediaPath() . '/magento_image.jpg'; + $absolutePath = $mediaDirectory->getAbsolutePath() . $path; + $product->addImageToMediaGallery($absolutePath, [ + 'image', + 'small_image', + ], false, false); + + /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ + $productRepository = Bootstrap::getObjectManager() + ->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); + $productRepository->save($product); + + $gallery = $product->getData('media_gallery'); + $this->assertArrayHasKey('images', $gallery); + $images = array_values($gallery['images']); + + $this->assertNotEmpty($gallery); + $this->assertTrue(isset($images[0]['file'])); + $this->assertStringStartsWith('/m/a/magento_image', $images[0]['file']); + $this->assertArrayHasKey('media_type', $images[0]); + $this->assertEquals('image', $images[0]['media_type']); + $this->assertStringStartsWith('/m/a/magento_image', $product->getData('image')); + $this->assertStringStartsWith('/m/a/magento_image', $product->getData('small_image')); + } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_image.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_image.php new file mode 100644 index 0000000000000..252f99c97b787 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_image.php @@ -0,0 +1,45 @@ +reinitialize(); + +/** @var \Magento\TestFramework\ObjectManager $objectManager */ +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = $objectManager->create(\Magento\Catalog\Model\Product::class); +$product->isObjectNew(true); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setId(1) + ->setAttributeSetId(4) + ->setWebsiteIds([1]) + ->setName('Simple Product') + ->setSku('simple') + ->setPrice(10) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED); + +/** @var $mediaConfig \Magento\Catalog\Model\Product\Media\Config */ +$mediaConfig = $objectManager->get(\Magento\Catalog\Model\Product\Media\Config::class); + +/** @var $mediaDirectory \Magento\Framework\Filesystem\Directory\WriteInterface */ +$mediaDirectory = $objectManager->get(\Magento\Framework\Filesystem::class) + ->getDirectoryWrite(DirectoryList::MEDIA); + +$targetDirPath = $mediaConfig->getBaseMediaPath(); +$targetTmpDirPath = $mediaConfig->getBaseTmpMediaPath(); + +$mediaDirectory->create($targetDirPath); +$mediaDirectory->create($targetTmpDirPath); + +$dist = $mediaDirectory->getAbsolutePath($mediaConfig->getBaseMediaPath() . DIRECTORY_SEPARATOR . 'magento_image.jpg'); +copy(__DIR__ . '/magento_image.jpg', $dist); + +/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); +$productRepository->save($product); From 15dc79bea4a604a22a68e3a14fbd643336b3a400 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi Date: Fri, 9 Nov 2018 16:04:29 -0600 Subject: [PATCH 5/5] ENGCOM-3421: Magento 2.3 Fix Notice and Exception while adding image to product programmatically #18952 - Fixed docblocks --- .../Magento/Catalog/Model/Product/Gallery/Processor.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php index 9cd5073f4357c..0912324745360 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php @@ -88,6 +88,8 @@ public function __construct( } /** + * Return media_gallery attribute + * * @return \Magento\Catalog\Api\Data\ProductAttributeInterface * @since 101.0.0 */ @@ -383,7 +385,8 @@ public function setMediaAttribute(\Magento\Catalog\Model\Product $product, $medi } /** - * get media attribute codes + * Get media attribute codes + * * @return array * @since 101.0.0 */ @@ -393,6 +396,8 @@ public function getMediaAttributeCodes() } /** + * Trim .tmp ending from filename + * * @param string $file * @return string * @since 101.0.0 @@ -514,7 +519,6 @@ public function getAffectedFields($object) /** * Attribute value is not to be saved in a conventional way, separate table is used to store the complex value * - * {@inheritdoc} * @since 101.0.0 */ public function isScalar()