diff --git a/module/Common/functions/functions.php b/module/Common/functions/functions.php index e28e4fb2..b2c5d307 100644 --- a/module/Common/functions/functions.php +++ b/module/Common/functions/functions.php @@ -4,8 +4,11 @@ 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; @@ -59,3 +62,39 @@ 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; +} diff --git a/module/Installer/src/Model/CustomizableAppConfig.php b/module/Installer/src/Model/CustomizableAppConfig.php index 27a7dcd0..94da5ec4 100644 --- a/module/Installer/src/Model/CustomizableAppConfig.php +++ b/module/Installer/src/Model/CustomizableAppConfig.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Installer\Model; 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 { @@ -112,43 +114,43 @@ final class CustomizableAppConfig implements ArraySerializableInterface public function exchangeArray(array $array): void { - $this->setApp([ - 'SECRET' => $array['app_options']['secret_key'] ?? null, - 'DISABLE_TRACK_PARAM' => $array['app_options']['disable_track_param'] ?? null, - ]); + $this->setApp($this->mapExistingPathsToKeys([ + 'SECRET' => ['app_options', 'secret_key'], + 'DISABLE_TRACK_PARAM' => ['app_options', 'disable_track_param'], + ], $array)); - $this->setDatabase($this->deserializeDatabase($array['entity_manager']['connection'] ?? [])); + $this->setDatabase($this->mapExistingPathsToKeys([ + 'DRIVER' => ['entity_manager', 'connection', 'driver'], + 'USER' => ['entity_manager', 'connection', 'user'], + 'PASSWORD' => ['entity_manager', 'connection', 'password'], + 'NAME' => ['entity_manager', 'connection', 'dbname'], + 'HOST' => ['entity_manager', 'connection', 'host'], + 'PORT' => ['entity_manager', 'connection', 'port'], + ], $array)); - $this->setLanguage([ - 'DEFAULT' => $array['translator']['locale'] ?? null, - 'CLI' => $array['cli']['locale'] ?? null, - ]); + $this->setLanguage($this->mapExistingPathsToKeys([ + 'DEFAULT' => ['translator', 'locale'], + 'CLI' => ['cli', 'locale'], + ], $array)); - $this->setUrlShortener([ - 'SCHEMA' => $array['url_shortener']['domain']['schema'] ?? null, - 'HOSTNAME' => $array['url_shortener']['domain']['hostname'] ?? null, - 'CHARS' => $array['url_shortener']['shortcode_chars'] ?? null, - 'VALIDATE_URL' => $array['url_shortener']['validate_url'] ?? true, - ]); + $this->setUrlShortener($this->mapExistingPathsToKeys([ + 'SCHEMA' => ['url_shortener', 'domain', 'schema'], + 'HOSTNAME' => ['url_shortener', 'domain', 'hostname'], + 'CHARS' => ['url_shortener', 'shortcode_chars'], + 'VALIDATE_URL' => ['url_shortener', 'validate_url'], + ], $array)); } - private function deserializeDatabase(array $conn): array + private function mapExistingPathsToKeys(array $map, array $config): array { - if (! isset($conn['driver'])) { - return []; - } - $driver = $conn['driver']; - - $params = ['DRIVER' => $driver]; - if ($driver !== 'pdo_sqlite') { - $params['USER'] = $conn['user'] ?? null; - $params['PASSWORD'] = $conn['password'] ?? null; - $params['NAME'] = $conn['dbname'] ?? null; - $params['HOST'] = $conn['host'] ?? null; - $params['PORT'] = $conn['port'] ?? null; + $result = []; + foreach ($map as $key => $path) { + if (array_path_exists($path, $config)) { + $result[$key] = array_get_path($path, $config); + } } - return $params; + return $result; } public function getArrayCopy(): array diff --git a/module/Installer/test/ConfigProviderTest.php b/module/Installer/test/ConfigProviderTest.php new file mode 100644 index 00000000..a75a5fe0 --- /dev/null +++ b/module/Installer/test/ConfigProviderTest.php @@ -0,0 +1,29 @@ +configProvider = new ConfigProvider(); + } + + /** + * @test + */ + public function configIsReturned() + { + $config = $this->configProvider->__invoke(); + $this->assertEmpty($config); + } +} diff --git a/phpunit.xml.dist b/phpunit.xml.dist index f9f7797b..199b49bb 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -24,10 +24,7 @@ - ./module/Common/src - ./module/Core/src - ./module/Rest/src - ./module/CLI/src + ./module/*/src ./module/Core/src/Repository