From 9ca5d97d00b69a93f2b12c34ec3a47621ae644df Mon Sep 17 00:00:00 2001 From: Andreas von Studnitz Date: Fri, 23 Feb 2018 18:33:41 +0200 Subject: [PATCH] [Forwardport] Add option "lock-config" for shell command "config:set" --- .../ConfigSet/ConfigSetProcessorFactory.php | 7 + .../Command/ConfigSet/DefaultProcessor.php | 2 +- .../Command/ConfigSet/LockProcessor.php | 14 +- .../Command/ConfigSet/ProcessorFacade.php | 52 ++++- .../Console/Command/ConfigSetCommand.php | 34 ++- .../ConfigSetProcessorFactoryTest.php | 4 +- .../ConfigSet/DefaultProcessorTest.php | 4 +- .../ConfigSet/LockConfigProcessorTest.php | 220 ++++++++++++++++++ ...essorTest.php => LockEnvProcessorTest.php} | 5 +- .../Command/ConfigSet/ProcessorFacadeTest.php | 78 ++++++- .../Console/Command/ConfigSetCommandTest.php | 8 +- app/code/Magento/Config/etc/di.xml | 13 +- app/code/Magento/Deploy/Model/Mode.php | 2 +- .../Deploy/Test/Unit/Model/ModeTest.php | 2 +- .../Console/Command/ConfigSetCommandTest.php | 14 +- .../Model/Logger/Handler/DebugTest.php | 22 +- 16 files changed, 426 insertions(+), 55 deletions(-) create mode 100644 app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/LockConfigProcessorTest.php rename app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/{LockProcessorTest.php => LockEnvProcessorTest.php} (98%) diff --git a/app/code/Magento/Config/Console/Command/ConfigSet/ConfigSetProcessorFactory.php b/app/code/Magento/Config/Console/Command/ConfigSet/ConfigSetProcessorFactory.php index b884fc2d91f3b..1b287573a9285 100644 --- a/app/code/Magento/Config/Console/Command/ConfigSet/ConfigSetProcessorFactory.php +++ b/app/code/Magento/Config/Console/Command/ConfigSet/ConfigSetProcessorFactory.php @@ -28,7 +28,14 @@ class ConfigSetProcessorFactory * lock - save and lock configuration */ const TYPE_DEFAULT = 'default'; + + /** + * @deprecated + * @see TYPE_LOCK_ENV or TYPE_LOCK_CONFIG + */ const TYPE_LOCK = 'lock'; + const TYPE_LOCK_ENV = 'lock-env'; + const TYPE_LOCK_CONFIG = 'lock-config'; /**#@-*/ /**#@-*/ diff --git a/app/code/Magento/Config/Console/Command/ConfigSet/DefaultProcessor.php b/app/code/Magento/Config/Console/Command/ConfigSet/DefaultProcessor.php index 2f5c10037ef06..d7d513bfad423 100644 --- a/app/code/Magento/Config/Console/Command/ConfigSet/DefaultProcessor.php +++ b/app/code/Magento/Config/Console/Command/ConfigSet/DefaultProcessor.php @@ -72,7 +72,7 @@ public function process($path, $value, $scope, $scopeCode) throw new CouldNotSaveException( __( 'The value you set has already been locked. To change the value, use the --%1 option.', - ConfigSetCommand::OPTION_LOCK + ConfigSetCommand::OPTION_LOCK_ENV ) ); } diff --git a/app/code/Magento/Config/Console/Command/ConfigSet/LockProcessor.php b/app/code/Magento/Config/Console/Command/ConfigSet/LockProcessor.php index 0bd28f0f78d96..6fe2adde3c41e 100644 --- a/app/code/Magento/Config/Console/Command/ConfigSet/LockProcessor.php +++ b/app/code/Magento/Config/Console/Command/ConfigSet/LockProcessor.php @@ -16,7 +16,8 @@ /** * Processes file lock flow of config:set command. - * This processor saves the value of configuration and lock it for editing in Admin interface. + * This processor saves the value of configuration into app/etc/env.php + * and locks it for editing in Admin interface. * * {@inheritdoc} */ @@ -49,23 +50,30 @@ class LockProcessor implements ConfigSetProcessorInterface * @var ConfigPathResolver */ private $configPathResolver; + /** + * @var string + */ + private $target; /** * @param PreparedValueFactory $preparedValueFactory The factory for prepared value * @param DeploymentConfig\Writer $writer The deployment configuration writer * @param ArrayManager $arrayManager An array manager for different manipulations with arrays * @param ConfigPathResolver $configPathResolver The resolver for configuration paths according to source type + * @param string $target */ public function __construct( PreparedValueFactory $preparedValueFactory, DeploymentConfig\Writer $writer, ArrayManager $arrayManager, - ConfigPathResolver $configPathResolver + ConfigPathResolver $configPathResolver, + $target = ConfigFilePool::APP_ENV ) { $this->preparedValueFactory = $preparedValueFactory; $this->deploymentConfigWriter = $writer; $this->arrayManager = $arrayManager; $this->configPathResolver = $configPathResolver; + $this->target = $target; } /** @@ -97,7 +105,7 @@ public function process($path, $value, $scope, $scopeCode) * we'll write value just after all validations are triggered. */ $this->deploymentConfigWriter->saveConfig( - [ConfigFilePool::APP_ENV => $this->arrayManager->set($configPath, [], $value)], + [$this->target => $this->arrayManager->set($configPath, [], $value)], false ); } diff --git a/app/code/Magento/Config/Console/Command/ConfigSet/ProcessorFacade.php b/app/code/Magento/Config/Console/Command/ConfigSet/ProcessorFacade.php index 06a01c6686bfd..fcd7c0d5335b1 100644 --- a/app/code/Magento/Config/Console/Command/ConfigSet/ProcessorFacade.php +++ b/app/code/Magento/Config/Console/Command/ConfigSet/ProcessorFacade.php @@ -9,6 +9,7 @@ use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\Scope\ValidatorInterface; use Magento\Config\Model\Config\PathValidator; +use Magento\Framework\Config\File\ConfigFilePool; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\ConfigurationMismatchException; use Magento\Framework\Exception\CouldNotSaveException; @@ -98,12 +99,35 @@ public function __construct( * @param boolean $lock The lock flag * @return string Processor response message * @throws ValidatorException If some validation is wrong - * @throws CouldNotSaveException If cannot save config value - * @throws ConfigurationMismatchException If processor can not be instantiated * @since 100.2.0 + * @deprecated + * @see processWithLockTarget() */ public function process($path, $value, $scope, $scopeCode, $lock) { + return $this->processWithLockTarget($path, $value, $scope, $scopeCode, $lock); + } + + /** + * Processes config:set command with the option to set a target file. + * + * @param string $path The configuration path in format section/group/field_name + * @param string $value The configuration value + * @param string $scope The configuration scope (default, website, or store) + * @param string $scopeCode The scope code + * @param boolean $lock The lock flag + * @param string $lockTarget + * @return string Processor response message + * @throws ValidatorException If some validation is wrong + */ + public function processWithLockTarget( + $path, + $value, + $scope, + $scopeCode, + $lock, + $lockTarget = ConfigFilePool::APP_ENV + ) { try { $this->scopeValidator->isValid($scope, $scopeCode); $this->pathValidator->validate($path); @@ -111,14 +135,24 @@ public function process($path, $value, $scope, $scopeCode, $lock) throw new ValidatorException(__($exception->getMessage()), $exception); } - $processor = $lock - ? $this->configSetProcessorFactory->create(ConfigSetProcessorFactory::TYPE_LOCK) - : $this->configSetProcessorFactory->create(ConfigSetProcessorFactory::TYPE_DEFAULT); - $message = $lock - ? 'Value was saved and locked.' - : 'Value was saved.'; + $processor = + $lock + ? ( $lockTarget == ConfigFilePool::APP_ENV + ? $this->configSetProcessorFactory->create(ConfigSetProcessorFactory::TYPE_LOCK_ENV) + : $this->configSetProcessorFactory->create(ConfigSetProcessorFactory::TYPE_LOCK_CONFIG) + ) + : $this->configSetProcessorFactory->create(ConfigSetProcessorFactory::TYPE_DEFAULT) + ; + + $message = + $lock + ? ( $lockTarget == ConfigFilePool::APP_ENV + ? 'Value was saved in app/etc/env.php and locked.' + : 'Value was saved in app/etc/config.php and locked.' + ) + : 'Value was saved.'; - // The processing flow depends on --lock option. + // The processing flow depends on --lock and --share options. $processor->process($path, $value, $scope, $scopeCode); $this->hash->regenerate(System::CONFIG_TYPE); diff --git a/app/code/Magento/Config/Console/Command/ConfigSetCommand.php b/app/code/Magento/Config/Console/Command/ConfigSetCommand.php index 1df1b3c4bed14..cb79daddbf5f9 100644 --- a/app/code/Magento/Config/Console/Command/ConfigSetCommand.php +++ b/app/code/Magento/Config/Console/Command/ConfigSetCommand.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Config\Console\Command; use Magento\Config\App\Config\Type\System; @@ -10,6 +11,7 @@ use Magento\Deploy\Model\DeploymentConfig\ChangeDetector; use Magento\Framework\App\DeploymentConfig; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Config\File\ConfigFilePool; use Magento\Framework\Console\Cli; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; @@ -34,6 +36,8 @@ class ConfigSetCommand extends Command const OPTION_SCOPE = 'scope'; const OPTION_SCOPE_CODE = 'scope-code'; const OPTION_LOCK = 'lock'; + const OPTION_LOCK_ENV = 'lock-env'; + const OPTION_LOCK_CONFIG = 'lock-config'; /**#@-*/ /**#@-*/ @@ -108,11 +112,24 @@ protected function configure() InputArgument::OPTIONAL, 'Scope code (required only if scope is not \'default\')' ), + new InputOption( + static::OPTION_LOCK_ENV, + 'le', + InputOption::VALUE_NONE, + 'Lock value which prevents modification in the Admin (will be saved in app/etc/env.php)' + ), + new InputOption( + static::OPTION_LOCK_CONFIG, + 'lc', + InputOption::VALUE_NONE, + 'Lock and share value with other installations, prevents modification in the Admin ' + . '(will be saved in app/etc/config.php)' + ), new InputOption( static::OPTION_LOCK, 'l', InputOption::VALUE_NONE, - 'Lock value which prevents modification in the Admin' + 'Deprecated, use the --' . static::OPTION_LOCK_ENV . ' option instead.' ), ]); @@ -146,12 +163,23 @@ protected function execute(InputInterface $input, OutputInterface $output) try { $message = $this->emulatedAreaProcessor->process(function () use ($input) { - return $this->processorFacadeFactory->create()->process( + + $lock = $input->getOption(static::OPTION_LOCK_ENV) + || $input->getOption(static::OPTION_LOCK_CONFIG) + || $input->getOption(static::OPTION_LOCK); + + $lockTargetPath = ConfigFilePool::APP_ENV; + if ($input->getOption(static::OPTION_LOCK_CONFIG)) { + $lockTargetPath = ConfigFilePool::APP_CONFIG; + } + + return $this->processorFacadeFactory->create()->processWithLockTarget( $input->getArgument(static::ARG_PATH), $input->getArgument(static::ARG_VALUE), $input->getOption(static::OPTION_SCOPE), $input->getOption(static::OPTION_SCOPE_CODE), - $input->getOption(static::OPTION_LOCK) + $lock, + $lockTargetPath ); }); diff --git a/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/ConfigSetProcessorFactoryTest.php b/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/ConfigSetProcessorFactoryTest.php index decb7d52a5e0c..12b97eb254ded 100644 --- a/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/ConfigSetProcessorFactoryTest.php +++ b/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/ConfigSetProcessorFactoryTest.php @@ -41,7 +41,7 @@ protected function setUp() $this->model = new ConfigSetProcessorFactory( $this->objectManagerMock, [ - ConfigSetProcessorFactory::TYPE_LOCK => LockProcessor::class, + ConfigSetProcessorFactory::TYPE_LOCK_ENV => LockProcessor::class, ConfigSetProcessorFactory::TYPE_DEFAULT => DefaultProcessor::class, 'wrongType' => \stdClass::class, ] @@ -59,7 +59,7 @@ public function testCreate() $this->assertInstanceOf( ConfigSetProcessorInterface::class, - $this->model->create(ConfigSetProcessorFactory::TYPE_LOCK) + $this->model->create(ConfigSetProcessorFactory::TYPE_LOCK_ENV) ); } diff --git a/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/DefaultProcessorTest.php b/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/DefaultProcessorTest.php index 066b0fbe84b50..984e0fe842687 100644 --- a/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/DefaultProcessorTest.php +++ b/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/DefaultProcessorTest.php @@ -166,7 +166,9 @@ private function configMockForProcessTest($path, $scope, $scopeCode) /** * @expectedException \Magento\Framework\Exception\LocalizedException - * @expectedExceptionMessage The value you set has already been locked. To change the value, use the --lock option. + * @codingStandardsIgnoreStart + * @expectedExceptionMessage The value you set has already been locked. To change the value, use the --lock-env option. + * @codingStandardsIgnoreEnd */ public function testProcessLockedValue() { diff --git a/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/LockConfigProcessorTest.php b/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/LockConfigProcessorTest.php new file mode 100644 index 0000000000000..c727184efb4fc --- /dev/null +++ b/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/LockConfigProcessorTest.php @@ -0,0 +1,220 @@ +preparedValueFactory = $this->getMockBuilder(PreparedValueFactory::class) + ->disableOriginalConstructor() + ->getMock(); + $this->deploymentConfigWriterMock = $this->getMockBuilder(DeploymentConfig\Writer::class) + ->disableOriginalConstructor() + ->getMock(); + $this->arrayManagerMock = $this->getMockBuilder(ArrayManager::class) + ->disableOriginalConstructor() + ->getMock(); + $this->configPathResolver = $this->getMockBuilder(ConfigPathResolver::class) + ->disableOriginalConstructor() + ->getMock(); + $this->valueMock = $this->getMockBuilder(Value::class) + ->setMethods(['validateBeforeSave', 'beforeSave', 'setValue', 'getValue', 'afterSave']) + ->disableOriginalConstructor() + ->getMock(); + + $this->model = new LockProcessor( + $this->preparedValueFactory, + $this->deploymentConfigWriterMock, + $this->arrayManagerMock, + $this->configPathResolver, + ConfigFilePool::APP_CONFIG + ); + } + + /** + * Tests process of share flow. + * + * @param string $path + * @param string $value + * @param string $scope + * @param string|null $scopeCode + * @dataProvider processDataProvider + */ + public function testProcess($path, $value, $scope, $scopeCode) + { + $this->preparedValueFactory->expects($this->once()) + ->method('create') + ->with($path, $value, $scope, $scopeCode) + ->willReturn($this->valueMock); + $this->configPathResolver->expects($this->once()) + ->method('resolve') + ->willReturn('system/default/test/test/test'); + $this->arrayManagerMock->expects($this->once()) + ->method('set') + ->with('system/default/test/test/test', [], $value) + ->willReturn([ + 'system' => [ + 'default' => [ + 'test' => [ + 'test' => [ + 'test' => $value + ] + ] + ] + ] + ]); + $this->valueMock->expects($this->once()) + ->method('getValue') + ->willReturn($value); + $this->deploymentConfigWriterMock->expects($this->once()) + ->method('saveConfig') + ->with( + [ + ConfigFilePool::APP_CONFIG => [ + 'system' => [ + 'default' => [ + 'test' => [ + 'test' => [ + 'test' => $value + ] + ] + ] + ] + ] + ], + false + ); + $this->valueMock->expects($this->once()) + ->method('validateBeforeSave'); + $this->valueMock->expects($this->once()) + ->method('beforeSave'); + $this->valueMock->expects($this->once()) + ->method('afterSave'); + + $this->model->process($path, $value, $scope, $scopeCode); + } + + /** + * @return array + */ + public function processDataProvider() + { + return [ + ['test/test/test', 'value', ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null], + ['test/test/test', 'value', ScopeInterface::SCOPE_WEBSITE, 'base'], + ['test/test/test', 'value', ScopeInterface::SCOPE_STORE, 'test'], + ]; + } + + /** + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage Filesystem is not writable. + */ + public function testProcessNotReadableFs() + { + $path = 'test/test/test'; + $value = 'value'; + + $this->preparedValueFactory->expects($this->once()) + ->method('create') + ->willReturn($this->valueMock); + $this->valueMock->expects($this->once()) + ->method('getValue') + ->willReturn($value); + $this->configPathResolver->expects($this->once()) + ->method('resolve') + ->willReturn('system/default/test/test/test'); + $this->arrayManagerMock->expects($this->once()) + ->method('set') + ->with('system/default/test/test/test', [], $value) + ->willReturn(null); + $this->deploymentConfigWriterMock->expects($this->once()) + ->method('saveConfig') + ->willThrowException(new FileSystemException(__('Filesystem is not writable.'))); + + $this->model->process($path, $value, ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage Invalid values + */ + public function testCustomException() + { + $path = 'test/test/test'; + $value = 'value'; + + $this->configPathResolver->expects($this->once()) + ->method('resolve') + ->willReturn('system/default/test/test/test'); + $this->preparedValueFactory->expects($this->once()) + ->method('create') + ->willReturn($this->valueMock); + $this->arrayManagerMock->expects($this->never()) + ->method('set'); + $this->valueMock->expects($this->once()) + ->method('getValue'); + $this->valueMock->expects($this->once()) + ->method('afterSave') + ->willThrowException(new \Exception('Invalid values')); + $this->deploymentConfigWriterMock->expects($this->never()) + ->method('saveConfig'); + + $this->model->process($path, $value, ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null); + } +} diff --git a/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/LockProcessorTest.php b/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/LockEnvProcessorTest.php similarity index 98% rename from app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/LockProcessorTest.php rename to app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/LockEnvProcessorTest.php index 4535e9ad888c2..4e0248f886028 100644 --- a/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/LockProcessorTest.php +++ b/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/LockEnvProcessorTest.php @@ -23,7 +23,7 @@ * @see LockProcessor * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class LockProcessorTest extends \PHPUnit\Framework\TestCase +class LockEnvProcessorTest extends \PHPUnit\Framework\TestCase { /** * @var LockProcessor @@ -81,7 +81,8 @@ protected function setUp() $this->preparedValueFactory, $this->deploymentConfigWriterMock, $this->arrayManagerMock, - $this->configPathResolver + $this->configPathResolver, + ConfigFilePool::APP_ENV ); } diff --git a/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/ProcessorFacadeTest.php b/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/ProcessorFacadeTest.php index 4e65ab3f4cc21..ac4dda2a98517 100644 --- a/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/ProcessorFacadeTest.php +++ b/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/ProcessorFacadeTest.php @@ -11,6 +11,7 @@ use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\Scope\ValidatorInterface; use Magento\Config\Model\Config\PathValidator; +use Magento\Framework\Config\File\ConfigFilePool; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\ValidatorException; use Magento\Framework\Exception\CouldNotSaveException; @@ -122,7 +123,13 @@ public function testProcess() $this->assertSame( 'Value was saved.', - $this->model->process('test/test/test', 'test', ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null, false) + $this->model->processWithLockTarget( + 'test/test/test', + 'test', + ScopeConfigInterface::SCOPE_TYPE_DEFAULT, + null, + false + ) ); } @@ -132,12 +139,19 @@ public function testProcess() */ public function testProcessWithValidatorException(LocalizedException $exception) { - $this->expectException(ValidatorException::class, 'Some error'); + $this->expectException(ValidatorException::class); + $this->expectExceptionMessage('Some error'); $this->scopeValidatorMock->expects($this->once()) ->method('isValid') ->willThrowException($exception); - $this->model->process('test/test/test', 'test', ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null, false); + $this->model->processWithLockTarget( + 'test/test/test', + 'test', + ScopeConfigInterface::SCOPE_TYPE_DEFAULT, + null, + false + ); } /** @@ -172,7 +186,13 @@ public function testProcessWithConfigurationMismatchException() $this->configMock->expects($this->never()) ->method('clean'); - $this->model->process('test/test/test', 'test', ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null, false); + $this->model->processWithLockTarget( + 'test/test/test', + 'test', + ScopeConfigInterface::SCOPE_TYPE_DEFAULT, + null, + false + ); } /** @@ -198,17 +218,50 @@ public function testProcessWithCouldNotSaveException() $this->configMock->expects($this->never()) ->method('clean'); - $this->model->process('test/test/test', 'test', ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null, false); + $this->model->processWithLockTarget( + 'test/test/test', + 'test', + ScopeConfigInterface::SCOPE_TYPE_DEFAULT, + null, + false + ); + } + + public function testExecuteLockEnv() + { + $this->scopeValidatorMock->expects($this->once()) + ->method('isValid') + ->willReturn(true); + $this->configSetProcessorFactoryMock->expects($this->once()) + ->method('create') + ->with(ConfigSetProcessorFactory::TYPE_LOCK_ENV) + ->willReturn($this->processorMock); + $this->processorMock->expects($this->once()) + ->method('process') + ->with('test/test/test', 'test', ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null); + $this->configMock->expects($this->once()) + ->method('clean'); + + $this->assertSame( + 'Value was saved in app/etc/env.php and locked.', + $this->model->processWithLockTarget( + 'test/test/test', + 'test', + ScopeConfigInterface::SCOPE_TYPE_DEFAULT, + null, + true + ) + ); } - public function testExecuteLock() + public function testExecuteLockConfig() { $this->scopeValidatorMock->expects($this->once()) ->method('isValid') ->willReturn(true); $this->configSetProcessorFactoryMock->expects($this->once()) ->method('create') - ->with(ConfigSetProcessorFactory::TYPE_LOCK) + ->with(ConfigSetProcessorFactory::TYPE_LOCK_CONFIG) ->willReturn($this->processorMock); $this->processorMock->expects($this->once()) ->method('process') @@ -217,8 +270,15 @@ public function testExecuteLock() ->method('clean'); $this->assertSame( - 'Value was saved and locked.', - $this->model->process('test/test/test', 'test', ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null, true) + 'Value was saved in app/etc/config.php and locked.', + $this->model->processWithLockTarget( + 'test/test/test', + 'test', + ScopeConfigInterface::SCOPE_TYPE_DEFAULT, + null, + true, + ConfigFilePool::APP_CONFIG + ) ); } } diff --git a/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSetCommandTest.php b/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSetCommandTest.php index 0271de0da81f4..cb3a401e6f1d1 100644 --- a/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSetCommandTest.php +++ b/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSetCommandTest.php @@ -95,7 +95,7 @@ public function testExecute() ->method('create') ->willReturn($this->processorFacadeMock); $this->processorFacadeMock->expects($this->once()) - ->method('process') + ->method('processWithLockTarget') ->willReturn('Some message'); $this->emulatedAreProcessorMock->expects($this->once()) ->method('process') @@ -171,9 +171,7 @@ public function testExecuteWithException() ->willReturn(false); $this->emulatedAreProcessorMock->expects($this->once()) ->method('process') - ->willThrowException( - new ValidatorException(__('The "test/test/test" path doesn\'t exist. Verify and try again.')) - ); + ->willThrowException(new ValidatorException(__('The "test/test/test" path does not exists'))); $tester = new CommandTester($this->command); $tester->execute([ @@ -182,7 +180,7 @@ public function testExecuteWithException() ]); $this->assertContains( - __('The "test/test/test" path doesn\'t exist. Verify and try again.')->render(), + __('The "test/test/test" path does not exists')->render(), $tester->getDisplay() ); $this->assertSame(Cli::RETURN_FAILURE, $tester->getStatusCode()); diff --git a/app/code/Magento/Config/etc/di.xml b/app/code/Magento/Config/etc/di.xml index bcddd8ceaf27a..a5dd18097fb47 100644 --- a/app/code/Magento/Config/etc/di.xml +++ b/app/code/Magento/Config/etc/di.xml @@ -296,10 +296,21 @@ Magento\Config\Console\Command\ConfigSet\DefaultProcessor - Magento\Config\Console\Command\ConfigSet\LockProcessor + Magento\Config\Console\Command\ConfigSet\VirtualLockEnvProcessor + Magento\Config\Console\Command\ConfigSet\VirtualLockConfigProcessor + + + app_env + + + + + app_config + + diff --git a/app/code/Magento/Deploy/Model/Mode.php b/app/code/Magento/Deploy/Model/Mode.php index c7ee9b6849665..d4ae72d63bce7 100644 --- a/app/code/Magento/Deploy/Model/Mode.php +++ b/app/code/Magento/Deploy/Model/Mode.php @@ -236,7 +236,7 @@ private function saveAppConfigs($mode) $configs = $this->configProvider->getConfigs($this->getMode(), $mode); foreach ($configs as $path => $item) { $this->emulatedAreaProcessor->process(function () use ($path, $item) { - $this->processorFacadeFactory->create()->process( + $this->processorFacadeFactory->create()->processWithLockTarget( $path, $item['value'], ScopeConfigInterface::SCOPE_TYPE_DEFAULT, diff --git a/app/code/Magento/Deploy/Test/Unit/Model/ModeTest.php b/app/code/Magento/Deploy/Test/Unit/Model/ModeTest.php index 25625eaa5e267..50725a3382073 100644 --- a/app/code/Magento/Deploy/Test/Unit/Model/ModeTest.php +++ b/app/code/Magento/Deploy/Test/Unit/Model/ModeTest.php @@ -241,7 +241,7 @@ public function testEnableProductionModeMinimal() ->willReturn($this->processorFacade); $this->processorFacade ->expects($this->once()) - ->method('process') + ->method('processWithLockTarget') ->with( 'dev/debug/debug_logging', 0, diff --git a/dev/tests/integration/testsuite/Magento/Config/Console/Command/ConfigSetCommandTest.php b/dev/tests/integration/testsuite/Magento/Config/Console/Command/ConfigSetCommandTest.php index 358742ae69ee8..f68f3cf37b079 100644 --- a/dev/tests/integration/testsuite/Magento/Config/Console/Command/ConfigSetCommandTest.php +++ b/dev/tests/integration/testsuite/Magento/Config/Console/Command/ConfigSetCommandTest.php @@ -142,7 +142,7 @@ private function loadConfig() * @magentoDbIsolation enabled * @dataProvider runLockDataProvider */ - public function testRunLock($path, $value, $scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT, $scopeCode = null) + public function testRunLockEnv($path, $value, $scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT, $scopeCode = null) { $this->inputMock->expects($this->any()) ->method('getArgument') @@ -153,15 +153,15 @@ public function testRunLock($path, $value, $scope = ScopeConfigInterface::SCOPE_ $this->inputMock->expects($this->any()) ->method('getOption') ->willReturnMap([ - [ConfigSetCommand::OPTION_LOCK, true], + [ConfigSetCommand::OPTION_LOCK_ENV, true], [ConfigSetCommand::OPTION_SCOPE, $scope], [ConfigSetCommand::OPTION_SCOPE_CODE, $scopeCode] ]); $this->outputMock->expects($this->exactly(2)) ->method('writeln') ->withConsecutive( - ['Value was saved and locked.'], - ['Value was saved and locked.'] + ['Value was saved in app/etc/env.php and locked.'], + ['Value was saved in app/etc/env.php and locked.'] ); /** @var ConfigSetCommand $command */ @@ -218,7 +218,7 @@ public function testRunExtended( [ConfigSetCommand::OPTION_SCOPE, $scope], [ConfigSetCommand::OPTION_SCOPE_CODE, $scopeCode] ]; - $optionsLock = array_merge($options, [[ConfigSetCommand::OPTION_LOCK, true]]); + $optionsLock = array_merge($options, [[ConfigSetCommand::OPTION_LOCK_ENV, true]]); /** @var ConfigPathResolver $resolver */ $resolver = $this->objectManager->get(ConfigPathResolver::class); @@ -234,8 +234,8 @@ public function testRunExtended( ); $this->assertSame(null, $this->arrayManager->get($configPath, $this->loadConfig())); - $this->runCommand($arguments, $optionsLock, 'Value was saved and locked.'); - $this->runCommand($arguments, $optionsLock, 'Value was saved and locked.'); + $this->runCommand($arguments, $optionsLock, 'Value was saved in app/etc/env.php and locked.'); + $this->runCommand($arguments, $optionsLock, 'Value was saved in app/etc/env.php and locked.'); $this->assertSame($value, $this->arrayManager->get($configPath, $this->loadConfig())); } diff --git a/dev/tests/integration/testsuite/Magento/Developer/Model/Logger/Handler/DebugTest.php b/dev/tests/integration/testsuite/Magento/Developer/Model/Logger/Handler/DebugTest.php index a40a7c8ad2962..3b006b5044337 100644 --- a/dev/tests/integration/testsuite/Magento/Developer/Model/Logger/Handler/DebugTest.php +++ b/dev/tests/integration/testsuite/Magento/Developer/Model/Logger/Handler/DebugTest.php @@ -112,25 +112,27 @@ private function enableDebugging() ->getMockForAbstractClass(); $this->outputMock = $this->getMockBuilder(OutputInterface::class) ->getMockForAbstractClass(); - $this->inputMock->expects($this->exactly(2)) - ->method('getArgument') - ->withConsecutive([ConfigSetCommand::ARG_PATH], [ConfigSetCommand::ARG_VALUE]) - ->willReturnOnConsecutiveCalls('dev/debug/debug_logging', 1); - $this->inputMock->expects($this->exactly(3)) + $this->inputMock->expects($this->exactly(4)) ->method('getOption') ->withConsecutive( + [ConfigSetCommand::OPTION_LOCK_ENV], + [ConfigSetCommand::OPTION_LOCK_CONFIG], [ConfigSetCommand::OPTION_SCOPE], - [ConfigSetCommand::OPTION_SCOPE_CODE], - [ConfigSetCommand::OPTION_LOCK] + [ConfigSetCommand::OPTION_SCOPE_CODE] ) ->willReturnOnConsecutiveCalls( + true, + false, ScopeConfigInterface::SCOPE_TYPE_DEFAULT, - null, - true + null ); + $this->inputMock->expects($this->exactly(2)) + ->method('getArgument') + ->withConsecutive([ConfigSetCommand::ARG_PATH], [ConfigSetCommand::ARG_VALUE]) + ->willReturnOnConsecutiveCalls('dev/debug/debug_logging', 1); $this->outputMock->expects($this->once()) ->method('writeln') - ->with('Value was saved and locked.'); + ->with('Value was saved in app/etc/env.php and locked.'); $this->assertFalse((bool)$this->configSetCommand->run($this->inputMock, $this->outputMock)); }