This repository has been archived by the owner on Jul 10, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
892 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
<?php declare(strict_types=1); | ||
|
||
/** | ||
* This file is part of the Phalconator extension for Phalcon Framework. | ||
* | ||
* Copyright (C) Toroia Team <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE.txt | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Phalconator; | ||
|
||
use DirectoryIterator; | ||
use Exception; | ||
use Phalcon\Application; | ||
use Phalcon\Config; | ||
use Phalcon\Config\Adapter\Php as PhpConfig; | ||
use Phalcon\Config\Exception as ExceptionConfig; | ||
use Phalcon\Di; | ||
use Phalcon\DiInterface; | ||
use Phalconator\Config\Adapter\Env as EnvConfig; | ||
use function implode; | ||
|
||
/** | ||
* Class Bootstrap | ||
* | ||
* @package Phalconator | ||
*/ | ||
final class Bootstrap | ||
{ | ||
/** @var DiInterface $di */ | ||
protected $di; | ||
|
||
/** @var string $basePath */ | ||
protected $basePath; | ||
|
||
/** @var Application $app */ | ||
protected $app; | ||
|
||
/** @var Config $services */ | ||
protected $services; | ||
|
||
/** @var array $options */ | ||
protected $options = []; | ||
|
||
const ENV_PREFIX = 'TWA_'; | ||
const ENV_DELIMITER = '_'; | ||
const ENV_FILE_PATH = '/.env'; | ||
const API_MODULE_PREFIX = 'ApiModule'; | ||
const MODULES_DEFAULT_PATH = '/src/modules/'; | ||
const ENV_DEFAULT_PATH = '/src/config/env_default.php'; | ||
const SERVICES_DEFAULT_FILE = '/src/config/services_default.php'; | ||
|
||
/** | ||
* Bootstrap constructor. | ||
* | ||
* @param string $basePath | ||
* @param Application $app | ||
* @param Config $services | ||
* @param array $options | ||
*/ | ||
public function __construct(string $basePath, Application $app, ?Config $services, array $options = []) | ||
{ | ||
defined('STARTTIME') OR define('STARTTIME', microtime(true)); | ||
|
||
$this->di = new Di; | ||
|
||
$this->basePath = $basePath; | ||
$this->app = $app; | ||
$this->services = $services; | ||
|
||
$this->options = array_merge([ | ||
'envPrefix' => self::ENV_PREFIX, | ||
'envDelimiter' => self::ENV_DELIMITER, | ||
'envFilePath' => self::ENV_FILE_PATH, | ||
'envDefaultPath' => self::ENV_DEFAULT_PATH, | ||
'apiModulePrefix' => self::API_MODULE_PREFIX, | ||
'modulesDefaultPath' => self::MODULES_DEFAULT_PATH, | ||
'servicesDefaultFile' => self::SERVICES_DEFAULT_FILE | ||
], $options); | ||
} | ||
|
||
/** | ||
* Démarre l'application | ||
* | ||
* @return Application | ||
*/ | ||
public function run(): Application | ||
{ | ||
$this->configureApplication(); | ||
$this->importProviders(); | ||
|
||
if (!is_null($this->services)) { | ||
$this->registerModules(); | ||
} | ||
|
||
$this->app->setDI($this->di); | ||
return $this->app; | ||
} | ||
|
||
/** | ||
* Configure l'application | ||
* | ||
* @return self | ||
*/ | ||
protected function configureApplication(): self | ||
{ | ||
$basePath = $this->basePath; | ||
$options = $this->options; | ||
|
||
$this->di->setShared('config', function () use ($basePath, $options) { | ||
$configPath = implode(DIRECTORY_SEPARATOR, [$basePath, $options['envDefaultPath']]); | ||
|
||
$config = new PhpConfig($configPath); | ||
|
||
try { | ||
$envPath = implode(DIRECTORY_SEPARATOR, [$basePath, $options['envFilePath']]); | ||
|
||
if (file_exists($envPath)) { | ||
$envConfig = new EnvConfig($envPath, $options['envPrefix'], $options['envDelimiter']); | ||
$config->merge($envConfig); | ||
} | ||
|
||
// TODO: Gérer un warning log pour prévenir que l'application n'utilise pas de fichier de configuration | ||
|
||
} catch (ExceptionConfig $e) { | ||
//TODO: Gérer l'exception de configuration | ||
} | ||
|
||
return $config; | ||
}); | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Importe les providers | ||
* | ||
* @return self | ||
*/ | ||
protected function importProviders(): self | ||
{ | ||
$providerPath = implode(DIRECTORY_SEPARATOR, [$this->basePath, $this->options['servicesDefaultFile']]); | ||
|
||
$providerServices = new PhpConfig($providerPath); | ||
$providerServices->merge($this->services); | ||
|
||
// TODO: Gérer un warning pour prévenir que l'application n'implémente pas de service personalisés | ||
|
||
try { | ||
(new Provider($this->di)) | ||
->load($providerServices->toArray()) | ||
->register(); | ||
|
||
} catch (Exception $e) { | ||
//TODO: Gérer l'exception de génération du provider | ||
} | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Enregistre les modules au sein de l'application | ||
* | ||
* @return self | ||
*/ | ||
protected function registerModules(): self | ||
{ | ||
$registeredModules = []; | ||
$modulesPath = implode(DIRECTORY_SEPARATOR, [$this->basePath, $this->options['modulesDefaultPath']]); | ||
|
||
foreach (new DirectoryIterator($modulesPath) as $module) { | ||
if ($module->isDot()) continue; | ||
if (!$module->isDir()) continue; | ||
|
||
if (($strpos = strpos($module->getBasename(), $this->options['apiModulePrefix'])) !== false) { | ||
$moduleName = substr($module->getBasename(), $strpos + strlen($this->options['apiModulePrefix'])); | ||
|
||
$registeredModules[strtolower($moduleName)] = [ | ||
'className' => 'Toroia\Modules\\' . ucfirst($moduleName) . '\Module', | ||
'path' => implode(DIRECTORY_SEPARATOR, [$module->getRealPath(), 'Module.php']) | ||
]; | ||
} | ||
|
||
// TODO: Gérer un warning quand un dossier ne contient pas le préfix | ||
} | ||
$this->app->registerModules($registeredModules); | ||
|
||
return $this; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
<?php declare(strict_types=1); | ||
|
||
/** | ||
* This file is part of the Phalconator extension for Phalcon Framework. | ||
* | ||
* Copyright (C) Toroia Team <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE.txt | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Phalconator\Config\Adapter; | ||
|
||
use Phalcon\Config; | ||
use Phalcon\Config\Exception; | ||
|
||
/** | ||
* Class Env | ||
* | ||
* @package Phalconator\Config\Adapter | ||
*/ | ||
class Env extends Config | ||
{ | ||
const DEFAULT_DELIMITER = '_'; | ||
|
||
/** | ||
* Env constructor. | ||
* | ||
* @param string|null $filePath | ||
* @param string|null $prefix | ||
* @param string|null $delimiter | ||
* @throws Exception | ||
*/ | ||
public function __construct(?string $filePath, ?string $prefix, ?string $delimiter) | ||
{ | ||
if (empty($delimiter)) { | ||
$delimiter = self::DEFAULT_DELIMITER; | ||
} | ||
|
||
$envConfig = $this->parseEnvConfig($prefix, $delimiter); | ||
|
||
if (!is_null($filePath)) { | ||
$envFile = $this->parseEnvFile($filePath, $prefix, $delimiter); | ||
|
||
if ($envFile === false) { | ||
throw new Exception("Configuration file " . basename($filePath) . " can't be loaded"); | ||
} | ||
} | ||
|
||
$config = array_merge($envConfig, $envFile ?? []); | ||
|
||
parent::__construct($config); | ||
} | ||
|
||
private function parseEnvConfig($prefix, $delimiter) | ||
{ | ||
$config = []; | ||
|
||
foreach (getenv() as $key => $value) { | ||
if (strpos($key, $prefix) !== false) { | ||
$key = str_replace($prefix, '', $key); | ||
$keys = explode($delimiter, $key); | ||
|
||
$value = $this->assignValueType($value); | ||
|
||
$this->assignArrayKeys($config, $keys, $value); | ||
} | ||
} | ||
|
||
return $config; | ||
} | ||
|
||
/** | ||
* Envfile parser | ||
* | ||
* @param string $filePath | ||
* @param string $prefix | ||
* @param null|string $delimiter | ||
* @return array|bool | ||
*/ | ||
private function parseEnvFile(string $filePath, string $prefix, ?string $delimiter) | ||
{ | ||
if ($content = file_get_contents($filePath)) { | ||
$config = []; | ||
$lines = explode(PHP_EOL, $content); | ||
$re = '/^(?:' . $prefix . ')\s*([\w\.\-]+)\s*=\s*(.*)?\s*$/'; | ||
|
||
foreach ($lines as $line) { | ||
if (preg_match($re, $line, $keysValue)) { | ||
$keys = explode($delimiter, $keysValue[1]); | ||
$value = $keysValue[2] ?? null; | ||
$length = strlen($value) ?? 0; | ||
|
||
if ($length > 0 && strpos($value, '"') === 0 && substr($value, -1) === '"') { | ||
$value = preg_replace('/\\n/gm', "\n", $value); | ||
} | ||
|
||
$value = trim(preg_replace('/(^[\'"]|[\'"]$)/', '', $value)); | ||
|
||
$value = $this->assignValueType($value); | ||
|
||
$this->assignArrayKeys($config, $keys, $value); | ||
} | ||
} | ||
|
||
return $config; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/** | ||
* Assigne une chaine à son type respectif | ||
* | ||
* @param string|null $value | ||
* @return mixed | ||
*/ | ||
private function assignValueType(?string $value) | ||
{ | ||
switch (true) { | ||
// Integer | ||
case ctype_digit($value): | ||
return intval($value); | ||
|
||
// Float | ||
case !ctype_digit($value) && is_numeric($value): | ||
return floatval($value); | ||
|
||
// Boolean | ||
case $value == "true": | ||
return true; | ||
case $value == "false": | ||
return false; | ||
|
||
// Null | ||
case $value == "null": | ||
case empty($value): | ||
return null; | ||
|
||
// String | ||
default: | ||
return $value; | ||
} | ||
} | ||
|
||
/** | ||
* Assigne en cascade un tableau clé/valeurs | ||
* | ||
* @param array $arr | ||
* @param array $keys | ||
* @param mixed $value | ||
*/ | ||
private function assignArrayKeys(array &$arr, array $keys, $value) | ||
{ | ||
foreach ($keys as $key) { | ||
$arr = &$arr[strtolower($key)]; | ||
} | ||
|
||
$arr = $value; | ||
} | ||
} |
Oops, something went wrong.