diff --git a/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/MassRemove.php b/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/MassRemove.php
index 6c0dfd1db7d16..94c7d955f592b 100644
--- a/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/MassRemove.php
+++ b/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/MassRemove.php
@@ -39,6 +39,6 @@ public function execute()
$this->messageManager->addException($e, __("We couldn't remove the messages because of an error."));
}
}
- $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
+ $this->_redirect('adminhtml/*/');
}
}
diff --git a/app/code/Magento/GoogleAnalytics/Block/Ga.php b/app/code/Magento/GoogleAnalytics/Block/Ga.php
index 0afd6c51e967f..63c16bab4220d 100644
--- a/app/code/Magento/GoogleAnalytics/Block/Ga.php
+++ b/app/code/Magento/GoogleAnalytics/Block/Ga.php
@@ -130,8 +130,8 @@ public function getOrdersTrackingCode()
'price': '%s',
'quantity': %s
});",
- $this->escapeJs($item->getSku()),
- $this->escapeJs($item->getName()),
+ $this->escapeJsQuote($item->getSku()),
+ $this->escapeJsQuote($item->getName()),
$item->getPrice(),
$item->getQtyOrdered()
);
@@ -146,7 +146,7 @@ public function getOrdersTrackingCode()
'shipping': '%s'
});",
$order->getIncrementId(),
- $this->escapeJs($this->_storeManager->getStore()->getFrontendName()),
+ $this->escapeJsQuote($this->_storeManager->getStore()->getFrontendName()),
$order->getGrandTotal(),
$order->getTaxAmount(),
$order->getShippingAmount()
@@ -236,15 +236,15 @@ public function getOrdersTrackingData()
foreach ($collection as $order) {
foreach ($order->getAllVisibleItems() as $item) {
$result['products'][] = [
- 'id' => $this->escapeJs($item->getSku()),
- 'name' => $this->escapeJs($item->getName()),
+ 'id' => $this->escapeJsQuote($item->getSku()),
+ 'name' => $this->escapeJsQuote($item->getName()),
'price' => $item->getPrice(),
'quantity' => $item->getQtyOrdered(),
];
}
$result['orders'][] = [
'id' => $order->getIncrementId(),
- 'affiliation' => $this->escapeJs($this->_storeManager->getStore()->getFrontendName()),
+ 'affiliation' => $this->escapeJsQuote($this->_storeManager->getStore()->getFrontendName()),
'revenue' => $order->getGrandTotal(),
'tax' => $order->getTaxAmount(),
'shipping' => $order->getShippingAmount(),
diff --git a/app/code/Magento/Theme/view/frontend/templates/html/header.phtml b/app/code/Magento/Theme/view/frontend/templates/html/header.phtml
index 58548a0ba268a..4395cab651de1 100644
--- a/app/code/Magento/Theme/view/frontend/templates/html/header.phtml
+++ b/app/code/Magento/Theme/view/frontend/templates/html/header.phtml
@@ -19,7 +19,7 @@ $welcomeMessage = $block->getWelcome();
-
+
= $block->getBlockHtml('header.additional') ?>
diff --git a/app/code/Magento/User/Observer/Backend/ForceAdminPasswordChangeObserver.php b/app/code/Magento/User/Observer/Backend/ForceAdminPasswordChangeObserver.php
index 7d96c1c3b0d62..bfa9b064b8fb0 100644
--- a/app/code/Magento/User/Observer/Backend/ForceAdminPasswordChangeObserver.php
+++ b/app/code/Magento/User/Observer/Backend/ForceAdminPasswordChangeObserver.php
@@ -108,6 +108,7 @@ public function execute(EventObserver $observer)
'adminhtml_system_account_index',
'adminhtml_system_account_save',
'adminhtml_auth_logout',
+ 'mui_index_render'
];
/** @var \Magento\Framework\App\Action\Action $controller */
$controller = $observer->getEvent()->getControllerAction();
diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserverTest.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserverTest.php
new file mode 100644
index 0000000000000..34f873df71abb
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserverTest.php
@@ -0,0 +1,230 @@
+objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+ }
+
+ /**
+ * @param array $filter
+ * @return array
+ */
+ private function getActualResults(array $filter)
+ {
+ /** @var \Magento\UrlRewrite\Model\UrlFinderInterface $urlFinder */
+ $urlFinder = $this->objectManager->get(\Magento\UrlRewrite\Model\UrlFinderInterface::class);
+ $actualResults = [];
+ foreach ($urlFinder->findAllByData($filter) as $url) {
+ $actualResults[] = [
+ 'request_path' => $url->getRequestPath(),
+ 'target_path' => $url->getTargetPath(),
+ 'is_auto_generated' => (int)$url->getIsAutogenerated(),
+ 'redirect_type' => $url->getRedirectType(),
+ 'store_id' => $url->getStoreId()
+ ];
+ }
+ return $actualResults;
+ }
+
+ /**
+ * @magentoDataFixture Magento/CatalogUrlRewrite/_files/product_rewrite_multistore.php
+ * @magentoAppIsolation enabled
+ */
+ public function testUrlKeyHasChangedInGlobalContext()
+ {
+ /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository*/
+ $productRepository = $this->objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
+ /** @var \Magento\Catalog\Model\Product $product*/
+ $product = $productRepository->get('product1');
+
+ /** @var StoreManagerInterface $storeManager */
+ $storeManager = $this->objectManager->get(StoreManagerInterface::class);
+ $storeManager->setCurrentStore(0);
+
+ $testStore = $storeManager->getStore('test');
+ $productFilter = [
+ UrlRewrite::ENTITY_TYPE => 'product',
+ ];
+
+ $expected = [
+ [
+ 'request_path' => "product-1.html",
+ 'target_path' => "catalog/product/view/id/" . $product->getId(),
+ 'is_auto_generated' => 1,
+ 'redirect_type' => 0,
+ 'store_id' => 1,
+ ],
+ [
+ 'request_path' => "product-1.html",
+ 'target_path' => "catalog/product/view/id/" . $product->getId(),
+ 'is_auto_generated' => 1,
+ 'redirect_type' => 0,
+ 'store_id' => $testStore->getId(),
+ ],
+ ];
+ $actual = $this->getActualResults($productFilter);
+ foreach ($expected as $row) {
+ $this->assertContains($row, $actual);
+ }
+
+ $product->setData('save_rewrites_history', true);
+ $product->setUrlKey('new-url');
+ $product->save();
+
+ $expected = [
+ [
+ 'request_path' => "new-url.html",
+ 'target_path' => "catalog/product/view/id/" . $product->getId(),
+ 'is_auto_generated' => 1,
+ 'redirect_type' => 0,
+ 'store_id' => 1,
+ ],
+ [
+ 'request_path' => "new-url.html",
+ 'target_path' => "catalog/product/view/id/" . $product->getId(),
+ 'is_auto_generated' => 1,
+ 'redirect_type' => 0,
+ 'store_id' => $testStore->getId(),
+ ],
+ [
+ 'request_path' => "product-1.html",
+ 'target_path' => "new-url.html",
+ 'is_auto_generated' => 0,
+ 'redirect_type' => 301,
+ 'store_id' => 1,
+ ],
+ [
+ 'request_path' => "product-1.html",
+ 'target_path' => "new-url.html",
+ 'is_auto_generated' => 0,
+ 'redirect_type' => 301,
+ 'store_id' => $testStore->getId(),
+ ],
+ ];
+
+ $actual = $this->getActualResults($productFilter);
+ foreach ($expected as $row) {
+ $this->assertContains($row, $actual);
+ }
+ }
+
+ /**
+ * @magentoDataFixture Magento/CatalogUrlRewrite/_files/product_rewrite_multistore.php
+ * @magentoAppIsolation enabled
+ */
+ public function testUrlKeyHasChangedInStoreviewContextWithPermanentRedirection()
+ {
+ /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository*/
+ $productRepository = $this->objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
+ /** @var \Magento\Catalog\Model\Product $product*/
+ $product = $productRepository->get('product1');
+
+ /** @var StoreManagerInterface $storeManager */
+ $storeManager = $this->objectManager->get(StoreManagerInterface::class);
+ $storeManager->setCurrentStore(1);
+
+ $testStore = $storeManager->getStore('test');
+
+ $productFilter = [
+ UrlRewrite::ENTITY_TYPE => 'product',
+ ];
+
+ $product->setData('save_rewrites_history', true);
+ $product->setUrlKey('new-url');
+ $product->save();
+
+ $expected = [
+ [
+ 'request_path' => "new-url.html",
+ 'target_path' => "catalog/product/view/id/" . $product->getId(),
+ 'is_auto_generated' => 1,
+ 'redirect_type' => 0,
+ 'store_id' => 1,
+ ],
+ [
+ 'request_path' => "product-1.html",
+ 'target_path' => "catalog/product/view/id/" . $product->getId(),
+ 'is_auto_generated' => 1,
+ 'redirect_type' => 0,
+ 'store_id' => $testStore->getId(),
+ ],
+ [
+ 'request_path' => "product-1.html",
+ 'target_path' => "new-url.html",
+ 'is_auto_generated' => 0,
+ 'redirect_type' => 301,
+ 'store_id' => 1,
+ ],
+ ];
+
+ $actual = $this->getActualResults($productFilter);
+ foreach ($expected as $row) {
+ $this->assertContains($row, $actual);
+ }
+ }
+
+ /**
+ * @magentoDataFixture Magento/CatalogUrlRewrite/_files/product_rewrite_multistore.php
+ * @magentoAppIsolation enabled
+ */
+ public function testUrlKeyHasChangedInStoreviewContextWithoutPermanentRedirection()
+ {
+ /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository*/
+ $productRepository = $this->objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
+ /** @var \Magento\Catalog\Model\Product $product*/
+ $product = $productRepository->get('product1');
+
+ /** @var StoreManagerInterface $storeManager */
+ $storeManager = $this->objectManager->get(StoreManagerInterface::class);
+ $storeManager->setCurrentStore(1);
+
+ $testStore = $storeManager->getStore('test');
+
+ $productFilter = [
+ UrlRewrite::ENTITY_TYPE => 'product',
+ ];
+
+ $product->setData('save_rewrites_history', false);
+ $product->setUrlKey('new-url');
+ $product->save();
+
+ $expected = [
+ [
+ 'request_path' => "new-url.html",
+ 'target_path' => "catalog/product/view/id/" . $product->getId(),
+ 'is_auto_generated' => 1,
+ 'redirect_type' => 0,
+ 'store_id' => 1,
+ ],
+ [
+ 'request_path' => "product-1.html",
+ 'target_path' => "catalog/product/view/id/" . $product->getId(),
+ 'is_auto_generated' => 1,
+ 'redirect_type' => 0,
+ 'store_id' => $testStore->getId(),
+ ],
+ ];
+
+ $actual = $this->getActualResults($productFilter);
+ foreach ($expected as $row) {
+ $this->assertContains($row, $actual);
+ }
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_rewrite_multistore.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_rewrite_multistore.php
new file mode 100644
index 0000000000000..dfdf03b2f1bac
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_rewrite_multistore.php
@@ -0,0 +1,39 @@
+loadArea(\Magento\Backend\App\Area\FrontNameResolver::AREA_CODE);
+
+require __DIR__ . '/../../Store/_files/store.php';
+
+/** @var $installer CategorySetup */
+$objectManager = Bootstrap::getObjectManager();
+$installer = $objectManager->create(CategorySetup::class);
+$storeManager = $objectManager->get(StoreManagerInterface::class);
+$storeManager->setCurrentStore(0);
+
+/** @var $product \Magento\Catalog\Model\Product */
+$product = $objectManager->create(\Magento\Catalog\Model\Product::class);
+$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
+ ->setAttributeSetId($installer->getAttributeSetId('catalog_product', 'Default'))
+ ->setStoreId(0)
+ ->setWebsiteIds([1])
+ ->setName('Product1')
+ ->setSku('product1')
+ ->setPrice(10)
+ ->setWeight(18)
+ ->setStockData(['use_config_manage_stock' => 0])
+ ->setUrlKey('product-1')
+ ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
+ ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
+
+/** @var ProductRepositoryInterface $productRepository */
+$productRepository = $objectManager->get(ProductRepositoryInterface::class);
+$productRepository->save($product);
diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_rewrite_multistore_rollback.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_rewrite_multistore_rollback.php
new file mode 100644
index 0000000000000..13941bfb93651
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_rewrite_multistore_rollback.php
@@ -0,0 +1,12 @@
+
+
+
@@ -14,6 +16,8 @@
+
+