11<?php
22/**
3- *
43 * Copyright © Magento, Inc. All rights reserved.
54 * See COPYING.txt for license details.
65 */
1110use Magento \Catalog \Api \Data \ProductExtension ;
1211use Magento \Catalog \Api \Data \ProductInterface ;
1312use Magento \Catalog \Model \Product \Gallery \MimeTypeExtensionMap ;
13+ use Magento \Catalog \Model \ProductRepository \MediaGalleryProcessor ;
1414use Magento \Catalog \Model \ResourceModel \Product \Collection ;
1515use Magento \Eav \Model \Entity \Attribute \Exception as AttributeException ;
16- use Magento \Framework \Api \Data \ImageContentInterface ;
1716use Magento \Framework \Api \Data \ImageContentInterfaceFactory ;
1817use Magento \Framework \Api \ImageContentValidatorInterface ;
1918use Magento \Framework \Api \ImageProcessorInterface ;
2625use Magento \Framework \Exception \InputException ;
2726use Magento \Framework \Exception \LocalizedException ;
2827use Magento \Framework \Exception \NoSuchEntityException ;
29- use Magento \Framework \Exception \TemporaryState \CouldNotSaveException as TemporaryCouldNotSaveException ;
3028use Magento \Framework \Exception \StateException ;
29+ use Magento \Framework \Exception \TemporaryState \CouldNotSaveException as TemporaryCouldNotSaveException ;
3130use Magento \Framework \Exception \ValidatorException ;
3231
3332/**
@@ -123,11 +122,15 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
123122 protected $ fileSystem ;
124123
125124 /**
125+ * @deprecated
126+ *
126127 * @var ImageContentInterfaceFactory
127128 */
128129 protected $ contentFactory ;
129130
130131 /**
132+ * @deprecated
133+ *
131134 * @var ImageProcessorInterface
132135 */
133136 protected $ imageProcessor ;
@@ -138,10 +141,17 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
138141 protected $ extensionAttributesJoinProcessor ;
139142
140143 /**
144+ * @deprecated
145+ *
141146 * @var \Magento\Catalog\Model\Product\Gallery\Processor
142147 */
143148 protected $ mediaGalleryProcessor ;
144149
150+ /**
151+ * @var MediaGalleryProcessor
152+ */
153+ private $ mediaProcessor ;
154+
145155 /**
146156 * @var CollectionProcessorInterface
147157 */
@@ -192,8 +202,8 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
192202 * @param CollectionProcessorInterface $collectionProcessor [optional]
193203 * @param \Magento\Framework\Serialize\Serializer\Json|null $serializer
194204 * @param int $cacheLimit [optional]
195- * @param ReadExtensions|null $readExtensions
196- * @param Magento\Catalog\Api\ CategoryLinkManagementInterface|null $linkManagement
205+ * @param ReadExtensions $readExtensions
206+ * @param CategoryLinkManagementInterface $linkManagement
197207 * @SuppressWarnings(PHPMD.ExcessiveParameterList)
198208 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
199209 */
@@ -391,6 +401,9 @@ private function assignProductToWebsites(\Magento\Catalog\Model\Product $product
391401 /**
392402 * Process new gallery media entry.
393403 *
404+ * @deprecated
405+ * @see MediaGalleryProcessor::processNewMediaGalleryEntry()
406+ *
394407 * @param ProductInterface $product
395408 * @param array $newEntry
396409 * @return $this
@@ -402,40 +415,8 @@ protected function processNewMediaGalleryEntry(
402415 ProductInterface $ product ,
403416 array $ newEntry
404417 ) {
405- /** @var ImageContentInterface $contentDataObject */
406- $ contentDataObject = $ newEntry ['content ' ];
407-
408- /** @var \Magento\Catalog\Model\Product\Media\Config $mediaConfig */
409- $ mediaConfig = $ product ->getMediaConfig ();
410- $ mediaTmpPath = $ mediaConfig ->getBaseTmpMediaPath ();
411-
412- $ relativeFilePath = $ this ->imageProcessor ->processImageContent ($ mediaTmpPath , $ contentDataObject );
413- $ tmpFilePath = $ mediaConfig ->getTmpMediaShortUrl ($ relativeFilePath );
418+ $ this ->getMediaGalleryProcessor ()->processNewMediaGalleryEntry ($ product , $ newEntry );
414419
415- if (!$ product ->hasGalleryAttribute ()) {
416- throw new StateException (
417- __ ("The product that was requested doesn't exist. Verify the product and try again. " )
418- );
419- }
420-
421- $ imageFileUri = $ this ->getMediaGalleryProcessor ()->addImage (
422- $ product ,
423- $ tmpFilePath ,
424- isset ($ newEntry ['types ' ]) ? $ newEntry ['types ' ] : [],
425- true ,
426- isset ($ newEntry ['disabled ' ]) ? $ newEntry ['disabled ' ] : true
427- );
428- // Update additional fields that are still empty after addImage call
429- $ this ->getMediaGalleryProcessor ()->updateImage (
430- $ product ,
431- $ imageFileUri ,
432- [
433- 'label ' => $ newEntry ['label ' ],
434- 'position ' => $ newEntry ['position ' ],
435- 'disabled ' => $ newEntry ['disabled ' ],
436- 'media_type ' => $ newEntry ['media_type ' ],
437- ]
438- );
439420 return $ this ;
440421 }
441422
@@ -510,68 +491,13 @@ private function processLinks(ProductInterface $product, $newLinks)
510491 * @return $this
511492 * @throws InputException
512493 * @throws StateException
494+ * @throws LocalizedException
513495 * @SuppressWarnings(PHPMD.CyclomaticComplexity)
514496 */
515497 protected function processMediaGallery (ProductInterface $ product , $ mediaGalleryEntries )
516498 {
517- $ existingMediaGallery = $ product ->getMediaGallery ('images ' );
518- $ newEntries = [];
519- $ entriesById = [];
520- if (!empty ($ existingMediaGallery )) {
521- foreach ($ mediaGalleryEntries as $ entry ) {
522- if (isset ($ entry ['value_id ' ])) {
523- $ entriesById [$ entry ['value_id ' ]] = $ entry ;
524- } else {
525- $ newEntries [] = $ entry ;
526- }
527- }
528- foreach ($ existingMediaGallery as $ key => &$ existingEntry ) {
529- if (isset ($ entriesById [$ existingEntry ['value_id ' ]])) {
530- $ updatedEntry = $ entriesById [$ existingEntry ['value_id ' ]];
531- if ($ updatedEntry ['file ' ] === null ) {
532- unset($ updatedEntry ['file ' ]);
533- }
534- $ existingMediaGallery [$ key ] = array_merge ($ existingEntry , $ updatedEntry );
535- } else {
536- //set the removed flag
537- $ existingEntry ['removed ' ] = true ;
538- }
539- }
540- $ product ->setData ('media_gallery ' , ["images " => $ existingMediaGallery ]);
541- } else {
542- $ newEntries = $ mediaGalleryEntries ;
543- }
544-
545- $ images = (array )$ product ->getMediaGallery ('images ' );
546- $ images = $ this ->determineImageRoles ($ product , $ images );
547-
548- $ this ->getMediaGalleryProcessor ()->clearMediaAttribute ($ product , array_keys ($ product ->getMediaAttributes ()));
549-
550- foreach ($ images as $ image ) {
551- if (!isset ($ image ['removed ' ]) && !empty ($ image ['types ' ])) {
552- $ this ->getMediaGalleryProcessor ()->setMediaAttribute ($ product , $ image ['types ' ], $ image ['file ' ]);
553- }
554- }
499+ $ this ->getMediaGalleryProcessor ()->processMediaGallery ($ product , $ mediaGalleryEntries );
555500
556- foreach ($ newEntries as $ newEntry ) {
557- if (!isset ($ newEntry ['content ' ])) {
558- throw new InputException (__ ('The image content is invalid. Verify the content and try again. ' ));
559- }
560- /** @var ImageContentInterface $contentDataObject */
561- $ contentDataObject = $ this ->contentFactory ->create ()
562- ->setName ($ newEntry ['content ' ]['data ' ][ImageContentInterface::NAME ])
563- ->setBase64EncodedData ($ newEntry ['content ' ]['data ' ][ImageContentInterface::BASE64_ENCODED_DATA ])
564- ->setType ($ newEntry ['content ' ]['data ' ][ImageContentInterface::TYPE ]);
565- $ newEntry ['content ' ] = $ contentDataObject ;
566- $ this ->processNewMediaGalleryEntry ($ product , $ newEntry );
567-
568- $ finalGallery = $ product ->getData ('media_gallery ' );
569- $ newEntryId = key (array_diff_key ($ product ->getData ('media_gallery ' )['images ' ], $ entriesById ));
570- $ newEntry = array_replace_recursive ($ newEntry , $ finalGallery ['images ' ][$ newEntryId ]);
571- $ entriesById [$ newEntryId ] = $ newEntry ;
572- $ finalGallery ['images ' ][$ newEntryId ] = $ newEntry ;
573- $ product ->setData ('media_gallery ' , $ finalGallery );
574- }
575501 return $ this ;
576502 }
577503
@@ -781,44 +707,19 @@ public function cleanCache()
781707 $ this ->instancesById = null ;
782708 }
783709
784- /**
785- * Ascertain image roles, if they are not set against the gallery entries
786- *
787- * @param ProductInterface $product
788- * @param array $images
789- * @return array
790- */
791- private function determineImageRoles (ProductInterface $ product , array $ images ) : array
792- {
793- $ imagesWithRoles = [];
794- foreach ($ images as $ image ) {
795- if (!isset ($ image ['types ' ])) {
796- $ image ['types ' ] = [];
797- if (isset ($ image ['file ' ])) {
798- foreach (array_keys ($ product ->getMediaAttributes ()) as $ attribute ) {
799- if ($ image ['file ' ] == $ product ->getData ($ attribute )) {
800- $ image ['types ' ][] = $ attribute ;
801- }
802- }
803- }
804- }
805- $ imagesWithRoles [] = $ image ;
806- }
807- return $ imagesWithRoles ;
808- }
809-
810710 /**
811711 * Retrieve media gallery processor.
812712 *
813- * @return Product\Gallery\Processor
713+ * @return MediaGalleryProcessor
814714 */
815715 private function getMediaGalleryProcessor ()
816716 {
817- if (null === $ this ->mediaGalleryProcessor ) {
818- $ this ->mediaGalleryProcessor = \Magento \Framework \App \ObjectManager::getInstance ()
819- ->get (\ Magento \ Catalog \ Model \ Product \ Gallery \Processor ::class);
717+ if (null === $ this ->mediaProcessor ) {
718+ $ this ->mediaProcessor = \Magento \Framework \App \ObjectManager::getInstance ()
719+ ->get (MediaGalleryProcessor ::class);
820720 }
821- return $ this ->mediaGalleryProcessor ;
721+
722+ return $ this ->mediaProcessor ;
822723 }
823724
824725 /**
@@ -930,6 +831,7 @@ private function saveProduct($product): void
930831 throw new CouldNotSaveException (__ ($ e ->getMessage ()));
931832 } catch (LocalizedException $ e ) {
932833 throw $ e ;
834+ // phpcs:disable Magento2.Exceptions.ThrowCatch
933835 } catch (\Exception $ e ) {
934836 throw new CouldNotSaveException (
935837 __ ('The product was unable to be saved. Please try again. ' ),
0 commit comments