Skip to content

Commit 1224795

Browse files
authored
Merge pull request #2371 from magento-tango/MAGETWO-86554
MAGETWO-86554: Customer is redirected to 404 from Catalog page if switches to the Store with another root Category
2 parents 4518560 + 2ab6c99 commit 1224795

File tree

5 files changed

+301
-0
lines changed

5 files changed

+301
-0
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\CatalogUrlRewrite\Plugin\Store\Block;
7+
8+
use Magento\Framework\Data\Helper\PostHelper;
9+
use Magento\Store\Api\StoreResolverInterface;
10+
use Magento\Store\Model\Store;
11+
use Magento\UrlRewrite\Model\UrlFinderInterface;
12+
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
13+
use Magento\Framework\App\Request\Http as HttpRequest;
14+
15+
/**
16+
* Plugin makes connection between Store and UrlRewrite modules
17+
* because Magento\Store\Block\Switcher should not know about UrlRewrite module functionality
18+
*/
19+
class Switcher
20+
{
21+
/**
22+
* @var PostHelper
23+
*/
24+
private $postHelper;
25+
26+
/**
27+
* @var UrlFinderInterface
28+
*/
29+
private $urlFinder;
30+
31+
/**
32+
* @var HttpRequest
33+
*/
34+
private $request;
35+
36+
/**
37+
* @param PostHelper $postHelper
38+
* @param UrlFinderInterface $urlFinder
39+
* @param HttpRequest $request
40+
*/
41+
public function __construct(
42+
PostHelper $postHelper,
43+
UrlFinderInterface $urlFinder,
44+
HttpRequest $request
45+
) {
46+
$this->postHelper = $postHelper;
47+
$this->urlFinder = $urlFinder;
48+
$this->request = $request;
49+
}
50+
51+
/**
52+
* @param \Magento\Store\Block\Switcher $subject
53+
* @param string $result
54+
* @param Store $store
55+
* @param array $data
56+
* @return string
57+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
58+
*/
59+
public function afterGetTargetStorePostData(
60+
\Magento\Store\Block\Switcher $subject,
61+
string $result,
62+
Store $store,
63+
array $data = []
64+
): string {
65+
$data[StoreResolverInterface::PARAM_NAME] = $store->getCode();
66+
67+
$currentUrl = $store->getCurrentUrl(true);
68+
$baseUrl = $store->getBaseUrl();
69+
$urlPath = parse_url($currentUrl, PHP_URL_PATH);
70+
71+
$urlToSwitch = $currentUrl;
72+
73+
//check only catalog pages
74+
if ($this->request->getFrontName() === 'catalog') {
75+
$currentRewrite = $this->urlFinder->findOneByData([
76+
UrlRewrite::REQUEST_PATH => ltrim($urlPath, '/'),
77+
UrlRewrite::STORE_ID => $store->getId(),
78+
]);
79+
if (null === $currentRewrite) {
80+
$urlToSwitch = $baseUrl;
81+
}
82+
}
83+
84+
return $this->postHelper->getPostData($urlToSwitch, $data);
85+
}
86+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
9+
<type name="\Magento\Store\Block\Switcher">
10+
<plugin name="store_switcher_plugin" type="Magento\CatalogUrlRewrite\Plugin\Store\Block\Switcher"/>
11+
</type>
12+
</config>
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\CatalogUrlRewrite\Plugin\Store\Block;
7+
8+
/**
9+
* Integration tests for Magento\CatalogUrlRewrite\Plugin\Store\Block\Switcher block.
10+
*/
11+
class SwitcherTest extends \PHPUnit\Framework\TestCase
12+
{
13+
/**
14+
* @var \Magento\TestFramework\ObjectManager
15+
*/
16+
private $objectManager;
17+
18+
/**
19+
* @var \Magento\Store\Block\Switcher
20+
*/
21+
private $model;
22+
23+
/**
24+
* @var \Magento\Store\Api\StoreRepositoryInterface
25+
*/
26+
private $storeRepository;
27+
28+
/**
29+
* Set up.
30+
*
31+
* @return void
32+
*/
33+
protected function setUp()
34+
{
35+
$this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
36+
$this->model = $this->objectManager->create(\Magento\Store\Block\Switcher::class);
37+
$this->storeRepository = $this->objectManager->create(\Magento\Store\Api\StoreRepositoryInterface::class);
38+
}
39+
40+
/**
41+
* Test that after switching from Store 1 to Store 2 with another root Category user gets correct store url.
42+
*
43+
* @magentoDataFixture Magento/Store/_files/store.php
44+
* @magentoDataFixture Magento/CatalogUrlRewrite/_files/two_categories_per_two_store_groups.php
45+
* @magentoAppArea frontend
46+
* @return void
47+
* @throws \Magento\Framework\Exception\NoSuchEntityException
48+
*/
49+
public function testGetTargetStorePostData()
50+
{
51+
$storeCode = 'test';
52+
$store = $this->storeRepository->get($storeCode);
53+
$result = json_decode($this->model->getTargetStorePostData($store), true);
54+
55+
$this->assertContains($storeCode, $result['action']);
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
8+
9+
/** @var \Magento\Catalog\Model\Category $category */
10+
$category = $objectManager->create(\Magento\Catalog\Model\Category::class);
11+
$category->isObjectNew(true);
12+
$category->setId(333)
13+
->setCreatedAt('2014-06-23 09:50:07')
14+
->setName('Category 1')
15+
->setParentId(2)
16+
->setPath('1/2/3')
17+
->setLevel(2)
18+
->setAvailableSortBy('name')
19+
->setDefaultSortBy('name')
20+
->setIsActive(true)
21+
->setPosition(1)
22+
->setAvailableSortBy(['position'])
23+
->save();
24+
25+
/** @var $product \Magento\Catalog\Model\Product */
26+
$product = $objectManager->create(\Magento\Catalog\Model\Product::class);
27+
$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
28+
->setId(333)
29+
->setAttributeSetId(4)
30+
->setStoreId(1)
31+
->setWebsiteIds([1])
32+
->setName('Simple Product Three')
33+
->setSku('simple333')
34+
->setPrice(10)
35+
->setWeight(18)
36+
->setStockData(['use_config_manage_stock' => 0])
37+
->setCategoryIds([333])
38+
->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
39+
->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
40+
->save();
41+
42+
/** @var \Magento\Store\Model\Store $store */
43+
$store = $objectManager->create(\Magento\Store\Model\Store::class);
44+
45+
$category->setStoreId($store->load('default')->getId())
46+
->setName('category-default-store')
47+
->setUrlKey('category-default-store')
48+
->save();
49+
50+
$rootCategoryForTestStoreGroup = $objectManager->create(\Magento\Catalog\Model\Category::class);
51+
$rootCategoryForTestStoreGroup->isObjectNew(true);
52+
$rootCategoryForTestStoreGroup->setId(334)
53+
->setCreatedAt('2014-06-23 09:50:07')
54+
->setName('Category 2')
55+
->setParentId(1)
56+
->setPath('1/2/334')
57+
->setLevel(2)
58+
->setAvailableSortBy('name')
59+
->setDefaultSortBy('name')
60+
->setIsActive(true)
61+
->setPosition(1)
62+
->setAvailableSortBy(['position'])
63+
->save();
64+
65+
$rootCategoryForTestStoreGroup->setStoreId($store->load('test')->getId())
66+
->setName('category-test-store')
67+
->setUrlKey('category-test-store')
68+
->save();
69+
70+
$storeCode = 'test';
71+
/** @var \Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository */
72+
$categoryRepository = $objectManager->create(\Magento\Catalog\Api\CategoryRepositoryInterface::class);
73+
/** @var \Magento\Catalog\Api\Data\CategoryInterface $category */
74+
$category = $categoryRepository->get(334);
75+
/** @var \Magento\Store\Api\StoreRepositoryInterface $storeRepository */
76+
$storeRepository = $objectManager->create(\Magento\Store\Api\StoreRepositoryInterface::class);
77+
/** @var \Magento\Store\Api\Data\StoreInterface $store */
78+
$store = $storeRepository->get($storeCode);
79+
80+
/** @var \Magento\Store\Model\Group $storeGroup */
81+
$storeGroup = $objectManager->create(\Magento\Store\Model\Group::class);
82+
$storeGroup->setWebsiteId('1');
83+
$storeGroup->setCode('test_store_group');
84+
$storeGroup->setName('Test Store Group');
85+
$storeGroup->setRootCategoryId($category->getId());
86+
$storeGroup->setDefaultStoreId($store->getId());
87+
$storeGroup->save();
88+
89+
$store->setGroupId($storeGroup->getId())->save();
90+
91+
/* Refresh stores memory cache */
92+
$objectManager->get(\Magento\Store\Model\StoreManagerInterface::class)->reinitStores();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
use Magento\Framework\Registry;
8+
use Magento\Store\Model\Group;
9+
use Magento\TestFramework\Helper\Bootstrap;
10+
use Magento\Catalog\Api\CategoryListInterface;
11+
use Magento\Catalog\Api\CategoryRepositoryInterface;
12+
use Magento\Framework\Api\SearchCriteriaBuilder;
13+
14+
$objectManager = Bootstrap::getObjectManager();
15+
16+
/** @var Registry $registry */
17+
$registry = $objectManager->get(Registry::class);
18+
$registry->unregister('isSecureArea');
19+
$registry->register('isSecureArea', true);
20+
// Delete product
21+
$productRepository = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
22+
try {
23+
$product = $productRepository->get('simple333', false, null, true);
24+
$product->delete();
25+
} catch (\Magento\Framework\Exception\NoSuchEntityException $exception) {
26+
//Product already removed
27+
}
28+
// Delete first category
29+
/** @var SearchCriteriaBuilder $searchCriteriaBuilder */
30+
$searchCriteriaBuilder = $objectManager->get(SearchCriteriaBuilder::class);
31+
$searchCriteria = $searchCriteriaBuilder->addFilter('name', 'Category 1')->create();
32+
/** @var CategoryListInterface $categoryList */
33+
$categoryList = $objectManager->get(CategoryListInterface::class);
34+
$categories = $categoryList->getList($searchCriteria)->getItems();
35+
/** @var CategoryRepositoryInterface $categoryRepository */
36+
$categoryRepository = $objectManager->get(CategoryRepositoryInterface::class);
37+
foreach ($categories as $category) {
38+
$categoryRepository->delete($category);
39+
}
40+
// Delete second category
41+
$searchCriteria = $searchCriteriaBuilder->addFilter('name', 'Category 2')->create();
42+
$categories = $categoryList->getList($searchCriteria)->getItems();
43+
foreach ($categories as $category) {
44+
$categoryRepository->delete($category);
45+
}
46+
// Delete store group
47+
/** @var Group $store */
48+
$storeGroup = $objectManager->get(Group::class);
49+
$storeGroup->load('test_store_group', 'code');
50+
if ($storeGroup->getId()) {
51+
$storeGroup->delete();
52+
}
53+
$registry->unregister('isSecureArea');
54+
$registry->register('isSecureArea', false);

0 commit comments

Comments
 (0)