Skip to content

Commit fce92ae

Browse files
committed
MAGETWO-93276: [2.3] Downloadable product links removal on update via API
1 parent 05f9df7 commit fce92ae

File tree

3 files changed

+469
-395
lines changed

3 files changed

+469
-395
lines changed

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

Lines changed: 74 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44
* Copyright © Magento, Inc. All rights reserved.
55
* See COPYING.txt for license details.
66
*/
7+
declare(strict_types=1);
78

89
namespace Magento\Catalog\Model;
910

11+
use Magento\Catalog\Api\Data\ProductExtension;
1012
use Magento\Catalog\Api\Data\ProductInterface;
1113
use Magento\Catalog\Model\Product\Gallery\MimeTypeExtensionMap;
1214
use Magento\Catalog\Model\ResourceModel\Product\Collection;
15+
use Magento\Eav\Model\Entity\Attribute\Exception as AttributeException;
1316
use Magento\Framework\Api\Data\ImageContentInterface;
1417
use Magento\Framework\Api\Data\ImageContentInterfaceFactory;
1518
use Magento\Framework\Api\ImageContentValidatorInterface;
@@ -22,6 +25,7 @@
2225
use Magento\Framework\Exception\InputException;
2326
use Magento\Framework\Exception\LocalizedException;
2427
use Magento\Framework\Exception\NoSuchEntityException;
28+
use Magento\Framework\Exception\TemporaryState\CouldNotSaveException as TemporaryCouldNotSaveException;
2529
use Magento\Framework\Exception\StateException;
2630
use Magento\Framework\Exception\ValidatorException;
2731

@@ -306,10 +310,10 @@ protected function getCacheKey($data)
306310
* Add product to internal cache and truncate cache if it has more than cacheLimit elements.
307311
*
308312
* @param string $cacheKey
309-
* @param \Magento\Catalog\Api\Data\ProductInterface $product
313+
* @param ProductInterface $product
310314
* @return void
311315
*/
312-
private function cacheProduct($cacheKey, \Magento\Catalog\Api\Data\ProductInterface $product)
316+
private function cacheProduct($cacheKey, ProductInterface $product)
313317
{
314318
$this->instancesById[$product->getId()][$cacheKey] = $product;
315319
$this->saveProductInLocalCache($product, $cacheKey);
@@ -326,7 +330,7 @@ private function cacheProduct($cacheKey, \Magento\Catalog\Api\Data\ProductInterf
326330
*
327331
* @param array $productData
328332
* @param bool $createNew
329-
* @return \Magento\Catalog\Api\Data\ProductInterface|Product
333+
* @return ProductInterface|Product
330334
* @throws NoSuchEntityException
331335
*/
332336
protected function initializeProductData(array $productData, $createNew)
@@ -414,12 +418,12 @@ protected function processNewMediaGalleryEntry(
414418
/**
415419
* Process product links, creating new links, updating and deleting existing links
416420
*
417-
* @param \Magento\Catalog\Api\Data\ProductInterface $product
421+
* @param ProductInterface $product
418422
* @param \Magento\Catalog\Api\Data\ProductLinkInterface[] $newLinks
419423
* @return $this
420424
* @throws NoSuchEntityException
421425
*/
422-
private function processLinks(\Magento\Catalog\Api\Data\ProductInterface $product, $newLinks)
426+
private function processLinks(ProductInterface $product, $newLinks)
423427
{
424428
if ($newLinks === null) {
425429
// If product links were not specified, don't do anything
@@ -547,11 +551,11 @@ protected function processMediaGallery(ProductInterface $product, $mediaGalleryE
547551
}
548552

549553
/**
550-
* {@inheritdoc}
554+
* @inheritdoc
551555
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
552556
* @SuppressWarnings(PHPMD.NPathComplexity)
553557
*/
554-
public function save(\Magento\Catalog\Api\Data\ProductInterface $product, $saveOptions = false)
558+
public function save(ProductInterface $product, $saveOptions = false)
555559
{
556560
$tierPrices = $product->getData('tier_price');
557561

@@ -565,12 +569,18 @@ public function save(\Magento\Catalog\Api\Data\ProductInterface $product, $saveO
565569
if (!$product->hasData(Product::STATUS)) {
566570
$product->setStatus($existingProduct->getStatus());
567571
}
572+
573+
/** @var ProductExtension $extensionAttributes */
574+
$extensionAttributes = $product->getExtensionAttributes();
575+
if (empty($extensionAttributes->__toArray())) {
576+
$product->setExtensionAttributes($existingProduct->getExtensionAttributes());
577+
}
568578
} catch (NoSuchEntityException $e) {
569579
$existingProduct = null;
570580
}
571581

572582
$productDataArray = $this->extensibleDataObjectConverter
573-
->toNestedArray($product, [], \Magento\Catalog\Api\Data\ProductInterface::class);
583+
->toNestedArray($product, [], ProductInterface::class);
574584
$productDataArray = array_replace($productDataArray, $product->getData());
575585
$ignoreLinksFlag = $product->getData('ignore_links_flag');
576586
$productLinks = null;
@@ -596,47 +606,11 @@ public function save(\Magento\Catalog\Api\Data\ProductInterface $product, $saveO
596606
);
597607
}
598608

599-
try {
600-
if ($tierPrices !== null) {
601-
$product->setData('tier_price', $tierPrices);
602-
}
603-
$this->removeProductFromLocalCache($product->getSku());
604-
unset($this->instancesById[$product->getId()]);
605-
$this->resourceModel->save($product);
606-
} catch (ConnectionException $exception) {
607-
throw new \Magento\Framework\Exception\TemporaryState\CouldNotSaveException(
608-
__('Database connection error'),
609-
$exception,
610-
$exception->getCode()
611-
);
612-
} catch (DeadlockException $exception) {
613-
throw new \Magento\Framework\Exception\TemporaryState\CouldNotSaveException(
614-
__('Database deadlock found when trying to get lock'),
615-
$exception,
616-
$exception->getCode()
617-
);
618-
} catch (LockWaitException $exception) {
619-
throw new \Magento\Framework\Exception\TemporaryState\CouldNotSaveException(
620-
__('Database lock wait timeout exceeded'),
621-
$exception,
622-
$exception->getCode()
623-
);
624-
} catch (\Magento\Eav\Model\Entity\Attribute\Exception $exception) {
625-
throw \Magento\Framework\Exception\InputException::invalidFieldValue(
626-
$exception->getAttributeCode(),
627-
$product->getData($exception->getAttributeCode()),
628-
$exception
629-
);
630-
} catch (ValidatorException $e) {
631-
throw new CouldNotSaveException(__($e->getMessage()));
632-
} catch (LocalizedException $e) {
633-
throw $e;
634-
} catch (\Exception $e) {
635-
throw new \Magento\Framework\Exception\CouldNotSaveException(
636-
__('The product was unable to be saved. Please try again.'),
637-
$e
638-
);
609+
if ($tierPrices !== null) {
610+
$product->setData('tier_price', $tierPrices);
639611
}
612+
613+
$this->saveProduct($product);
640614
$this->removeProductFromLocalCache($product->getSku());
641615
unset($this->instancesById[$product->getId()]);
642616

@@ -646,7 +620,7 @@ public function save(\Magento\Catalog\Api\Data\ProductInterface $product, $saveO
646620
/**
647621
* {@inheritdoc}
648622
*/
649-
public function delete(\Magento\Catalog\Api\Data\ProductInterface $product)
623+
public function delete(ProductInterface $product)
650624
{
651625
$sku = $product->getSku();
652626
$productId = $product->getId();
@@ -835,4 +809,55 @@ private function prepareSku(string $sku): string
835809
{
836810
return mb_strtolower(trim($sku));
837811
}
812+
813+
/**
814+
* Save product resource model.
815+
*
816+
* @param ProductInterface|Product $product
817+
* @throws TemporaryCouldNotSaveException
818+
* @throws InputException
819+
* @throws CouldNotSaveException
820+
* @throws LocalizedException
821+
*/
822+
private function saveProduct($product): void
823+
{
824+
try {
825+
$this->removeProductFromLocalCache($product->getSku());
826+
unset($this->instancesById[$product->getId()]);
827+
$this->resourceModel->save($product);
828+
} catch (ConnectionException $exception) {
829+
throw new TemporaryCouldNotSaveException(
830+
__('Database connection error'),
831+
$exception,
832+
$exception->getCode()
833+
);
834+
} catch (DeadlockException $exception) {
835+
throw new TemporaryCouldNotSaveException(
836+
__('Database deadlock found when trying to get lock'),
837+
$exception,
838+
$exception->getCode()
839+
);
840+
} catch (LockWaitException $exception) {
841+
throw new TemporaryCouldNotSaveException(
842+
__('Database lock wait timeout exceeded'),
843+
$exception,
844+
$exception->getCode()
845+
);
846+
} catch (AttributeException $exception) {
847+
throw InputException::invalidFieldValue(
848+
$exception->getAttributeCode(),
849+
$product->getData($exception->getAttributeCode()),
850+
$exception
851+
);
852+
} catch (ValidatorException $e) {
853+
throw new CouldNotSaveException(__($e->getMessage()));
854+
} catch (LocalizedException $e) {
855+
throw $e;
856+
} catch (\Exception $e) {
857+
throw new CouldNotSaveException(
858+
__('The product was unable to be saved. Please try again.'),
859+
$e
860+
);
861+
}
862+
}
838863
}

0 commit comments

Comments
 (0)