Skip to content

Commit

Permalink
Merge pull request #40 from gacela-project/feature/refactor-config
Browse files Browse the repository at this point in the history
Refactor Config: extract ConfigInit logic
  • Loading branch information
Chemaclass authored Jul 10, 2021
2 parents 73c2573 + 22138d2 commit 7773a0d
Show file tree
Hide file tree
Showing 9 changed files with 353 additions and 116 deletions.
141 changes: 32 additions & 109 deletions src/Framework/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

namespace Gacela\Framework;

use Gacela\Framework\Config\ConfigInit;
use Gacela\Framework\Config\ConfigReader\EnvConfigReader;
use Gacela\Framework\Config\ConfigReader\PhpConfigReader;
use Gacela\Framework\Config\ConfigReaderException;
use Gacela\Framework\Config\ConfigReaderInterface;
use Gacela\Framework\Config\GacelaJsonConfig;
use Gacela\Framework\Config\GacelaJsonConfigItem;
use Gacela\Framework\Config\GacelaJsonConfigFactory;
use Gacela\Framework\Config\GacelaJsonConfigFactoryInterface;
use Gacela\Framework\Config\PathFinder;
use Gacela\Framework\Config\PathFinderInterface;
use Gacela\Framework\Exception\ConfigException;

final class Config
Expand All @@ -20,31 +22,22 @@ final class Config

private static ?self $instance = null;

/** @var array<string,ConfigReaderInterface> */
private array $readers;

private array $config = [];

/**
* @param array<string,ConfigReaderInterface> $readers
*/
private function __construct(array $readers)
{
$this->readers = $readers;
}

public static function getInstance(): self
{
if (self::$instance === null) {
self::$instance = new self([
'php' => new PhpConfigReader(),
'env' => new EnvConfigReader(),
]);
self::$instance = new self();
}

return self::$instance;
}

public static function setApplicationRootDir(string $dir): void
{
self::$applicationRootDir = $dir;
}

public static function getApplicationRootDir(): string
{
if (empty(self::$applicationRootDir)) {
Expand All @@ -54,11 +47,6 @@ public static function getApplicationRootDir(): string
return self::$applicationRootDir;
}

public static function setApplicationRootDir(string $dir): void
{
self::$applicationRootDir = $dir;
}

/**
* @param null|mixed $default
*
Expand Down Expand Up @@ -88,105 +76,40 @@ public function get(string $key, $default = null)
*/
public function init(): void
{
$gacelaJson = $this->createGacelaJsonConfig();
$configs = [];

foreach ($this->scanAllConfigFiles($gacelaJson) as $absolutePath) {
$configs[] = $this->readConfigFromFile($gacelaJson, $absolutePath);
}

$configs[] = $this->loadLocalConfigFile($gacelaJson);

$this->config = array_merge(...$configs);
$this->config = (new ConfigInit(
self::getApplicationRootDir(),
$this->createGacelaJsonConfigCreator(),
$this->createPathFinder(),
$this->createConfigReaders()
))->readAll();
}

private function hasValue(string $key): bool
private function createGacelaJsonConfigCreator(): GacelaJsonConfigFactoryInterface
{
return isset($this->config[$key]);
return new GacelaJsonConfigFactory(
self::$applicationRootDir,
self::GACELA_CONFIG_FILENAME
);
}

private function createGacelaJsonConfig(): GacelaJsonConfig
private function createPathFinder(): PathFinderInterface
{
$gacelaJsonPath = self::getApplicationRootDir() . '/' . self::GACELA_CONFIG_FILENAME;

if (is_file($gacelaJsonPath)) {
/** @psalm-suppress MixedArgumentTypeCoercion */
return GacelaJsonConfig::fromArray(
(array)json_decode(file_get_contents($gacelaJsonPath), true)
);
}

return GacelaJsonConfig::withDefaults();
return new PathFinder();
}

/**
* @throws ConfigException
*
* @return string[]
* @return array<string, ConfigReaderInterface>
*/
private function scanAllConfigFiles(GacelaJsonConfig $gacelaJsonConfig): array
{
$configGroup = array_map(
fn (GacelaJsonConfigItem $config): array => array_map(
static fn ($p): string => (string)$p,
array_diff(
glob($this->generateAbsolutePath($config->path())),
[$this->generateAbsolutePath($config->pathLocal())]
)
),
$gacelaJsonConfig->configs()
);

return array_merge(...$configGroup);
}

private function readConfigFromFile(GacelaJsonConfig $gacelaJson, string $absolutePath): array
{
$result = [];

foreach ($gacelaJson->configs() as $config) {
$result[] = $this->readConfigItem($config, $absolutePath);
}

return array_merge(...array_filter($result));
}

private function loadLocalConfigFile(GacelaJsonConfig $gacelaJson): array
{
$result = [];

foreach ($gacelaJson->configs() as $config) {
$configLocalAbsolutePath = $this->generateAbsolutePath($config->pathLocal());

if (is_file($configLocalAbsolutePath)) {
$result[] = $this->readConfigItem($config, $configLocalAbsolutePath);
}
}

return array_merge(...array_filter($result));
}

private function generateAbsolutePath(string $relativePath): string
private function createConfigReaders(): array
{
return sprintf(
'%s/%s',
self::getApplicationRootDir(),
$relativePath
);
return [
'php' => new PhpConfigReader(),
'env' => new EnvConfigReader(),
];
}

private function readConfigItem(GacelaJsonConfigItem $config, string $absolutePath): array
private function hasValue(string $key): bool
{
$reader = $this->readers[$config->type()] ?? null;

if ($reader === null) {
throw ConfigReaderException::notSupported($config->type(), $this->readers);
}

if ($reader->canRead($absolutePath)) {
return $reader->read($absolutePath);
}

return [];
return isset($this->config[$key]);
}
}
113 changes: 113 additions & 0 deletions src/Framework/Config/ConfigInit.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?php

declare(strict_types=1);

namespace Gacela\Framework\Config;

final class ConfigInit
{
private string $applicationRootDir;

private GacelaJsonConfigFactoryInterface $configFactory;

private PathFinderInterface $pathFinder;

/** @var array<string,ConfigReaderInterface> */
private array $readers;

/**
* @param array<string,ConfigReaderInterface> $readers
*/
public function __construct(
string $applicationRootDir,
GacelaJsonConfigFactoryInterface $configFactory,
PathFinderInterface $pathFinder,
array $readers
) {
$this->applicationRootDir = $applicationRootDir;
$this->configFactory = $configFactory;
$this->pathFinder = $pathFinder;
$this->readers = $readers;
}

public function readAll(): array
{
$gacelaJsonConfig = $this->configFactory->createGacelaJsonConfig();
$configs = [];

foreach ($this->scanAllConfigFiles($gacelaJsonConfig) as $absolutePath) {
$configs[] = $this->readConfigFromFile($gacelaJsonConfig, $absolutePath);
}

$configs[] = $this->readLocalConfigFile($gacelaJsonConfig);

return array_merge(...$configs);
}

/**
* @return string[]
*/
private function scanAllConfigFiles(GacelaJsonConfig $gacelaJsonConfig): array
{
$configGroup = array_map(
fn (GacelaJsonConfigItem $config): array => array_map(
static fn ($p): string => (string)$p,
array_diff(
$this->pathFinder->matchingPattern($this->generateAbsolutePath($config->path())),
[$this->generateAbsolutePath($config->pathLocal())]
)
),
$gacelaJsonConfig->configs()
);

return array_merge(...$configGroup);
}

private function readConfigFromFile(GacelaJsonConfig $gacelaJson, string $absolutePath): array
{
$result = [];

foreach ($gacelaJson->configs() as $config) {
$result[] = $this->readConfigItem($config, $absolutePath);
}

return array_merge(...array_filter($result));
}

private function readLocalConfigFile(GacelaJsonConfig $gacelaJson): array
{
$result = [];

foreach ($gacelaJson->configs() as $config) {
$absolutePath = $this->generateAbsolutePath($config->pathLocal());

$result[] = $this->readConfigItem($config, $absolutePath);
}

return array_merge(...array_filter($result));
}

private function generateAbsolutePath(string $relativePath): string
{
return sprintf(
'%s/%s',
$this->applicationRootDir,
$relativePath
);
}

private function readConfigItem(GacelaJsonConfigItem $config, string $absolutePath): array
{
$reader = $this->readers[$config->type()] ?? null;

if ($reader === null) {
throw ConfigReaderException::notSupported($config->type(), $this->readers);
}

if ($reader->canRead($absolutePath)) {
return $reader->read($absolutePath);
}

return [];
}
}
6 changes: 5 additions & 1 deletion src/Framework/Config/ConfigReader/EnvConfigReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@ public function canRead(string $absolutePath): bool

public function read(string $absolutePath): array
{
$config = [];
if (!is_file($absolutePath)) {
return [];
}

$config = [];
$lines = file($absolutePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

foreach ($lines as $line) {
if (strpos(trim($line), '#') === 0) {
continue;
Expand Down
12 changes: 6 additions & 6 deletions src/Framework/Config/ConfigReader/PhpConfigReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ public function canRead(string $absolutePath): bool

public function read(string $absolutePath): array
{
if (file_exists($absolutePath)) {
/** @var null|array $content */
$content = include $absolutePath;

return is_array($content) ? $content : [];
if (!file_exists($absolutePath)) {
return [];
}

return [];
/** @var null|array $content */
$content = include $absolutePath;

return is_array($content) ? $content : [];
}
}
33 changes: 33 additions & 0 deletions src/Framework/Config/GacelaJsonConfigFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Gacela\Framework\Config;

final class GacelaJsonConfigFactory implements GacelaJsonConfigFactoryInterface
{
private string $applicationRootDir;
private string $gacelaConfigFilename;

public function __construct(
string $applicationRootDir,
string $gacelaConfigFilename
) {
$this->applicationRootDir = $applicationRootDir;
$this->gacelaConfigFilename = $gacelaConfigFilename;
}

public function createGacelaJsonConfig(): GacelaJsonConfig
{
$gacelaJsonPath = $this->applicationRootDir . '/' . $this->gacelaConfigFilename;

if (is_file($gacelaJsonPath)) {
/** @psalm-suppress MixedArgumentTypeCoercion */
return GacelaJsonConfig::fromArray(
(array)json_decode(file_get_contents($gacelaJsonPath), true)
);
}

return GacelaJsonConfig::withDefaults();
}
}
10 changes: 10 additions & 0 deletions src/Framework/Config/GacelaJsonConfigFactoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Gacela\Framework\Config;

interface GacelaJsonConfigFactoryInterface
{
public function createGacelaJsonConfig(): GacelaJsonConfig;
}
Loading

0 comments on commit 7773a0d

Please sign in to comment.