Skip to content

Commit b14d70e

Browse files
Merge pull request #911 from magento-falcons/MAGETWO-65701
Bugs - MAGETWO-65308 CLI command config:set fails on configurations which requires session - MAGETWO-62560 Catalog Module UpgradeData to 2.1.3 breaks when cost attribute is deleted #7804 - for 2.2.0 Task - MAGETWO-65208 Store checksum for every section of configuration file & change behavior on read-only FS & add sorting of importers
2 parents aa93ea8 + 85a3ef6 commit b14d70e

File tree

30 files changed

+886
-444
lines changed

30 files changed

+886
-444
lines changed

app/code/Magento/Catalog/Setup/UpgradeData.php

+8-7
Original file line numberDiff line numberDiff line change
@@ -401,13 +401,14 @@ private function changePriceAttributeDefaultScope($categorySetup)
401401
$entityTypeId = $categorySetup->getEntityTypeId(\Magento\Catalog\Model\Product::ENTITY);
402402
foreach (['price', 'cost', 'special_price'] as $attributeCode) {
403403
$attribute = $categorySetup->getAttribute($entityTypeId, $attributeCode);
404-
$categorySetup->updateAttribute(
405-
$entityTypeId,
406-
$attribute['attribute_id'],
407-
'is_global',
408-
\Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL
409-
);
410-
404+
if (isset($attribute['attribute_id'])) {
405+
$categorySetup->updateAttribute(
406+
$entityTypeId,
407+
$attribute['attribute_id'],
408+
'is_global',
409+
\Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL
410+
);
411+
}
411412
}
412413
}
413414
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
/**
3+
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Config\Console\Command\ConfigSet;
7+
8+
use Magento\Config\Console\Command\ConfigSetCommand;
9+
use Magento\Framework\App\Scope\ValidatorInterface;
10+
use Magento\Config\Model\Config\PathValidator;
11+
use Magento\Framework\Exception\ConfigurationMismatchException;
12+
use Magento\Framework\Exception\CouldNotSaveException;
13+
use Magento\Framework\Exception\LocalizedException;
14+
use Magento\Framework\Exception\ValidatorException;
15+
16+
/**
17+
* Processor facade for config:set command.
18+
*
19+
* @see ConfigSetCommand
20+
*/
21+
class ProcessorFacade
22+
{
23+
/**
24+
* The scope validator.
25+
*
26+
* @var ValidatorInterface
27+
*/
28+
private $scopeValidator;
29+
30+
/**
31+
* The path validator.
32+
*
33+
* @var PathValidator
34+
*/
35+
private $pathValidator;
36+
37+
/**
38+
* The factory for config:set processors.
39+
*
40+
* @var ConfigSetProcessorFactory
41+
*/
42+
private $configSetProcessorFactory;
43+
44+
/**
45+
* @param ValidatorInterface $scopeValidator The scope validator
46+
* @param PathValidator $pathValidator The path validator
47+
* @param ConfigSetProcessorFactory $configSetProcessorFactory The factory for config:set processors
48+
*/
49+
public function __construct(
50+
ValidatorInterface $scopeValidator,
51+
PathValidator $pathValidator,
52+
ConfigSetProcessorFactory $configSetProcessorFactory
53+
) {
54+
$this->scopeValidator = $scopeValidator;
55+
$this->pathValidator = $pathValidator;
56+
$this->configSetProcessorFactory = $configSetProcessorFactory;
57+
}
58+
59+
/**
60+
* Processes config:set command.
61+
*
62+
* @param string $path The configuration path in format group/section/field_name
63+
* @param string $value The configuration value
64+
* @param string $scope The configuration scope (default, website, or store)
65+
* @param string $scopeCode The scope code
66+
* @param boolean $lock The lock flag
67+
* @return string Processor response message
68+
* @throws LocalizedException If scope validation failed
69+
* @throws ValidatorException If path validation failed
70+
* @throws CouldNotSaveException If processing failed
71+
* @throws ConfigurationMismatchException If processor can not be instantiated
72+
*/
73+
public function process($path, $value, $scope, $scopeCode, $lock)
74+
{
75+
$this->scopeValidator->isValid($scope, $scopeCode);
76+
$this->pathValidator->validate($path);
77+
78+
$processor = $lock
79+
? $this->configSetProcessorFactory->create(ConfigSetProcessorFactory::TYPE_LOCK)
80+
: $this->configSetProcessorFactory->create(ConfigSetProcessorFactory::TYPE_DEFAULT);
81+
$message = $lock
82+
? 'Value was saved and locked.'
83+
: 'Value was saved.';
84+
85+
// The processing flow depends on --lock option.
86+
$processor->process($path, $value, $scope, $scopeCode);
87+
88+
return $message;
89+
}
90+
}

app/code/Magento/Config/Console/Command/ConfigSetCommand.php

+31-60
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,17 @@
55
*/
66
namespace Magento\Config\Console\Command;
77

8-
use Magento\Config\Console\Command\ConfigSet\ConfigSetProcessorFactory;
9-
use Magento\Config\Model\Config\PathValidatorFactory;
108
use Magento\Framework\App\Area;
11-
use Magento\Framework\App\Config\ScopeConfigInterface;
12-
use Magento\Framework\App\Scope\ValidatorInterface;
9+
use Magento\Framework\App\State;
1310
use Magento\Framework\Config\ScopeInterface;
11+
use Magento\Framework\App\Config\ScopeConfigInterface;
1412
use Magento\Framework\Console\Cli;
1513
use Symfony\Component\Console\Command\Command;
1614
use Symfony\Component\Console\Input\InputArgument;
1715
use Symfony\Component\Console\Input\InputInterface;
1816
use Symfony\Component\Console\Input\InputOption;
1917
use Symfony\Component\Console\Output\OutputInterface;
18+
use Magento\Config\Console\Command\ConfigSet\ProcessorFacadeFactory;
2019

2120
/**
2221
* Command provides possibility to change system configuration.
@@ -34,49 +33,39 @@ class ConfigSetCommand extends Command
3433
/**#@-*/
3534

3635
/**
37-
* The factory for config:set processors.
36+
* Scope manager.
3837
*
39-
* @var ConfigSetProcessorFactory
38+
* @var ScopeInterface
4039
*/
41-
private $configSetProcessorFactory;
40+
private $scope;
4241

4342
/**
44-
* Scope validator.
43+
* Application state.
4544
*
46-
* @var ValidatorInterface
45+
* @var State
4746
*/
48-
private $validator;
47+
private $state;
4948

5049
/**
51-
* Scope manager.
50+
* The processor facade factory
5251
*
53-
* @var ScopeInterface
52+
* @var ProcessorFacadeFactory
5453
*/
55-
private $scope;
54+
private $processorFacadeFactory;
5655

5756
/**
58-
* The factory for path validator.
59-
*
60-
* @var PathValidatorFactory
61-
*/
62-
private $pathValidatorFactory;
63-
64-
/**
65-
* @param ConfigSetProcessorFactory $configSetProcessorFactory The factory for config:set processors
66-
* @param ValidatorInterface $validator Scope validator
6757
* @param ScopeInterface $scope Scope manager
68-
* @param PathValidatorFactory $pathValidatorFactory The factory for path validator
58+
* @param State $state Application state
59+
* @param ProcessorFacadeFactory $processorFacadeFactory The processor facade factory
6960
*/
7061
public function __construct(
71-
ConfigSetProcessorFactory $configSetProcessorFactory,
72-
ValidatorInterface $validator,
7362
ScopeInterface $scope,
74-
PathValidatorFactory $pathValidatorFactory
63+
State $state,
64+
ProcessorFacadeFactory $processorFacadeFactory
7565
) {
76-
$this->configSetProcessorFactory = $configSetProcessorFactory;
77-
$this->validator = $validator;
7866
$this->scope = $scope;
79-
$this->pathValidatorFactory = $pathValidatorFactory;
67+
$this->state = $state;
68+
$this->processorFacadeFactory = $processorFacadeFactory;
8069

8170
parent::__construct();
8271
}
@@ -127,38 +116,20 @@ protected function configure()
127116
protected function execute(InputInterface $input, OutputInterface $output)
128117
{
129118
try {
130-
$this->validator->isValid(
131-
$input->getOption(static::OPTION_SCOPE),
132-
$input->getOption(static::OPTION_SCOPE_CODE)
133-
);
134-
135119
// Emulating adminhtml scope to be able to read configs.
136-
$this->scope->setCurrentScope(Area::AREA_ADMINHTML);
137-
138-
/**
139-
* Validates the entered config path.
140-
* Requires emulated area.
141-
*/
142-
$this->pathValidatorFactory->create()->validate(
143-
$input->getArgument(ConfigSetCommand::ARG_PATH)
144-
);
145-
146-
$processor = $input->getOption(static::OPTION_LOCK)
147-
? $this->configSetProcessorFactory->create(ConfigSetProcessorFactory::TYPE_LOCK)
148-
: $this->configSetProcessorFactory->create(ConfigSetProcessorFactory::TYPE_DEFAULT);
149-
$message = $input->getOption(static::OPTION_LOCK)
150-
? 'Value was saved and locked.'
151-
: 'Value was saved.';
152-
153-
// The processing flow depends on --lock option.
154-
$processor->process(
155-
$input->getArgument(ConfigSetCommand::ARG_PATH),
156-
$input->getArgument(ConfigSetCommand::ARG_VALUE),
157-
$input->getOption(ConfigSetCommand::OPTION_SCOPE),
158-
$input->getOption(ConfigSetCommand::OPTION_SCOPE_CODE)
159-
);
160-
161-
$output->writeln('<info>' . $message . '</info>');
120+
$this->state->emulateAreaCode(Area::AREA_ADMINHTML, function () use ($input, $output) {
121+
$this->scope->setCurrentScope(Area::AREA_ADMINHTML);
122+
123+
$message = $this->processorFacadeFactory->create()->process(
124+
$input->getArgument(static::ARG_PATH),
125+
$input->getArgument(static::ARG_VALUE),
126+
$input->getOption(static::OPTION_SCOPE),
127+
$input->getOption(static::OPTION_SCOPE_CODE),
128+
$input->getOption(static::OPTION_LOCK)
129+
);
130+
131+
$output->writeln('<info>' . $message . '</info>');
132+
});
162133

163134
return Cli::RETURN_SUCCESS;
164135
} catch (\Exception $exception) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
/**
3+
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Config\Test\Unit\Console\Command\ConfigSet;
7+
8+
use Magento\Config\Console\Command\ConfigSet\ConfigSetProcessorFactory;
9+
use Magento\Config\Console\Command\ConfigSet\ConfigSetProcessorInterface;
10+
use Magento\Config\Console\Command\ConfigSet\ProcessorFacade;
11+
use Magento\Framework\App\Config\ScopeConfigInterface;
12+
use Magento\Framework\App\Scope\ValidatorInterface;
13+
use Magento\Config\Model\Config\PathValidator;
14+
use PHPUnit_Framework_MockObject_MockObject as Mock;
15+
16+
/**
17+
* Test for ProcessorFacade.
18+
*
19+
* @see ProcessorFacade
20+
*/
21+
class ProcessorFacadeTest extends \PHPUnit_Framework_TestCase
22+
{
23+
/**
24+
* @var ProcessorFacade
25+
*/
26+
private $model;
27+
28+
/**
29+
* @var ValidatorInterface|Mock
30+
*/
31+
private $scopeValidatorMock;
32+
33+
/**
34+
* @var PathValidator|Mock
35+
*/
36+
private $pathValidatorMock;
37+
38+
/**
39+
* @var ConfigSetProcessorFactory|Mock
40+
*/
41+
private $configSetProcessorFactoryMock;
42+
43+
/**
44+
* @var ConfigSetProcessorInterface|Mock
45+
*/
46+
private $processorMock;
47+
48+
/**
49+
* @inheritdoc
50+
*/
51+
protected function setUp()
52+
{
53+
$this->scopeValidatorMock = $this->getMockBuilder(ValidatorInterface::class)
54+
->getMockForAbstractClass();
55+
$this->pathValidatorMock = $this->getMockBuilder(PathValidator::class)
56+
->disableOriginalConstructor()
57+
->getMock();
58+
$this->configSetProcessorFactoryMock = $this->getMockBuilder(ConfigSetProcessorFactory::class)
59+
->disableOriginalConstructor()
60+
->getMock();
61+
$this->processorMock = $this->getMockBuilder(ConfigSetProcessorInterface::class)
62+
->getMockForAbstractClass();
63+
64+
$this->configSetProcessorFactoryMock->expects($this->any())
65+
->method('create')
66+
->willReturn($this->processorMock);
67+
68+
$this->model = new ProcessorFacade(
69+
$this->scopeValidatorMock,
70+
$this->pathValidatorMock,
71+
$this->configSetProcessorFactoryMock
72+
);
73+
}
74+
75+
public function testProcess()
76+
{
77+
$this->scopeValidatorMock->expects($this->once())
78+
->method('isValid')
79+
->willReturn(true);
80+
$this->configSetProcessorFactoryMock->expects($this->once())
81+
->method('create')
82+
->with(ConfigSetProcessorFactory::TYPE_DEFAULT)
83+
->willReturn($this->processorMock);
84+
$this->processorMock->expects($this->once())
85+
->method('process')
86+
->with('test/test/test', 'test', ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null);
87+
88+
$this->assertSame(
89+
'Value was saved.',
90+
$this->model->process('test/test/test', 'test', ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null, false)
91+
);
92+
}
93+
94+
public function testExecuteLock()
95+
{
96+
$this->scopeValidatorMock->expects($this->once())
97+
->method('isValid')
98+
->willReturn(true);
99+
$this->configSetProcessorFactoryMock->expects($this->once())
100+
->method('create')
101+
->with(ConfigSetProcessorFactory::TYPE_LOCK)
102+
->willReturn($this->processorMock);
103+
$this->processorMock->expects($this->once())
104+
->method('process')
105+
->with('test/test/test', 'test', ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null);
106+
107+
$this->assertSame(
108+
'Value was saved and locked.',
109+
$this->model->process('test/test/test', 'test', ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null, true)
110+
);
111+
}
112+
}

0 commit comments

Comments
 (0)