Update Composer, update everything
This commit is contained in:
parent
ea3e94409f
commit
dda5c284b6
19527 changed files with 1135420 additions and 351004 deletions
15
vendor/consolidation/config/.editorconfig
vendored
Normal file
15
vendor/consolidation/config/.editorconfig
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
# This file is for unifying the coding style for different editors and IDEs
|
||||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[**.php]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
51
vendor/consolidation/config/CHANGELOG.md
vendored
Normal file
51
vendor/consolidation/config/CHANGELOG.md
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
# Changelog
|
||||
|
||||
### 1.0.11 2018-05-26
|
||||
|
||||
* BUGFIX: Ensure that duplicate keys added to different contexts in a config overlay only appear once in the final export. (#21)
|
||||
|
||||
### 1.0.10 2018-05-25
|
||||
|
||||
* Rename g-1-a/composer-test-scenarios to g1a/composer-test-scenarios (#20)
|
||||
|
||||
### 1.0.9 2017-12-22
|
||||
|
||||
* Make yaml component optional. (#17)
|
||||
|
||||
### 1.0.8 2017-12-16
|
||||
|
||||
* Use test scenarios to test multiple versions of Symfony. (#14) & (#15)
|
||||
* Fix defaults to work with DotAccessData by thomscode (#13)
|
||||
|
||||
### 1.0.7 2017-10-24
|
||||
|
||||
* Deprecate Config::import(); recommand Config::replace() instead.
|
||||
|
||||
### 1.0.6 10/17/2017
|
||||
|
||||
* Add a 'Config::combine()' method for importing without overwriting.
|
||||
* Factor out ArrayUtil as a reusable utility class.
|
||||
|
||||
### 1.0.4 10/16/2017
|
||||
|
||||
* BUGFIX: Go back to injecting boolean options only if their value is 'true'.
|
||||
|
||||
### 1.0.3 10/04/2017
|
||||
|
||||
* Add an EnvConfig utility class.
|
||||
* BUGFIX: Fix bug in envKey calculation: it was missing its prefix.
|
||||
* BUGFIX: Export must always return something.
|
||||
* BUGFIX: Pass reference array through to Expander class.
|
||||
|
||||
### 1.0.2 09/16/2017
|
||||
|
||||
* BUGFIX: Allow global boolean options to have either `true` or `false` initial values.
|
||||
|
||||
### 1.0.1 07/28/2017
|
||||
|
||||
* Inject default values into InputOption objects when 'help' command executed.
|
||||
|
||||
### 1.0.0 06/28/2017
|
||||
|
||||
* Initial release
|
||||
|
31
vendor/consolidation/config/CONTRIBUTING.md
vendored
Normal file
31
vendor/consolidation/config/CONTRIBUTING.md
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
# Contributing to Consolidation
|
||||
|
||||
Thank you for your interest in contributing to the Consolidation effort! Consolidation aims to provide reusable, loosely-coupled components useful for building command-line tools. Consolidation is built on top of Symfony Console, but aims to separate the tool from the implementation details of Symfony.
|
||||
|
||||
Here are some of the guidelines you should follow to make the most of your efforts:
|
||||
|
||||
## Code Style Guidelines
|
||||
|
||||
Consolidation adheres to the [PSR-2 Coding Style Guide](http://www.php-fig.org/psr/psr-2/) for PHP code.
|
||||
|
||||
## Pull Request Guidelines
|
||||
|
||||
Every pull request is run through:
|
||||
|
||||
- phpcs -n --standard=PSR2 src
|
||||
- phpunit
|
||||
- [Scrutinizer](https://scrutinizer-ci.com/g/consolidation/config/)
|
||||
|
||||
It is easy to run the unit tests and code sniffer locally; just run:
|
||||
|
||||
- composer cs
|
||||
|
||||
To run the code beautifier, which will fix many of the problems reported by phpcs:
|
||||
|
||||
- composer cbf
|
||||
|
||||
These two commands (`composer cs` and `composer cbf`) are defined in the `scripts` section of [composer.json](composer.json).
|
||||
|
||||
After submitting a pull request, please examine the Scrutinizer report. It is not required to fix all Scrutinizer issues; you may ignore recommendations that you disagree with. The spacing patches produced by Scrutinizer do not conform to PSR2 standards, and therefore should never be applied. DocBlock patches may be applied at your discression. Things that Scrutinizer identifies as a bug nearly always need to be addressed.
|
||||
|
||||
Pull requests must pass phpcs and phpunit in order to be merged; ideally, new functionality will also include new unit tests.
|
8
vendor/consolidation/config/LICENSE
vendored
Normal file
8
vendor/consolidation/config/LICENSE
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
Copyright (c) 2017 Consolidation Developers
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
224
vendor/consolidation/config/README.md
vendored
Normal file
224
vendor/consolidation/config/README.md
vendored
Normal file
|
@ -0,0 +1,224 @@
|
|||
# Consolidation\Config
|
||||
|
||||
Manage configuration for a commandline tool.
|
||||
|
||||
[](https://travis-ci.org/consolidation/config)
|
||||
[](https://scrutinizer-ci.com/g/consolidation/config/?branch=master)
|
||||
[](https://coveralls.io/github/consolidation/config?branch=master)
|
||||
[](https://packagist.org/packages/consolidation/config)
|
||||
|
||||
This component is designed to provide the components needed to manage configuration options from different sources, including:
|
||||
|
||||
- Commandline options
|
||||
- Configuration files
|
||||
- Alias files (special configuration files that identify a specific target site)
|
||||
- Default values (provided by command)
|
||||
|
||||
Symfony Console is used to provide the framework for the commandline tool, and the Symfony Configuration component is used to load and merge configuration files. This project provides the glue that binds the components together in an easy-to-use package.
|
||||
|
||||
If your goal is to be able to quickly write configurable commandline tools, you might want to consider using [Robo as a Framework](https://robo.li/framework), as the work for setting up this component is already done in that project. Consolidation/Config may be used with any Symfony Console application, though.
|
||||
|
||||
## Component Status
|
||||
|
||||
In use in Robo (1.x), Terminus (1.x) and Drush (9.x).
|
||||
|
||||
## Motivation
|
||||
|
||||
Provide a simple Config class that can be injected where needed to provide configuration values in non-command classes, and make configuration settings a no-op for command classes by automatically initializing the Input object from configuration as needed.
|
||||
|
||||
## Configuration File Usage
|
||||
|
||||
Configuration files are simple hierarchical yaml files.
|
||||
|
||||
### Providing Command Options
|
||||
|
||||
Command options are defined by creating an entry for each command name under the `command:` section of the configuration file. The options for the command should be defined within an `options:` section. For example, to set a configuration value `red` for the option `--color` in the `example` command:
|
||||
```
|
||||
command:
|
||||
example:
|
||||
options:
|
||||
color: red
|
||||
```
|
||||
If a command name contains a `:`, then each section of the command name defines another level of heirarchy in the command option configuration. For example, to set a configuration value `George` for the option `--name` of the command `my:foo`:
|
||||
```
|
||||
command:
|
||||
my:
|
||||
foo:
|
||||
options:
|
||||
name: George
|
||||
```
|
||||
Furthermore, every level of the command name heirarchy may contain options. For example, to define a configuration value for the option `--dir` for any command that begins with `my:`:
|
||||
```
|
||||
command:
|
||||
my:
|
||||
options:
|
||||
dir: '/base/path'
|
||||
foo:
|
||||
options:
|
||||
name: George
|
||||
bar:
|
||||
options:
|
||||
priority: high
|
||||
```
|
||||
|
||||
### Providing Global Options
|
||||
|
||||
If your Symfony Console application defines global options, like so (from a method in an extension of the Application class):
|
||||
```
|
||||
$this->getDefinition()
|
||||
->addOption(
|
||||
new InputOption('--simulate', null, InputOption::VALUE_NONE, 'Run in simulated mode (show what would have happened).')
|
||||
);
|
||||
```
|
||||
Default values for global options can then be declared in the global options section:
|
||||
```
|
||||
options:
|
||||
simulate: false
|
||||
```
|
||||
If this is done, then global option values set on the command line will be used to alter the value of the configuration item at runtime. For example, `$config->get('options.simulate')` will return `false` when the `--simulate` global option is not used, and will return `true` when it is.
|
||||
|
||||
See the section "Set Up Command Option Configuration Injection", below, for instructions on how to enable this setup.
|
||||
|
||||
### Configuration Value Substitution
|
||||
|
||||
It is possible to define values in a configuration file that will be substituted in wherever used. For example:
|
||||
```
|
||||
common:
|
||||
path: '/shared/path'
|
||||
command:
|
||||
my:
|
||||
options:
|
||||
dir: '${common.path}'
|
||||
foo:
|
||||
options:
|
||||
name: George
|
||||
```
|
||||
|
||||
[grasmash/yaml-expander](https://github.com/grasmash/expander) is used to provide this capability.
|
||||
|
||||
## API Usage
|
||||
|
||||
The easiest way to utilize the capabilities of this project is to use [Robo as a framework](https://robo.li/framework) to create your commandline tools. Using Robo is optional, though, as this project will work with any Symfony Console application.
|
||||
|
||||
### Load Configuration Files with Provided Loader
|
||||
|
||||
Consolidation/config includes a built-in yaml loader / processor. To use it directly, use a YamlConfigLoader to load each of your configuration files, and a ConfigProcessor to merge them together. Then, export the result from the configuration processor, and import it into a Config object.
|
||||
```
|
||||
use Consolidation\Config\Config;
|
||||
use Consolidation\Config\YamlConfigLoader;
|
||||
use Consolidation\Config\ConfigProcessor;
|
||||
|
||||
$config = new Config();
|
||||
$loader = new YamlConfigLoader();
|
||||
$processor = new ConfigProcessor();
|
||||
$processor->extend($loader->load('defaults.yml'));
|
||||
$processor->extend($loader->load('myconf.yml'));
|
||||
$config->import($processor->export());
|
||||
```
|
||||
|
||||
### Set Up Command Option Configuration Injection
|
||||
|
||||
The command option configuration feature described above in the section `Providing Command Options` is provided via a configuration injection class. All that you need to do to use this feature as attach this object to your Symfony Console application's event dispatcher:
|
||||
```
|
||||
$application = new Symfony\Component\Console\Application($name, $version);
|
||||
$configInjector = new \Consolidation\Config\Inject\ConfigForCommand($config);
|
||||
$configInjector->setApplication($application);
|
||||
|
||||
$eventDispatcher = new \Symfony\Component\EventDispatcher\EventDispatcher();
|
||||
$eventDispatcher->addSubscriber($configInjector);
|
||||
$application->setDispatcher($eventDispatcher);
|
||||
```
|
||||
|
||||
|
||||
### Get Configuration Values
|
||||
|
||||
If you have a configuration file that looks like this:
|
||||
```
|
||||
a:
|
||||
b:
|
||||
c: foo
|
||||
```
|
||||
Then you can fetch the value of the configuration option `c` via:
|
||||
```
|
||||
$value = $config->get('a.b.c');
|
||||
```
|
||||
[dflydev/dot-access-data](https://github.com/dflydev/dot-access-data) is leveraged to provide this capability.
|
||||
|
||||
### Interpolation
|
||||
|
||||
Interpolation allows configuration values to be injected into a string with tokens. The tokens are used as keys that are looked up in the config object; the resulting configuration values will be used to replace the tokens in the provided string.
|
||||
|
||||
For example, using the same configuration file shown above:
|
||||
```
|
||||
$result = $config->interpolate('The value is: {{a.b.c}}')
|
||||
```
|
||||
In this example, the `$result` string would be:
|
||||
```
|
||||
The value is: foo
|
||||
```
|
||||
|
||||
### Configuration Overlays
|
||||
|
||||
Optionally, you may use the ConfigOverlay class to combine multiple configuration objects implamenting ConfigInterface into a single, prioritized configuration object. It is not necessary to use a configuration overlay; if your only goal is to merge configuration from multiple files, you may follow the example above to extend a processor with multiple configuration files, and then import the result into a single configuration object. This will cause newer configuration items to overwrite any existing values stored under the same key.
|
||||
|
||||
A configuration overlay can achieve the same end result without overwriting any config values. The advantage of doing this is that different configuration overlays could be used to create separate "views" on different collections of configuration. A configuration overlay is also useful if you wish to temporarily override some configuration values, and then put things back the way they were by removing the overlay.
|
||||
```
|
||||
use Consolidation\Config\Config;
|
||||
use Consolidation\Config\YamlConfigLoader;
|
||||
use Consolidation\Config\ConfigProcessor;
|
||||
use Consolidation\Config\Util\ConfigOverlay;
|
||||
|
||||
$config1 = new Config();
|
||||
$config2 = new Config();
|
||||
$loader = new YamlConfigLoader();
|
||||
$processor = new ConfigProcessor();
|
||||
$processor->extend($loader->load('c1.yml'));
|
||||
$config1->import($processor->export());
|
||||
$processor = new ConfigProcessor();
|
||||
$processor->extend($loader->load('c2.yml'));
|
||||
$config2->import($processor->export());
|
||||
|
||||
$configOverlay = (new ConfigOverlay())
|
||||
->addContext('one', $config1)
|
||||
->addContext('two', $config2);
|
||||
|
||||
$value = $configOverlay->get('key');
|
||||
|
||||
$configOverlay->removeContext('two');
|
||||
|
||||
$value = $configOverlay->get('key');
|
||||
```
|
||||
The first call to `$configOverlay->get('key')`, above, will return the value from `key` in `$config2`, if it exists, or from `$config1` otherwise. The second call to the same function, after `$config2` is removed, will only consider configuration values stored in `$config1`.
|
||||
|
||||
## External Examples
|
||||
|
||||
### Load Configuration Files with Symfony/Config
|
||||
|
||||
The [Symfony Config](http://symfony.com/doc/current/components/config.html) component provides the capability to locate configuration file, load them from either YAML or XML sources, and validate that they match a certain defined schema. Classes to find configuration files are also available.
|
||||
|
||||
If these features are needed, the results from `Symfony\Component\Config\Definition\Processor::processConfiguration()` may be provided directly to the `Consolidation\Config\Config::import()` method.
|
||||
|
||||
### Use Configuration to Call Setter Methods
|
||||
|
||||
[Robo](https://robo.li) provides a facility for configuration files to [define default values for task setter methods](http://robo.li/getting-started/#configuration-for-task-settings). This is done via the `ConfigForSetters::apply()` method.
|
||||
```
|
||||
$taskClass = static::configClassIdentifier($taskClass);
|
||||
$configurationApplier = new \Consolidation\Config\Inject\ConfigForSetters($this->getConfig(), $taskClass, 'task.');
|
||||
$configurationApplier->apply($task, 'settings');
|
||||
```
|
||||
The `configClassIdentifier` method converts `\`-separated class and namespace names into `.`-separated identifiers; it is provided by ConfigAwareTrait:
|
||||
```
|
||||
protected static function configClassIdentifier($classname)
|
||||
{
|
||||
$configIdentifier = strtr($classname, '\\', '.');
|
||||
$configIdentifier = preg_replace('#^(.*\.Task\.|\.)#', '', $configIdentifier);
|
||||
|
||||
return $configIdentifier;
|
||||
}
|
||||
```
|
||||
A similar pattern may be used in other applications that may wish to inject values into objects using their setter methods.
|
||||
|
||||
## Comparison to Existing Solutions
|
||||
|
||||
Drush has an existing procedural mechanism for loading configuration values from multiple files, and overlaying the results in priority order. Command-specific options from configuration files and site aliases may also be applied.
|
||||
|
68
vendor/consolidation/config/composer.json
vendored
Normal file
68
vendor/consolidation/config/composer.json
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"name": "consolidation/config",
|
||||
"description": "Provide configuration services for a commandline tool.",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Greg Anderson",
|
||||
"email": "greg.1.anderson@greenknowe.org"
|
||||
}
|
||||
],
|
||||
"autoload":{
|
||||
"psr-4":{
|
||||
"Consolidation\\Config\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Consolidation\\TestUtils\\": "tests/src"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4.0",
|
||||
"dflydev/dot-access-data": "^1.1.0",
|
||||
"grasmash/expander": "^1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5",
|
||||
"g1a/composer-test-scenarios": "^1",
|
||||
"symfony/console": "^2.5|^3|^4",
|
||||
"symfony/yaml": "^2.8.11|^3|^4",
|
||||
"satooshi/php-coveralls": "^1.0",
|
||||
"squizlabs/php_codesniffer": "2.*"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/yaml": "Required to use Consolidation\\Config\\Loader\\YamlConfigLoader"
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"sort-packages": true,
|
||||
"platform": {
|
||||
"php": "5.6"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"cs": "phpcs --standard=PSR2 -n src",
|
||||
"cbf": "phpcbf --standard=PSR2 -n src",
|
||||
"unit": "SHELL_INTERACTIVE=true phpunit --colors=always",
|
||||
"lint": [
|
||||
"find src -name '*.php' -print0 | xargs -0 -n1 php -l",
|
||||
"find tests/src -name '*.php' -print0 | xargs -0 -n1 php -l"
|
||||
],
|
||||
"test": [
|
||||
"@lint",
|
||||
"@unit",
|
||||
"@cs"
|
||||
],
|
||||
"scenario": "scenarios/install",
|
||||
"post-update-cmd": [
|
||||
"create-scenario symfony4 'symfony/console:^4.0'",
|
||||
"create-scenario symfony2 'symfony/console:^2.8' 'phpunit/phpunit:^4' --platform-php '5.4' --no-lockfile"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
2231
vendor/consolidation/config/composer.lock
generated
vendored
Normal file
2231
vendor/consolidation/config/composer.lock
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
19
vendor/consolidation/config/phpunit.xml.dist
vendored
Normal file
19
vendor/consolidation/config/phpunit.xml.dist
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
<phpunit bootstrap="vendor/autoload.php" colors="true">
|
||||
<testsuites>
|
||||
<testsuite name="config">
|
||||
<directory prefix="" suffix="Test.php">tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<logging>
|
||||
<!--
|
||||
<log type="coverage-html" target="build/logs/coverage" lowUpperBound="35"
|
||||
highLowerBound="70"/>
|
||||
-->
|
||||
<log type="coverage-clover" target="build/logs/clover.xml"/>
|
||||
</logging>
|
||||
<filter>
|
||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||
<directory suffix=".php">src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
160
vendor/consolidation/config/src/Config.php
vendored
Normal file
160
vendor/consolidation/config/src/Config.php
vendored
Normal file
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
|
||||
namespace Consolidation\Config;
|
||||
|
||||
use Dflydev\DotAccessData\Data;
|
||||
use Consolidation\Config\Util\ConfigInterpolatorInterface;
|
||||
use Consolidation\Config\Util\ConfigInterpolatorTrait;
|
||||
|
||||
class Config implements ConfigInterface, ConfigInterpolatorInterface
|
||||
{
|
||||
use ConfigInterpolatorTrait;
|
||||
|
||||
/**
|
||||
* @var Data
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* TODO: make this private in 2.0 to prevent being saved as an array
|
||||
* Making private now breaks backward compatibility
|
||||
*
|
||||
* @var Data
|
||||
*/
|
||||
protected $defaults;
|
||||
|
||||
/**
|
||||
* Create a new configuration object, and initialize it with
|
||||
* the provided nested array containing configuration data.
|
||||
*
|
||||
* @param array $data - Config data to store
|
||||
*/
|
||||
public function __construct(array $data = null)
|
||||
{
|
||||
$this->config = new Data($data);
|
||||
$this->setDefaults(new Data());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
return ($this->config->has($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($key, $defaultFallback = null)
|
||||
{
|
||||
if ($this->has($key)) {
|
||||
return $this->config->get($key);
|
||||
}
|
||||
return $this->getDefault($key, $defaultFallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->config->set($key, $value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function import($data)
|
||||
{
|
||||
return $this->replace($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function replace($data)
|
||||
{
|
||||
$this->config = new Data($data);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function combine($data)
|
||||
{
|
||||
if (!empty($data)) {
|
||||
$this->config->import($data, true);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function export()
|
||||
{
|
||||
return $this->config->export();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasDefault($key)
|
||||
{
|
||||
return $this->getDefaults()->has($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefault($key, $defaultFallback = null)
|
||||
{
|
||||
return $this->hasDefault($key) ? $this->getDefaults()->get($key) : $defaultFallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setDefault($key, $value)
|
||||
{
|
||||
$this->getDefaults()->set($key, $value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the class $defaults property and ensure it's a Data object
|
||||
* TODO: remove Data object validation in 2.0
|
||||
*
|
||||
* @return Data
|
||||
*/
|
||||
protected function getDefaults()
|
||||
{
|
||||
// Ensure $this->defaults is a Data object (not an array)
|
||||
if (!$this->defaults instanceof Data) {
|
||||
$this->setDefaults($this->defaults);
|
||||
}
|
||||
return $this->defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the $defaults class parameter
|
||||
* TODO: remove support for array in 2.0 as this would currently break backward compatibility
|
||||
*
|
||||
* @param Data|array $defaults
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function setDefaults($defaults)
|
||||
{
|
||||
if (is_array($defaults)) {
|
||||
$this->defaults = new Data($defaults);
|
||||
} elseif ($defaults instanceof Data) {
|
||||
$this->defaults = $defaults;
|
||||
} else {
|
||||
throw new \Exception("Unknown type provided for \$defaults");
|
||||
}
|
||||
}
|
||||
}
|
105
vendor/consolidation/config/src/ConfigInterface.php
vendored
Normal file
105
vendor/consolidation/config/src/ConfigInterface.php
vendored
Normal file
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
namespace Consolidation\Config;
|
||||
|
||||
interface ConfigInterface
|
||||
{
|
||||
/**
|
||||
* Determine if a non-default config value exists.
|
||||
*/
|
||||
public function has($key);
|
||||
|
||||
/**
|
||||
* Fetch a configuration value
|
||||
*
|
||||
* @param string $key Which config item to look up
|
||||
* @param string|null $defaultFallback Fallback default value to use when
|
||||
* configuration object has neither a value nor a default. Use is
|
||||
* discouraged; use default context in ConfigOverlay, or provide defaults
|
||||
* using a config processor.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key, $defaultFallback = null);
|
||||
|
||||
/**
|
||||
* Set a config value
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set($key, $value);
|
||||
|
||||
/**
|
||||
* Import configuration from the provided nexted array, replacing whatever
|
||||
* was here previously. No processing is done on the provided data.
|
||||
*
|
||||
* @deprecated Use 'replace'. Dflydev\DotAccessData\Data::import() merges, which is confusing, since this method replaces.
|
||||
*
|
||||
* @param array $data
|
||||
* @return Config
|
||||
*/
|
||||
public function import($data);
|
||||
|
||||
/**
|
||||
* Load configuration from the provided nexted array, replacing whatever
|
||||
* was here previously. No processing is done on the provided data.
|
||||
*
|
||||
* TODO: This will become a required method in version 2.0. Adding now
|
||||
* would break clients that implement ConfigInterface.
|
||||
*
|
||||
* @param array $data
|
||||
* @return Config
|
||||
*/
|
||||
// public function replace($data);
|
||||
|
||||
/**
|
||||
* Import configuration from the provided nexted array, merging with whatever
|
||||
* was here previously. No processing is done on the provided data.
|
||||
* Any data provided to the combine() method will overwrite existing data
|
||||
* with the same key.
|
||||
*
|
||||
* TODO: This will become a required method in version 2.0. Adding now
|
||||
* would break clients that implement ConfigInterface.
|
||||
*
|
||||
* @param array $data
|
||||
* @return Config
|
||||
*/
|
||||
// public function combine($data);
|
||||
|
||||
/**
|
||||
* Export all configuration as a nested array.
|
||||
*/
|
||||
public function export();
|
||||
|
||||
/**
|
||||
* Return the default value for a given configuration item.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function hasDefault($key);
|
||||
|
||||
/**
|
||||
* Return the default value for a given configuration item.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $defaultFallback
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDefault($key, $defaultFallback = null);
|
||||
|
||||
/**
|
||||
* Set the default value for a configuration setting. This allows us to
|
||||
* set defaults either before or after more specific configuration values
|
||||
* are loaded. Keeping defaults separate from current settings also
|
||||
* allows us to determine when a setting has been overridden.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
*/
|
||||
public function setDefault($key, $value);
|
||||
}
|
10
vendor/consolidation/config/src/GlobalOptionDefaultValuesInterface.php
vendored
Normal file
10
vendor/consolidation/config/src/GlobalOptionDefaultValuesInterface.php
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
namespace Consolidation\Config;
|
||||
|
||||
interface GlobalOptionDefaultValuesInterface
|
||||
{
|
||||
/**
|
||||
* Return an associative array of option-key => default-value
|
||||
*/
|
||||
public function getGlobalOptionDefaultValues();
|
||||
}
|
127
vendor/consolidation/config/src/Inject/ConfigForCommand.php
vendored
Normal file
127
vendor/consolidation/config/src/Inject/ConfigForCommand.php
vendored
Normal file
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
namespace Consolidation\Config\Inject;
|
||||
|
||||
use Consolidation\Config\ConfigInterface;
|
||||
use Consolidation\Config\Util\ConfigFallback;
|
||||
|
||||
use Symfony\Component\Console\ConsoleEvents;
|
||||
use Symfony\Component\Console\Event\ConsoleCommandEvent;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
class ConfigForCommand implements EventSubscriberInterface
|
||||
{
|
||||
protected $config;
|
||||
protected $application;
|
||||
|
||||
public function __construct(ConfigInterface $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function setApplication(Application $application)
|
||||
{
|
||||
$this->application = $application;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [ConsoleEvents::COMMAND => 'injectConfiguration'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Before a Console command runs, inject configuration settings
|
||||
* for this command into the default value of the options of
|
||||
* this command.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Event\ConsoleCommandEvent $event
|
||||
*/
|
||||
public function injectConfiguration(ConsoleCommandEvent $event)
|
||||
{
|
||||
$command = $event->getCommand();
|
||||
$this->injectConfigurationForGlobalOptions($event->getInput());
|
||||
$this->injectConfigurationForCommand($command, $event->getInput());
|
||||
|
||||
$targetOfHelpCommand = $this->getHelpCommandTarget($command, $event->getInput());
|
||||
if ($targetOfHelpCommand) {
|
||||
$this->injectConfigurationForCommand($targetOfHelpCommand, $event->getInput());
|
||||
}
|
||||
}
|
||||
|
||||
protected function injectConfigurationForGlobalOptions($input)
|
||||
{
|
||||
if (!$this->application) {
|
||||
return;
|
||||
}
|
||||
|
||||
$configGroup = new ConfigFallback($this->config, 'options');
|
||||
|
||||
$definition = $this->application->getDefinition();
|
||||
$options = $definition->getOptions();
|
||||
|
||||
return $this->injectConfigGroupIntoOptions($configGroup, $options, $input);
|
||||
}
|
||||
|
||||
protected function injectConfigurationForCommand($command, $input)
|
||||
{
|
||||
$commandName = $command->getName();
|
||||
$commandName = str_replace(':', '.', $commandName);
|
||||
$configGroup = new ConfigFallback($this->config, $commandName, 'command.', '.options.');
|
||||
|
||||
$definition = $command->getDefinition();
|
||||
$options = $definition->getOptions();
|
||||
|
||||
return $this->injectConfigGroupIntoOptions($configGroup, $options, $input);
|
||||
}
|
||||
|
||||
protected function injectConfigGroupIntoOptions($configGroup, $options, $input)
|
||||
{
|
||||
foreach ($options as $option => $inputOption) {
|
||||
$key = str_replace('.', '-', $option);
|
||||
$value = $configGroup->get($key);
|
||||
if ($value !== null) {
|
||||
if (is_bool($value) && ($value == true)) {
|
||||
$input->setOption($key, $value);
|
||||
} elseif ($inputOption->acceptValue()) {
|
||||
$inputOption->setDefault($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function getHelpCommandTarget($command, $input)
|
||||
{
|
||||
if (($command->getName() != 'help') || (!isset($this->application))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->fixInputForSymfony2($command, $input);
|
||||
|
||||
// Symfony Console helpfully swaps 'command_name' and 'command'
|
||||
// depending on whether the user entered `help foo` or `--help foo`.
|
||||
// One of these is always `help`, and the other is the command we
|
||||
// are actually interested in.
|
||||
$nameOfCommandToDescribe = $input->getArgument('command_name');
|
||||
if ($nameOfCommandToDescribe == 'help') {
|
||||
$nameOfCommandToDescribe = $input->getArgument('command');
|
||||
}
|
||||
return $this->application->find($nameOfCommandToDescribe);
|
||||
}
|
||||
|
||||
protected function fixInputForSymfony2($command, $input)
|
||||
{
|
||||
// Symfony 3.x prepares $input for us; Symfony 2.x, on the other
|
||||
// hand, passes it in prior to binding with the command definition,
|
||||
// so we have to go to a little extra work. It may be inadvisable
|
||||
// to do these steps for commands other than 'help'.
|
||||
if (!$input->hasArgument('command_name')) {
|
||||
$command->ignoreValidationErrors();
|
||||
$command->mergeApplicationDefinition();
|
||||
$input->bind($command->getDefinition());
|
||||
}
|
||||
}
|
||||
}
|
47
vendor/consolidation/config/src/Inject/ConfigForSetters.php
vendored
Normal file
47
vendor/consolidation/config/src/Inject/ConfigForSetters.php
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
namespace Consolidation\Config\Inject;
|
||||
|
||||
use Consolidation\Config\Util\ConfigMerge;
|
||||
|
||||
/**
|
||||
* Given an object that contains configuration methods, inject any
|
||||
* configuration found in the configuration file.
|
||||
*
|
||||
* The proper use for this method is to call setter methods of the
|
||||
* provided object. Using configuration to call methods that do work
|
||||
* is an abuse of this mechanism.
|
||||
*/
|
||||
class ConfigForSetters
|
||||
{
|
||||
protected $config;
|
||||
|
||||
public function __construct($config, $group, $prefix = '', $postfix = '')
|
||||
{
|
||||
if (!empty($group) && empty($postfix)) {
|
||||
$postfix = '.';
|
||||
}
|
||||
|
||||
$this->config = new ConfigMerge($config, $group, $prefix, $postfix);
|
||||
}
|
||||
|
||||
public function apply($object, $configurationKey)
|
||||
{
|
||||
$settings = $this->config->get($configurationKey);
|
||||
foreach ($settings as $setterMethod => $args) {
|
||||
$fn = [$object, $setterMethod];
|
||||
if (is_callable($fn)) {
|
||||
$result = call_user_func_array($fn, (array)$args);
|
||||
|
||||
// We require that $fn must only be used with setter methods.
|
||||
// Setter methods are required to always return $this so that
|
||||
// they may be chained. We will therefore throw an exception
|
||||
// for any setter that returns something else.
|
||||
if ($result != $object) {
|
||||
$methodDescription = get_class($object) . "::$setterMethod";
|
||||
$propertyDescription = $this->config->describe($configurationKey);
|
||||
throw new \Exception("$methodDescription did not return '\$this' when processing $propertyDescription.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
35
vendor/consolidation/config/src/Loader/ConfigLoader.php
vendored
Normal file
35
vendor/consolidation/config/src/Loader/ConfigLoader.php
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Consolidation\Config\Loader;
|
||||
|
||||
/**
|
||||
* Load configuration files.
|
||||
*/
|
||||
abstract class ConfigLoader implements ConfigLoaderInterface
|
||||
{
|
||||
protected $config = [];
|
||||
protected $source = '';
|
||||
|
||||
public function getSourceName()
|
||||
{
|
||||
return $this->source;
|
||||
}
|
||||
|
||||
protected function setSourceName($source)
|
||||
{
|
||||
$this->source = $source;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function export()
|
||||
{
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
public function keys()
|
||||
{
|
||||
return array_keys($this->config);
|
||||
}
|
||||
|
||||
abstract public function load($path);
|
||||
}
|
29
vendor/consolidation/config/src/Loader/ConfigLoaderInterface.php
vendored
Normal file
29
vendor/consolidation/config/src/Loader/ConfigLoaderInterface.php
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Consolidation\Config\Loader;
|
||||
|
||||
/**
|
||||
* Load configuration files, and fill in any property values that
|
||||
* need to be expanded.
|
||||
*/
|
||||
interface ConfigLoaderInterface
|
||||
{
|
||||
/**
|
||||
* Convert loaded configuration into a simple php nested array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function export();
|
||||
|
||||
/**
|
||||
* Return the top-level keys in the exported data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function keys();
|
||||
|
||||
/**
|
||||
* Return a symbolic name for this configuration loader instance.
|
||||
*/
|
||||
public function getSourceName();
|
||||
}
|
184
vendor/consolidation/config/src/Loader/ConfigProcessor.php
vendored
Normal file
184
vendor/consolidation/config/src/Loader/ConfigProcessor.php
vendored
Normal file
|
@ -0,0 +1,184 @@
|
|||
<?php
|
||||
|
||||
namespace Consolidation\Config\Loader;
|
||||
|
||||
use Grasmash\Expander\Expander;
|
||||
use Consolidation\Config\Util\ArrayUtil;
|
||||
|
||||
/**
|
||||
* The config processor combines multiple configuration
|
||||
* files together, and processes them as necessary.
|
||||
*/
|
||||
class ConfigProcessor
|
||||
{
|
||||
protected $processedConfig = [];
|
||||
protected $unprocessedConfig = [];
|
||||
protected $nameOfItemsToMerge = [];
|
||||
protected $expander;
|
||||
|
||||
public function __construct($expander = null)
|
||||
{
|
||||
$this->expander = $expander ?: new Expander();
|
||||
}
|
||||
|
||||
/**
|
||||
* By default, string config items always REPLACE, not MERGE when added
|
||||
* from different sources. This method will allow applications to alter
|
||||
* this behavior for specific items so that strings from multiple sources
|
||||
* will be merged together into an array instead.
|
||||
*/
|
||||
public function useMergeStrategyForKeys($itemName)
|
||||
{
|
||||
if (is_array($itemName)) {
|
||||
$this->nameOfItemsToMerge = array_merge($this->nameOfItemsToMerge, $itemName);
|
||||
return $this;
|
||||
}
|
||||
$this->nameOfItemsToMerge[] = $itemName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend the configuration to be processed with the
|
||||
* configuration provided by the specified loader.
|
||||
*
|
||||
* @param ConfigLoaderInterface $loader
|
||||
*/
|
||||
public function extend(ConfigLoaderInterface $loader)
|
||||
{
|
||||
return $this->addFromSource($loader->export(), $loader->getSourceName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend the configuration to be processed with
|
||||
* the provided nested array.
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public function add($data)
|
||||
{
|
||||
$this->unprocessedConfig[] = $data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend the configuration to be processed with
|
||||
* the provided nested array. Also record the name
|
||||
* of the data source, if applicable.
|
||||
*
|
||||
* @param array $data
|
||||
* @param string $source
|
||||
*/
|
||||
protected function addFromSource($data, $source = '')
|
||||
{
|
||||
if (empty($source)) {
|
||||
return $this->add($data);
|
||||
}
|
||||
$this->unprocessedConfig[$source] = $data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process all of the configuration that has been collected,
|
||||
* and return a nested array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function export($referenceArray = [])
|
||||
{
|
||||
if (!empty($this->unprocessedConfig)) {
|
||||
$this->processedConfig = $this->process(
|
||||
$this->processedConfig,
|
||||
$this->fetchUnprocessed(),
|
||||
$referenceArray
|
||||
);
|
||||
}
|
||||
return $this->processedConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* To aid in debugging: return the source of each configuration item.
|
||||
* n.b. Must call this function *before* export and save the result
|
||||
* if persistence is desired.
|
||||
*/
|
||||
public function sources()
|
||||
{
|
||||
$sources = [];
|
||||
foreach ($this->unprocessedConfig as $sourceName => $config) {
|
||||
if (!empty($sourceName)) {
|
||||
$configSources = ArrayUtil::fillRecursive($config, $sourceName);
|
||||
$sources = ArrayUtil::mergeRecursiveDistinct($sources, $configSources);
|
||||
}
|
||||
}
|
||||
return $sources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the configuration to be processed, and clear out the
|
||||
* 'unprocessed' list.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function fetchUnprocessed()
|
||||
{
|
||||
$toBeProcessed = $this->unprocessedConfig;
|
||||
$this->unprocessedConfig = [];
|
||||
return $toBeProcessed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a map-reduce to evaluate the items to be processed,
|
||||
* and merge them into the processed array.
|
||||
*
|
||||
* @param array $processed
|
||||
* @param array $toBeProcessed
|
||||
* @return array
|
||||
*/
|
||||
protected function process(array $processed, array $toBeProcessed, $referenceArray = [])
|
||||
{
|
||||
$toBeReduced = array_map([$this, 'preprocess'], $toBeProcessed);
|
||||
$reduced = array_reduce($toBeReduced, [$this, 'reduceOne'], $processed);
|
||||
return $this->evaluate($reduced, $referenceArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a single configuration file from the 'to be processed'
|
||||
* list. By default this is a no-op. Override this method to
|
||||
* provide any desired configuration preprocessing, e.g. dot-notation
|
||||
* expansion of the configuration keys, etc.
|
||||
*
|
||||
* @param array $config
|
||||
* @return array
|
||||
*/
|
||||
protected function preprocess(array $config)
|
||||
{
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate one item in the 'to be evaluated' list, and then
|
||||
* merge it into the processed configuration (the 'carry').
|
||||
*
|
||||
* @param array $processed
|
||||
* @param array $config
|
||||
* @return array
|
||||
*/
|
||||
protected function reduceOne(array $processed, array $config)
|
||||
{
|
||||
return ArrayUtil::mergeRecursiveSelect($processed, $config, $this->nameOfItemsToMerge);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate one configuration item.
|
||||
*
|
||||
* @param array $processed
|
||||
* @param array $config
|
||||
* @return array
|
||||
*/
|
||||
protected function evaluate(array $config, $referenceArray = [])
|
||||
{
|
||||
return $this->expander->expandArrayProperties(
|
||||
$config,
|
||||
$referenceArray
|
||||
);
|
||||
}
|
||||
}
|
26
vendor/consolidation/config/src/Loader/YamlConfigLoader.php
vendored
Normal file
26
vendor/consolidation/config/src/Loader/YamlConfigLoader.php
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Consolidation\Config\Loader;
|
||||
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
/**
|
||||
* Load configuration files, and fill in any property values that
|
||||
* need to be expanded.
|
||||
*/
|
||||
class YamlConfigLoader extends ConfigLoader
|
||||
{
|
||||
public function load($path)
|
||||
{
|
||||
$this->setSourceName($path);
|
||||
|
||||
// We silently skip any nonexistent config files, so that
|
||||
// clients may simply `load` all of their candidates.
|
||||
if (!file_exists($path)) {
|
||||
$this->config = [];
|
||||
return $this;
|
||||
}
|
||||
$this->config = (array) Yaml::parse(file_get_contents($path));
|
||||
return $this;
|
||||
}
|
||||
}
|
122
vendor/consolidation/config/src/Util/ArrayUtil.php
vendored
Normal file
122
vendor/consolidation/config/src/Util/ArrayUtil.php
vendored
Normal file
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
namespace Consolidation\Config\Util;
|
||||
|
||||
/**
|
||||
* Useful array utilities.
|
||||
*/
|
||||
class ArrayUtil
|
||||
{
|
||||
/**
|
||||
* Merges arrays recursively while preserving.
|
||||
*
|
||||
* @param array $array1
|
||||
* @param array $array2
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @see http://php.net/manual/en/function.array-merge-recursive.php#92195
|
||||
* @see https://github.com/grasmash/bolt/blob/robo-rebase/src/Robo/Common/ArrayManipulator.php#L22
|
||||
*/
|
||||
public static function mergeRecursiveDistinct(
|
||||
array &$array1,
|
||||
array &$array2
|
||||
) {
|
||||
$merged = $array1;
|
||||
foreach ($array2 as $key => &$value) {
|
||||
$merged[$key] = self::mergeRecursiveValue($merged, $key, $value);
|
||||
}
|
||||
return $merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the value in an mergeRecursiveDistinct - make a recursive
|
||||
* call if needed.
|
||||
*/
|
||||
protected static function mergeRecursiveValue(&$merged, $key, $value)
|
||||
{
|
||||
if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
|
||||
return self::mergeRecursiveDistinct($merged[$key], $value);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Merges arrays recursively while preserving.
|
||||
*
|
||||
* @param array $array1
|
||||
* @param array $array2
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @see http://php.net/manual/en/function.array-merge-recursive.php#92195
|
||||
* @see https://github.com/grasmash/bolt/blob/robo-rebase/src/Robo/Common/ArrayManipulator.php#L22
|
||||
*/
|
||||
public static function mergeRecursiveSelect(
|
||||
array &$array1,
|
||||
array &$array2,
|
||||
array $selectionList,
|
||||
$keyPrefix = ''
|
||||
) {
|
||||
$merged = $array1;
|
||||
foreach ($array2 as $key => &$value) {
|
||||
$merged[$key] = self::mergeRecursiveSelectValue($merged, $key, $value, $selectionList, $keyPrefix);
|
||||
}
|
||||
return $merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the value in an mergeRecursiveDistinct - make a recursive
|
||||
* call if needed.
|
||||
*/
|
||||
protected static function mergeRecursiveSelectValue(&$merged, $key, $value, $selectionList, $keyPrefix)
|
||||
{
|
||||
if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
|
||||
if (self::selectMerge($keyPrefix, $key, $selectionList)) {
|
||||
return array_merge_recursive($merged[$key], $value);
|
||||
} else {
|
||||
return self::mergeRecursiveSelect($merged[$key], $value, $selectionList, "${keyPrefix}${key}.");
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
protected static function selectMerge($keyPrefix, $key, $selectionList)
|
||||
{
|
||||
return in_array("${keyPrefix}${key}", $selectionList);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fills all of the leaf-node values of a nested array with the
|
||||
* provided replacement value.
|
||||
*/
|
||||
public static function fillRecursive(array $data, $fill)
|
||||
{
|
||||
$result = [];
|
||||
foreach ($data as $key => $value) {
|
||||
$result[$key] = $fill;
|
||||
if (self::isAssociative($value)) {
|
||||
$result[$key] = self::fillRecursive($value, $fill);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the provided parameter is an array, and at least
|
||||
* one key is non-numeric.
|
||||
*/
|
||||
public static function isAssociative($testArray)
|
||||
{
|
||||
if (!is_array($testArray)) {
|
||||
return false;
|
||||
}
|
||||
foreach (array_keys($testArray) as $key) {
|
||||
if (!is_numeric($key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
51
vendor/consolidation/config/src/Util/ConfigFallback.php
vendored
Normal file
51
vendor/consolidation/config/src/Util/ConfigFallback.php
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
namespace Consolidation\Config\Util;
|
||||
|
||||
/**
|
||||
* Fetch a configuration value from a configuration group. If the
|
||||
* desired configuration value is not found in the most specific
|
||||
* group named, keep stepping up to the next parent group until a
|
||||
* value is located.
|
||||
*
|
||||
* Given the following constructor inputs:
|
||||
* - $prefix = "command."
|
||||
* - $group = "foo.bar.baz"
|
||||
* - $postfix = ".options."
|
||||
* Then the `get` method will then consider, in order:
|
||||
* - command.foo.bar.baz.options
|
||||
* - command.foo.bar.options
|
||||
* - command.foo.options
|
||||
* If any of these contain an option for "$key", then return its value.
|
||||
*/
|
||||
class ConfigFallback extends ConfigGroup
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
return $this->getWithFallback($key, $this->group, $this->prefix, $this->postfix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch an option value from a given key, or, if that specific key does
|
||||
* not contain a value, then consult various fallback options until a
|
||||
* value is found.
|
||||
*
|
||||
*/
|
||||
protected function getWithFallback($key, $group, $prefix = '', $postfix = '.')
|
||||
{
|
||||
$configKey = "{$prefix}{$group}${postfix}{$key}";
|
||||
if ($this->config->has($configKey)) {
|
||||
return $this->config->get($configKey);
|
||||
}
|
||||
if ($this->config->hasDefault($configKey)) {
|
||||
return $this->config->getDefault($configKey);
|
||||
}
|
||||
$moreGeneralGroupname = $this->moreGeneralGroupName($group);
|
||||
if ($moreGeneralGroupname) {
|
||||
return $this->getWithFallback($key, $moreGeneralGroupname, $prefix, $postfix);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
61
vendor/consolidation/config/src/Util/ConfigGroup.php
vendored
Normal file
61
vendor/consolidation/config/src/Util/ConfigGroup.php
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
namespace Consolidation\Config\Util;
|
||||
|
||||
/**
|
||||
* Fetch a configuration value from a configuration group. If the
|
||||
* desired configuration value is not found in the most specific
|
||||
* group named, keep stepping up to the next parent group until a
|
||||
* value is located.
|
||||
*
|
||||
* Given the following constructor inputs:
|
||||
* - $prefix = "command."
|
||||
* - $group = "foo.bar.baz"
|
||||
* - $postfix = ".options."
|
||||
* Then the `get` method will then consider, in order:
|
||||
* - command.foo.bar.baz.options
|
||||
* - command.foo.bar.options
|
||||
* - command.foo.options
|
||||
* If any of these contain an option for "$key", then return its value.
|
||||
*/
|
||||
abstract class ConfigGroup
|
||||
{
|
||||
protected $config;
|
||||
protected $group;
|
||||
protected $prefix;
|
||||
protected $postfix;
|
||||
|
||||
public function __construct($config, $group, $prefix = '', $postfix = '.')
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->group = $group;
|
||||
$this->prefix = $prefix;
|
||||
$this->postfix = $postfix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a description of the configuration group (with prefix and postfix).
|
||||
*/
|
||||
public function describe($property)
|
||||
{
|
||||
return $this->prefix . $this->group . $this->postfix . $property;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the requested configuration key from the most specific configuration
|
||||
* group that contains it.
|
||||
*/
|
||||
abstract public function get($key);
|
||||
|
||||
/**
|
||||
* Given a group name, such as "foo.bar.baz", return the next configuration
|
||||
* group in the fallback hierarchy, e.g. "foo.bar".
|
||||
*/
|
||||
protected function moreGeneralGroupName($group)
|
||||
{
|
||||
$result = preg_replace('#\.[^.]*$#', '', $group);
|
||||
if ($result != $group) {
|
||||
return $result;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
37
vendor/consolidation/config/src/Util/ConfigInterpolatorInterface.php
vendored
Normal file
37
vendor/consolidation/config/src/Util/ConfigInterpolatorInterface.php
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
namespace Consolidation\Config\Util;
|
||||
|
||||
use Consolidation\Config\Config;
|
||||
use Consolidation\Config\ConfigInterface;
|
||||
|
||||
/**
|
||||
* Provides configuration objects with an 'interpolate' method
|
||||
* that may be used to inject config values into tokens embedded
|
||||
* in strings.
|
||||
*/
|
||||
interface ConfigInterpolatorInterface extends ConfigInterface
|
||||
{
|
||||
/**
|
||||
* interpolate replaces tokens in a string with the correspnding
|
||||
* value from this config object. Tokens are surrounded by double
|
||||
* curley braces, e.g. "{{key}}".
|
||||
*
|
||||
* Example:
|
||||
* If the message is 'Hello, {{user.name}}', then the key user.name
|
||||
* is fetched from the config object, and the token {{user.name}} is
|
||||
* replaced with the result.
|
||||
*
|
||||
* @param string $message Message containing tokens to be replaced
|
||||
* @param string|bool $default The value to substitute for tokens that
|
||||
* are not found in the configuration. If `false`, then missing
|
||||
* tokens are not replaced.
|
||||
* @return string
|
||||
*/
|
||||
public function interpolate($message, $default = '');
|
||||
|
||||
/**
|
||||
* mustInterpolate works exactly like interpolate, save for the fact
|
||||
* that an exception is thrown is any of the tokens are not replaced.
|
||||
*/
|
||||
public function mustInterpolate($message);
|
||||
}
|
38
vendor/consolidation/config/src/Util/ConfigInterpolatorTrait.php
vendored
Normal file
38
vendor/consolidation/config/src/Util/ConfigInterpolatorTrait.php
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
namespace Consolidation\Config\Util;
|
||||
|
||||
use Consolidation\Config\Config;
|
||||
use Consolidation\Config\ConfigInterface;
|
||||
|
||||
/**
|
||||
* Provides configuration objects with an 'interpolate' method
|
||||
* that may be used to inject config values into tokens embedded
|
||||
* in strings..
|
||||
*/
|
||||
trait ConfigInterpolatorTrait
|
||||
{
|
||||
protected $interpolator;
|
||||
|
||||
protected function getInterpolator()
|
||||
{
|
||||
if (!isset($this->interpolator)) {
|
||||
$this->interpolator = new Interpolator();
|
||||
}
|
||||
return $this->interpolator;
|
||||
}
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function interpolate($message, $default = '')
|
||||
{
|
||||
return $this->getInterpolator()->interpolate($this, $message, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function mustInterpolate($message)
|
||||
{
|
||||
return $this->getInterpolator()->mustInterpolate($this, $message);
|
||||
}
|
||||
}
|
34
vendor/consolidation/config/src/Util/ConfigMerge.php
vendored
Normal file
34
vendor/consolidation/config/src/Util/ConfigMerge.php
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
namespace Consolidation\Config\Util;
|
||||
|
||||
/**
|
||||
* Works like 'getWithFallback', but merges results from all applicable
|
||||
* groups. Settings from most specific group take precedence.
|
||||
*/
|
||||
class ConfigMerge extends ConfigGroup
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
return $this->getWithMerge($key, $this->group, $this->prefix, $this->postfix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge available configuration from each configuration group.
|
||||
*/
|
||||
public function getWithMerge($key, $group, $prefix = '', $postfix = '.')
|
||||
{
|
||||
$configKey = "{$prefix}{$group}${postfix}{$key}";
|
||||
$result = $this->config->get($configKey, []);
|
||||
if (!is_array($result)) {
|
||||
throw new \UnexpectedValueException($configKey . ' must be a list of settings to apply.');
|
||||
}
|
||||
$moreGeneralGroupname = $this->moreGeneralGroupName($group);
|
||||
if ($moreGeneralGroupname) {
|
||||
$result += $this->getWithMerge($key, $moreGeneralGroupname, $prefix, $postfix);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
228
vendor/consolidation/config/src/Util/ConfigOverlay.php
vendored
Normal file
228
vendor/consolidation/config/src/Util/ConfigOverlay.php
vendored
Normal file
|
@ -0,0 +1,228 @@
|
|||
<?php
|
||||
namespace Consolidation\Config\Util;
|
||||
|
||||
use Consolidation\Config\Config;
|
||||
use Consolidation\Config\ConfigInterface;
|
||||
use Consolidation\Config\Util\ArrayUtil;
|
||||
use Consolidation\Config\Util\ConfigInterpolatorInterface;
|
||||
use Consolidation\Config\Util\ConfigInterpolatorTrait;
|
||||
|
||||
/**
|
||||
* Overlay different configuration objects that implement ConfigInterface
|
||||
* to make a priority-based, merged configuration object.
|
||||
*
|
||||
* Note that using a ConfigOverlay hides the defaults stored in each
|
||||
* individual configuration context. When using overlays, always call
|
||||
* getDefault / setDefault on the ConfigOverlay object itself.
|
||||
*/
|
||||
class ConfigOverlay implements ConfigInterface, ConfigInterpolatorInterface
|
||||
{
|
||||
use ConfigInterpolatorTrait;
|
||||
protected $contexts = [];
|
||||
|
||||
const DEFAULT_CONTEXT = 'default';
|
||||
const PROCESS_CONTEXT = 'process';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->contexts[self::DEFAULT_CONTEXT] = new Config();
|
||||
$this->contexts[self::PROCESS_CONTEXT] = new Config();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a named configuration object to the configuration overlay.
|
||||
* Configuration objects added LAST have HIGHEST priority, with the
|
||||
* exception of the fact that the process context always has the
|
||||
* highest priority.
|
||||
*
|
||||
* If a context has already been added, its priority will not change.
|
||||
*/
|
||||
public function addContext($name, ConfigInterface $config)
|
||||
{
|
||||
$process = $this->contexts[self::PROCESS_CONTEXT];
|
||||
unset($this->contexts[self::PROCESS_CONTEXT]);
|
||||
$this->contexts[$name] = $config;
|
||||
$this->contexts[self::PROCESS_CONTEXT] = $process;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a placeholder context that will be prioritized higher than
|
||||
* existing contexts. This is done to ensure that contexts added
|
||||
* later will maintain a higher priority if the placeholder context
|
||||
* is later relaced with a different configuration set via addContext().
|
||||
*
|
||||
* @param string $name
|
||||
* @return $this
|
||||
*/
|
||||
public function addPlaceholder($name)
|
||||
{
|
||||
return $this->addContext($name, new Config());
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase the priority of the named context such that it is higher
|
||||
* in priority than any existing context except for the 'process'
|
||||
* context.
|
||||
*
|
||||
* @param string $name
|
||||
* @return $this
|
||||
*/
|
||||
public function increasePriority($name)
|
||||
{
|
||||
$config = $this->getContext($name);
|
||||
unset($this->contexts[$name]);
|
||||
return $this->addContext($name, $config);
|
||||
}
|
||||
|
||||
public function hasContext($name)
|
||||
{
|
||||
return isset($this->contexts[$name]);
|
||||
}
|
||||
|
||||
public function getContext($name)
|
||||
{
|
||||
if ($this->hasContext($name)) {
|
||||
return $this->contexts[$name];
|
||||
}
|
||||
return new Config();
|
||||
}
|
||||
|
||||
public function removeContext($name)
|
||||
{
|
||||
unset($this->contexts[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a non-default config value exists.
|
||||
*/
|
||||
public function findContext($key)
|
||||
{
|
||||
foreach (array_reverse($this->contexts) as $name => $config) {
|
||||
if ($config->has($key)) {
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
return $this->findContext($key) != false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
if (is_array($default)) {
|
||||
return $this->getUnion($key);
|
||||
}
|
||||
return $this->getSingle($key, $default);
|
||||
}
|
||||
|
||||
public function getSingle($key, $default = null)
|
||||
{
|
||||
$context = $this->findContext($key);
|
||||
if ($context) {
|
||||
return $context->get($key, $default);
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
public function getUnion($key)
|
||||
{
|
||||
$result = [];
|
||||
foreach (array_reverse($this->contexts) as $name => $config) {
|
||||
$item = (array) $config->get($key, []);
|
||||
if ($item !== null) {
|
||||
$result = array_merge($result, $item);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->contexts[self::PROCESS_CONTEXT]->set($key, $value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function import($data)
|
||||
{
|
||||
$this->unsupported(__FUNCTION__);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function replace($data)
|
||||
{
|
||||
$this->unsupported(__FUNCTION__);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function combine($data)
|
||||
{
|
||||
$this->unsupported(__FUNCTION__);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function unsupported($fn)
|
||||
{
|
||||
throw new \Exception("The method '$fn' is not supported for the ConfigOverlay class.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function export()
|
||||
{
|
||||
$export = [];
|
||||
foreach ($this->contexts as $name => $config) {
|
||||
$exportToMerge = $config->export();
|
||||
$export = \array_replace_recursive($export, $exportToMerge);
|
||||
}
|
||||
return $export;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function hasDefault($key)
|
||||
{
|
||||
return $this->contexts[self::DEFAULT_CONTEXT]->has($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDefault($key, $default = null)
|
||||
{
|
||||
return $this->contexts[self::DEFAULT_CONTEXT]->get($key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function setDefault($key, $value)
|
||||
{
|
||||
$this->contexts[self::DEFAULT_CONTEXT]->set($key, $value);
|
||||
return $this;
|
||||
}
|
||||
}
|
96
vendor/consolidation/config/src/Util/EnvConfig.php
vendored
Normal file
96
vendor/consolidation/config/src/Util/EnvConfig.php
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
namespace Consolidation\Config\Util;
|
||||
|
||||
use Consolidation\Config\Config;
|
||||
use Consolidation\Config\ConfigInterface;
|
||||
|
||||
/**
|
||||
* Provide a configuration object that fetches values from environment
|
||||
* variables.
|
||||
*/
|
||||
class EnvConfig implements ConfigInterface
|
||||
{
|
||||
/** @var string */
|
||||
protected $prefix;
|
||||
|
||||
/**
|
||||
* EnvConfig constructor
|
||||
*
|
||||
* @param $prefix The string to appear before every environment
|
||||
* variable key. For example, if the prefix is 'MYAPP_', then
|
||||
* the key 'foo.bar' will be fetched from the environment variable
|
||||
* MYAPP_FOO_BAR.
|
||||
*/
|
||||
public function __construct($prefix)
|
||||
{
|
||||
// Ensure that the prefix is always uppercase, and always
|
||||
// ends with a '_', regardless of the form the caller provided.
|
||||
$this->prefix = strtoupper(rtrim($prefix, '_')) . '_';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
return $this->get($key) !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function get($key, $defaultFallback = null)
|
||||
{
|
||||
$envKey = $this->prefix . strtoupper(strtr($key, '.-', '__'));
|
||||
$envKey = str_replace($this->prefix . $this->prefix, $this->prefix, $envKey);
|
||||
return getenv($envKey) ?: $defaultFallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
throw new \Exception('Cannot call "set" on environmental configuration.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function import($data)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function export()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function hasDefault($key)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDefault($key, $defaultFallback = null)
|
||||
{
|
||||
return $defaultFallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function setDefault($key, $value)
|
||||
{
|
||||
throw new \Exception('Cannot call "setDefault" on environmental configuration.');
|
||||
}
|
||||
}
|
97
vendor/consolidation/config/src/Util/Interpolator.php
vendored
Normal file
97
vendor/consolidation/config/src/Util/Interpolator.php
vendored
Normal file
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
namespace Consolidation\Config\Util;
|
||||
|
||||
use Consolidation\Config\Config;
|
||||
use Consolidation\Config\ConfigInterface;
|
||||
|
||||
/**
|
||||
* Provides configuration objects with an 'interpolate' method
|
||||
* that may be used to inject config values into tokens embedded
|
||||
* in strings..
|
||||
*/
|
||||
class Interpolator
|
||||
{
|
||||
/**
|
||||
* interpolate replaces tokens in a string with the correspnding
|
||||
* value from this config object. Tokens are surrounded by double
|
||||
* curley braces, e.g. "{{key}}".
|
||||
*
|
||||
* Example:
|
||||
* If the message is 'Hello, {{user.name}}', then the key user.name
|
||||
* is fetched from the config object, and the token {{user.name}} is
|
||||
* replaced with the result.
|
||||
*
|
||||
* @param string $message Message containing tokens to be replaced
|
||||
* @param string|bool $default The value to substitute for tokens that
|
||||
* are not found in the configuration. If `false`, then missing
|
||||
* tokens are not replaced.
|
||||
* @return string
|
||||
*/
|
||||
public function interpolate($data, $message, $default = '')
|
||||
{
|
||||
$replacements = $this->replacements($data, $message, $default);
|
||||
return strtr($message, $replacements);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function mustInterpolate($data, $message)
|
||||
{
|
||||
$result = $this->interpolate($data, $message, false);
|
||||
$tokens = $this->findTokens($result);
|
||||
if (!empty($tokens)) {
|
||||
throw new \Exception('The following required keys were not found in configuration: ' . implode(',', $tokens));
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* findTokens finds all of the tokens in the provided message
|
||||
*
|
||||
* @param string $message String with tokens
|
||||
* @return string[] map of token to key, e.g. {{key}} => key
|
||||
*/
|
||||
public function findTokens($message)
|
||||
{
|
||||
if (!preg_match_all('#{{([a-zA-Z0-9._-]+)}}#', $message, $matches, PREG_SET_ORDER)) {
|
||||
return [];
|
||||
}
|
||||
$tokens = [];
|
||||
foreach ($matches as $matchSet) {
|
||||
list($sourceText, $key) = $matchSet;
|
||||
$tokens[$sourceText] = $key;
|
||||
}
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replacements looks up all of the replacements in the configuration
|
||||
* object, given the token keys from the provided message. Keys that
|
||||
* do not exist in the configuration are replaced with the default value.
|
||||
*/
|
||||
public function replacements($data, $message, $default = '')
|
||||
{
|
||||
$tokens = $this->findTokens($message);
|
||||
|
||||
$replacements = [];
|
||||
foreach ($tokens as $sourceText => $key) {
|
||||
$replacementText = $this->get($data, $key, $default);
|
||||
if ($replacementText !== false) {
|
||||
$replacements[$sourceText] = $replacementText;
|
||||
}
|
||||
}
|
||||
return $replacements;
|
||||
}
|
||||
|
||||
protected function get($data, $key, $default)
|
||||
{
|
||||
if (is_array($data)) {
|
||||
return array_key_exists($key, $data) ? $data[$key] : $default;
|
||||
}
|
||||
if ($data instanceof ConfigInterface) {
|
||||
return $data->get($key, $default);
|
||||
}
|
||||
throw new \Exception('Bad data type provided to Interpolator');
|
||||
}
|
||||
}
|
Reference in a new issue