diff --git a/app/code/Magento/Catalog/Plugin/Api/ProductLinkRepositoryInterface/ReindexAfterDeleteByIdProductLinksPlugin.php b/app/code/Magento/Catalog/Plugin/Api/ProductLinkRepositoryInterface/ReindexAfterDeleteByIdProductLinksPlugin.php new file mode 100644 index 0000000000000..91e8629ec212a --- /dev/null +++ b/app/code/Magento/Catalog/Plugin/Api/ProductLinkRepositoryInterface/ReindexAfterDeleteByIdProductLinksPlugin.php @@ -0,0 +1,57 @@ +fullProductIndexer = $fullProductIndexer; + $this->productRepository = $productRepository; + } + + /** + * Complex reindex after product links has been deleted. + * + * @param ProductLinkRepositoryInterface $subject + * @param bool $result + * @param string $sku + * @param string $type + * @param string $linkedProductSku + * @return bool + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterDeleteById(ProductLinkRepositoryInterface $subject, bool $result, $sku): bool + { + $product = $this->productRepository->get($sku); + $this->fullProductIndexer->executeRow($product->getId()); + + return $result; + } +} diff --git a/app/code/Magento/Catalog/Plugin/Api/ProductLinkRepositoryInterface/ReindexAfterSaveProductLinksPlugin.php b/app/code/Magento/Catalog/Plugin/Api/ProductLinkRepositoryInterface/ReindexAfterSaveProductLinksPlugin.php new file mode 100644 index 0000000000000..480399035a7a3 --- /dev/null +++ b/app/code/Magento/Catalog/Plugin/Api/ProductLinkRepositoryInterface/ReindexAfterSaveProductLinksPlugin.php @@ -0,0 +1,56 @@ +fullProductIndexer = $fullProductIndexer; + $this->productRepository = $productRepository; + } + + /** + * Complex reindex after product links has been saved. + * + * @param ProductLinkRepositoryInterface $subject + * @param bool $result + * @param ProductLinkInterface $entity + * @return bool + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterSave(ProductLinkRepositoryInterface $subject, bool $result, ProductLinkInterface $entity): bool + { + $product = $this->productRepository->get($entity->getSku()); + $this->fullProductIndexer->executeRow($product->getId()); + + return $result; + } +} diff --git a/app/code/Magento/Catalog/etc/webapi_rest/di.xml b/app/code/Magento/Catalog/etc/webapi_rest/di.xml index 1fd47fde304ec..a33c3a19e1e4f 100644 --- a/app/code/Magento/Catalog/etc/webapi_rest/di.xml +++ b/app/code/Magento/Catalog/etc/webapi_rest/di.xml @@ -40,4 +40,8 @@ Magento\Catalog\Model\Product\Webapi\Rest\RequestTypeBasedDeserializer + + + + diff --git a/app/code/Magento/Catalog/etc/webapi_soap/di.xml b/app/code/Magento/Catalog/etc/webapi_soap/di.xml index a709f23d8c12b..03671ba0bb2e0 100644 --- a/app/code/Magento/Catalog/etc/webapi_soap/di.xml +++ b/app/code/Magento/Catalog/etc/webapi_soap/di.xml @@ -40,4 +40,8 @@ Magento\Framework\Webapi\Rest\Request\Deserializer\Xml + + + + diff --git a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js index 4040ff9d684f4..d460c93714b3d 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js @@ -47,10 +47,14 @@ define([ * Initialize object */ initialize: function () { - var self = this; + var self = this, + popupDialog = jQuery('#product_composite_configure'); this._initWindowElements(); jQuery.async('#product_composite_configure', function (el) { + if (el !== popupDialog[0]) { + el = popupDialog[0]; + } self.dialog = jQuery(el).modal({ title: jQuery.mage.__('Configure Product'), type: 'slide', diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage/link.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage/link.phtml index b667764ac7bba..c2f99c03c8f4c 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/onepage/link.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/onepage/link.phtml @@ -4,21 +4,27 @@ * See COPYING.txt for license details. */ -/** @var $block \Magento\Checkout\Block\Onepage\Link */ +use Magento\Checkout\Block\Onepage\Link; +use Magento\Framework\Escaper; + +/** + * @var Link $block + * @var Escaper $escaper + */ ?> -isPossibleOnepageCheckout()) :?> +isPossibleOnepageCheckout()): ?> diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js b/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js index aba0c31b998d1..fe525bddc02f3 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js @@ -22,7 +22,7 @@ define([ quoteItems(newValue.items); }); - if (quoteSubtotal !== subtotalAmount) { + if (!isNaN(subtotalAmount) && quoteSubtotal !== subtotalAmount) { customerData.reload(['cart'], false); } diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerWishlistConfigureItemActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerWishlistConfigureItemActionGroup.xml new file mode 100644 index 0000000000000..de126e6cc6585 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerWishlistConfigureItemActionGroup.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml index 39a67968c66e4..0a44149cb067b 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml @@ -14,5 +14,8 @@ + + + diff --git a/app/code/Magento/Downloadable/Model/Link/DeleteHandler.php b/app/code/Magento/Downloadable/Model/Link/DeleteHandler.php index 399550e5f33c0..c2a3b20ff9e36 100644 --- a/app/code/Magento/Downloadable/Model/Link/DeleteHandler.php +++ b/app/code/Magento/Downloadable/Model/Link/DeleteHandler.php @@ -9,7 +9,7 @@ use Magento\Framework\EntityManager\Operation\ExtensionInterface; /** - * Class DeleteHandler + * Delete Handler for Downloadable Product Links. */ class DeleteHandler implements ExtensionInterface { @@ -27,6 +27,8 @@ public function __construct(LinkRepository $linkRepository) } /** + * Delete Downloadable Links for the provided Product. + * * @param object $entity * @param array $arguments * @return \Magento\Catalog\Api\Data\ProductInterface|object @@ -41,6 +43,8 @@ public function execute($entity, $arguments = []) foreach ($this->linkRepository->getList($entity->getSku()) as $link) { $this->linkRepository->delete($link->getId()); } + $entity->setDownloadableLinks(null); + return $entity; } } diff --git a/app/code/Magento/Downloadable/Model/Link/ReadHandler.php b/app/code/Magento/Downloadable/Model/Link/ReadHandler.php index a11b38ee3afd8..d3a2349739c26 100644 --- a/app/code/Magento/Downloadable/Model/Link/ReadHandler.php +++ b/app/code/Magento/Downloadable/Model/Link/ReadHandler.php @@ -9,7 +9,7 @@ use Magento\Framework\EntityManager\Operation\ExtensionInterface; /** - * Class ReadHandler + * Read Handler for Downloadable Product Links. */ class ReadHandler implements ExtensionInterface { @@ -27,6 +27,8 @@ public function __construct(LinkRepository $linkRepository) } /** + * Read Downloadable Links for the provided Product. + * * @param object $entity * @param array $arguments * @return \Magento\Catalog\Api\Data\ProductInterface|object @@ -40,10 +42,9 @@ public function execute($entity, $arguments = []) } $entityExtension = $entity->getExtensionAttributes(); $links = $this->linkRepository->getLinksByProduct($entity); - if ($links) { - $entityExtension->setDownloadableProductLinks($links); - } + $entityExtension->setDownloadableProductLinks($links); $entity->setExtensionAttributes($entityExtension); + return $entity; } } diff --git a/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AssertStorefrontLinkOnDownloadableProductPageActionGroup.xml b/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AssertStorefrontLinkOnDownloadableProductPageActionGroup.xml new file mode 100644 index 0000000000000..978fff04938f0 --- /dev/null +++ b/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AssertStorefrontLinkOnDownloadableProductPageActionGroup.xml @@ -0,0 +1,22 @@ + + + + + + + Validates that the provided Link Title is present on Downloadable Product details page. + + + + + + + + + diff --git a/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AssertStorefrontNoLinkOnDownloadableProductPageActionGroup.xml b/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AssertStorefrontNoLinkOnDownloadableProductPageActionGroup.xml new file mode 100644 index 0000000000000..8b71839669876 --- /dev/null +++ b/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AssertStorefrontNoLinkOnDownloadableProductPageActionGroup.xml @@ -0,0 +1,22 @@ + + + + + + + Validates that the provided Link Title is NOT present on Downloadable Product details page. + + + + + + + + + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Section/StorefrontDownloadableProductSection.xml b/app/code/Magento/Downloadable/Test/Mftf/Section/StorefrontDownloadableProductSection.xml index dc2a58be138e7..e3302c7337e09 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Section/StorefrontDownloadableProductSection.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Section/StorefrontDownloadableProductSection.xml @@ -16,5 +16,6 @@ + diff --git a/app/code/Magento/Paypal/view/frontend/templates/express/review.phtml b/app/code/Magento/Paypal/view/frontend/templates/express/review.phtml index 69c7c8179850a..afd1e91c6e588 100644 --- a/app/code/Magento/Paypal/view/frontend/templates/express/review.phtml +++ b/app/code/Magento/Paypal/view/frontend/templates/express/review.phtml @@ -4,9 +4,14 @@ * See COPYING.txt for license details. */ +use Magento\Framework\Escaper; +use Magento\Framework\View\Helper\SecureHtmlRenderer; +use Magento\Paypal\Block\Express\Review; + /** - * @var \Magento\Paypal\Block\Express\Review $block - * @var \Magento\Framework\View\Helper\SecureHtmlRenderer $secureRenderer + * @var Review $block + * @var Escaper $escaper + * @var SecureHtmlRenderer $secureRenderer */ ?>
@@ -15,11 +20,11 @@ getShippingAddress()): ?>
- escapeHtml(__('Shipping Method')) ?> + escapeHtml(__('Shipping Method')) ?>
canEditShippingMethod()): ?> getShippingRateGroups()): ?> @@ -28,11 +33,14 @@