From 8ad25b794c2fa5a08e6114e25cebc14669bebc37 Mon Sep 17 00:00:00 2001 From: Joshua Parker Date: Sat, 16 Aug 2025 09:07:48 -0700 Subject: [PATCH 1/3] Added new application builder class. Signed-off-by: Joshua Parker --- Application.php | 31 ++++++++- Bootstrap/RegisterProviders.php | 55 +++++++++++++++- Configuration/ApplicationBuilder.php | 99 ++++++++++++++++++++++++++++ Console/ConsoleKernel.php | 22 ++----- Console/Kernel.php | 51 ++++++++++++++ tests/Pipes/PipelineTest.php | 2 +- tests/vendor/bootstrap.php | 2 +- 7 files changed, 241 insertions(+), 21 deletions(-) create mode 100644 Configuration/ApplicationBuilder.php create mode 100644 Console/Kernel.php diff --git a/Application.php b/Application.php index b458dee..41bcbdd 100644 --- a/Application.php +++ b/Application.php @@ -4,6 +4,7 @@ namespace Codefy\Framework; +use Codefy\Framework\Configuration\ApplicationBuilder; use Codefy\Framework\Factory\FileLoggerFactory; use Codefy\Framework\Factory\FileLoggerSmtpFactory; use Codefy\Framework\Pipeline\PipelineBuilder; @@ -68,7 +69,7 @@ final class Application extends Container { use InvokerAware; - public const APP_VERSION = '2.1.2'; + public const APP_VERSION = '2.1.3'; public const MIN_PHP_VERSION = '8.2'; @@ -107,6 +108,8 @@ final class Application extends Container protected array $bootedCallbacks = []; + protected array $registeredCallbacks = []; + private array $param = []; /** @@ -349,7 +352,7 @@ public function forceRegisterServiceProvider(string|Serviceable|Bootable $provid } /** - * Register all configured service providers via config/app.php. + * Register all configured providers. * * @return void * @throws TypeException @@ -365,6 +368,8 @@ public function registerConfiguredServiceProviders(): void foreach ($providers as $serviceProvider) { $this->registerServiceProvider(serviceProvider: $serviceProvider); } + + $this->fireAppCallbacks($this->registeredCallbacks); } /** @@ -750,6 +755,17 @@ public function hasDebugModeEnabled(): bool return false; } + /** + * Register a new callable function. + * + * @param callable $callback + * @return void + */ + public function registered(callable $callback): void + { + $this->registeredCallbacks[] = $callback; + } + protected function coreAliases(): array { return [ @@ -862,6 +878,17 @@ public function isDevelopment(): bool return env(key: 'APP_ENV') === 'development'; } + /** + * Configure a new CodefyPHP application instance. + * + * @throws TypeException + */ + public static function configure(array $config): ApplicationBuilder + { + return (new ApplicationBuilder(new self($config))) + ->withKernels(); + } + /** * Get the globally available instance of the container. * diff --git a/Bootstrap/RegisterProviders.php b/Bootstrap/RegisterProviders.php index 0d49e17..c73d7ca 100644 --- a/Bootstrap/RegisterProviders.php +++ b/Bootstrap/RegisterProviders.php @@ -5,17 +5,70 @@ namespace Codefy\Framework\Bootstrap; use Codefy\Framework\Application; +use Qubus\Config\ConfigContainer; use Qubus\Exception\Data\TypeException; use Qubus\Exception\Exception; -class RegisterProviders +use function array_filter; +use function array_merge; +use function array_unique; +use function array_values; + +final class RegisterProviders { + protected static array $merge = []; + /** * @throws TypeException * @throws Exception */ public function bootstrap(Application $app): void { + $this->mergeAdditionalProviders($app); $app->registerConfiguredServiceProviders(); } + + /** + * Merge additional configured providers into the configuration. + * + * @param Application $app + * @return void + * @throws Exception + */ + protected function mergeAdditionalProviders(Application $app): void + { + /** @var ConfigContainer $config */ + $config = $app->make(name: 'codefy.config'); + + $config->setConfigKey( + 'app.providers', + array_merge( + $config->getConfigKey('app.providers'), + self::$merge + ) + ); + } + + /** + * Merge the given providers into the provider configuration + * before registration. + * + * @param array $providers + * @return void + */ + public static function merge(array $providers): void + { + self::$merge = array_values( + array_filter( + array_unique( + array_merge(self::$merge, $providers) + ) + ) + ); + } + + public static function flushState(): void + { + self::$merge = []; + } } diff --git a/Configuration/ApplicationBuilder.php b/Configuration/ApplicationBuilder.php new file mode 100644 index 0000000..41ad118 --- /dev/null +++ b/Configuration/ApplicationBuilder.php @@ -0,0 +1,99 @@ +app->singleton( + \Codefy\Framework\Contracts\Kernel::class, + fn() => $this->app->make(name: \Codefy\Framework\Http\Kernel::class) + ); + + $this->app->singleton( + key: \Codefy\Framework\Console\Kernel::class, + value: fn() => $this->app->make(name: \Codefy\Framework\Console\ConsoleKernel::class) + ); + /*$this->app->alias( + original: \Codefy\Framework\Contracts\Kernel::class, + alias: \Codefy\Framework\Http\Kernel::class + ); + + $this->app->alias( + original: \Codefy\Framework\Console\Kernel::class, + alias: \Codefy\Framework\Console\ConsoleKernel::class + );*/ + + return $this; + } + + /** + * Register additional service providers. + * + * @param array $providers + * @return $this + */ + public function withProviders(array $providers = []): self + { + RegisterProviders::merge($providers); + + return $this; + } + + /** + * Register an array of singletons that are resource intensive + * or are not called often. + * + * @param array $singletons + * @return $this + */ + public function withSingletons(array $singletons): self + { + $this->registered(function ($app) use ($singletons) { + foreach ($singletons as $key => $callable) { + $app->singleton($key, $callable); + } + }); + + return $this; + } + + /** + * Register a callback to be invoked when the application's + * service providers are registered. + * + * @param callable $callback + * @return $this + */ + public function registered(callable $callback): self + { + $this->app->registered(callback: $callback); + + return $this; + } + + /** + * Return the application instance. + * + * @return Application + */ + public function return(): Application + { + return $this->app; + } +} diff --git a/Console/ConsoleKernel.php b/Console/ConsoleKernel.php index 62b932c..57b1c7a 100644 --- a/Console/ConsoleKernel.php +++ b/Console/ConsoleKernel.php @@ -19,7 +19,7 @@ use function Qubus\Inheritance\Helpers\tap; -class ConsoleKernel +class ConsoleKernel implements Kernel { protected ?Codex $codex = null; @@ -61,6 +61,7 @@ protected function defineConsoleSchedule(): void } /** + * {@inheritDoc} * @throws Exception */ public function handle(InputInterface $input, ?OutputInterface $output = null): int @@ -97,9 +98,7 @@ public function registerCommand(Command $command): void } /** - * Gets all the commands registered. - * - * @return array + * {@inheritDoc} */ public function all(): array { @@ -109,9 +108,7 @@ public function all(): array } /** - * Get the output for the last run command. - * - * @return string + * {@inheritDoc} */ public function output(): string { @@ -121,9 +118,7 @@ public function output(): string } /** - * Bootstrap the console kernel. - * - * @return void + * {@inheritDoc} */ public function bootstrap(): void { @@ -153,12 +148,7 @@ protected function getCodex(): Codex } /** - * Run a Codex console command by name. - * - * @param string $command - * @param array $parameters - * @param bool|OutputInterface|null $outputBuffer - * @return int + * {@inheritDoc} * * @throws CommandNotFoundException * @throws Exception diff --git a/Console/Kernel.php b/Console/Kernel.php new file mode 100644 index 0000000..2abad8d --- /dev/null +++ b/Console/Kernel.php @@ -0,0 +1,51 @@ +return()); it('has exception handled by onFailure method.', function () use ($pipeline) { $result = $pipeline diff --git a/tests/vendor/bootstrap.php b/tests/vendor/bootstrap.php index 2ba7675..f98e8d4 100644 --- a/tests/vendor/bootstrap.php +++ b/tests/vendor/bootstrap.php @@ -4,7 +4,7 @@ use Qubus\Exception\Data\TypeException; try { - return Application::getInstance(dirname(__DIR__, 2)); + return Application::configure(['basePath' => dirname(path: __DIR__, levels: 2)]); } catch (TypeException $e) { return $e->getMessage(); } From b65a42c523950e61f4e98a3c7ecd8d023f13fc36 Mon Sep 17 00:00:00 2001 From: Joshua Parker Date: Sat, 16 Aug 2025 09:46:29 -0700 Subject: [PATCH 2/3] Added docblock for autocompletion. Signed-off-by: Joshua Parker --- tests/Pipes/PipelineTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/Pipes/PipelineTest.php b/tests/Pipes/PipelineTest.php index c751beb..362ffcb 100644 --- a/tests/Pipes/PipelineTest.php +++ b/tests/Pipes/PipelineTest.php @@ -2,6 +2,7 @@ declare(strict_types=1); +use Codefy\Framework\Configuration\ApplicationBuilder; use Codefy\Framework\Pipeline\Pipeline; use Codefy\Framework\Pipeline\PipelineBuilder; use Codefy\Framework\tests\Pipes\PipeFour; @@ -10,7 +11,9 @@ use Codefy\Framework\tests\Pipes\PipeTwo; use PHPUnit\Framework\Assert; +/** @var ApplicationBuilder $app */ $app = require_once __DIR__ . '/../vendor/bootstrap.php'; + $pipeline = new Pipeline($app->return()); it('has exception handled by onFailure method.', function () use ($pipeline) { From ddd38d2399f7c3da73c1f1ccb602686074d59b52 Mon Sep 17 00:00:00 2001 From: Joshua Parker Date: Sat, 16 Aug 2025 22:56:17 -0700 Subject: [PATCH 3/3] Removed commented code. Signed-off-by: Joshua Parker --- Configuration/ApplicationBuilder.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Configuration/ApplicationBuilder.php b/Configuration/ApplicationBuilder.php index 41ad118..4b5c554 100644 --- a/Configuration/ApplicationBuilder.php +++ b/Configuration/ApplicationBuilder.php @@ -29,15 +29,6 @@ public function withKernels(): self key: \Codefy\Framework\Console\Kernel::class, value: fn() => $this->app->make(name: \Codefy\Framework\Console\ConsoleKernel::class) ); - /*$this->app->alias( - original: \Codefy\Framework\Contracts\Kernel::class, - alias: \Codefy\Framework\Http\Kernel::class - ); - - $this->app->alias( - original: \Codefy\Framework\Console\Kernel::class, - alias: \Codefy\Framework\Console\ConsoleKernel::class - );*/ return $this; }