Merge pull request #242 from acelaya/feature/functions-as-object

Moved global functions to handle array paths to a wrapper class
This commit is contained in:
Alejandro Celaya 2018-10-20 08:59:40 +02:00 committed by GitHub
commit 46482522bb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 159 additions and 48 deletions

View file

@ -4,11 +4,8 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Common;
use const JSON_ERROR_NONE;
use function array_key_exists;
use function array_shift;
use function getenv;
use function in_array;
use function is_array;
use function json_last_error;
use function json_last_error_msg;
use function strtolower;
@ -62,39 +59,3 @@ function json_decode(string $json, int $depth = 512, int $options = 0): array
return $data;
}
function array_path_exists(array $path, array $array): bool
{
// As soon as a step is not found, the path does not exist
$step = array_shift($path);
if (! array_key_exists($step, $array)) {
return false;
}
// Once the path is empty, we have found all the parts in the path
if (empty($path)) {
return true;
}
// If current value is not an array, then we have not found the path
$newArray = $array[$step];
if (! is_array($newArray)) {
return false;
}
return array_path_exists($path, $newArray);
}
function array_get_path(array $path, array $array)
{
do {
$step = array_shift($path);
if (! is_array($array) || ! array_key_exists($step, $array)) {
return null;
}
$array = $array[$step];
} while (! empty($path));
return $array;
}

View file

@ -0,0 +1,67 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Common\Collection;
use function array_key_exists;
use function array_shift;
use function is_array;
final class PathCollection
{
/**
* @var array
*/
private $array;
public function __construct(array $array)
{
$this->array = $array;
}
public function pathExists(array $path): bool
{
return $this->checkPathExists($path, $this->array);
}
private function checkPathExists(array $path, array $array): bool
{
// As soon as a step is not found, the path does not exist
$step = array_shift($path);
if (! array_key_exists($step, $array)) {
return false;
}
// Once the path is empty, we have found all the parts in the path
if (empty($path)) {
return true;
}
// If current value is not an array, then we have not found the path
$newArray = $array[$step];
if (! is_array($newArray)) {
return false;
}
return $this->checkPathExists($path, $newArray);
}
/**
* @return mixed
*/
public function getValueInPath(array $path)
{
$array = $this->array;
do {
$step = array_shift($path);
if (! is_array($array) || ! array_key_exists($step, $array)) {
return null;
}
$array = $array[$step];
} while (! empty($path));
return $array;
}
}

View file

@ -0,0 +1,82 @@
<?php
declare(strict_types=1);
namespace ShlinkioTest\Shlink\Common\Collection;
use PHPUnit\Framework\TestCase;
use Shlinkio\Shlink\Common\Collection\PathCollection;
class PathCollectionTest extends TestCase
{
/**
* @var PathCollection
*/
private $collection;
public function setUp()
{
$this->collection = new PathCollection([
'foo' => [
'bar' => [
'baz' => 'Hello world!',
],
],
'something' => [],
'another' => [
'one' => 'Shlink',
],
]);
}
/**
* @test
* @dataProvider providePaths
*/
public function pathExistsReturnsExpectedValue(array $path, bool $expected)
{
$this->assertEquals($expected, $this->collection->pathExists($path));
}
public function providePaths(): array
{
return [
[[], false],
[['boo'], false],
[['foo', 'nop'], false],
[['another', 'one', 'nop'], false],
[['foo'], true],
[['foo', 'bar'], true],
[['foo', 'bar', 'baz'], true],
[['something'], true],
];
}
/**
* @test
* @dataProvider providePathsWithValue
*/
public function getValueInPathReturnsExpectedValue(array $path, $expected)
{
$this->assertEquals($expected, $this->collection->getValueInPath($path));
}
public function providePathsWithValue(): array
{
return [
[[], null],
[['boo'], null],
[['foo', 'nop'], null],
[['another', 'one', 'nop'], null],
[['foo'], [
'bar' => [
'baz' => 'Hello world!',
],
]],
[['foo', 'bar'], [
'baz' => 'Hello world!',
]],
[['foo', 'bar', 'baz'], 'Hello world!'],
[['something'], []],
];
}
}

View file

@ -3,13 +3,12 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Installer\Model;
use Shlinkio\Shlink\Common\Collection\PathCollection;
use Shlinkio\Shlink\Installer\Config\Plugin\ApplicationConfigCustomizer;
use Shlinkio\Shlink\Installer\Config\Plugin\DatabaseConfigCustomizer;
use Shlinkio\Shlink\Installer\Config\Plugin\LanguageConfigCustomizer;
use Shlinkio\Shlink\Installer\Config\Plugin\UrlShortenerConfigCustomizer;
use Zend\Stdlib\ArraySerializableInterface;
use function Shlinkio\Shlink\Common\array_get_path;
use function Shlinkio\Shlink\Common\array_path_exists;
final class CustomizableAppConfig implements ArraySerializableInterface
{
@ -118,12 +117,14 @@ final class CustomizableAppConfig implements ArraySerializableInterface
public function exchangeArray(array $array): void
{
$pathCollection = new PathCollection($array);
$this->setApp($this->mapExistingPathsToKeys([
ApplicationConfigCustomizer::SECRET => ['app_options', 'secret_key'],
ApplicationConfigCustomizer::DISABLE_TRACK_PARAM => ['app_options', 'disable_track_param'],
ApplicationConfigCustomizer::CHECK_VISITS_THRESHOLD => ['delete_short_urls', 'check_visits_threshold'],
ApplicationConfigCustomizer::VISITS_THRESHOLD => ['delete_short_urls', 'visits_threshold'],
], $array));
], $pathCollection));
$this->setDatabase($this->mapExistingPathsToKeys([
DatabaseConfigCustomizer::DRIVER => ['entity_manager', 'connection', 'driver'],
@ -132,27 +133,27 @@ final class CustomizableAppConfig implements ArraySerializableInterface
DatabaseConfigCustomizer::NAME => ['entity_manager', 'connection', 'dbname'],
DatabaseConfigCustomizer::HOST => ['entity_manager', 'connection', 'host'],
DatabaseConfigCustomizer::PORT => ['entity_manager', 'connection', 'port'],
], $array));
], $pathCollection));
$this->setLanguage($this->mapExistingPathsToKeys([
LanguageConfigCustomizer::DEFAULT_LANG => ['translator', 'locale'],
LanguageConfigCustomizer::CLI_LANG => ['cli', 'locale'],
], $array));
], $pathCollection));
$this->setUrlShortener($this->mapExistingPathsToKeys([
UrlShortenerConfigCustomizer::SCHEMA => ['url_shortener', 'domain', 'schema'],
UrlShortenerConfigCustomizer::HOSTNAME => ['url_shortener', 'domain', 'hostname'],
UrlShortenerConfigCustomizer::CHARS => ['url_shortener', 'shortcode_chars'],
UrlShortenerConfigCustomizer::VALIDATE_URL => ['url_shortener', 'validate_url'],
], $array));
], $pathCollection));
}
private function mapExistingPathsToKeys(array $map, array $config): array
private function mapExistingPathsToKeys(array $map, PathCollection $pathCollection): array
{
$result = [];
foreach ($map as $key => $path) {
if (array_path_exists($path, $config)) {
$result[$key] = array_get_path($path, $config);
if ($pathCollection->pathExists($path)) {
$result[$key] = $pathCollection->getValueInPath($path);
}
}