Add pear modules, mail and net_smtp via composer (#93)
Add pear modules, mail and net_smtp via composer, remove php 5.6 build due to phpunit 6
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
<?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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
namespace Consolidation\Config\Util;
|
||||
|
||||
use Consolidation\Config\Config;
|
||||
use Consolidation\Config\ConfigInterface;
|
||||
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
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)
|
||||
{
|
||||
$context = $this->findContext($key);
|
||||
if ($context) {
|
||||
return $context->get($key, $default);
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
$export = array_merge_recursive($export, $config->export());
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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.');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user