diff --git a/app/code/Magento/Analytics/Cron/SignUp.php b/app/code/Magento/Analytics/Cron/SignUp.php
index 8b0b797177234..c17b9b8c381c3 100644
--- a/app/code/Magento/Analytics/Cron/SignUp.php
+++ b/app/code/Magento/Analytics/Cron/SignUp.php
@@ -7,7 +7,7 @@
use Magento\Analytics\Model\Config\Backend\Enabled\SubscriptionHandler;
use Magento\Analytics\Model\Connector;
-use Magento\Analytics\Model\FlagManager;
+use Magento\Framework\FlagManager;
use Magento\Framework\App\Config\ReinitableConfigInterface;
use Magento\Framework\App\Config\Storage\WriterInterface;
diff --git a/app/code/Magento/Analytics/Cron/Update.php b/app/code/Magento/Analytics/Cron/Update.php
index c3c5ede3d4020..36e6c3e59e5c7 100644
--- a/app/code/Magento/Analytics/Cron/Update.php
+++ b/app/code/Magento/Analytics/Cron/Update.php
@@ -6,8 +6,8 @@
namespace Magento\Analytics\Cron;
use Magento\Analytics\Model\Connector;
-use Magento\Analytics\Model\FlagManager;
use Magento\Analytics\Model\Plugin\BaseUrlConfigPlugin;
+use Magento\Framework\FlagManager;
use Magento\Framework\App\Config\ReinitableConfigInterface;
use Magento\Framework\App\Config\Storage\WriterInterface;
diff --git a/app/code/Magento/Analytics/Model/Config/Backend/Enabled/SubscriptionHandler.php b/app/code/Magento/Analytics/Model/Config/Backend/Enabled/SubscriptionHandler.php
index fb9b6ecede0d5..71f2100a5cebc 100644
--- a/app/code/Magento/Analytics/Model/Config/Backend/Enabled/SubscriptionHandler.php
+++ b/app/code/Magento/Analytics/Model/Config/Backend/Enabled/SubscriptionHandler.php
@@ -7,8 +7,8 @@
use Magento\Analytics\Model\AnalyticsToken;
use Magento\Analytics\Model\Config\Backend\CollectionTime;
-use Magento\Analytics\Model\FlagManager;
use Magento\Analytics\Model\NotificationTime;
+use Magento\Framework\FlagManager;
use Magento\Framework\App\Config\Storage\WriterInterface;
/**
diff --git a/app/code/Magento/Analytics/Model/Connector/UpdateCommand.php b/app/code/Magento/Analytics/Model/Connector/UpdateCommand.php
index a4560c43904b9..185b2c1ebe606 100644
--- a/app/code/Magento/Analytics/Model/Connector/UpdateCommand.php
+++ b/app/code/Magento/Analytics/Model/Connector/UpdateCommand.php
@@ -6,9 +6,9 @@
namespace Magento\Analytics\Model\Connector;
use Magento\Analytics\Model\AnalyticsToken;
-use Magento\Analytics\Model\FlagManager;
use Magento\Analytics\Model\Plugin\BaseUrlConfigPlugin;
use Magento\Config\Model\Config;
+use Magento\Framework\FlagManager;
use Magento\Framework\HTTP\ZendClient;
use Magento\Store\Model\Store;
use Psr\Log\LoggerInterface;
diff --git a/app/code/Magento/Analytics/Model/FileInfoManager.php b/app/code/Magento/Analytics/Model/FileInfoManager.php
index c8ca204acd83b..e37700e665420 100644
--- a/app/code/Magento/Analytics/Model/FileInfoManager.php
+++ b/app/code/Magento/Analytics/Model/FileInfoManager.php
@@ -6,6 +6,7 @@
namespace Magento\Analytics\Model;
use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\FlagManager;
/**
* Manage saving and loading FileInfo object.
diff --git a/app/code/Magento/Analytics/Model/NotificationTime.php b/app/code/Magento/Analytics/Model/NotificationTime.php
index 06be68e709f03..47b9f35cc77b9 100644
--- a/app/code/Magento/Analytics/Model/NotificationTime.php
+++ b/app/code/Magento/Analytics/Model/NotificationTime.php
@@ -3,9 +3,10 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-
namespace Magento\Analytics\Model;
+use Magento\Framework\FlagManager;
+
/**
* Class NotificationTime
*
diff --git a/app/code/Magento/Analytics/Model/Plugin/BaseUrlConfigPlugin.php b/app/code/Magento/Analytics/Model/Plugin/BaseUrlConfigPlugin.php
index d7bfcafc013e5..705c627798aa9 100644
--- a/app/code/Magento/Analytics/Model/Plugin/BaseUrlConfigPlugin.php
+++ b/app/code/Magento/Analytics/Model/Plugin/BaseUrlConfigPlugin.php
@@ -5,8 +5,8 @@
*/
namespace Magento\Analytics\Model\Plugin;
-use Magento\Analytics\Model\FlagManager;
use Magento\Analytics\Model\SubscriptionStatusProvider;
+use Magento\Framework\FlagManager;
use Magento\Framework\App\Config\Storage\WriterInterface;
/**
diff --git a/app/code/Magento/Analytics/Model/SubscriptionStatusProvider.php b/app/code/Magento/Analytics/Model/SubscriptionStatusProvider.php
index da1bc856ce0a5..fc363231cf4d5 100644
--- a/app/code/Magento/Analytics/Model/SubscriptionStatusProvider.php
+++ b/app/code/Magento/Analytics/Model/SubscriptionStatusProvider.php
@@ -7,6 +7,7 @@
use Magento\Analytics\Model\Config\Backend\Enabled\SubscriptionHandler;
use Magento\Config\App\Config\Type\System;
+use Magento\Framework\FlagManager;
/**
* Provider of subscription status.
diff --git a/app/code/Magento/Analytics/Test/Unit/Cron/SignUpTest.php b/app/code/Magento/Analytics/Test/Unit/Cron/SignUpTest.php
index 38a9dc59216db..c8ab5a6f4649e 100644
--- a/app/code/Magento/Analytics/Test/Unit/Cron/SignUpTest.php
+++ b/app/code/Magento/Analytics/Test/Unit/Cron/SignUpTest.php
@@ -8,9 +8,9 @@
use Magento\Analytics\Cron\SignUp;
use Magento\Analytics\Model\Config\Backend\Enabled\SubscriptionHandler;
use Magento\Analytics\Model\Connector;
-use Magento\Analytics\Model\FlagManager;
use Magento\Framework\App\Config\ReinitableConfigInterface;
use Magento\Framework\App\Config\Storage\WriterInterface;
+use Magento\Framework\FlagManager;
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
diff --git a/app/code/Magento/Analytics/Test/Unit/Cron/UpdateTest.php b/app/code/Magento/Analytics/Test/Unit/Cron/UpdateTest.php
index 23d1df343cdf8..9a5355de62a5c 100644
--- a/app/code/Magento/Analytics/Test/Unit/Cron/UpdateTest.php
+++ b/app/code/Magento/Analytics/Test/Unit/Cron/UpdateTest.php
@@ -7,10 +7,10 @@
use Magento\Analytics\Cron\Update;
use Magento\Analytics\Model\Connector;
-use Magento\Analytics\Model\FlagManager;
use Magento\Analytics\Model\Plugin\BaseUrlConfigPlugin;
use Magento\Framework\App\Config\ReinitableConfigInterface;
use Magento\Framework\App\Config\Storage\WriterInterface;
+use Magento\Framework\FlagManager;
/**
* Class Update
diff --git a/app/code/Magento/Analytics/Test/Unit/Model/Config/Backend/Enabled/SubscriptionHandlerTest.php b/app/code/Magento/Analytics/Test/Unit/Model/Config/Backend/Enabled/SubscriptionHandlerTest.php
index 646babebfe54a..d01101bf5cc3b 100644
--- a/app/code/Magento/Analytics/Test/Unit/Model/Config/Backend/Enabled/SubscriptionHandlerTest.php
+++ b/app/code/Magento/Analytics/Test/Unit/Model/Config/Backend/Enabled/SubscriptionHandlerTest.php
@@ -9,9 +9,9 @@
use Magento\Analytics\Model\AnalyticsToken;
use Magento\Analytics\Model\Config\Backend\CollectionTime;
use Magento\Analytics\Model\Config\Backend\Enabled\SubscriptionHandler;
-use Magento\Analytics\Model\FlagManager;
use Magento\Analytics\Model\NotificationTime;
use Magento\Framework\App\Config\Storage\WriterInterface;
+use Magento\Framework\FlagManager;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
/**
diff --git a/app/code/Magento/Analytics/Test/Unit/Model/Connector/UpdateCommandTest.php b/app/code/Magento/Analytics/Test/Unit/Model/Connector/UpdateCommandTest.php
index e51952aa23022..c9cb6b8b0f712 100644
--- a/app/code/Magento/Analytics/Test/Unit/Model/Connector/UpdateCommandTest.php
+++ b/app/code/Magento/Analytics/Test/Unit/Model/Connector/UpdateCommandTest.php
@@ -8,9 +8,9 @@
use Magento\Analytics\Model\AnalyticsToken;
use Magento\Analytics\Model\Connector\Http\ClientInterface;
use Magento\Analytics\Model\Connector\UpdateCommand;
-use Magento\Analytics\Model\FlagManager;
use Magento\Analytics\Model\Plugin\BaseUrlConfigPlugin;
use Magento\Config\Model\Config;
+use Magento\Framework\FlagManager;
use Magento\Framework\HTTP\ZendClient;
use Psr\Log\LoggerInterface;
diff --git a/app/code/Magento/Analytics/Test/Unit/Model/FileInfoManagerTest.php b/app/code/Magento/Analytics/Test/Unit/Model/FileInfoManagerTest.php
index 6e60d8b9678fb..c8c07ae8240c3 100644
--- a/app/code/Magento/Analytics/Test/Unit/Model/FileInfoManagerTest.php
+++ b/app/code/Magento/Analytics/Test/Unit/Model/FileInfoManagerTest.php
@@ -8,7 +8,7 @@
use Magento\Analytics\Model\FileInfo;
use Magento\Analytics\Model\FileInfoFactory;
use Magento\Analytics\Model\FileInfoManager;
-use Magento\Analytics\Model\FlagManager;
+use Magento\Framework\FlagManager;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
/**
diff --git a/app/code/Magento/Analytics/Test/Unit/Model/NotificationTimeTest.php b/app/code/Magento/Analytics/Test/Unit/Model/NotificationTimeTest.php
index 61e11a86d8662..c2a947362d1db 100644
--- a/app/code/Magento/Analytics/Test/Unit/Model/NotificationTimeTest.php
+++ b/app/code/Magento/Analytics/Test/Unit/Model/NotificationTimeTest.php
@@ -6,7 +6,7 @@
namespace Magento\Analytics\Test\Unit\Model;
-use Magento\Analytics\Model\FlagManager;
+use Magento\Framework\FlagManager;
use Magento\Analytics\Model\NotificationTime;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
diff --git a/app/code/Magento/Analytics/Test/Unit/Model/Plugin/BaseUrlConfigPluginTest.php b/app/code/Magento/Analytics/Test/Unit/Model/Plugin/BaseUrlConfigPluginTest.php
index 85b2ced0705f3..caf81b77fbdf9 100644
--- a/app/code/Magento/Analytics/Test/Unit/Model/Plugin/BaseUrlConfigPluginTest.php
+++ b/app/code/Magento/Analytics/Test/Unit/Model/Plugin/BaseUrlConfigPluginTest.php
@@ -5,10 +5,10 @@
*/
namespace Magento\Analytics\Test\Unit\Model\Plugin;
-use Magento\Analytics\Model\FlagManager;
use Magento\Analytics\Model\Plugin\BaseUrlConfigPlugin;
use Magento\Analytics\Model\SubscriptionStatusProvider;
use Magento\Config\Model\Config\Backend\Baseurl;
+use Magento\Framework\FlagManager;
use Magento\Framework\App\Config\Storage\WriterInterface;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
use Magento\Store\Model\Store;
diff --git a/app/code/Magento/Analytics/Test/Unit/Model/SubscriptionStatusProviderTest.php b/app/code/Magento/Analytics/Test/Unit/Model/SubscriptionStatusProviderTest.php
index eb4403ad7d4d1..9e4defe195b32 100644
--- a/app/code/Magento/Analytics/Test/Unit/Model/SubscriptionStatusProviderTest.php
+++ b/app/code/Magento/Analytics/Test/Unit/Model/SubscriptionStatusProviderTest.php
@@ -7,9 +7,9 @@
use Magento\Analytics\Model\AnalyticsToken;
use Magento\Analytics\Model\Config\Backend\Enabled\SubscriptionHandler;
-use Magento\Analytics\Model\FlagManager;
use Magento\Analytics\Model\SubscriptionStatusProvider;
use Magento\Config\App\Config\Type\System;
+use Magento\Framework\FlagManager;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
/**
diff --git a/app/code/Magento/Config/App/Config/Source/InitialSnapshotConfigSource.php b/app/code/Magento/Config/App/Config/Source/InitialSnapshotConfigSource.php
new file mode 100644
index 0000000000000..d1658a4badf37
--- /dev/null
+++ b/app/code/Magento/Config/App/Config/Source/InitialSnapshotConfigSource.php
@@ -0,0 +1,57 @@
+flagManager = $flagManager;
+ $this->dataObjectFactory = $dataObjectFactory;
+ }
+
+ /**
+ * Retrieves previously imported configuration.
+ * Snapshots are stored in flags.
+ *
+ * {@inheritdoc}
+ */
+ public function get($path = '')
+ {
+ $flagData = (array)($this->flagManager->getFlagData('system_config_snapshot') ?: []);
+
+ $data = $this->dataObjectFactory->create(
+ ['data' => $flagData]
+ );
+
+ return $data->getData($path) ?: [];
+ }
+}
diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php
index 04ec7ee856776..c8712eb1f4420 100644
--- a/app/code/Magento/Config/App/Config/Type/System.php
+++ b/app/code/Magento/Config/App/Config/Type/System.php
@@ -57,6 +57,13 @@ class System implements ConfigTypeInterface
*/
private $serializer;
+ /**
+ * The type of config.
+ *
+ * @var string
+ */
+ private $configType;
+
/**
* @param \Magento\Framework\App\Config\ConfigSourceInterface $source
* @param \Magento\Framework\App\Config\Spi\PostProcessorInterface $postProcessor
@@ -65,6 +72,7 @@ class System implements ConfigTypeInterface
* @param \Magento\Framework\Serialize\SerializerInterface $serializer
* @param \Magento\Framework\App\Config\Spi\PreProcessorInterface $preProcessor
* @param int $cachingNestedLevel
+ * @param string $configType
*/
public function __construct(
\Magento\Framework\App\Config\ConfigSourceInterface $source,
@@ -73,7 +81,8 @@ public function __construct(
\Magento\Framework\Cache\FrontendInterface $cache,
\Magento\Framework\Serialize\SerializerInterface $serializer,
\Magento\Framework\App\Config\Spi\PreProcessorInterface $preProcessor,
- $cachingNestedLevel = 1
+ $cachingNestedLevel = 1,
+ $configType = self::CONFIG_TYPE
) {
$this->source = $source;
$this->postProcessor = $postProcessor;
@@ -82,6 +91,7 @@ public function __construct(
$this->cachingNestedLevel = $cachingNestedLevel;
$this->fallback = $fallback;
$this->serializer = $serializer;
+ $this->configType = $configType;
}
/**
@@ -93,7 +103,7 @@ public function get($path = '')
$path = '';
}
if (!$this->data) {
- $data = $this->cache->load(self::CONFIG_TYPE);
+ $data = $this->cache->load($this->configType);
if (!$data) {
$data = $this->preProcessor->process($this->source->get());
$this->data = new DataObject($data);
@@ -104,7 +114,7 @@ public function get($path = '')
$this->data = new DataObject($data);
$this->cache->save(
$this->serializer->serialize($this->data->getData()),
- self::CONFIG_TYPE,
+ $this->configType,
[self::CACHE_TAG]
);
} else {
diff --git a/app/code/Magento/Config/Console/Command/ConfigSet/EmulatedProcessorFacade.php b/app/code/Magento/Config/Console/Command/ConfigSet/EmulatedProcessorFacade.php
new file mode 100644
index 0000000000000..cb5ba6f09a5e1
--- /dev/null
+++ b/app/code/Magento/Config/Console/Command/ConfigSet/EmulatedProcessorFacade.php
@@ -0,0 +1,95 @@
+scope = $scope;
+ $this->state = $state;
+ $this->processorFacadeFactory = $processorFacadeFactory;
+ }
+
+ /**
+ * Processes config:set command.
+ *
+ * @param string $path The configuration path in format group/section/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
+ * @return string Processor response message
+ * @throws RuntimeException If exception was catch
+ */
+ public function process($path, $value, $scope, $scopeCode, $lock)
+ {
+ $currentScope = $this->scope->getCurrentScope();
+
+ try {
+ // Emulating adminhtml scope to be able to read configs.
+ return $this->state->emulateAreaCode(Area::AREA_ADMINHTML, function () use (
+ $path,
+ $value,
+ $scope,
+ $scopeCode,
+ $lock
+ ) {
+ $this->scope->setCurrentScope(Area::AREA_ADMINHTML);
+
+ return $this->processorFacadeFactory->create()->process(
+ $path,
+ $value,
+ $scope,
+ $scopeCode,
+ $lock
+ );
+ });
+ } catch (LocalizedException $exception) {
+ throw new RuntimeException(__('%1', $exception->getMessage()), $exception);
+ } finally {
+ $this->scope->setCurrentScope($currentScope);
+ }
+ }
+}
diff --git a/app/code/Magento/Config/Console/Command/ConfigSet/LockProcessor.php b/app/code/Magento/Config/Console/Command/ConfigSet/LockProcessor.php
index 0a9da86aecf32..3b09bd55b8b45 100644
--- a/app/code/Magento/Config/Console/Command/ConfigSet/LockProcessor.php
+++ b/app/code/Magento/Config/Console/Command/ConfigSet/LockProcessor.php
@@ -6,10 +6,8 @@
namespace Magento\Config\Console\Command\ConfigSet;
use Magento\Config\App\Config\Type\System;
-use Magento\Config\Model\Config\Structure;
+use Magento\Config\Model\PreparedValueFactory;
use Magento\Framework\App\Config\ConfigPathResolver;
-use Magento\Framework\App\Config\Value;
-use Magento\Framework\App\Config\ValueFactory;
use Magento\Framework\App\DeploymentConfig;
use Magento\Framework\Config\File\ConfigFilePool;
use Magento\Framework\Exception\CouldNotSaveException;
@@ -24,11 +22,11 @@
class LockProcessor implements ConfigSetProcessorInterface
{
/**
- * The deployment configuration reader.
+ * The factory for prepared value.
*
- * @var DeploymentConfig
+ * @var PreparedValueFactory
*/
- private $deploymentConfig;
+ private $preparedValueFactory;
/**
* The deployment configuration writer.
@@ -52,42 +50,21 @@ class LockProcessor implements ConfigSetProcessorInterface
private $configPathResolver;
/**
- * The manager for system configuration structure.
- *
- * @var Structure
- */
- private $configStructure;
-
- /**
- * The factory for configuration value objects.
- *
- * @see Value
- * @var ValueFactory
- */
- private $configValueFactory;
-
- /**
- * @param DeploymentConfig $deploymentConfig The deployment configuration reader
+ * @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 Structure $configStructure The manager for system configuration structure
- * @param ValueFactory $configValueFactory The factory for configuration value objects
*/
public function __construct(
- DeploymentConfig $deploymentConfig,
+ PreparedValueFactory $preparedValueFactory,
DeploymentConfig\Writer $writer,
ArrayManager $arrayManager,
- ConfigPathResolver $configPathResolver,
- Structure $configStructure,
- ValueFactory $configValueFactory
+ ConfigPathResolver $configPathResolver
) {
- $this->deploymentConfig = $deploymentConfig;
+ $this->preparedValueFactory = $preparedValueFactory;
$this->deploymentConfigWriter = $writer;
$this->arrayManager = $arrayManager;
$this->configPathResolver = $configPathResolver;
- $this->configStructure = $configStructure;
- $this->configValueFactory = $configValueFactory;
}
/**
@@ -100,19 +77,7 @@ public function process($path, $value, $scope, $scopeCode)
{
try {
$configPath = $this->configPathResolver->resolve($path, $scope, $scopeCode, System::CONFIG_TYPE);
- /** @var Structure\Element\Field $field */
- $field = $this->deploymentConfig->isAvailable()
- ? $this->configStructure->getElement($path)
- : null;
- /** @var Value $backendModel */
- $backendModel = $field && $field->hasBackendModel()
- ? $field->getBackendModel()
- : $this->configValueFactory->create();
-
- $backendModel->setPath($path);
- $backendModel->setScope($scope);
- $backendModel->setScopeId($scopeCode);
- $backendModel->setValue($value);
+ $backendModel = $this->preparedValueFactory->create($path, $value, $scope, $scopeCode);
/**
* Temporary solution until Magento introduce unified interface
diff --git a/app/code/Magento/Config/Console/Command/ConfigSetCommand.php b/app/code/Magento/Config/Console/Command/ConfigSetCommand.php
index 54759be8943d6..3629cde113d2e 100644
--- a/app/code/Magento/Config/Console/Command/ConfigSetCommand.php
+++ b/app/code/Magento/Config/Console/Command/ConfigSetCommand.php
@@ -5,11 +5,12 @@
*/
namespace Magento\Config\Console\Command;
-use Magento\Config\Console\Command\ConfigSet\ProcessorFacadeFactory;
-use Magento\Framework\App\Area;
+use Magento\Config\App\Config\Type\System;
+use Magento\Config\Console\Command\ConfigSet\EmulatedProcessorFacade;
+use Magento\Deploy\Model\DeploymentConfig\ChangeDetector;
+use Magento\Deploy\Model\DeploymentConfig\Hash;
+use Magento\Deploy\Model\DeploymentConfig\Validator;
use Magento\Framework\App\Config\ScopeConfigInterface;
-use Magento\Framework\App\State;
-use Magento\Framework\Config\ScopeInterface;
use Magento\Framework\Console\Cli;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
@@ -33,39 +34,39 @@ class ConfigSetCommand extends Command
/**#@-*/
/**
- * Scope manager.
+ * The emulated processor facade.
*
- * @var ScopeInterface
+ * @var EmulatedProcessorFacade
*/
- private $scope;
+ private $emulatedProcessorFacade;
/**
- * Application state.
+ * The config change detector.
*
- * @var State
+ * @var ChangeDetector
*/
- private $state;
+ private $changeDetector;
/**
- * The processor facade factory
+ * The hash manager.
*
- * @var ProcessorFacadeFactory
+ * @var Hash
*/
- private $processorFacadeFactory;
+ private $hash;
/**
- * @param ScopeInterface $scope Scope manager
- * @param State $state Application state
- * @param ProcessorFacadeFactory $processorFacadeFactory The processor facade factory
+ * @param EmulatedProcessorFacade $emulatedProcessorFacade The emulated processor facade
+ * @param ChangeDetector $changeDetector The config change detector
+ * @param Hash $hash The hash manager
*/
public function __construct(
- ScopeInterface $scope,
- State $state,
- ProcessorFacadeFactory $processorFacadeFactory
+ EmulatedProcessorFacade $emulatedProcessorFacade,
+ ChangeDetector $changeDetector,
+ Hash $hash
) {
- $this->scope = $scope;
- $this->state = $state;
- $this->processorFacadeFactory = $processorFacadeFactory;
+ $this->emulatedProcessorFacade = $emulatedProcessorFacade;
+ $this->changeDetector = $changeDetector;
+ $this->hash = $hash;
parent::__construct();
}
@@ -115,24 +116,29 @@ protected function configure()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
+ if ($this->changeDetector->hasChanges(System::CONFIG_TYPE)) {
+ $output->writeln(
+ ''
+ . 'This command is unavailable right now. '
+ . 'To continue working with it please run app:config:import or setup:upgrade command before.'
+ . ''
+ );
+
+ return Cli::RETURN_FAILURE;
+ }
+
try {
- $areaScope = $this->scope->getCurrentScope();
- // Emulating adminhtml scope to be able to read configs.
- $this->state->emulateAreaCode(Area::AREA_ADMINHTML, function () use ($input, $output) {
- $this->scope->setCurrentScope(Area::AREA_ADMINHTML);
-
- $message = $this->processorFacadeFactory->create()->process(
- $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)
- );
-
- $output->writeln('' . $message . '');
- });
-
- $this->scope->setCurrentScope($areaScope);
+ $message = $this->emulatedProcessorFacade->process(
+ $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)
+ );
+
+ $this->hash->regenerate(System::CONFIG_TYPE);
+
+ $output->writeln('' . $message . '');
return Cli::RETURN_SUCCESS;
} catch (\Exception $exception) {
diff --git a/app/code/Magento/Config/Model/Config/BackendFactory.php b/app/code/Magento/Config/Model/Config/BackendFactory.php
index 21e97fec9f88d..235b4e309c8ee 100644
--- a/app/code/Magento/Config/Model/Config/BackendFactory.php
+++ b/app/code/Magento/Config/Model/Config/BackendFactory.php
@@ -26,12 +26,13 @@ public function __construct(\Magento\Framework\ObjectManagerInterface $objectman
* Create backend model by name
*
* @param string $modelName
+ * @param array $arguments The object arguments
* @return \Magento\Framework\App\Config\ValueInterface
* @throws \InvalidArgumentException
*/
- public function create($modelName)
+ public function create($modelName, array $arguments = [])
{
- $model = $this->_objectManager->create($modelName);
+ $model = $this->_objectManager->create($modelName, $arguments);
if (!$model instanceof \Magento\Framework\App\Config\ValueInterface) {
throw new \InvalidArgumentException('Invalid config field backend model: ' . $modelName);
}
diff --git a/app/code/Magento/Config/Model/Config/Importer.php b/app/code/Magento/Config/Model/Config/Importer.php
index 573f0e646f14d..7c3e4450e3469 100644
--- a/app/code/Magento/Config/Model/Config/Importer.php
+++ b/app/code/Magento/Config/Model/Config/Importer.php
@@ -212,7 +212,6 @@ private function invokeSave(array $scopeData, $scope, $scopeCode = null)
$backendModel = $this->valueFactory->create($path, $value, $scope, $scopeCode);
if ($backendModel instanceof Config\Value) {
- $backendModel->setData('force_changed_value', true);
$backendModel->beforeSave();
$backendModel->afterSave();
}
diff --git a/app/code/Magento/Config/Model/PreparedValueFactory.php b/app/code/Magento/Config/Model/PreparedValueFactory.php
index 20484f3532c36..14555096336c6 100644
--- a/app/code/Magento/Config/Model/PreparedValueFactory.php
+++ b/app/code/Magento/Config/Model/PreparedValueFactory.php
@@ -5,11 +5,12 @@
*/
namespace Magento\Config\Model;
+use Magento\Config\Model\Config\BackendFactory;
use Magento\Config\Model\Config\Structure;
use Magento\Config\Model\Config\StructureFactory;
+use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\Config\ValueInterface;
use Magento\Framework\App\Config\Value;
-use Magento\Framework\App\Config\ValueFactory;
use Magento\Framework\App\ScopeInterface;
use Magento\Framework\App\ScopeResolverPool;
use Magento\Framework\Exception\RuntimeException;
@@ -39,23 +40,33 @@ class PreparedValueFactory
* The factory for configuration value objects.
*
* @see ValueInterface
- * @var ValueFactory
+ * @var BackendFactory
*/
private $valueFactory;
+ /**
+ * The scope configuration.
+ *
+ * @var ScopeConfigInterface
+ */
+ private $config;
+
/**
* @param ScopeResolverPool $scopeResolverPool The scope resolver pool
* @param StructureFactory $structureFactory The manager for system configuration structure
- * @param ValueFactory $valueFactory The factory for configuration value objects
+ * @param BackendFactory $valueFactory The factory for configuration value objects
+ * @param ScopeConfigInterface $config The scope configuration
*/
public function __construct(
ScopeResolverPool $scopeResolverPool,
StructureFactory $structureFactory,
- ValueFactory $valueFactory
+ BackendFactory $valueFactory,
+ ScopeConfigInterface $config
) {
$this->scopeResolverPool = $scopeResolverPool;
$this->structureFactory = $structureFactory;
$this->valueFactory = $valueFactory;
+ $this->config = $config;
}
/**
@@ -77,10 +88,15 @@ public function create($path, $value, $scope, $scopeCode = null)
$structure = $this->structureFactory->create();
/** @var Structure\ElementInterface $field */
$field = $structure->getElement($path);
+ /** @var string $backendModelName */
+ $backendModelName = $field instanceof Structure\Element\Field && $field->hasBackendModel()
+ ? $field->getData()['backend_model']
+ : ValueInterface::class;
/** @var ValueInterface $backendModel */
- $backendModel = $field instanceof Structure\Element\Field && $field->hasBackendModel()
- ? $field->getBackendModel()
- : $this->valueFactory->create();
+ $backendModel = $this->valueFactory->create(
+ $backendModelName,
+ ['config' => $this->config]
+ );
if ($backendModel instanceof Value) {
$scopeId = 0;
diff --git a/app/code/Magento/Config/Test/Unit/App/Config/Source/InitialSnapshotConfigSourceTest.php b/app/code/Magento/Config/Test/Unit/App/Config/Source/InitialSnapshotConfigSourceTest.php
new file mode 100644
index 0000000000000..67b0f3d034d11
--- /dev/null
+++ b/app/code/Magento/Config/Test/Unit/App/Config/Source/InitialSnapshotConfigSourceTest.php
@@ -0,0 +1,84 @@
+flagManagerMock = $this->getMockBuilder(FlagManager::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->dataObjectFactoryMock = $this->getMockBuilder(DataObjectFactory::class)
+ ->setMethods(['create'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->dataObjectMock = $this->getMockBuilder(DataObject::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->dataObjectFactoryMock->expects($this->any())
+ ->method('create')
+ ->willReturn($this->dataObjectMock);
+
+ $this->model = new InitialSnapshotConfigSource(
+ $this->flagManagerMock,
+ $this->dataObjectFactoryMock
+ );
+ }
+
+ public function testGet()
+ {
+ $this->flagManagerMock->expects($this->exactly(2))
+ ->method('getFlagData')
+ ->with('system_config_snapshot')
+ ->willReturnOnConsecutiveCalls(
+ ['some' => 'data'],
+ 'data'
+ );
+ $this->dataObjectMock->expects($this->exactly(2))
+ ->method('getData')
+ ->willReturnOnConsecutiveCalls(
+ ['some' => 'data'],
+ 'data'
+ );
+
+ $this->assertSame(['some' => 'data'], $this->model->get());
+ $this->assertSame('data', $this->model->get('some/path'));
+ }
+}
diff --git a/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/EmulatedProcessorFacadeTest.php b/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/EmulatedProcessorFacadeTest.php
new file mode 100644
index 0000000000000..07c119cda8742
--- /dev/null
+++ b/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/EmulatedProcessorFacadeTest.php
@@ -0,0 +1,74 @@
+scopeMock = $this->getMockBuilder(ScopeInterface::class)
+ ->getMockForAbstractClass();
+ $this->stateMock = $this->getMockBuilder(State::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->processorFacadeFactory = $this->getMockBuilder(ProcessorFacadeFactory::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->model = new EmulatedProcessorFacade(
+ $this->scopeMock,
+ $this->stateMock,
+ $this->processorFacadeFactory
+ );
+ }
+
+ public function testProcess()
+ {
+ $this->scopeMock->expects($this->once())
+ ->method('getCurrentScope')
+ ->willReturn('currentScope');
+ $this->scopeMock->expects($this->once())
+ ->method('setCurrentScope')
+ ->with('currentScope');
+ $this->stateMock->expects($this->once())
+ ->method('emulateAreaCode');
+
+ $this->model->process(
+ 'test/test/test',
+ 'value',
+ ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
+ null,
+ false
+ );
+ }
+}
diff --git a/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/LockProcessorTest.php b/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/LockProcessorTest.php
index 8686de88b19e1..e37214411ff51 100644
--- a/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/LockProcessorTest.php
+++ b/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/LockProcessorTest.php
@@ -6,12 +6,10 @@
namespace Magento\Config\Test\Unit\Console\Command\ConfigSet;
use Magento\Config\Console\Command\ConfigSet\LockProcessor;
-use Magento\Config\Model\Config\Structure;
-use Magento\Config\Model\Config\Structure\Element\Field;
+use Magento\Config\Model\PreparedValueFactory;
use Magento\Framework\App\Config\ConfigPathResolver;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\Config\Value;
-use Magento\Framework\App\Config\ValueFactory;
use Magento\Framework\App\DeploymentConfig;
use Magento\Framework\Config\File\ConfigFilePool;
use Magento\Framework\Exception\FileSystemException;
@@ -33,9 +31,9 @@ class LockProcessorTest extends \PHPUnit_Framework_TestCase
private $model;
/**
- * @var DeploymentConfig
+ * @var PreparedValueFactory|Mock
*/
- private $deploymentConfigMock;
+ private $preparedValueFactory;
/**
* @var DeploymentConfig\Writer|Mock
@@ -52,32 +50,17 @@ class LockProcessorTest extends \PHPUnit_Framework_TestCase
*/
private $configPathResolver;
- /**
- * @var Structure|Mock
- */
- private $structureMock;
-
/**
* @var Value|Mock
*/
private $valueMock;
- /**
- * @var ValueFactory|Mock
- */
- private $valueFactoryMock;
-
- /**
- * @var Field|Mock
- */
- private $fieldMock;
-
/**
* @inheritdoc
*/
protected function setUp()
{
- $this->deploymentConfigMock = $this->getMockBuilder(DeploymentConfig::class)
+ $this->preparedValueFactory = $this->getMockBuilder(PreparedValueFactory::class)
->disableOriginalConstructor()
->getMock();
$this->deploymentConfigWriterMock = $this->getMockBuilder(DeploymentConfig\Writer::class)
@@ -89,37 +72,16 @@ protected function setUp()
$this->configPathResolver = $this->getMockBuilder(ConfigPathResolver::class)
->disableOriginalConstructor()
->getMock();
- $this->structureMock = $this->getMockBuilder(Structure::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->valueFactoryMock = $this->getMockBuilder(ValueFactory::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->fieldMock = $this->getMockBuilder(Field::class)
- ->disableOriginalConstructor()
- ->getMock();
$this->valueMock = $this->getMockBuilder(Value::class)
->setMethods(['validateBeforeSave', 'beforeSave', 'setValue', 'getValue', 'afterSave'])
->disableOriginalConstructor()
->getMock();
- $this->structureMock->expects($this->any())
- ->method('getElement')
- ->willReturn($this->fieldMock);
- $this->deploymentConfigMock->expects($this->any())
- ->method('isAvailable')
- ->willReturn(true);
- $this->valueFactoryMock->expects($this->any())
- ->method('create')
- ->willReturn($this->valueMock);
-
$this->model = new LockProcessor(
- $this->deploymentConfigMock,
+ $this->preparedValueFactory,
$this->deploymentConfigWriterMock,
$this->arrayManagerMock,
- $this->configPathResolver,
- $this->structureMock,
- $this->valueFactoryMock
+ $this->configPathResolver
);
}
@@ -134,11 +96,9 @@ protected function setUp()
*/
public function testProcess($path, $value, $scope, $scopeCode)
{
- $this->fieldMock->expects($this->once())
- ->method('hasBackendModel')
- ->willReturn(true);
- $this->fieldMock->expects($this->once())
- ->method('getBackendModel')
+ $this->preparedValueFactory->expects($this->once())
+ ->method('create')
+ ->with($path, $value, $scope, $scopeCode)
->willReturn($this->valueMock);
$this->configPathResolver->expects($this->once())
->method('resolve')
@@ -200,58 +160,6 @@ public function processDataProvider()
];
}
- public function testProcessBackendModelNotExists()
- {
- $path = 'test/test/test';
- $value = 'value';
-
- $this->fieldMock->expects($this->once())
- ->method('hasBackendModel')
- ->willReturn(false);
- $this->fieldMock->expects($this->never())
- ->method('getBackendModel');
- $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_ENV => [
- 'system' => [
- 'default' => [
- 'test' => [
- 'test' => [
- 'test' => $value
- ]
- ]
- ]
- ]
- ]
- ],
- false
- );
-
- $this->model->process($path, $value, ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null);
- }
-
/**
* @expectedException \Magento\Framework\Exception\LocalizedException
* @expectedExceptionMessage Filesystem is not writable.
@@ -261,11 +169,8 @@ public function testProcessNotReadableFs()
$path = 'test/test/test';
$value = 'value';
- $this->fieldMock->expects($this->once())
- ->method('hasBackendModel')
- ->willReturn(true);
- $this->fieldMock->expects($this->once())
- ->method('getBackendModel')
+ $this->preparedValueFactory->expects($this->once())
+ ->method('create')
->willReturn($this->valueMock);
$this->valueMock->expects($this->once())
->method('getValue')
@@ -293,15 +198,12 @@ public function testCustomException()
$path = 'test/test/test';
$value = 'value';
- $this->fieldMock->expects($this->once())
- ->method('hasBackendModel')
- ->willReturn(true);
- $this->fieldMock->expects($this->once())
- ->method('getBackendModel')
- ->willReturn($this->valueMock);
$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->never())
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 bd62068d672c3..c0cbb210e457a 100644
--- a/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSetCommandTest.php
+++ b/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSetCommandTest.php
@@ -5,11 +5,12 @@
*/
namespace Magento\Config\Test\Unit\Console\Command;
-use Magento\Config\Console\Command\ConfigSet\ProcessorFacade;
-use Magento\Config\Console\Command\ConfigSet\ProcessorFacadeFactory;
+use Magento\Config\App\Config\Type\System;
+use Magento\Config\Console\Command\ConfigSet\EmulatedProcessorFacade;
use Magento\Config\Console\Command\ConfigSetCommand;
-use Magento\Framework\App\State;
-use Magento\Framework\Config\ScopeInterface;
+use Magento\Deploy\Model\DeploymentConfig\ChangeDetector;
+use Magento\Deploy\Model\DeploymentConfig\Hash;
+use Magento\Deploy\Model\DeploymentConfig\Validator;
use Magento\Framework\Console\Cli;
use Magento\Framework\Exception\ValidatorException;
use PHPUnit_Framework_MockObject_MockObject as Mock;
@@ -28,60 +29,96 @@ class ConfigSetCommandTest extends \PHPUnit_Framework_TestCase
private $command;
/**
- * @var ScopeInterface|Mock
+ * @var EmulatedProcessorFacade|Mock
*/
- private $scopeMock;
+ private $emulatedProcessorFacadeMock;
/**
- * @var State|Mock
+ * @var ChangeDetector|Mock
*/
- private $stateMock;
+ private $changeDetectorMock;
/**
- * @var ProcessorFacadeFactory|Mock
+ * @var Hash|Mock
*/
- private $processorFacadeFactoryMock;
-
- /**
- * @var ProcessorFacade|Mock
- */
- private $processorFacadeMock;
+ private $hashMock;
/**
* @inheritdoc
*/
protected function setUp()
{
- $this->scopeMock = $this->getMockBuilder(ScopeInterface::class)
- ->getMockForAbstractClass();
- $this->stateMock = $this->getMockBuilder(State::class)
+ $this->emulatedProcessorFacadeMock = $this->getMockBuilder(EmulatedProcessorFacade::class)
->disableOriginalConstructor()
->getMock();
- $this->processorFacadeFactoryMock = $this->getMockBuilder(ProcessorFacadeFactory::class)
+ $this->changeDetectorMock = $this->getMockBuilder(ChangeDetector::class)
->disableOriginalConstructor()
->getMock();
- $this->processorFacadeMock = $this->getMockBuilder(ProcessorFacade::class)
+ $this->hashMock = $this->getMockBuilder(Hash::class)
->disableOriginalConstructor()
->getMock();
- $this->processorFacadeFactoryMock->expects($this->any())
- ->method('create')
- ->willReturn($this->processorFacadeMock);
-
$this->command = new ConfigSetCommand(
- $this->scopeMock,
- $this->stateMock,
- $this->processorFacadeFactoryMock
+ $this->emulatedProcessorFacadeMock,
+ $this->changeDetectorMock,
+ $this->hashMock
);
}
+ public function testExecute()
+ {
+ $this->changeDetectorMock->expects($this->once())
+ ->method('hasChanges')
+ ->willReturn(false);
+ $this->emulatedProcessorFacadeMock->expects($this->once())
+ ->method('process')
+ ->willReturn('Some message');
+ $this->hashMock->expects($this->once())
+ ->method('regenerate')
+ ->with(System::CONFIG_TYPE);
+
+ $tester = new CommandTester($this->command);
+ $tester->execute([
+ ConfigSetCommand::ARG_PATH => 'test/test/test',
+ ConfigSetCommand::ARG_VALUE => 'value'
+ ]);
+
+ $this->assertContains(
+ __('Some message')->render(),
+ $tester->getDisplay()
+ );
+ $this->assertSame(Cli::RETURN_SUCCESS, $tester->getStatusCode());
+ }
+
+ public function testExecuteNeedsRegeneration()
+ {
+ $this->changeDetectorMock->expects($this->once())
+ ->method('hasChanges')
+ ->willReturn(true);
+ $this->emulatedProcessorFacadeMock->expects($this->never())
+ ->method('process');
+
+ $tester = new CommandTester($this->command);
+ $tester->execute([
+ ConfigSetCommand::ARG_PATH => 'test/test/test',
+ ConfigSetCommand::ARG_VALUE => 'value'
+ ]);
+
+ $this->assertContains(
+ __('This command is unavailable right now.')->render(),
+ $tester->getDisplay()
+ );
+ $this->assertSame(Cli::RETURN_FAILURE, $tester->getStatusCode());
+ }
+
public function testExecuteWithException()
{
- $this->stateMock->expects($this->once())
- ->method('emulateAreaCode')
+ $this->changeDetectorMock->expects($this->once())
+ ->method('hasChanges')
+ ->willReturn(false);
+ $this->emulatedProcessorFacadeMock->expects($this->once())
+ ->method('process')
->willThrowException(new ValidatorException(__('The "test/test/test" path does not exists')));
- $this->processorFacadeFactoryMock->expects($this->never())
- ->method('create');
$tester = new CommandTester($this->command);
$tester->execute([
diff --git a/app/code/Magento/Config/Test/Unit/Model/Config/ImporterTest.php b/app/code/Magento/Config/Test/Unit/Model/Config/ImporterTest.php
index 01fed0f916fb5..9ece6ba21226a 100644
--- a/app/code/Magento/Config/Test/Unit/Model/Config/ImporterTest.php
+++ b/app/code/Magento/Config/Test/Unit/Model/Config/ImporterTest.php
@@ -204,9 +204,6 @@ public function testInvokeSaveAll()
'websites' => ['base' => ['web' => ['unsecure' => ['base_url' => 'http://magento2.local/']]]],
];
- $this->valueMock->expects($this->exactly(2))
- ->method('setData')
- ->with('force_changed_value', true);
$this->valueMock->expects($this->exactly(2))
->method('beforeSave');
$this->valueMock->expects($this->exactly(2))
diff --git a/app/code/Magento/Config/Test/Unit/Model/PreparedValueFactoryTest.php b/app/code/Magento/Config/Test/Unit/Model/PreparedValueFactoryTest.php
index 2b3b870396da5..743ec0d991b32 100644
--- a/app/code/Magento/Config/Test/Unit/Model/PreparedValueFactoryTest.php
+++ b/app/code/Magento/Config/Test/Unit/Model/PreparedValueFactoryTest.php
@@ -5,8 +5,9 @@
*/
namespace Magento\Config\Test\Unit\Model;
+use Magento\Config\Model\Config\BackendFactory;
use Magento\Config\Model\PreparedValueFactory;
-use Magento\Framework\App\Config\ValueFactory;
+use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Config\Model\Config\StructureFactory;
use Magento\Framework\App\Config\Value;
use Magento\Config\Model\Config\Structure;
@@ -27,7 +28,7 @@ class PreparedValueFactoryTest extends \PHPUnit_Framework_TestCase
private $structureFactoryMock;
/**
- * @var ValueFactory|Mock
+ * @var BackendFactory|Mock
*/
private $valueFactoryMock;
@@ -46,6 +47,11 @@ class PreparedValueFactoryTest extends \PHPUnit_Framework_TestCase
*/
private $fieldMock;
+ /**
+ * @var ScopeConfigInterface|Mock
+ */
+ private $configMock;
+
/**
* @var ScopeResolverPool|Mock
*/
@@ -75,7 +81,7 @@ protected function setUp()
->disableOriginalConstructor()
->setMethods(['create'])
->getMock();
- $this->valueFactoryMock = $this->getMockBuilder(ValueFactory::class)
+ $this->valueFactoryMock = $this->getMockBuilder(BackendFactory::class)
->disableOriginalConstructor()
->setMethods(['create'])
->getMock();
@@ -89,6 +95,8 @@ protected function setUp()
->disableOriginalConstructor()
->setMethods(['setPath', 'setScope', 'setScopeId', 'setValue'])
->getMock();
+ $this->configMock = $this->getMockBuilder(ScopeConfigInterface::class)
+ ->getMockForAbstractClass();
$this->scopeResolverPoolMock = $this->getMockBuilder(ScopeResolverPool::class)
->disableOriginalConstructor()
->getMock();
@@ -101,7 +109,8 @@ protected function setUp()
$this->preparedValueFactory = new PreparedValueFactory(
$this->scopeResolverPoolMock,
$this->structureFactoryMock,
- $this->valueFactoryMock
+ $this->valueFactoryMock,
+ $this->configMock
);
}
@@ -143,10 +152,7 @@ public function testCreate(
$this->fieldMock->expects($this->once())
->method('hasBackendModel')
->willReturn(true);
- $this->fieldMock->expects($this->once())
- ->method('getBackendModel')
- ->willReturn($this->valueMock);
- $this->valueFactoryMock->expects($this->never())
+ $this->valueFactoryMock->expects($this->once())
->method('create')
->willReturn($this->valueMock);
$this->valueMock->expects($this->once())
diff --git a/app/code/Magento/Config/composer.json b/app/code/Magento/Config/composer.json
index 735618945ba35..c140b5cc187ac 100644
--- a/app/code/Magento/Config/composer.json
+++ b/app/code/Magento/Config/composer.json
@@ -9,9 +9,7 @@
"magento/module-email": "100.2.*",
"magento/module-directory": "100.2.*",
"magento/module-backend": "100.2.*",
- "magento/module-media-storage": "100.2.*"
- },
- "suggest": {
+ "magento/module-media-storage": "100.2.*",
"magento/module-deploy": "100.2.*"
},
"type": "magento2-module",
diff --git a/app/code/Magento/Config/etc/di.xml b/app/code/Magento/Config/etc/di.xml
index 728bb1334ebff..1abc5e35f578f 100644
--- a/app/code/Magento/Config/etc/di.xml
+++ b/app/code/Magento/Config/etc/di.xml
@@ -86,6 +86,29 @@
Magento\Framework\Serialize\Serializer\Serialize
+
+
+ systemConfigSnapshotSourceAggregated
+ system_snapshot
+
+
+
+
+
+ - systemSnapshot
+
+
+
+
+
+ configSnapshot
+
+
+
+
+ snapshotValueFactory
+
+
modulesDataProvider
@@ -141,6 +164,16 @@
+
+
+
+ -
+
- Magento\Config\App\Config\Source\InitialSnapshotConfigSource
+ - 1000
+
+
+
+
Magento\Framework\App\DeploymentConfig\Reader
diff --git a/app/code/Magento/Deploy/Console/Command/App/SensitiveConfigSet/SensitiveConfigSetFacade.php b/app/code/Magento/Deploy/Console/Command/App/SensitiveConfigSet/SensitiveConfigSetFacade.php
new file mode 100644
index 0000000000000..319b358c4ccc6
--- /dev/null
+++ b/app/code/Magento/Deploy/Console/Command/App/SensitiveConfigSet/SensitiveConfigSetFacade.php
@@ -0,0 +1,136 @@
+commentParser = $commentParser;
+ $this->configFilePool = $configFilePool;
+ $this->configWriter = $configWriter;
+ $this->scopeValidator = $scopeValidator;
+ $this->collectorFactory = $collectorFactory;
+ }
+
+ /**
+ * Processes the sensitive:config:set command.
+ *
+ * @param InputInterface $input The input manager
+ * @param OutputInterface $output The output manager
+ * @return void
+ * @throws RuntimeException If data can not be processed
+ */
+ public function process(InputInterface $input, OutputInterface $output)
+ {
+ $scope = $input->getOption(SensitiveConfigSetCommand::INPUT_OPTION_SCOPE);
+ $scopeCode = $input->getOption(SensitiveConfigSetCommand::INPUT_OPTION_SCOPE_CODE);
+ $isInteractive = $input->getOption(SensitiveConfigSetCommand::INPUT_OPTION_INTERACTIVE);
+
+ $this->scopeValidator->isValid($scope, $scopeCode);
+ $configPaths = $this->getConfigPaths();
+ $collector = $this->collectorFactory->create(
+ $isInteractive ? CollectorFactory::TYPE_INTERACTIVE : CollectorFactory::TYPE_SIMPLE
+ );
+ $values = $collector->getValues($input, $output, $configPaths);
+
+ $this->configWriter->save($values, $scope, $scopeCode);
+
+ $output->writeln(sprintf(
+ 'Configuration value%s saved in app/etc/%s',
+ $isInteractive ? 's' : '',
+ $this->configFilePool->getPath(ConfigFilePool::APP_ENV)
+ ));
+ }
+
+ /**
+ * Get sensitive configuration paths.
+ *
+ * @return array
+ * @throws LocalizedException if configuration file not exists or sensitive configuration is empty
+ */
+ private function getConfigPaths()
+ {
+ $configFilePath = $this->configFilePool->getPath(ConfigFilePool::APP_CONFIG);
+ try {
+ $configPaths = $this->commentParser->execute($configFilePath);
+ } catch (FileSystemException $e) {
+ throw new RuntimeException(__(
+ 'File app/etc/%1 can\'t be read. Please check if it exists and has read permissions.',
+ [
+ $configFilePath
+ ]
+ ));
+ }
+
+ if (empty($configPaths)) {
+ throw new RuntimeException(__('There are no sensitive configurations to fill'));
+ }
+
+ return $configPaths;
+ }
+}
diff --git a/app/code/Magento/Deploy/Console/Command/App/SensitiveConfigSetCommand.php b/app/code/Magento/Deploy/Console/Command/App/SensitiveConfigSetCommand.php
index 9b30fa95ddac8..30b2117b48864 100644
--- a/app/code/Magento/Deploy/Console/Command/App/SensitiveConfigSetCommand.php
+++ b/app/code/Magento/Deploy/Console/Command/App/SensitiveConfigSetCommand.php
@@ -5,15 +5,13 @@
*/
namespace Magento\Deploy\Console\Command\App;
-use Magento\Deploy\Console\Command\App\SensitiveConfigSet\CollectorFactory;
-use Magento\Deploy\Model\ConfigWriter;
-use Magento\Framework\App\Config\CommentParserInterface;
+use Magento\Config\App\Config\Type\System;
+use Magento\Deploy\Console\Command\App\SensitiveConfigSet\SensitiveConfigSetFacade;
+use Magento\Deploy\Model\DeploymentConfig\ChangeDetector;
+use Magento\Deploy\Model\DeploymentConfig\Hash;
+use Magento\Deploy\Model\DeploymentConfig\Validator;
use Magento\Framework\App\Config\ScopeConfigInterface;
-use Magento\Framework\App\Scope\ValidatorInterface;
-use Magento\Framework\Config\File\ConfigFilePool;
use Magento\Framework\Console\Cli;
-use Magento\Framework\Exception\FileSystemException;
-use Magento\Framework\Exception\LocalizedException;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
@@ -22,8 +20,6 @@
/**
* Command for set sensitive variable through deploy process
- *
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class SensitiveConfigSetCommand extends Command
{
@@ -53,52 +49,41 @@ class SensitiveConfigSetCommand extends Command
const INPUT_ARGUMENT_VALUE = 'value';
/**
- * @var CommentParserInterface
- */
- private $commentParser;
-
- /**
- * @var ConfigFilePool
- */
- private $configFilePool;
-
- /**
- * @var ConfigWriter
+ * The config change detector.
+ *
+ * @var ChangeDetector
*/
- private $configWriter;
+ private $changeDetector;
/**
- * @var ValidatorInterface
+ * The hash manager.
+ *
+ * @var Hash
*/
- private $scopeValidator;
+ private $hash;
/**
- * @var CollectorFactory
+ * The facade for command.
+ *
+ * @var SensitiveConfigSetFacade
*/
- private $collectorFactory;
+ private $facade;
/**
- * SensitiveConfigSetCommand constructor
- *
- * @param ConfigFilePool $configFilePool
- * @param CommentParserInterface $commentParser
- * @param ConfigWriter $configWriter
- * @param ValidatorInterface $scopeValidator
- * @param CollectorFactory $collectorFactory
+ * @param SensitiveConfigSetFacade $facade The processor facade
+ * @param ChangeDetector $changeDetector The config change detector
+ * @param Hash $hash The hash manager
*/
public function __construct(
- ConfigFilePool $configFilePool,
- CommentParserInterface $commentParser,
- ConfigWriter $configWriter,
- ValidatorInterface $scopeValidator,
- CollectorFactory $collectorFactory
+ SensitiveConfigSetFacade $facade,
+ ChangeDetector $changeDetector,
+ Hash $hash
) {
+ $this->facade = $facade;
+ $this->changeDetector = $changeDetector;
+ $this->hash = $hash;
+
parent::__construct();
- $this->commentParser = $commentParser;
- $this->configFilePool = $configFilePool;
- $this->configWriter = $configWriter;
- $this->scopeValidator = $scopeValidator;
- $this->collectorFactory = $collectorFactory;
}
/**
@@ -146,68 +131,28 @@ protected function configure()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
- $scope = $input->getOption(self::INPUT_OPTION_SCOPE);
- $scopeCode = $input->getOption(self::INPUT_OPTION_SCOPE_CODE);
-
- try {
- $this->scopeValidator->isValid($scope, $scopeCode);
- $configPaths = $this->getConfigPaths();
- $isInteractive = $input->getOption(self::INPUT_OPTION_INTERACTIVE);
- $collector = $this->collectorFactory->create(
- $isInteractive ? CollectorFactory::TYPE_INTERACTIVE : CollectorFactory::TYPE_SIMPLE
+ if ($this->changeDetector->hasChanges(System::CONFIG_TYPE)) {
+ $output->writeln(
+ ''
+ . 'This command is unavailable right now. '
+ . 'To continue working with it please run app:config:import or setup:upgrade command before.'
+ . ''
);
- $values = $collector->getValues($input, $output, $configPaths);
- $this->configWriter->save($values, $scope, $scopeCode);
- } catch (LocalizedException $e) {
- $output->writeln(sprintf('%s', $e->getMessage()));
+
return Cli::RETURN_FAILURE;
}
- $this->writeSuccessMessage($output, $isInteractive);
-
- return Cli::RETURN_SUCCESS;
- }
-
- /**
- * Writes success message
- *
- * @param OutputInterface $output
- * @param boolean $isInteractive
- * @return void
- */
- private function writeSuccessMessage(OutputInterface $output, $isInteractive)
- {
- $output->writeln(sprintf(
- 'Configuration value%s saved in app/etc/%s',
- $isInteractive ? 's' : '',
- $this->configFilePool->getPath(ConfigFilePool::APP_ENV)
- ));
- }
-
- /**
- * Get sensitive configuration paths
- *
- * @return array
- * @throws LocalizedException if configuration file not exists or sensitive configuration is empty
- */
- private function getConfigPaths()
- {
- $configFilePath = $this->configFilePool->getPath(ConfigFilePool::APP_CONFIG);
try {
- $configPaths = $this->commentParser->execute($configFilePath);
- } catch (FileSystemException $e) {
- throw new LocalizedException(__(
- 'File app/etc/%1 can\'t be read. Please check if it exists and has read permissions.',
- [
- $configFilePath
- ]
- ));
- }
+ $this->facade->process($input, $output);
+ $this->hash->regenerate(System::CONFIG_TYPE);
- if (empty($configPaths)) {
- throw new LocalizedException(__('There are no sensitive configurations to fill'));
- }
+ return Cli::RETURN_SUCCESS;
+ } catch (\Exception $e) {
+ $output->writeln(
+ sprintf('%s', $e->getMessage())
+ );
- return $configPaths;
+ return Cli::RETURN_FAILURE;
+ }
}
}
diff --git a/app/code/Magento/Deploy/Test/Unit/Console/Command/App/SensitiveConfigSet/SensitiveConfigSetFacadeTest.php b/app/code/Magento/Deploy/Test/Unit/Console/Command/App/SensitiveConfigSet/SensitiveConfigSetFacadeTest.php
new file mode 100644
index 0000000000000..d4c5d96689a8b
--- /dev/null
+++ b/app/code/Magento/Deploy/Test/Unit/Console/Command/App/SensitiveConfigSet/SensitiveConfigSetFacadeTest.php
@@ -0,0 +1,276 @@
+configFilePoolMock = $this->getMockBuilder(ConfigFilePool::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->commentParserMock = $this->getMockBuilder(CommentParserInterface::class)
+ ->getMockForAbstractClass();
+ $this->configWriterMock = $this->getMockBuilder(ConfigWriter::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->scopeValidatorMock = $this->getMockBuilder(ValidatorInterface::class)
+ ->getMockForAbstractClass();
+ $this->collectorFactoryMock = $this->getMockBuilder(CollectorFactory::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->inputMock = $this->getMockBuilder(InputInterface::class)
+ ->getMockForAbstractClass();
+ $this->outputMock = $this->getMockBuilder(OutputInterface::class)
+ ->getMockForAbstractClass();
+
+ $this->command = new SensitiveConfigSetFacade(
+ $this->configFilePoolMock,
+ $this->commentParserMock,
+ $this->configWriterMock,
+ $this->scopeValidatorMock,
+ $this->collectorFactoryMock
+ );
+ }
+
+ /**
+ * @expectedExceptionMessage File app/etc/config.php can't be read.
+ * @expectedException \Magento\Framework\Exception\RuntimeException
+ */
+ public function testConfigFileNotExist()
+ {
+ $this->inputMock->expects($this->any())
+ ->method('getOption')
+ ->with()
+ ->willReturnMap([
+ [SensitiveConfigSetCommand::INPUT_OPTION_SCOPE, 'default'],
+ ]);
+ $this->configFilePoolMock->expects($this->once())
+ ->method('getPath')
+ ->with(ConfigFilePool::APP_CONFIG)
+ ->willReturn('config.php');
+ $this->scopeValidatorMock->expects($this->once())
+ ->method('isValid')
+ ->with('default', '')
+ ->willReturn(true);
+ $this->commentParserMock->expects($this->any())
+ ->method('execute')
+ ->willThrowException(new FileSystemException(new Phrase('some message')));
+
+ $this->command->process(
+ $this->inputMock,
+ $this->outputMock
+ );
+ }
+
+ /**
+ * @expectedException \Magento\Framework\Exception\LocalizedException
+ * @expectedExceptionMessage Some exception
+ */
+ public function testWriterException()
+ {
+ $exceptionMessage = 'Some exception';
+ $this->inputMock->expects($this->any())
+ ->method('getOption')
+ ->with()
+ ->willReturnMap([
+ [SensitiveConfigSetCommand::INPUT_OPTION_SCOPE, 'default'],
+ ]);
+ $this->scopeValidatorMock->expects($this->once())
+ ->method('isValid')
+ ->with('default', '')
+ ->willReturn(true);
+ $this->commentParserMock->expects($this->once())
+ ->method('execute')
+ ->willReturn([
+ 'some/config/path1',
+ 'some/config/path2'
+ ]);
+ $collectorMock = $this->getMockBuilder(CollectorInterface::class)
+ ->getMockForAbstractClass();
+ $collectorMock->expects($this->once())
+ ->method('getValues')
+ ->willReturn(['some/config/pathNotExist' => 'value']);
+ $this->collectorFactoryMock->expects($this->once())
+ ->method('create')
+ ->with(CollectorFactory::TYPE_SIMPLE)
+ ->willReturn($collectorMock);
+ $this->configWriterMock->expects($this->once())
+ ->method('save')
+ ->willThrowException(new LocalizedException(__($exceptionMessage)));
+
+ $this->command->process(
+ $this->inputMock,
+ $this->outputMock
+ );
+ }
+
+ /**
+ * @expectedException \Magento\Framework\Exception\RuntimeException
+ * @expectedExceptionMessage There are no sensitive configurations to fill
+ */
+ public function testEmptyConfigPaths()
+ {
+ $this->inputMock->expects($this->any())
+ ->method('getOption')
+ ->with()
+ ->willReturnMap([
+ [SensitiveConfigSetCommand::INPUT_OPTION_SCOPE, 'default'],
+ ]);
+ $this->scopeValidatorMock->expects($this->once())
+ ->method('isValid')
+ ->with('default', '')
+ ->willReturn(true);
+ $this->commentParserMock->expects($this->once())
+ ->method('execute')
+ ->willReturn([]);
+
+ $this->command->process(
+ $this->inputMock,
+ $this->outputMock
+ );
+ }
+
+ public function testExecute()
+ {
+ $collectedValues = ['some/config/path1' => 'value'];
+ $this->inputMock->expects($this->any())
+ ->method('getOption')
+ ->with()
+ ->willReturnMap([
+ [SensitiveConfigSetCommand::INPUT_OPTION_SCOPE, 'default'],
+ ]);
+ $this->scopeValidatorMock->expects($this->once())
+ ->method('isValid')
+ ->with('default', '')
+ ->willReturn(true);
+ $this->commentParserMock->expects($this->once())
+ ->method('execute')
+ ->willReturn([
+ 'some/config/path1',
+ 'some/config/path2'
+ ]);
+ $collectorMock = $this->getMockBuilder(CollectorInterface::class)
+ ->getMockForAbstractClass();
+ $collectorMock->expects($this->once())
+ ->method('getValues')
+ ->willReturn($collectedValues);
+ $this->collectorFactoryMock->expects($this->once())
+ ->method('create')
+ ->with(CollectorFactory::TYPE_SIMPLE)
+ ->willReturn($collectorMock);
+ $this->configWriterMock->expects($this->once())
+ ->method('save')
+ ->with($collectedValues, ScopeConfigInterface::SCOPE_TYPE_DEFAULT, '');
+
+ $this->command->process(
+ $this->inputMock,
+ $this->outputMock
+ );
+ }
+
+ public function testExecuteInteractive()
+ {
+ $collectedValues = ['some/config/path1' => 'value'];
+ $this->inputMock->expects($this->any())
+ ->method('getOption')
+ ->with()
+ ->willReturnMap([
+ [SensitiveConfigSetCommand::INPUT_OPTION_SCOPE, 'default'],
+ [SensitiveConfigSetCommand::INPUT_OPTION_INTERACTIVE, true],
+ ]);
+ $this->scopeValidatorMock->expects($this->once())
+ ->method('isValid')
+ ->with('default', '')
+ ->willReturn(true);
+ $this->commentParserMock->expects($this->once())
+ ->method('execute')
+ ->willReturn([
+ 'some/config/path1',
+ 'some/config/path2',
+ 'some/config/path3'
+ ]);
+ $collectorMock = $this->getMockBuilder(CollectorInterface::class)
+ ->getMockForAbstractClass();
+ $collectorMock->expects($this->once())
+ ->method('getValues')
+ ->willReturn($collectedValues);
+ $this->collectorFactoryMock->expects($this->once())
+ ->method('create')
+ ->with(CollectorFactory::TYPE_INTERACTIVE)
+ ->willReturn($collectorMock);
+ $this->configWriterMock->expects($this->once())
+ ->method('save')
+ ->with($collectedValues, ScopeConfigInterface::SCOPE_TYPE_DEFAULT, '');
+
+ $this->command->process(
+ $this->inputMock,
+ $this->outputMock
+ );
+ }
+}
diff --git a/app/code/Magento/Deploy/Test/Unit/Console/Command/App/SensitiveConfigSetCommandTest.php b/app/code/Magento/Deploy/Test/Unit/Console/Command/App/SensitiveConfigSetCommandTest.php
index 779cb5f0fd500..a227d130ef38a 100644
--- a/app/code/Magento/Deploy/Test/Unit/Console/Command/App/SensitiveConfigSetCommandTest.php
+++ b/app/code/Magento/Deploy/Test/Unit/Console/Command/App/SensitiveConfigSetCommandTest.php
@@ -5,18 +5,13 @@
*/
namespace Magento\Deploy\Test\Unit\Console\Command\App;
-use Magento\Deploy\Console\Command\App\SensitiveConfigSet\CollectorFactory;
-use Magento\Deploy\Console\Command\App\SensitiveConfigSet\CollectorInterface;
+use Magento\Config\App\Config\Type\System;
+use Magento\Deploy\Console\Command\App\SensitiveConfigSet\SensitiveConfigSetFacade;
use Magento\Deploy\Console\Command\App\SensitiveConfigSetCommand;
-use Magento\Deploy\Model\ConfigWriter;
-use Magento\Framework\App\Config\CommentParserInterface;
-use Magento\Framework\App\Config\ScopeConfigInterface;
-use Magento\Framework\App\Scope\ValidatorInterface;
-use Magento\Framework\Config\File\ConfigFilePool;
+use Magento\Deploy\Model\DeploymentConfig\ChangeDetector;
+use Magento\Deploy\Model\DeploymentConfig\Hash;
+use Magento\Deploy\Model\DeploymentConfig\Validator;
use Magento\Framework\Console\Cli;
-use Magento\Framework\Exception\FileSystemException;
-use Magento\Framework\Exception\LocalizedException;
-use Magento\Framework\Phrase;
use PHPUnit_Framework_MockObject_MockObject as MockObject;
use Symfony\Component\Console\Tester\CommandTester;
@@ -26,237 +21,108 @@
class SensitiveConfigSetCommandTest extends \PHPUnit_Framework_TestCase
{
/**
- * @var ConfigFilePool|MockObject
+ * @var SensitiveConfigSetFacade|MockObject
*/
- private $configFilePoolMock;
+ private $facadeMock;
/**
- * @var CommentParserInterface|MockObject
+ * @var ChangeDetector|MockObject
*/
- private $commentParserMock;
+ private $changeDetectorMock;
/**
- * @var ConfigWriter|MockObject
+ * @var Hash|MockObject
*/
- private $configWriterMock;
-
- /**
- * @var ValidatorInterface|MockObject
- */
- private $scopeValidatorMock;
-
- /**
- * @var CollectorFactory|MockObject
- */
- private $collectorFactoryMock;
+ private $hashMock;
/**
* @var SensitiveConfigSetCommand
*/
- private $command;
+ private $model;
/**
* @inheritdoc
*/
public function setUp()
{
- $this->configFilePoolMock = $this->getMockBuilder(ConfigFilePool::class)
+ $this->facadeMock = $this->getMockBuilder(SensitiveConfigSetFacade::class)
->disableOriginalConstructor()
->getMock();
- $this->commentParserMock = $this->getMockBuilder(CommentParserInterface::class)
- ->getMockForAbstractClass();
- $this->configWriterMock = $this->getMockBuilder(ConfigWriter::class)
+ $this->changeDetectorMock = $this->getMockBuilder(ChangeDetector::class)
->disableOriginalConstructor()
->getMock();
- $this->scopeValidatorMock = $this->getMockBuilder(ValidatorInterface::class)
- ->getMockForAbstractClass();
- $this->collectorFactoryMock = $this->getMockBuilder(CollectorFactory::class)
+ $this->hashMock = $this->getMockBuilder(Hash::class)
->disableOriginalConstructor()
->getMock();
- $this->command = new SensitiveConfigSetCommand(
- $this->configFilePoolMock,
- $this->commentParserMock,
- $this->configWriterMock,
- $this->scopeValidatorMock,
- $this->collectorFactoryMock
- );
- }
-
- public function testConfigFileNotExist()
- {
- $this->configFilePoolMock->expects($this->once())
- ->method('getPath')
- ->with(ConfigFilePool::APP_CONFIG)
- ->willReturn('config.php');
- $this->scopeValidatorMock->expects($this->once())
- ->method('isValid')
- ->with('default', '')
- ->willReturn(true);
- $this->commentParserMock->expects($this->any())
- ->method('execute')
- ->willThrowException(new FileSystemException(new Phrase('some message')));
-
- $tester = new CommandTester($this->command);
- $tester->execute([
- 'path' => 'some/path',
- 'value' => 'some value'
- ]);
-
- $this->assertEquals(
- Cli::RETURN_FAILURE,
- $tester->getStatusCode()
- );
- $this->assertContains(
- 'File app/etc/config.php can\'t be read. '
- . 'Please check if it exists and has read permissions.',
- $tester->getDisplay()
+ $this->model = new SensitiveConfigSetCommand(
+ $this->facadeMock,
+ $this->changeDetectorMock,
+ $this->hashMock
);
}
- public function testWriterException()
+ public function testExecute()
{
- $exceptionMessage = 'exception';
- $this->scopeValidatorMock->expects($this->once())
- ->method('isValid')
- ->with('default', '')
- ->willReturn(true);
- $this->commentParserMock->expects($this->once())
- ->method('execute')
- ->willReturn([
- 'some/config/path1',
- 'some/config/path2'
- ]);
- $collectorMock = $this->getMockBuilder(CollectorInterface::class)
- ->getMockForAbstractClass();
- $collectorMock->expects($this->once())
- ->method('getValues')
- ->willReturn(['some/config/pathNotExist' => 'value']);
- $this->collectorFactoryMock->expects($this->once())
- ->method('create')
- ->with(CollectorFactory::TYPE_SIMPLE)
- ->willReturn($collectorMock);
- $this->configWriterMock->expects($this->once())
- ->method('save')
- ->willThrowException(new LocalizedException(__($exceptionMessage)));
-
- $tester = new CommandTester($this->command);
- $tester->execute([
- 'path' => 'some/config/pathNotExist',
- 'value' => 'some value'
- ]);
+ $this->changeDetectorMock->expects($this->once())
+ ->method('hasChanges')
+ ->willReturn(false);
+ $this->facadeMock->expects($this->once())
+ ->method('process');
+ $this->hashMock->expects($this->once())
+ ->method('regenerate')
+ ->with(System::CONFIG_TYPE);
+
+ $tester = new CommandTester($this->model);
+ $tester->execute([]);
$this->assertEquals(
- Cli::RETURN_FAILURE,
+ Cli::RETURN_SUCCESS,
$tester->getStatusCode()
);
- $this->assertContains(
- $exceptionMessage,
- $tester->getDisplay()
- );
}
- public function testEmptyConfigPaths()
+ public function testExecuteNeedsRegeneration()
{
- $this->scopeValidatorMock->expects($this->once())
- ->method('isValid')
- ->with('default', '')
+ $this->changeDetectorMock->expects($this->once())
+ ->method('hasChanges')
->willReturn(true);
- $this->commentParserMock->expects($this->once())
- ->method('execute')
- ->willReturn([]);
+ $this->facadeMock->expects($this->never())
+ ->method('process');
+ $this->hashMock->expects($this->never())
+ ->method('regenerate');
- $tester = new CommandTester($this->command);
- $tester->execute([
- 'path' => 'some/config/pathNotExist',
- 'value' => 'some value'
- ]);
+ $tester = new CommandTester($this->model);
+ $tester->execute([]);
$this->assertEquals(
Cli::RETURN_FAILURE,
$tester->getStatusCode()
);
$this->assertContains(
- 'There are no sensitive configurations to fill',
+ 'This command is unavailable right now.',
$tester->getDisplay()
);
}
- public function testExecute()
+ public function testExecuteWithException()
{
- $collectedValues = ['some/config/path1' => 'value'];
- $this->scopeValidatorMock->expects($this->once())
- ->method('isValid')
- ->with('default', '')
- ->willReturn(true);
- $this->commentParserMock->expects($this->once())
- ->method('execute')
- ->willReturn([
- 'some/config/path1',
- 'some/config/path2'
- ]);
- $collectorMock = $this->getMockBuilder(CollectorInterface::class)
- ->getMockForAbstractClass();
- $collectorMock->expects($this->once())
- ->method('getValues')
- ->willReturn($collectedValues);
- $this->collectorFactoryMock->expects($this->once())
- ->method('create')
- ->with(CollectorFactory::TYPE_SIMPLE)
- ->willReturn($collectorMock);
- $this->configWriterMock->expects($this->once())
- ->method('save')
- ->with($collectedValues, ScopeConfigInterface::SCOPE_TYPE_DEFAULT, '');
-
- $tester = new CommandTester($this->command);
+ $this->changeDetectorMock->expects($this->once())
+ ->method('hasChanges')
+ ->willReturn(false);
+ $this->facadeMock->expects($this->once())
+ ->method('process')
+ ->willThrowException(new \Exception('Some exception'));
+
+ $tester = new CommandTester($this->model);
$tester->execute([]);
$this->assertEquals(
- Cli::RETURN_SUCCESS,
- $tester->getStatusCode()
- );
- $this->assertContains(
- 'Configuration value saved in',
- $tester->getDisplay()
- );
- }
-
- public function testExecuteInteractive()
- {
- $collectedValues = ['some/config/path1' => 'value'];
- $this->scopeValidatorMock->expects($this->once())
- ->method('isValid')
- ->with('default', '')
- ->willReturn(true);
- $this->commentParserMock->expects($this->once())
- ->method('execute')
- ->willReturn([
- 'some/config/path1',
- 'some/config/path2',
- 'some/config/path3'
- ]);
- $collectorMock = $this->getMockBuilder(CollectorInterface::class)
- ->getMockForAbstractClass();
- $collectorMock->expects($this->once())
- ->method('getValues')
- ->willReturn($collectedValues);
- $this->collectorFactoryMock->expects($this->once())
- ->method('create')
- ->with(CollectorFactory::TYPE_INTERACTIVE)
- ->willReturn($collectorMock);
- $this->configWriterMock->expects($this->once())
- ->method('save')
- ->with($collectedValues, ScopeConfigInterface::SCOPE_TYPE_DEFAULT, '');
-
- $tester = new CommandTester($this->command);
- $tester->execute(['--interactive' => true]);
-
- $this->assertEquals(
- Cli::RETURN_SUCCESS,
+ Cli::RETURN_FAILURE,
$tester->getStatusCode()
);
$this->assertContains(
- 'Configuration values saved in',
+ 'Some exception',
$tester->getDisplay()
);
}
diff --git a/dev/tests/integration/testsuite/Magento/Deploy/Console/Command/App/SensitiveConfigSetCommandTest.php b/dev/tests/integration/testsuite/Magento/Deploy/Console/Command/App/SensitiveConfigSetCommandTest.php
index abd35fd478c0d..40212c5e11563 100644
--- a/dev/tests/integration/testsuite/Magento/Deploy/Console/Command/App/SensitiveConfigSetCommandTest.php
+++ b/dev/tests/integration/testsuite/Magento/Deploy/Console/Command/App/SensitiveConfigSetCommandTest.php
@@ -7,6 +7,7 @@
use Magento\Deploy\Console\Command\App\SensitiveConfigSet\CollectorFactory;
use Magento\Deploy\Console\Command\App\SensitiveConfigSet\InteractiveCollector;
+use Magento\Deploy\Console\Command\App\SensitiveConfigSet\SensitiveConfigSetFacade;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\DeploymentConfig\FileReader;
use Magento\Framework\App\DeploymentConfig\Writer;
@@ -210,7 +211,12 @@ public function testExecuteInteractive($scope, $scopeCode, callable $assertCallb
$command = $this->objectManager->create(
SensitiveConfigSetCommand::class,
[
- 'collectorFactory' => $collectorFactoryMock
+ 'facade' => $this->objectManager->create(
+ SensitiveConfigSetFacade::class,
+ [
+ 'collectorFactory' => $collectorFactoryMock
+ ]
+ )
]
);
$command->run($inputMock, $outputMock);
diff --git a/dev/tests/integration/testsuite/Magento/Deploy/_files/config.php b/dev/tests/integration/testsuite/Magento/Deploy/_files/config.php
index 03476ae2e2c3a..8aa7d8fd617af 100644
--- a/dev/tests/integration/testsuite/Magento/Deploy/_files/config.php
+++ b/dev/tests/integration/testsuite/Magento/Deploy/_files/config.php
@@ -15,12 +15,7 @@
* CONFIG__DEFAULT__SOME__CONFIG__PATH_TWO for some/config/path_two
* CONFIG__DEFAULT__SOME__CONFIG__PATH_THREE for some/config/path_three
*/
- 'system' => [
- 'default' => [
- 'web' => [],
- 'general' => []
- ]
- ],
+ 'system' => [],
'integrationTestImporter' => [
'someGroup' => [
'someField' => 'testValue',
diff --git a/lib/internal/Magento/Framework/App/Config/Value.php b/lib/internal/Magento/Framework/App/Config/Value.php
index 7e2ed867e91e6..2f83205fc1cf0 100644
--- a/lib/internal/Magento/Framework/App/Config/Value.php
+++ b/lib/internal/Magento/Framework/App/Config/Value.php
@@ -78,10 +78,6 @@ public function __construct(
*/
public function isValueChanged()
{
- if ($this->getData('force_changed_value')) {
- return true;
- }
-
return $this->getValue() != $this->getOldValue();
}
diff --git a/app/code/Magento/Analytics/Model/FlagManager.php b/lib/internal/Magento/Framework/FlagManager.php
similarity index 50%
rename from app/code/Magento/Analytics/Model/FlagManager.php
rename to lib/internal/Magento/Framework/FlagManager.php
index 13390c3921b0c..05c2c1156a1d2 100644
--- a/app/code/Magento/Analytics/Model/FlagManager.php
+++ b/lib/internal/Magento/Framework/FlagManager.php
@@ -3,11 +3,9 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-namespace Magento\Analytics\Model;
+namespace Magento\Framework;
-use Magento\Framework\FlagFactory;
use Magento\Framework\Flag\FlagResource;
-use Magento\Framework\Flag;
/**
* Service that allows to handle a flag object as a scalar value.
@@ -15,19 +13,24 @@
class FlagManager
{
/**
+ * The factory of flags.
+ *
* @var FlagFactory
+ * @see Flag
*/
private $flagFactory;
/**
+ * The flag resource.
+ *
* @var FlagResource
*/
private $flagResource;
/**
- * FlagManager constructor.
- * @param FlagFactory $flagFactory
- * @param FlagResource $flagResource
+ *
+ * @param FlagFactory $flagFactory The factory of flags
+ * @param FlagResource $flagResource The flag resource
*/
public function __construct(
FlagFactory $flagFactory,
@@ -38,56 +41,65 @@ public function __construct(
}
/**
- * Return raw data from flag
- * @param string $flagCode
+ * Retrieves raw data from the flag.
+ *
+ * @param string $code The code of flag
* @return mixed
*/
- public function getFlagData($flagCode)
+ public function getFlagData($code)
{
- return $this->getFlagObject($flagCode)->getFlagData();
+ return $this->getFlagObject($code)->getFlagData();
}
/**
- * Save flag by code
- * @param string $flagCode
- * @param mixed $value
+ * Saves the flag value by code.
+ *
+ * @param string $code The code of flag
+ * @param mixed $value The value of flag
* @return bool
*/
- public function saveFlag($flagCode, $value)
+ public function saveFlag($code, $value)
{
- $flag = $this->getFlagObject($flagCode);
+ $flag = $this->getFlagObject($code);
$flag->setFlagData($value);
$this->flagResource->save($flag);
+
return true;
}
/**
- * Delete flag by code
+ * Deletes the flag by code.
*
- * @param string $flagCode
+ * @param string $code The code of flag
* @return bool
*/
- public function deleteFlag($flagCode)
+ public function deleteFlag($code)
{
- $flag = $this->getFlagObject($flagCode);
+ $flag = $this->getFlagObject($code);
+
if ($flag->getId()) {
$this->flagResource->delete($flag);
}
+
return true;
}
/**
* Returns flag object
*
- * @param string $flagCode
+ * @param string $code
* @return Flag
*/
- private function getFlagObject($flagCode)
+ private function getFlagObject($code)
{
/** @var Flag $flag */
- $flag = $this->flagFactory
- ->create(['data' => ['flag_code' => $flagCode]]);
- $this->flagResource->load($flag, $flagCode, 'flag_code');
+ $flag = $this->flagFactory->create(['data' => ['flag_code' => $code]]);
+ $this->flagResource->load(
+ $flag,
+ $code,
+ 'flag_code'
+ );
+
return $flag;
}
}
diff --git a/app/code/Magento/Analytics/Test/Unit/Model/FlagManagerTest.php b/lib/internal/Magento/Framework/Test/Unit/FlagManagerTest.php
similarity index 78%
rename from app/code/Magento/Analytics/Test/Unit/Model/FlagManagerTest.php
rename to lib/internal/Magento/Framework/Test/Unit/FlagManagerTest.php
index 7143d398c9dc4..1aaabbbf78b2e 100644
--- a/app/code/Magento/Analytics/Test/Unit/Model/FlagManagerTest.php
+++ b/lib/internal/Magento/Framework/Test/Unit/FlagManagerTest.php
@@ -3,12 +3,13 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-namespace Magento\Analytics\Test\Unit\Model;
+namespace Magento\Framework\Test\Unit;
-use Magento\Analytics\Model\FlagManager;
use Magento\Framework\FlagFactory;
use Magento\Framework\Flag\FlagResource;
use Magento\Framework\Flag;
+use Magento\Framework\FlagManager;
+use PHPUnit_Framework_MockObject_MockObject as Mock;
/**
* Class FlagManagerTest
@@ -16,36 +17,40 @@
class FlagManagerTest extends \PHPUnit_Framework_TestCase
{
/**
- * @var FlagFactory|\PHPUnit_Framework_MockObject_MockObject
+ * @var FlagFactory|Mock
*/
private $flagFactoryMock;
/**
- * @var FlagManager
+ * @var Flag|Mock
*/
- private $flagManager;
+ private $flagMock;
/**
- * @var Flag|\PHPUnit_Framework_MockObject_MockObject
+ * @var FlagResource|Mock
*/
- private $flagMock;
+ private $flagResourceMock;
/**
- * @var FlagResource|\PHPUnit_Framework_MockObject_MockObject
+ * @var FlagManager
*/
- private $flagResourceMock;
+ private $flagManager;
+ /**
+ * @inheritdoc
+ */
protected function setUp()
{
- $this->flagFactoryMock = $this->getMockBuilder(FlagFactory::class)
+ $this->flagFactoryMock = $this->getMockBuilder(FlagFactory::class)
->disableOriginalConstructor()
->getMock();
- $this->flagResourceMock = $this->getMockBuilder(FlagResource::class)
+ $this->flagResourceMock = $this->getMockBuilder(FlagResource::class)
->disableOriginalConstructor()
->getMock();
- $this->flagMock = $this->getMockBuilder(Flag::class)
+ $this->flagMock = $this->getMockBuilder(Flag::class)
->disableOriginalConstructor()
->getMock();
+
$this->flagManager = new FlagManager(
$this->flagFactoryMock,
$this->flagResourceMock
@@ -54,17 +59,18 @@ protected function setUp()
public function testGetFlagData()
{
- $flagCode = "flag";
+ $flagCode = 'flag';
$this->setupFlagObject($flagCode);
$this->flagMock->expects($this->once())
->method('getFlagData')
->willReturn(10);
+
$this->assertEquals($this->flagManager->getFlagData($flagCode), 10);
}
public function testSaveFlag()
{
- $flagCode = "flag";
+ $flagCode = 'flag';
$this->setupFlagObject($flagCode);
$this->flagMock->expects($this->once())
->method('setFlagData')
@@ -72,7 +78,10 @@ public function testSaveFlag()
$this->flagResourceMock->expects($this->once())
->method('save')
->with($this->flagMock);
- $this->assertTrue($this->flagManager->saveFlag($flagCode, 10));
+
+ $this->assertTrue(
+ $this->flagManager->saveFlag($flagCode, 10)
+ );
}
/**
@@ -82,19 +91,25 @@ public function testSaveFlag()
*/
public function testDeleteFlag($isFlagExist)
{
- $flagCode = "flag";
+ $flagCode = 'flag';
+
$this->setupFlagObject($flagCode);
+
$this->flagMock
->expects($this->once())
->method('getId')
->willReturn($isFlagExist);
+
if ($isFlagExist) {
$this->flagResourceMock
->expects($this->once())
->method('delete')
->with($this->flagMock);
}
- $this->assertTrue($this->flagManager->deleteFlag($flagCode));
+
+ $this->assertTrue(
+ $this->flagManager->deleteFlag($flagCode)
+ );
}
private function setupFlagObject($flagCode)