Skip to content

Commit 4f17e02

Browse files
committed
Merge remote-tracking branch 'l3/MC-40538' into L3-PR-20210310
2 parents 3a814d9 + 42a3588 commit 4f17e02

File tree

16 files changed

+1054
-520
lines changed

16 files changed

+1054
-520
lines changed

app/code/Magento/Store/App/Request/PathInfoProcessor.php

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,56 +7,48 @@
77

88
namespace Magento\Store\App\Request;
99

10+
use Magento\Framework\App\Request\PathInfoProcessorInterface;
11+
use Magento\Framework\App\RequestInterface;
12+
1013
/**
1114
* Processes the path and looks for the store in the url and removes it and modifies the path accordingly.
1215
*/
13-
class PathInfoProcessor implements \Magento\Framework\App\Request\PathInfoProcessorInterface
16+
class PathInfoProcessor implements PathInfoProcessorInterface
1417
{
1518
/**
1619
* @var StorePathInfoValidator
1720
*/
1821
private $storePathInfoValidator;
1922

2023
/**
21-
* @var \Magento\Framework\App\Config\ReinitableConfigInterface
22-
*/
23-
private $config;
24-
25-
/**
26-
* @param \Magento\Store\App\Request\StorePathInfoValidator $storePathInfoValidator
27-
* @param \Magento\Framework\App\Config\ReinitableConfigInterface $config
24+
* @param StorePathInfoValidator $storePathInfoValidator
2825
*/
29-
public function __construct(
30-
\Magento\Store\App\Request\StorePathInfoValidator $storePathInfoValidator,
31-
\Magento\Framework\App\Config\ReinitableConfigInterface $config
32-
) {
26+
public function __construct(StorePathInfoValidator $storePathInfoValidator)
27+
{
3328
$this->storePathInfoValidator = $storePathInfoValidator;
34-
$this->config = $config;
3529
}
3630

3731
/**
3832
* Process path info and remove store from pathInfo.
3933
*
4034
* This method also sets request to no route if store is not valid and store is present in url config is enabled
4135
*
42-
* @param \Magento\Framework\App\RequestInterface $request
36+
* @param RequestInterface $request
4337
* @param string $pathInfo
4438
* @return string
4539
*/
46-
public function process(\Magento\Framework\App\RequestInterface $request, $pathInfo) : string
40+
public function process(RequestInterface $request, $pathInfo) : string
4741
{
48-
//can store code be used in url
49-
if ((bool)$this->config->getValue(\Magento\Store\Model\Store::XML_PATH_STORE_IN_URL)) {
50-
$storeCode = $this->storePathInfoValidator->getValidStoreCode($request, $pathInfo);
51-
if (!empty($storeCode)) {
52-
if (!$request->isDirectAccessFrontendName($storeCode)) {
53-
$pathInfo = $this->trimStoreCodeFromPathInfo($pathInfo, $storeCode);
54-
} else {
55-
//no route in case we're trying to access a store that has the same code as a direct access
56-
$request->setActionName(\Magento\Framework\App\Router\Base::NO_ROUTE);
57-
}
42+
$storeCode = $this->storePathInfoValidator->getValidStoreCode($request, $pathInfo);
43+
if (!empty($storeCode)) {
44+
if (!$request->isDirectAccessFrontendName($storeCode)) {
45+
$pathInfo = $this->trimStoreCodeFromPathInfo($pathInfo, $storeCode);
46+
} else {
47+
//no route in case we're trying to access a store that has the same code as a direct access
48+
$request->setActionName(\Magento\Framework\App\Router\Base::NO_ROUTE);
5849
}
5950
}
51+
6052
return $pathInfo;
6153
}
6254

@@ -67,7 +59,7 @@ public function process(\Magento\Framework\App\RequestInterface $request, $pathI
6759
* @param string $storeCode
6860
* @return string
6961
*/
70-
private function trimStoreCodeFromPathInfo(string $pathInfo, string $storeCode) : ?string
62+
private function trimStoreCodeFromPathInfo(string $pathInfo, string $storeCode) : string
7163
{
7264
if (substr($pathInfo, 0, strlen('/' . $storeCode)) == '/'. $storeCode) {
7365
$pathInfo = substr($pathInfo, strlen($storeCode)+1);

app/code/Magento/Store/App/Request/StorePathInfoValidator.php

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,14 @@
77

88
namespace Magento\Store\App\Request;
99

10+
use Magento\Framework\App\Config\ScopeConfigInterface;
11+
use Magento\Framework\App\Request\Http;
12+
use Magento\Framework\App\Request\PathInfo;
1013
use Magento\Framework\Exception\NoSuchEntityException;
14+
use Magento\Store\Api\StoreRepositoryInterface;
1115
use Magento\Store\Model\Store;
16+
use Magento\Store\Model\StoreIsInactiveException;
17+
use Magento\Store\Model\Validation\StoreCodeValidator;
1218

1319
/**
1420
* Gets the store from the path if valid
@@ -18,74 +24,74 @@ class StorePathInfoValidator
1824
/**
1925
* Store Config
2026
*
21-
* @var \Magento\Framework\App\Config\ReinitableConfigInterface
27+
* @var ScopeConfigInterface
2228
*/
2329
private $config;
2430

2531
/**
26-
* @var \Magento\Store\Api\StoreRepositoryInterface
32+
* @var StoreRepositoryInterface
2733
*/
2834
private $storeRepository;
2935

3036
/**
31-
* @var \Magento\Framework\App\Request\PathInfo
37+
* @var PathInfo
3238
*/
3339
private $pathInfo;
3440

3541
/**
36-
* @param \Magento\Framework\App\Config\ReinitableConfigInterface $config
37-
* @param \Magento\Store\Api\StoreRepositoryInterface $storeRepository
38-
* @param \Magento\Framework\App\Request\PathInfo $pathInfo
42+
* @var StoreCodeValidator
43+
*/
44+
private $storeCodeValidator;
45+
46+
/**
47+
* @param ScopeConfigInterface $config
48+
* @param StoreRepositoryInterface $storeRepository
49+
* @param PathInfo $pathInfo
50+
* @param StoreCodeValidator $storeCodeValidator
3951
*/
4052
public function __construct(
41-
\Magento\Framework\App\Config\ReinitableConfigInterface $config,
42-
\Magento\Store\Api\StoreRepositoryInterface $storeRepository,
43-
\Magento\Framework\App\Request\PathInfo $pathInfo
53+
ScopeConfigInterface $config,
54+
StoreRepositoryInterface $storeRepository,
55+
PathInfo $pathInfo,
56+
StoreCodeValidator $storeCodeValidator
4457
) {
4558
$this->config = $config;
4659
$this->storeRepository = $storeRepository;
4760
$this->pathInfo = $pathInfo;
61+
$this->storeCodeValidator = $storeCodeValidator;
4862
}
4963

5064
/**
5165
* Get store code from path info validate if config value. If path info is empty the try to calculate from request.
5266
*
53-
* @param \Magento\Framework\App\Request\Http $request
67+
* @param Http $request
5468
* @param string $pathInfo
5569
* @return string|null
5670
*/
57-
public function getValidStoreCode(
58-
\Magento\Framework\App\Request\Http $request,
59-
string $pathInfo = ''
60-
) : ?string {
71+
public function getValidStoreCode(Http $request, string $pathInfo = '') : ?string
72+
{
73+
$useStoreCodeInUrl = (bool) $this->config->getValue(Store::XML_PATH_STORE_IN_URL);
74+
if (!$useStoreCodeInUrl) {
75+
return null;
76+
}
77+
6178
if (empty($pathInfo)) {
62-
$pathInfo = $this->pathInfo->getPathInfo(
63-
$request->getRequestUri(),
64-
$request->getBaseUrl()
65-
);
79+
$pathInfo = $this->pathInfo->getPathInfo($request->getRequestUri(), $request->getBaseUrl());
6680
}
6781
$storeCode = $this->getStoreCode($pathInfo);
68-
if (!empty($storeCode)
69-
&& $storeCode != Store::ADMIN_CODE
70-
&& (bool)$this->config->getValue(\Magento\Store\Model\Store::XML_PATH_STORE_IN_URL)
71-
) {
72-
try {
73-
$this->storeRepository->getActiveStoreByCode($storeCode);
82+
if (empty($storeCode) || $storeCode === Store::ADMIN_CODE || !$this->storeCodeValidator->isValid($storeCode)) {
83+
return null;
84+
}
85+
86+
try {
87+
$this->storeRepository->getActiveStoreByCode($storeCode);
7488

75-
if ((bool)$this->config->getValue(
76-
\Magento\Store\Model\Store::XML_PATH_STORE_IN_URL,
77-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE,
78-
$storeCode
79-
)) {
80-
return $storeCode;
81-
}
82-
} catch (NoSuchEntityException $e) {
83-
//return null;
84-
} catch (\Magento\Store\Model\StoreIsInactiveException $e) {
85-
//return null;
86-
}
89+
return $storeCode;
90+
} catch (NoSuchEntityException $e) {
91+
return null;
92+
} catch (StoreIsInactiveException $e) {
93+
return null;
8794
}
88-
return null;
8995
}
9096

9197
/**

app/code/Magento/Store/Model/Store.php

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,11 @@ class Store extends AbstractExtensibleModel implements
332332
*/
333333
private $pillPut;
334334

335+
/**
336+
* @var \Magento\Store\Model\Validation\StoreValidator
337+
*/
338+
private $modelValidator;
339+
335340
/**
336341
* @param \Magento\Framework\Model\Context $context
337342
* @param \Magento\Framework\Registry $registry
@@ -359,6 +364,7 @@ class Store extends AbstractExtensibleModel implements
359364
* @param array $data optional generic object data
360365
* @param \Magento\Framework\Event\ManagerInterface|null $eventManager
361366
* @param \Magento\Framework\MessageQueue\PoisonPill\PoisonPillPutInterface|null $pillPut
367+
* @param \Magento\Store\Model\Validation\StoreValidator|null $modelValidator
362368
*
363369
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
364370
*/
@@ -388,7 +394,8 @@ public function __construct(
388394
$isCustomEntryPoint = false,
389395
array $data = [],
390396
\Magento\Framework\Event\ManagerInterface $eventManager = null,
391-
\Magento\Framework\MessageQueue\PoisonPill\PoisonPillPutInterface $pillPut = null
397+
\Magento\Framework\MessageQueue\PoisonPill\PoisonPillPutInterface $pillPut = null,
398+
\Magento\Store\Model\Validation\StoreValidator $modelValidator = null
392399
) {
393400
$this->_coreFileStorageDatabase = $coreFileStorageDatabase;
394401
$this->_config = $config;
@@ -411,6 +418,9 @@ public function __construct(
411418
->get(\Magento\Framework\Event\ManagerInterface::class);
412419
$this->pillPut = $pillPut ?: \Magento\Framework\App\ObjectManager::getInstance()
413420
->get(\Magento\Framework\MessageQueue\PoisonPill\PoisonPillPutInterface::class);
421+
$this->modelValidator = $modelValidator ?: \Magento\Framework\App\ObjectManager::getInstance()
422+
->get(\Magento\Store\Model\Validation\StoreValidator::class);
423+
414424
parent::__construct(
415425
$context,
416426
$registry,
@@ -479,23 +489,7 @@ protected function _getSession()
479489
*/
480490
protected function _getValidationRulesBeforeSave()
481491
{
482-
$validator = new \Magento\Framework\Validator\DataObject();
483-
484-
$storeLabelRule = new \Zend_Validate_NotEmpty();
485-
$storeLabelRule->setMessage(__('Name is required'), \Zend_Validate_NotEmpty::IS_EMPTY);
486-
$validator->addRule($storeLabelRule, 'name');
487-
488-
$storeCodeRule = new \Zend_Validate_Regex('/^[a-z]+[a-z0-9_]*$/i');
489-
$storeCodeRule->setMessage(
490-
__(
491-
'The store code may contain only letters (a-z), numbers (0-9) or underscore (_),'
492-
. ' and the first character must be a letter.'
493-
),
494-
\Zend_Validate_Regex::NOT_MATCH
495-
);
496-
$validator->addRule($storeCodeRule, 'code');
497-
498-
return $validator;
492+
return $this->modelValidator;
499493
}
500494

501495
/**
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Store\Model\Validation;
9+
10+
use Magento\Framework\Validator\AbstractValidator;
11+
use Magento\Framework\Validator\RegexFactory;
12+
13+
/**
14+
* Validator for store code.
15+
*/
16+
class StoreCodeValidator extends AbstractValidator
17+
{
18+
/**
19+
* @var RegexFactory
20+
*/
21+
private $regexValidatorFactory;
22+
23+
/**
24+
* @param RegexFactory $regexValidatorFactory
25+
*/
26+
public function __construct(RegexFactory $regexValidatorFactory)
27+
{
28+
$this->regexValidatorFactory = $regexValidatorFactory;
29+
}
30+
31+
/**
32+
* @inheritDoc
33+
*/
34+
public function isValid($value)
35+
{
36+
$validator = $this->regexValidatorFactory->create(['pattern' => '/^[a-z]+[a-z0-9_]*$/i']);
37+
$validator->setMessage(
38+
__(
39+
'The store code may contain only letters (a-z), numbers (0-9) or underscore (_),'
40+
. ' and the first character must be a letter.'
41+
),
42+
\Zend_Validate_Regex::NOT_MATCH
43+
);
44+
$result = $validator->isValid($value);
45+
$this->_messages = $validator->getMessages();
46+
47+
return $result;
48+
}
49+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Store\Model\Validation;
9+
10+
use Magento\Framework\Validator\AbstractValidator;
11+
use Magento\Framework\Validator\NotEmptyFactory;
12+
13+
/**
14+
* Validator for store name.
15+
*/
16+
class StoreNameValidator extends AbstractValidator
17+
{
18+
/**
19+
* @var NotEmptyFactory
20+
*/
21+
private $notEmptyValidatorFactory;
22+
23+
/**
24+
* @param NotEmptyFactory $notEmptyValidatorFactory
25+
*/
26+
public function __construct(NotEmptyFactory $notEmptyValidatorFactory)
27+
{
28+
$this->notEmptyValidatorFactory = $notEmptyValidatorFactory;
29+
}
30+
31+
/**
32+
* @inheritDoc
33+
*/
34+
public function isValid($value)
35+
{
36+
$validator = $this->notEmptyValidatorFactory->create(['options' => []]);
37+
$validator->setMessage(
38+
__('Name is required'),
39+
\Zend_Validate_NotEmpty::IS_EMPTY
40+
);
41+
$result = $validator->isValid($value);
42+
$this->_messages = $validator->getMessages();
43+
44+
return $result;
45+
}
46+
}

0 commit comments

Comments
 (0)