Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
ncou committed Nov 27, 2021
1 parent b431e4f commit 9424f91
Show file tree
Hide file tree
Showing 9 changed files with 46 additions and 32 deletions.
9 changes: 5 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"homepage": "https://github.com/ncou/Chiron",
"license": "MIT",
"require": {
"php": ">=7.2",
"php": "^8.0|^8.1",
"ext-json": "*",
"ext-xml": "*",
"ext-mbstring": "*",
Expand All @@ -16,9 +16,10 @@
"chiron/discover": "^1.0"
},
"require-dev": {
"squizlabs/php_codesniffer": "^3.0",
"phpunit/phpunit": "^7.0",
"phpstan/phpstan": "^0.9.2",
"phpunit/phpunit": "^9.5",
"phpstan/phpstan": "^0.12.0",
"phpstan/phpstan-phpunit": "^0.12",
"chiron/coding-standard": "^3.0",
"filp/whoops": "^2.2",
"chiron/template": "^1.1",
"nyholm/psr7": "^1.1"
Expand Down
24 changes: 15 additions & 9 deletions src/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use Chiron\Container\Container;
use Chiron\Core\Engine\EngineInterface;
use Chiron\Debug\ErrorHandler;
use Chiron\Exception\ApplicationException;
use Chiron\Core\Exception\ImproperlyConfiguredException;
use Chiron\Service\ServiceManager;
use Chiron\Core\Container\ContainerFactory;
use Chiron\Service\Provider\CoreServiceProvider;
Expand Down Expand Up @@ -61,6 +61,7 @@
// Exemple : https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Console/Application.php#L112
// Exemple : https://github.com/symfony/console/blob/master/Application.php#L595

// TOD : au lieu d'avoir la variable de classe public il faudrait plutot avoir une méthode public getContainer() dans cette classe.
final class Application
{
/** @var EngineInterface[] */
Expand All @@ -78,13 +79,14 @@ final class Application
// TODO : permettre de passer en paramétre une liste de "providers" ??? ca permettrait de facilement initialiser l'application avec une redéfinition de certains service par l'utilisateur !!!
// TODO : il faudrait automatiquement ajouter le ConsoleDispatcher à l'application car on aura toujours le package chiron/console de présent pour ce framework et on doit pourvoir utiliser la console, donc ajouter d'office cette classe au tableau des dispatchers ca nous fera gagner du temps (et donc la classe Console\Bootloader\ConsoleDispatcherBootloader n'est plus nécessaire !!!!)
// TODO : déplacer tout ce code directement dans le constructeur ? En passant le constructeur en public, car je ne pense pas qu'il y ait un interet particulier à garder une méthode static init !!!!
// TODO : il faudrait surement gérer une structure de répertoires par défaut si on ne passe pas de valeur pour le paramétre $paths !!!
public function __construct(array $paths, array $values = [])
{
// TODO : il faudrait gérer le cas ou l'application est déjà "create" et qu'on récupére cette instance plutot que de rappeller la méthode. (c'est dans le cas ou l'utilisateur fait un App::create qu'il ajoute des providers ou autre et qu'ensuite il fasse un App::init pour finaliser l'initialisation !!!) Je suppose qu'il faudra garder un constante public de classe static avec l'instance (comme pour Container::$instance). Cela permettra aussi de créer une fonction globale "app()" qui retournera l'instance de la classe Application::class. Cela permettra en plus de la facade Facade\Application de passer par cette méthode pour injecter des bootloader par exemple.
$this->services = new ServiceManager(); // TODO : créer une méthode privée self::create() qui retournerait l'application crééer, on pourrait aussi mettre dans cette fonction les lignes de code qui permettent de charger le CoseServiceProvider, et la ligne qui fait le bindsingleton de l'instance $app. Eventuellement utiliser aussi cette méthode pour faire le addDispatcher(new ConsoleDispatcher()) !!!

// +++ Bind all the core services. +++
$this->services->addProvider(new CoreServiceProvider());
$this->services->addProvider(new CoreServiceProvider()); // TODO : il faudrait créer dans ce CoreServiceProvider une partie pour binder en singleton une classe ServiceManager et qui utiliserait le ServicesConfig pour initialiser cette classe !!!! cela permettra de supprimer la classe ServicesBootloader (en fait on ferait comme pour les fichiers de config events et console/settings !!!!)
// +++ Boot all the app services. +++
$this->services->addBootloader(new DirectoriesBootloader($paths));
$this->services->addBootloader(new EnvironmentBootloader($values));
Expand All @@ -102,14 +104,14 @@ public function __construct(array $paths, array $values = [])
$this->services->addBootloader(new PackageManifestBootloader());
$this->services->addBootloader(new ServicesBootloader());


$container = $this->services->container;

// TODO : lever un évenement de type "InitEvent" en attachant l'application comme paramétre, et c'est à ce moment là que le listener ajouterai le ConsoleEngine !!!!
$this->addEngine(new ConsoleEngine($container->injector()));

// Register the application instance as singleton in the container.
// TODO : déplacer cet appel directement dans le constructeur de la classe Application::class ????
// TODO : il faudrait récupérer ici le eventdispatcher et faire un trigger sur l'événement InitApplicationEvent::class avec l'instance de l'application à stocker dans ce event. On ajoutera un listener dans les packages Sapi/Roadrunner/Workerman/ReactPHP pour injecter le EngineInterface pour ces différents packages.

// Bind the application instance as singleton in the container.
$container->singleton(self::class, $this);
}

Expand All @@ -121,8 +123,7 @@ public function __construct(array $paths, array $values = [])
// TODO : il faudrait gérer le cas ou l'on souhaite ajouter un dispatcher au dessus de la stack. Ajouter un paramétre 'bool $onTop = false' à cette méthode ????
// TODO : permettre de gérer les dispatchers dans les fichiers composer.json (partie "extra") et les charger via le packagemanifest ????
// TODO : permettre de passer une string en paramétre et utiliser le container qui est aussi un FactoryInterface pour "créer" la classe passée en paramétre !!!
// TODO : permettre de passer une string pour le dispatcher ca sera plus simple pour l'utilisateur. utiliser la fonction "resolve()" et vérifier que le type de retour est bien un objet qui implémente DispatcherInterface !!!!
// TODO : renommer les dispatcher en engine et appeller la méthode ignite() puis run() et isActive() sur le engine au lieu de la méthode dispatch()
// TODO : permettre de passer une string pour le engine ca sera plus simple pour l'utilisateur. utiliser la fonction "resolve()" et vérifier que le type de retour est bien un objet qui implémente EngineInterface !!!!
public function addEngine(EngineInterface $engine): void
{
$this->engines[] = $engine;
Expand All @@ -131,7 +132,7 @@ public function addEngine(EngineInterface $engine): void
/**
* Start application and process user requests using selected dispatcher or throw an exception.
*
* @throws RuntimeException
* @throws ImproperlyConfiguredException
*
* @return mixed Could be an 'int' for command-line dispatcher or 'void' for web dispatcher.
*/
Expand All @@ -143,6 +144,10 @@ public function start()
// TODO : il faudrait surement mettre un try/catch autour de la méthode boot() et dans le catch utiliser la classe ErrorHandler::handleException($e) pour afficher les erreurs, ca permettrait d'aoir une gestion des erreurs même si l'utilisateur n'a pas utilisé la méthode init() avec le paramétre $handleErrors à true !!! https://github.com/spiral/framework/blob/e63b9218501ce882e661acac284b7167b79da30a/src/Boot/src/AbstractKernel.php#L146
$this->services->boot();

// TODO : récupérer le EventDispatcher dans le service->container et trigger l'evenement ApplicationStartedEvent::class avec en paramétre le $this pour qu'on puisse manipuler l'application (par exemple pour ajouter un engine !!!!). ou l'event ApplicationBootedEvent::class



// Dispatch the request based on the environment values (ex: Console or Web dispatcher).
foreach ($this->engines as $engine) {
if ($engine->isActive()) {
Expand All @@ -154,7 +159,8 @@ public function start()

// TODO : lever aussi une ApplicationException en début de méthode (juste aprés l'appel à la méthode ->boot()) dans le cas le tableau de $this->dispatchers est vide, car cela signifie que l'application est mal initialisée, et donc afficher un message pour demander à l'utilisateur de définir à minima un dispatcher !!!!
// TODO : utiliser plutot l'exception ImproperlyConfiguredException ???? qui est dans le package chiron/core, cela permettra de virer la classe ApplicationException !!!!
throw new ApplicationException('Unable to locate active engine.');
// TODO : créer une exception EngineNotFoundException ???? eventuellement la faire étendre de l'exception ImproperlyConfiguredException ????
throw new ImproperlyConfiguredException('Unable to locate active engine for application.'); // TODO : afficher le contenu du tableau $this->engines ? genre on affiche un message différent si il est vide, et sinon on affiche une liste des classname en utilisant un array_map + un explode($engines, ',') ????
}

/**
Expand Down
5 changes: 4 additions & 1 deletion src/Command/AboutCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Helper\TableSeparator;

//https://github.com/matriphe/larinfo/tree/master/src

//https://github.com/hhxsv5/laravel-s/blob/master/src/Illuminate/LaravelSCommand.php#L69
//https://github.com/flarum/core/blob/master/src/Foundation/Console/InfoCommand.php

Expand All @@ -24,6 +26,7 @@
// TODO : passer les méthodes "perform" en protected pour chaque classe de type "Command"
final class AboutCommand extends AbstractCommand
{
// TODO : renommer la commande en "info" ???? + renommer la commande !!!!
protected static $defaultName = 'about';

/**
Expand Down Expand Up @@ -98,7 +101,7 @@ private static function formatPath(string $path, string $baseDir): string

//https://github.com/cakephp/filesystem/blob/master/Folder.php#L658
//https://github.com/JBZoo/Utils/blob/5a2b7c01f48318585212fa9876c8c48c8817d974/src/FS.php#L222
// TODO : déplacer cette fonction dans la classe filesystem::class ou path::class ?
// TODO : déplacer cette fonction dans la classe Filesystem::class ou Path::class ?
private static function formatFileSize(string $path): string
{
if (is_file($path)) {
Expand Down
9 changes: 7 additions & 2 deletions src/Command/EventListCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@
use Chiron\Event\ListenerData;
use ReflectionObject;

// TODO : exemple avec un filtre sur les noms => https://github.com/symfony/framework-bundle/blob/4a8f8840cc4c162cf1d31b22902db4c169b87517/Command/DebugAutowiringCommand.php

// TODO : améliorer le filtrage des évents via l'option --events https://symfony.com/doc/current/event_dispatcher.html#debugging-event-listeners

// TODO : https://github.com/symfony/symfony/blob/e34cd7dd2c6d0b30d24cad443b8f964daa841d71/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php

//https://github.com/hyperf/devtool/blob/master/src/Describe/ListenersCommand.php
//https://github.com/hyperf/hyperf/blob/2aa967ed6b0f55c4f8a09e0e69a85d5a4bf72f27/src/devtool/src/Describe/ListenersCommand.php

// TODO : afficher aussi la priorité de chaque event, éventuellement faire un sort sur la priorité pour afficher le détail des listeners à executer dans l'ordre des priorité, cela pourra aider lors du debug !!!!
Expand Down Expand Up @@ -82,7 +85,7 @@ private function handleData(ListenerProviderInterface $provider, ?array $events)
continue;
}

$data[$event] = $this->describesCallables($listeners);
$data[$event] = $this->describesCallables($listeners); // TODO : utiliser la méthode Support\Callback::toString pour avoir la description du callable !!!
}

return $data;
Expand All @@ -97,6 +100,7 @@ private function handleData(ListenerProviderInterface $provider, ?array $events)
*/
// TODO : code à améliorer !!! et à déplacer dans une classe de type VarDumper ???
// TODO : fonction à renommer en exportCallables ????
// TODO : utiliser la méthode Support\Callback::toString pour avoir la description du callable !!!
private function describesCallables(array $callables): array
{
$data = [];
Expand All @@ -107,7 +111,8 @@ private function describesCallables(array $callables): array
}
if (is_object($callable)) {
if($callable instanceof \Closure) {
$data[] = 'Closure()'; // TODO : éventuellement afficher le fichier+ligne de la closure en utilisant une reflection !!!
$data[] = 'Closure()'; // TODO : éventuellement afficher le fichier+ligne de la closure en utilisant une reflection !!! regarder la méthode getClosureSignature ici : https://github.com/yiisoft/injector/blob/master/src/ArgumentException.php#L40
// TODO : eventuellement faire un unwrap de la closure pour retrouver la méthode source lorsqu'on a fait un Closure::fromCallable => https://github.com/nette/utils/blob/master/src/Utils/Callback.php#L120
} else {
$data[] = get_class($callable);
}
Expand Down
2 changes: 2 additions & 0 deletions src/Command/PublishCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
use Chiron\Publisher\Exception\PublisherException;
use Closure;

//https://github.com/hyperf/devtool/blob/master/src/VendorPublishCommand.php

// DOCUMENTATION : https://stillat.com/blog/2016/12/07/laravel-artisan-vendor-command-the-vendorpublish-command

//https://github.com/laravelista/lumen-vendor-publish/blob/master/src/VendorPublishCommand.php
Expand Down
4 changes: 4 additions & 0 deletions src/Command/ThanksCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@

//https://github.com/loophp/launcher/blob/master/src/Launcher.php

//https://github.com/mezzio/mezzio-skeleton/blob/3.11.x/src/MezzioInstaller/OptionalPackages.php#L204
//https://github.com/mezzio/mezzio-skeleton/blob/3.11.x/src/MezzioInstaller/OptionalPackages.php#L234

//https://stackoverflow.com/questions/29078380/how-do-i-run-a-symfony-console-command-after-composer-install
//https://github.com/sensiolabs/SensioDistributionBundle/blob/master/Composer/ScriptHandler.php

Expand All @@ -42,6 +45,7 @@
// TODO : passer les méthodes "perform" en protected pour chaque classe de type "Command"
final class ThanksCommand extends AbstractCommand
{
// TODO : renommer en chiron:thanks
protected static $defaultName = 'thanks';

/** @var array<int, string> */
Expand Down
9 changes: 0 additions & 9 deletions src/Exception/ApplicationException.php

This file was deleted.

10 changes: 5 additions & 5 deletions src/Service/Bootloader/DirectoriesBootloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Chiron\Core\Directories;
use Chiron\Core\Container\Bootloader\AbstractBootloader;
use Chiron\Core\Exception\DirectoryException;
use Chiron\Core\Exception\ImproperlyConfiguredException;
//use Chiron\Framework;
use Chiron\Views\TemplateRendererInterface;
use Chiron\Filesystem\Filesystem;
Expand Down Expand Up @@ -57,7 +57,7 @@ private static function mapDirectories(array $paths): array
// TODO : je pense que root / public et runtime sont les 3 répertoires obligatoires, mais à vérifier !!!!
// ensure mandatory directory alias '@root' is defined by the user.
if (! isset($aliases['@root'])) {
throw new DirectoryException('Missing required directory alias "@root".');
throw new ImproperlyConfiguredException('Missing required directory alias "@root".');
}

// TODO : il faudrait pas ajouter un répertoire pour les logs ???? => https://github.com/spiral/app/blob/85705bb7a0dafd010a83fa4bcc7323b019d8dda3/app/src/Bootloader/LoggingBootloader.php#L29
Expand Down Expand Up @@ -95,7 +95,7 @@ private static function normalizeAliases(array $paths): array

foreach ($paths as $alias => $path) {
if (! is_string($alias)) {
throw new DirectoryException('Directories paths aliases must be an associative array.');
throw new ImproperlyConfiguredException('Directories paths aliases must be an associative array.');
}
// check if alias doesn't start with '@'
// TODO : utiliser la méthode Str::startWith(xxxx)
Expand All @@ -120,11 +120,11 @@ private static function assertWritableDir(Directories $directories, array $alias
$path = $directories->get($alias);

if (! is_dir($path)) {
throw new DirectoryException(sprintf('Directory "%s" (%s) does\'t exist.', $alias, $path));
throw new ImproperlyConfiguredException(sprintf('Directory "%s" (%s) does\'t exist.', $alias, $path));
}

if (! is_writable($path)) {
throw new DirectoryException(sprintf('Directory "%s" (%s) isn\'t writable.', $alias, $path));
throw new ImproperlyConfiguredException(sprintf('Directory "%s" (%s) isn\'t writable.', $alias, $path));
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/Service/Bootloader/EnvironmentBootloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use Chiron\Core\Environment;
use Chiron\Core\Container\Bootloader\AbstractBootloader;
use Chiron\Config\Config;
use Chiron\Core\Exception\EnvironmentException;
use Chiron\Core\Exception\ImproperlyConfiguredException;
use Dotenv\Dotenv;
use Dotenv\Exception\InvalidFileException;

Expand Down Expand Up @@ -68,6 +68,8 @@ public function boot(Environment $environment, Directories $directories): void
*
* @param string $path The directory path containing the dot env file.
*
* @throws ImproperlyConfiguredException
*
* @return array The keys/values readed in the dot env file
*/
private static function loadDotEnvFile(string $path): array
Expand All @@ -83,7 +85,7 @@ private static function loadDotEnvFile(string $path): array
// Load environment file in given directory path, silently failing if it doesn't exist.
return $dotenv->safeLoad();
} catch (InvalidFileException $e) {
throw new EnvironmentException('The environment file (.env) is invalid!');
throw new ImproperlyConfiguredException('The environment file (.env) is invalid!');
}
}
}

0 comments on commit 9424f91

Please sign in to comment.