Skip to content

Commit 6b8d561

Browse files
author
Bohdan Korablov
committed
Merge remote-tracking branch 'falcons/MAGETWO-63382' into MAGETWO-63936-2
# Conflicts: # app/code/Magento/Config/etc/di.xml # lib/internal/Magento/Framework/App/Config/ConfigPathResolver.php
2 parents 4d36a95 + d0a018d commit 6b8d561

File tree

14 files changed

+1316
-12
lines changed

14 files changed

+1316
-12
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
/**
3+
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Config\App\Config\Source;
7+
8+
use Magento\Framework\App\Config\ConfigSourceInterface;
9+
use Magento\Framework\DataObject;
10+
use Magento\Config\Model\Placeholder\PlaceholderFactory;
11+
use Magento\Config\Model\Placeholder\PlaceholderInterface;
12+
use Magento\Framework\Stdlib\ArrayManager;
13+
14+
/**
15+
* Class for retrieving configurations from environment variables.
16+
*/
17+
class EnvironmentConfigSource implements ConfigSourceInterface
18+
{
19+
/**
20+
* Library for working with arrays.
21+
*
22+
* @var ArrayManager
23+
*/
24+
private $arrayManager;
25+
26+
/**
27+
* Object for working with placeholders for environment variables.
28+
*
29+
* @var PlaceholderInterface
30+
*/
31+
private $placeholder;
32+
33+
/**
34+
* @param ArrayManager $arrayManager
35+
* @param PlaceholderFactory $placeholderFactory
36+
*/
37+
public function __construct(
38+
ArrayManager $arrayManager,
39+
PlaceholderFactory $placeholderFactory
40+
) {
41+
$this->arrayManager = $arrayManager;
42+
$this->placeholder = $placeholderFactory->create(PlaceholderFactory::TYPE_ENVIRONMENT);
43+
}
44+
45+
/**
46+
* @inheritdoc
47+
*/
48+
public function get($path = '')
49+
{
50+
$data = new DataObject($this->loadConfig());
51+
return $data->getData($path) ?: [];
52+
}
53+
54+
/**
55+
* Loads config from environment variables.
56+
*
57+
* @return array
58+
*/
59+
private function loadConfig()
60+
{
61+
$config = [];
62+
63+
$environmentVariables = $_ENV;
64+
65+
foreach ($environmentVariables as $template => $value) {
66+
if (!$this->placeholder->isApplicable($template)) {
67+
continue;
68+
}
69+
70+
$config = $this->arrayManager->set(
71+
$this->placeholder->restore($template),
72+
$config,
73+
$value
74+
);
75+
}
76+
77+
return $config;
78+
}
79+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
/**
3+
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Config\Console\Command\ConfigShow;
7+
8+
use Magento\Framework\App\Config\Value;
9+
use Magento\Framework\App\Config\ValueFactory;
10+
use Magento\Config\Model\Config\Structure;
11+
use Magento\Config\Model\Config\StructureFactory;
12+
use Magento\Config\Model\Config\Structure\Element\Field;
13+
use Magento\Framework\Config\ScopeInterface;
14+
use Magento\Framework\App\Area;
15+
16+
/**
17+
* Class processes values using backend model which declared in system.xml.
18+
*/
19+
class ValueProcessor
20+
{
21+
/**
22+
* System configuration structure factory.
23+
*
24+
* @var StructureFactory
25+
*/
26+
private $configStructureFactory;
27+
28+
/**
29+
* Factory of object that implement \Magento\Framework\App\Config\ValueInterface.
30+
*
31+
* @var ValueFactory
32+
*/
33+
private $configValueFactory;
34+
35+
/**
36+
* Object for managing configuration scope.
37+
*
38+
* @var ScopeInterface
39+
*/
40+
private $scope;
41+
42+
/**
43+
* @param ScopeInterface $scope
44+
* @param StructureFactory $structureFactory
45+
* @param ValueFactory $valueFactory
46+
*/
47+
public function __construct(
48+
ScopeInterface $scope,
49+
StructureFactory $structureFactory,
50+
ValueFactory $valueFactory
51+
) {
52+
$this->scope = $scope;
53+
$this->configStructureFactory = $structureFactory;
54+
$this->configValueFactory = $valueFactory;
55+
}
56+
57+
/**
58+
* Processes value using backend model.
59+
*
60+
* @param string $scope The scope of configuration. E.g. 'default', 'website' or 'store'
61+
* @param string $scopeCode The scope code of configuration
62+
* @param string $value The value to process
63+
* @param string $path The configuration path for getting backend model. E.g. scope_id/group_id/field_id
64+
* @return string processed value result
65+
*/
66+
public function process($scope, $scopeCode, $value, $path)
67+
{
68+
$areaScope = $this->scope->getCurrentScope();
69+
$this->scope->setCurrentScope(Area::AREA_ADMINHTML);
70+
/** @var Structure $configStructure */
71+
$configStructure = $this->configStructureFactory->create();
72+
$this->scope->setCurrentScope($areaScope);
73+
74+
/** @var Field $field */
75+
$field = $configStructure->getElement($path);
76+
77+
/** @var Value $backendModel */
78+
$backendModel = $field && $field->hasBackendModel()
79+
? $field->getBackendModel()
80+
: $this->configValueFactory->create();
81+
$backendModel->setPath($path);
82+
$backendModel->setScope($scope);
83+
$backendModel->setScopeId($scopeCode);
84+
$backendModel->setValue($value);
85+
$backendModel->afterLoad();
86+
87+
return $backendModel->getValue();
88+
}
89+
}
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
<?php
2+
/**
3+
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Config\Console\Command;
7+
8+
use Magento\Framework\App\Config\ConfigSourceInterface;
9+
use Magento\Framework\App\Config\ScopeConfigInterface;
10+
use Magento\Framework\App\Config\ConfigPathResolver;
11+
use Magento\Framework\Exception\LocalizedException;
12+
use Symfony\Component\Console\Command\Command;
13+
use Magento\Framework\App\Scope\ValidatorInterface;
14+
use Symfony\Component\Console\Input\InputInterface;
15+
use Symfony\Component\Console\Output\OutputInterface;
16+
use Symfony\Component\Console\Input\InputArgument;
17+
use Symfony\Component\Console\Input\InputOption;
18+
use Magento\Framework\Console\Cli;
19+
use Magento\Config\Console\Command\ConfigShow\ValueProcessor;
20+
21+
/**
22+
* Command provides possibility to show saved system configuration.
23+
*/
24+
class ConfigShowCommand extends Command
25+
{
26+
/**#@+
27+
* Names of input arguments or options.
28+
*/
29+
const INPUT_OPTION_SCOPE = 'scope';
30+
const INPUT_OPTION_SCOPE_CODE = 'scope-code';
31+
const INPUT_ARGUMENT_PATH = 'path';
32+
/**#@-*/
33+
34+
/**
35+
* Scope validator.
36+
*
37+
* @var ValidatorInterface
38+
*/
39+
private $scopeValidator;
40+
41+
/**
42+
* Source of configurations.
43+
*
44+
* @var ConfigSourceInterface
45+
*/
46+
private $configSource;
47+
48+
/**
49+
* Config path resolver.
50+
*
51+
* @var ConfigPathResolver
52+
*/
53+
private $pathResolver;
54+
55+
/**
56+
* Class for processing value using backend model.
57+
*
58+
* @var ValueProcessor
59+
*/
60+
private $valueProcessor;
61+
62+
/**
63+
* The scope of configuration.
64+
*
65+
* @var string
66+
*/
67+
private $scope;
68+
69+
/**
70+
* The scope code of configuration.
71+
*
72+
* @var string
73+
*/
74+
private $scopeCode;
75+
76+
/**
77+
* The configuration path.
78+
*
79+
* @var string
80+
*/
81+
private $inputPath;
82+
83+
/**
84+
* @param ValidatorInterface $scopeValidator
85+
* @param ConfigSourceInterface $configSource
86+
* @param ConfigPathResolver $pathResolver
87+
* @param ValueProcessor $valueProcessor
88+
* @internal param ScopeConfigInterface $appConfig
89+
*/
90+
public function __construct(
91+
ValidatorInterface $scopeValidator,
92+
ConfigSourceInterface $configSource,
93+
ConfigPathResolver $pathResolver,
94+
ValueProcessor $valueProcessor
95+
) {
96+
parent::__construct();
97+
$this->scopeValidator = $scopeValidator;
98+
$this->configSource = $configSource;
99+
$this->pathResolver = $pathResolver;
100+
$this->valueProcessor = $valueProcessor;
101+
}
102+
103+
/**
104+
* @inheritdoc
105+
*/
106+
protected function configure()
107+
{
108+
$this->addArgument(
109+
self::INPUT_ARGUMENT_PATH,
110+
InputArgument::OPTIONAL,
111+
'Configuration path, for example section_id/group_id/field_id'
112+
);
113+
$this->addOption(
114+
self::INPUT_OPTION_SCOPE,
115+
null,
116+
InputOption::VALUE_OPTIONAL,
117+
'Scope for configuration, if not specified, then \'default\' scope will be used',
118+
ScopeConfigInterface::SCOPE_TYPE_DEFAULT
119+
);
120+
$this->addOption(
121+
self::INPUT_OPTION_SCOPE_CODE,
122+
null,
123+
InputOption::VALUE_OPTIONAL,
124+
'Scope code (required only if scope is not `default`)',
125+
''
126+
);
127+
$this->setName('config:show')
128+
->setDescription(
129+
'Shows configuration value for given path. If path is not specified, all saved values will be shown'
130+
);
131+
parent::configure();
132+
}
133+
134+
/**
135+
* Displays configuration value for given configuration path.
136+
*
137+
* Shows error message if configuration for given path doesn't exist
138+
* or scope/scope-code doesn't pass validation.
139+
*
140+
* {@inheritdoc}
141+
*/
142+
protected function execute(InputInterface $input, OutputInterface $output)
143+
{
144+
try {
145+
$this->scope = $input->getOption(self::INPUT_OPTION_SCOPE);
146+
$this->scopeCode = $input->getOption(self::INPUT_OPTION_SCOPE_CODE);
147+
$this->inputPath = $input->getArgument(self::INPUT_ARGUMENT_PATH);
148+
149+
$this->scopeValidator->isValid($this->scope, $this->scopeCode);
150+
$configPath = $this->pathResolver->resolve($this->inputPath, $this->scope, $this->scopeCode);
151+
$configValue = $this->configSource->get($configPath);
152+
153+
if (empty($configValue)) {
154+
$output->writeln(sprintf(
155+
'<error>%s</error>',
156+
__('Configuration for path: "%1" doesn\'t exist', $this->inputPath)->render()
157+
));
158+
return Cli::RETURN_FAILURE;
159+
}
160+
161+
$this->outputResult($output, $configValue, $this->inputPath);
162+
return Cli::RETURN_SUCCESS;
163+
} catch (\Exception $e) {
164+
$output->writeln(sprintf('<error>%s</error>', $e->getMessage()));
165+
return Cli::RETURN_FAILURE;
166+
}
167+
}
168+
169+
/**
170+
* Outputs single configuration value or list of values if array given.
171+
*
172+
* @param OutputInterface $output an OutputInterface instance
173+
* @param string|array $configValue can be string when $configPath is a path for concreate field.
174+
* In other cases $configValue should be an array
175+
* ```php
176+
* [
177+
* 'section' =>
178+
* [
179+
* 'group1' =>
180+
* [
181+
* 'field1' => 'value1',
182+
* 'field2' => 'value2'
183+
* ],
184+
* 'group2' =>
185+
* [
186+
* 'field1' => 'value3'
187+
* ]
188+
* ]
189+
* ]
190+
* ```
191+
* @param string $configPath base configuration path
192+
* @return void
193+
*/
194+
private function outputResult(OutputInterface $output, $configValue, $configPath)
195+
{
196+
if (!is_array($configValue)) {
197+
$value = $this->valueProcessor->process($this->scope, $this->scopeCode, $configValue, $configPath);
198+
$output->writeln($this->inputPath === $configPath ? $value : sprintf("%s - %s", $configPath, $value));
199+
} elseif (is_array($configValue)) {
200+
foreach ($configValue as $name => $value) {
201+
$childPath = empty($configPath) ? $name : ($configPath . '/' . $name);
202+
$this->outputResult($output, $value, $childPath);
203+
}
204+
}
205+
}
206+
}

0 commit comments

Comments
 (0)