Skip to content

Commit d132c7e

Browse files
committed
6486: #6486: Unable to save certain product properties via Rest API. Decrease Product Repository overall complexity.
1 parent de67388 commit d132c7e

File tree

4 files changed

+478
-251
lines changed

4 files changed

+478
-251
lines changed

app/code/Magento/Catalog/Model/ProductRepository.php

+11-172
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66
*/
77
namespace Magento\Catalog\Model;
88

9-
use Magento\Catalog\Api\Data\ProductInterface;
109
use Magento\Catalog\Model\Product\Gallery\MimeTypeExtensionMap;
1110
use Magento\Catalog\Model\ResourceModel\Product\Collection;
12-
use Magento\Framework\Api\Data\ImageContentInterface;
1311
use Magento\Framework\Api\Data\ImageContentInterfaceFactory;
1412
use Magento\Framework\Api\ImageContentValidatorInterface;
1513
use Magento\Framework\Api\ImageProcessorInterface;
@@ -18,10 +16,8 @@
1816
use Magento\Framework\DB\Adapter\DeadlockException;
1917
use Magento\Framework\DB\Adapter\LockWaitException;
2018
use Magento\Framework\Exception\CouldNotSaveException;
21-
use Magento\Framework\Exception\InputException;
2219
use Magento\Framework\Exception\LocalizedException;
2320
use Magento\Framework\Exception\NoSuchEntityException;
24-
use Magento\Framework\Exception\StateException;
2521
use Magento\Framework\Exception\ValidatorException;
2622

2723
/**
@@ -116,11 +112,15 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
116112
protected $fileSystem;
117113

118114
/**
115+
* @deprecated
116+
* @see \Magento\Catalog\Model\MediaGalleryProcessor
119117
* @var ImageContentInterfaceFactory
120118
*/
121119
protected $contentFactory;
122120

123121
/**
122+
* @deprecated
123+
* @see \Magento\Catalog\Model\MediaGalleryProcessor
124124
* @var ImageProcessorInterface
125125
*/
126126
protected $imageProcessor;
@@ -131,7 +131,7 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
131131
protected $extensionAttributesJoinProcessor;
132132

133133
/**
134-
* @var \Magento\Catalog\Model\Product\Gallery\Processor
134+
* @var ProductRepository\MediaGalleryProcessor
135135
*/
136136
protected $mediaGalleryProcessor;
137137

@@ -378,53 +378,6 @@ private function assignProductToWebsites(\Magento\Catalog\Model\Product $product
378378
$product->setWebsiteIds($websiteIds);
379379
}
380380

381-
/**
382-
* @param ProductInterface $product
383-
* @param array $newEntry
384-
* @return $this
385-
* @throws InputException
386-
* @throws StateException
387-
* @throws \Magento\Framework\Exception\LocalizedException
388-
*/
389-
protected function processNewMediaGalleryEntry(
390-
ProductInterface $product,
391-
array $newEntry
392-
) {
393-
/** @var ImageContentInterface $contentDataObject */
394-
$contentDataObject = $newEntry['content'];
395-
396-
/** @var \Magento\Catalog\Model\Product\Media\Config $mediaConfig */
397-
$mediaConfig = $product->getMediaConfig();
398-
$mediaTmpPath = $mediaConfig->getBaseTmpMediaPath();
399-
400-
$relativeFilePath = $this->imageProcessor->processImageContent($mediaTmpPath, $contentDataObject);
401-
$tmpFilePath = $mediaConfig->getTmpMediaShortUrl($relativeFilePath);
402-
403-
if (!$product->hasGalleryAttribute()) {
404-
throw new StateException(__('Requested product does not support images.'));
405-
}
406-
407-
$imageFileUri = $this->getMediaGalleryProcessor()->addImage(
408-
$product,
409-
$tmpFilePath,
410-
isset($newEntry['types']) ? $newEntry['types'] : [],
411-
true,
412-
isset($newEntry['disabled']) ? $newEntry['disabled'] : true
413-
);
414-
// Update additional fields that are still empty after addImage call
415-
$this->getMediaGalleryProcessor()->updateImage(
416-
$product,
417-
$imageFileUri,
418-
[
419-
'label' => $newEntry['label'],
420-
'position' => $newEntry['position'],
421-
'disabled' => $newEntry['disabled'],
422-
'media_type' => $newEntry['media_type'],
423-
]
424-
);
425-
return $this;
426-
}
427-
428381
/**
429382
* Process product links, creating new links, updating and deleting existing links
430383
*
@@ -483,67 +436,6 @@ private function processLinks(\Magento\Catalog\Api\Data\ProductInterface $produc
483436
return $this;
484437
}
485438

486-
/**
487-
* Process Media gallery data before save product.
488-
*
489-
* Compare Media Gallery Entries Data with existing Media Gallery
490-
* * If Media entry has not value_id set it as new
491-
* * If Existing entry 'value_id' absent in Media Gallery set 'removed' flag
492-
* * Merge Existing and new media gallery
493-
*
494-
* @param ProductInterface $product contains only existing media gallery items
495-
* @param array $mediaGalleryEntries array which contains all media gallery items
496-
* @return $this
497-
* @throws InputException
498-
* @throws StateException
499-
* @throws LocalizedException
500-
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
501-
*/
502-
protected function processMediaGallery(ProductInterface $product, $mediaGalleryEntries)
503-
{
504-
$existingMediaGallery = $product->getMediaGallery('images');
505-
$newEntries = [];
506-
$entriesById = [];
507-
if (!empty($existingMediaGallery)) {
508-
foreach ($mediaGalleryEntries as $entry) {
509-
if (isset($entry['id'])) {
510-
$entriesById[$entry['id']] = $entry;
511-
} else {
512-
$newEntries[] = $entry;
513-
}
514-
}
515-
foreach ($existingMediaGallery as $key => &$existingEntry) {
516-
if (isset($entriesById[$existingEntry['value_id']])) {
517-
$updatedEntry = $entriesById[$existingEntry['value_id']];
518-
if (array_key_exists('file', $updatedEntry) && $updatedEntry['file'] === null) {
519-
unset($updatedEntry['file']);
520-
}
521-
$existingMediaGallery[$key] = array_merge($existingEntry, $updatedEntry);
522-
} else {
523-
//set the removed flag
524-
$existingEntry['removed'] = true;
525-
}
526-
}
527-
unset($existingEntry);
528-
$product->setData('media_gallery', ["images" => $existingMediaGallery]);
529-
} else {
530-
$newEntries = $mediaGalleryEntries;
531-
}
532-
533-
$this->getMediaGalleryProcessor()->clearMediaAttribute($product, array_keys($product->getMediaAttributes()));
534-
$images = $product->getMediaGallery('images');
535-
if ($images) {
536-
foreach ($images as $image) {
537-
if (!isset($image['removed']) && !empty($image['types'])) {
538-
$this->getMediaGalleryProcessor()->setMediaAttribute($product, $image['types'], $image['file']);
539-
}
540-
}
541-
}
542-
$this->processEntries($product, $newEntries, $entriesById);
543-
544-
return $this;
545-
}
546-
547439
/**
548440
* {@inheritdoc}
549441
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
@@ -580,7 +472,10 @@ public function save(\Magento\Catalog\Api\Data\ProductInterface $product, $saveO
580472

581473
$this->processLinks($product, $productLinks);
582474
if (isset($productDataArray['media_gallery_entries'])) {
583-
$this->processMediaGallery($product, $productDataArray['media_gallery_entries']);
475+
$this->getMediaGalleryProcessor()->processMediaGallery(
476+
$product,
477+
$productDataArray['media_gallery_entries']
478+
);
584479
}
585480

586481
if (!$product->getOptionsReadonly()) {
@@ -752,13 +647,13 @@ public function cleanCache()
752647
}
753648

754649
/**
755-
* @return Product\Gallery\Processor
650+
* @return ProductRepository\MediaGalleryProcessor
756651
*/
757652
private function getMediaGalleryProcessor()
758653
{
759654
if (null === $this->mediaGalleryProcessor) {
760655
$this->mediaGalleryProcessor = \Magento\Framework\App\ObjectManager::getInstance()
761-
->get(\Magento\Catalog\Model\Product\Gallery\Processor::class);
656+
->get(ProductRepository\MediaGalleryProcessor::class);
762657
}
763658
return $this->mediaGalleryProcessor;
764659
}
@@ -778,60 +673,4 @@ private function getCollectionProcessor()
778673
}
779674
return $this->collectionProcessor;
780675
}
781-
782-
/**
783-
* Convert extension attribute for product media gallery.
784-
*
785-
* @param array $newEntry
786-
* @param array $extensionAttributes
787-
* @return void
788-
*/
789-
private function processExtensionAttributes(array &$newEntry, array $extensionAttributes)
790-
{
791-
foreach ($extensionAttributes as $code => $value) {
792-
if (is_array($value)) {
793-
$this->processExtensionAttributes($newEntry, $value);
794-
} else {
795-
$newEntry[$code] = $value;
796-
}
797-
}
798-
unset($newEntry['extension_attributes']);
799-
}
800-
801-
/**
802-
* Convert entries into product media gallery data and set to product.
803-
*
804-
* @param ProductInterface $product
805-
* @param array $newEntries
806-
* @param array $entriesById
807-
* @throws InputException
808-
* @throws LocalizedException
809-
* @throws StateException
810-
* @return void
811-
*/
812-
private function processEntries(ProductInterface $product, array $newEntries, array $entriesById)
813-
{
814-
foreach ($newEntries as $newEntry) {
815-
if (!isset($newEntry['content'])) {
816-
throw new InputException(__('The image content is not valid.'));
817-
}
818-
/** @var ImageContentInterface $contentDataObject */
819-
$contentDataObject = $this->contentFactory->create()
820-
->setName($newEntry['content'][ImageContentInterface::NAME])
821-
->setBase64EncodedData($newEntry['content'][ImageContentInterface::BASE64_ENCODED_DATA])
822-
->setType($newEntry['content'][ImageContentInterface::TYPE]);
823-
$newEntry['content'] = $contentDataObject;
824-
$this->processNewMediaGalleryEntry($product, $newEntry);
825-
826-
$finalGallery = $product->getData('media_gallery');
827-
$newEntryId = key(array_diff_key($product->getData('media_gallery')['images'], $entriesById));
828-
if (isset($newEntry['extension_attributes'])) {
829-
$this->processExtensionAttributes($newEntry, $newEntry['extension_attributes']);
830-
}
831-
$newEntry = array_replace_recursive($newEntry, $finalGallery['images'][$newEntryId]);
832-
$entriesById[$newEntryId] = $newEntry;
833-
$finalGallery['images'][$newEntryId] = $newEntry;
834-
$product->setData('media_gallery', $finalGallery);
835-
}
836-
}
837676
}

0 commit comments

Comments
 (0)