BaseEnv → GenericConfig + InsensitiveCaseArrayClass

2.x
Julien Rosset 3 years ago
parent 70a7652db2
commit 0cc6aee547

@ -6,7 +6,8 @@
"minimum-stability": "stable", "minimum-stability": "stable",
"require": { "require": {
"php": "^7.4 || ^8.0", "php": "^7.4 || ^8.0",
"jrosset/singleton": "^1.0" "jrosset/singleton": "^1.0",
"jrosset/arrayclasses": "^1.0"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {

@ -5,6 +5,9 @@ namespace jrosset\EnvReader;
use DateTime; use DateTime;
use DateTimeInterface; use DateTimeInterface;
use Exception; use Exception;
use jrosset\ArrayClasses\IArrayCast;
use jrosset\ArrayClasses\ImmutableInsensitiveCaseArrayClass;
use jrosset\ArrayClasses\InsensitiveCaseArrayClass;
use jrosset\Singleton\TSingleton; use jrosset\Singleton\TSingleton;
use RangeException; use RangeException;
use UnexpectedValueException; use UnexpectedValueException;
@ -12,22 +15,15 @@ use UnexpectedValueException;
/** /**
* Utility class to get informations from ENV file * Utility class to get informations from ENV file
* *
* You should overwrite {@see BaseEnv::PATH_ENV} to set ENV file path<br> * Overwrite {@see GenericConfig::initialProperties()} to set initial properties
* Overwrite {@see BaseEnv::initProperties()} to set initial properties
*/ */
abstract class BaseEnv { abstract class GenericConfig {
use TSingleton; use TSingleton;
/** /**
* ENV file path * @var InsensitiveCaseArrayClass Current properties
*/ */
protected const PATH_ENV = '.env'; protected InsensitiveCaseArrayClass $properties;
/**
* @var string[] Current properties, read from ENV file (&lt;property name&gt; => &lt;property value&gt;)<br>
* <b>NOTE:</b> All properties' name are stored in upper-case
*/
private array $properties;
/** /**
* Initialize initial properties then read ENV file * Initialize initial properties then read ENV file
@ -35,66 +31,37 @@ abstract class BaseEnv {
* @throws Exception If ENV can't be read * @throws Exception If ENV can't be read
*/ */
protected function __construct () { protected function __construct () {
$this->properties = array_change_key_case($this->initProperties(), CASE_UPPER); $this->properties = new InsensitiveCaseArrayClass($this->initialProperties());
$this->readEnv(); $this->readConfig();
} }
/** /**
* Initialize initial properties * Initial properties
*
* @return string[]|IArrayCast Initial properties
* *
* @return string[] Properties initial values (&lt;property name&gt; => &lt;property value&gt;) * @noinspection PhpReturnDocTypeMismatchInspection
*/ */
protected function initProperties (): array { protected function initialProperties () {
return [ return [
'APP_DEV' => 0, 'APP_DEV' => 0,
]; ];
} }
/** /**
* Read the ENV file * Read the configuration file
* *
* @throws Exception If ENV can't be read * @return void
*
* @throws Exception If the configuration file is invalid
*/ */
private function readEnv (): void { protected abstract function readConfig (): void;
if (!file_exists(static::PATH_ENV)) {
return;
}
$lines = file(static::PATH_ENV, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if ($lines === false) {
throw new Exception('Unable to read environment file "' . static::PATH_ENV . '"');
}
foreach ($lines as $line) {
if (preg_match('/^\s*(?:(?<comment>#).*|(?<key>[a-zA-Z0-9_-]+)=(?<value>.+?))$/i', $line, $match) !== 1) {
continue; // Ligne invalide
}
if (isset($match['comment']) && trim($match['comment']) !== '') {
continue; // Commentaire
}
if (preg_match('/^"(?<payload>.+)(?<!(?<!\\\\)\\\\)"$/', $match['value'], $matchValue) === 1) {
$match['value'] = preg_replace(
[
'/(?<!\\\\)\\\\"/',
'/\\\\\\\\/',
],
[
'"',
'\\',
],
$matchValue['payload']
);
}
$this->properties[mb_strtoupper($match['key'])] = $match['value'];
}
}
/** /**
* Get all properties * Get all properties
* *
* @return string[] Get all properties (properties' name are in upper case) * @return ImmutableInsensitiveCaseArrayClass Get all properties (properties' name are in upper case)
*/ */
public function getProperties (): array { public function getProperties (): ImmutableInsensitiveCaseArrayClass {
return $this->properties; return $this->properties;
} }
/** /**
@ -105,7 +72,7 @@ abstract class BaseEnv {
* @return bool Is the property defined ? * @return bool Is the property defined ?
*/ */
public function hasProperty (string $name): bool { public function hasProperty (string $name): bool {
return array_key_exists(mb_strtoupper($name), $this->getProperties()); return $this->properties->has($name);
} }
/** /**
* Get a property value * Get a property value
@ -119,7 +86,6 @@ abstract class BaseEnv {
* @throws UnexpectedValueException If property is not set AND $default is Null * @throws UnexpectedValueException If property is not set AND $default is Null
*/ */
public function getProperty (string $name, ?string $default = null): string { public function getProperty (string $name, ?string $default = null): string {
$name = mb_strtoupper($name);
if (!$this->hasProperty($name)) { if (!$this->hasProperty($name)) {
if ($default === null) { if ($default === null) {
throw new UnexpectedValueException('The "' . $name . '" property is not set'); throw new UnexpectedValueException('The "' . $name . '" property is not set');
@ -127,7 +93,7 @@ abstract class BaseEnv {
return $default; return $default;
} }
return $this->properties[$name]; return $this->properties->get($name);
} }
/** /**
Loading…
Cancel
Save