diff --git a/vendor/magento/module-downloadable-staging/Model/Plugin/Link/UpdateHandlerPlugin.php b/vendor/magento/module-downloadable-staging/Model/Plugin/Link/UpdateHandlerPlugin.php new file mode 100644 index 00000000000..f00dbd664fc --- /dev/null +++ b/vendor/magento/module-downloadable-staging/Model/Plugin/Link/UpdateHandlerPlugin.php @@ -0,0 +1,150 @@ +linkFactory = $linkFactory; + $this->linkResource = $linkResource; + $this->downloadableType = $downloadableType; + $this->metadataPool = $metadataPool; + $this->versionManager = $versionManager; + } + + /** + * Update intersected rollbacks with new Downloadable Links data. + * + * @param UpdateHandler $subject + * @param ProductInterface $entity + * @param array $arguments + * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function beforeExecute( + UpdateHandler $subject, + ProductInterface $entity, + array $arguments = [] + ): array { + $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); + $extensionAttributes = $entity->getExtensionAttributes(); + $links = $extensionAttributes->getDownloadableProductLinks() ?? []; + + if ($links + && isset($arguments[$linkField], $arguments['created_in']) + && $arguments['created_in'] === $this->versionManager->getCurrentVersion()->getId() + && $entity->getTypeId() === Type::TYPE_DOWNLOADABLE + ) { + $intersectedRollbacks = $this->getLinksIds($entity); + $linksToUpdate = array_filter($links, function ($link) { + return (bool) $link->getId(); + }); + + if (count($intersectedRollbacks) >= count($linksToUpdate)) { + foreach ($linksToUpdate as $link) { + $this->updateLinkVersion( + $link, + (int) $arguments[$linkField], + array_shift($intersectedRollbacks) + ); + } + } + + $extensionAttributes->setDownloadableProductLinks($links); + } + + return [$entity, $arguments]; + } + + /** + * Retrieve Downloadable Links ids from the provided entity. + * + * @param ProductInterface $entity + * @return int[] + */ + private function getLinksIds(ProductInterface $entity): array + { + $linksIds = []; + $entity->unsDownloadableLinks(); + $links = $this->downloadableType->getLinks($entity); + + foreach ($links as $link) { + $linksIds[] = (int) $link->getId(); + } + + return $linksIds; + } + + /** + * Update Downloadable Link ID with the provided one. + * + * @param LinkInterface $link + * @param int $productId + * @param int $replacementId + */ + private function updateLinkVersion(LinkInterface $link, int $productId, int $replacementId): void + { + $existingLink = $this->linkFactory->create(); + $this->linkResource->load($existingLink, $link->getId()); + $linkProductId = (int) $existingLink->getProductId(); + + if ($linkProductId && $linkProductId !== $productId) { + $link->setId($replacementId); + } + } +} diff --git a/vendor/magento/module-downloadable-staging/Model/Plugin/Sample/UpdateHandlerPlugin.php b/vendor/magento/module-downloadable-staging/Model/Plugin/Sample/UpdateHandlerPlugin.php new file mode 100644 index 00000000000..af5c0a594a3 --- /dev/null +++ b/vendor/magento/module-downloadable-staging/Model/Plugin/Sample/UpdateHandlerPlugin.php @@ -0,0 +1,151 @@ +sampleFactory = $sampleFactory; + $this->sampleResource = $sampleResource; + $this->downloadableType = $downloadableType; + $this->metadataPool = $metadataPool; + $this->versionManager = $versionManager; + } + + /** + * Update intersected rollbacks with new Downloadable Samples data. + * + * @param UpdateHandler $subject + * @param ProductInterface $entity + * @param array $arguments + * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function beforeExecute( + UpdateHandler $subject, + ProductInterface $entity, + array $arguments = [] + ): array { + $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); + $extensionAttributes = $entity->getExtensionAttributes(); + $samples = $extensionAttributes->getDownloadableProductSamples() ?? []; + + if ($samples + && isset($arguments[$linkField], $arguments['created_in']) + && $arguments['created_in'] === $this->versionManager->getCurrentVersion()->getId() + && $entity->getTypeId() === Type::TYPE_DOWNLOADABLE + ) { + $intersectedRollbacks = $this->getSamplesIds($entity); + $samplesToUpdate = array_filter($samples, function ($sample) { + return (bool) $sample->getId(); + }); + + if (count($intersectedRollbacks) >= count($samplesToUpdate)) { + foreach ($samplesToUpdate as $sample) { + $this->updateSampleVersion( + $sample, + (int) $arguments[$linkField], + array_shift($intersectedRollbacks) + ); + } + } + + $extensionAttributes->setDownloadableProductSamples($samples); + } + + return [$entity, $arguments]; + } + + /** + * Retrieve Downloadable Samples ids from the provided entity. + * + * @param ProductInterface $entity + * @return int[] + */ + private function getSamplesIds(ProductInterface $entity): array + { + $samplesIds = []; + $entity->unsDownloadableSamples(); + $samples = $this->downloadableType->getSamples($entity); + + foreach ($samples as $sample) { + $samplesIds[] = (int) $sample->getId(); + } + + return $samplesIds; + } + + /** + * Update Downloadable Sample ID with the provided one. + * + * @param SampleInterface $sample + * @param int $productId + * @param int $replacementId + * @return void + */ + private function updateSampleVersion(SampleInterface $sample, int $productId, int $replacementId): void + { + $existingSample = $this->sampleFactory->create(); + $this->sampleResource->load($existingSample, $sample->getId()); + $sampleProductId = (int) $existingSample->getProductId(); + + if ($sampleProductId && $sampleProductId !== $productId) { + $sample->setId($replacementId); + } + } +} diff --git a/vendor/magento/module-downloadable-staging/etc/di.xml b/vendor/magento/module-downloadable-staging/etc/di.xml new file mode 100644 index 00000000000..ea4b82a7deb --- /dev/null +++ b/vendor/magento/module-downloadable-staging/etc/di.xml @@ -0,0 +1,15 @@ + + + + + + + + + +