Skip to content
This repository has been archived by the owner on Jul 10, 2020. It is now read-only.

Commit

Permalink
Base for MongoDb in Php #2
Browse files Browse the repository at this point in the history
  • Loading branch information
tacxou committed Apr 29, 2019
1 parent 5f13e0b commit 15607d3
Show file tree
Hide file tree
Showing 6 changed files with 892 additions and 0 deletions.
192 changes: 192 additions & 0 deletions src/Bootstrap.php
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;
}
}
161 changes: 161 additions & 0 deletions src/Config/Adapter/Env.php
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;
}
}
Loading

0 comments on commit 15607d3

Please sign in to comment.