From 12211289bf9609092cb63170b6dbbb598b2f3ec4 Mon Sep 17 00:00:00 2001 From: James Gilliland Date: Sat, 5 Mar 2022 13:57:22 -0600 Subject: [PATCH] Use container for dependencies This looks more complicated but removes a lot of hard coded class connections and will make injecting config easier. --- bin/pfatt | 12 ++-- box.json.dist | 3 +- cache/.gitignore | 2 + composer.json | 1 + src/Commands/Monitor.php | 22 +++---- src/Commands/Startup.php | 40 ++++++++----- src/PfattApplication.php | 11 ++++ src/PfattKernel.php | 94 ++++++++++++++++++++++++++++++ src/{ => Service}/Config.php | 2 +- src/{ => Service}/Logger.php | 4 +- src/{ => Service}/NgController.php | 2 +- 11 files changed, 156 insertions(+), 37 deletions(-) create mode 100644 cache/.gitignore create mode 100644 src/PfattApplication.php create mode 100644 src/PfattKernel.php rename src/{ => Service}/Config.php (98%) rename src/{ => Service}/Logger.php (92%) rename src/{ => Service}/NgController.php (99%) diff --git a/bin/pfatt b/bin/pfatt index 320b725..290d892 100755 --- a/bin/pfatt +++ b/bin/pfatt @@ -3,12 +3,8 @@ require __DIR__ . '/../vendor/autoload.php'; -use Pfatt\Commands\Monitor; -use Pfatt\Commands\Startup; -use Symfony\Component\Console\Application; +use Pfatt\PfattKernel; -$application = new Application(); -$application->add(new Monitor()); -$application->add(new Startup()); - -$application->run(); +(new PfattKernel()) + ->create() + ->run(); diff --git a/box.json.dist b/box.json.dist index 77c2e7b..c390835 100644 --- a/box.json.dist +++ b/box.json.dist @@ -1,6 +1,7 @@ { "output" : "build/pfatt.phar", "files": [ - "bin/pfatt" + "bin/pfatt", + "cache/container.php" ] } diff --git a/cache/.gitignore b/cache/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/cache/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/composer.json b/composer.json index 70a3f60..adab23a 100644 --- a/composer.json +++ b/composer.json @@ -18,6 +18,7 @@ "php": ">=7.4", "psr/log": "^1.1", "symfony/console": "^5.4", + "symfony/dependency-injection": "^5.4", "symfony/process": "^5.4" }, "require-dev": { diff --git a/src/Commands/Monitor.php b/src/Commands/Monitor.php index 9b85feb..76f0456 100644 --- a/src/Commands/Monitor.php +++ b/src/Commands/Monitor.php @@ -4,12 +4,11 @@ declare(strict_types=1); namespace Pfatt\Commands; -use Pfatt\Config; -use Pfatt\Logger; -use Pfatt\NgController; +use Pfatt\Service\Config; +use Pfatt\Service\Logger; +use Pfatt\Service\NgController; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Logger\ConsoleLogger; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Process\Process; @@ -21,12 +20,15 @@ final class Monitor extends Command protected Logger $logger; protected NgController $ngControl; - protected function configure(): void - { - // @todo Inject these. Maybe with a factory or container. - $this->config = new Config('', '', ''); - $this->logger = new Logger('pfatt-5268AC'); - $this->ngControl = new NgController($this->logger); + public function __construct( + Config $config, + Logger $logger, + NgController $ngControl + ) { + parent::__construct('monitor'); + $this->config = $config; + $this->logger = $logger; + $this->ngControl = $ngControl; } /** diff --git a/src/Commands/Startup.php b/src/Commands/Startup.php index 8072b1a..920147d 100644 --- a/src/Commands/Startup.php +++ b/src/Commands/Startup.php @@ -4,9 +4,9 @@ declare(strict_types=1); namespace Pfatt\Commands; -use Pfatt\Config; -use Pfatt\Logger; -use Pfatt\NgController; +use Pfatt\Service\Config; +use Pfatt\Service\Logger; +use Pfatt\Service\NgController; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -20,20 +20,26 @@ final class Startup extends Command protected Logger $logger; protected NgController $ngControl; - protected function configure(): void - { - // @todo Inject these. Maybe with a factory or container. - $this->config = new Config('', '', ''); - $this->logger = new Logger('pfatt'); - $this->ngControl = new NgController($this->logger); + public function __construct( + Config $config, + Logger $logger, + NgController $ngControl + ) { + parent::__construct('startup'); + $this->config = $config; + $this->logger = $logger; + $this->ngControl = $ngControl; } - /** * {@inheritDoc} */ - protected function execute(InputInterface $input, OutputInterface $output): int - { + protected function execute( + InputInterface $input, + OutputInterface $output + ): int { + $this->logger->setOutput($output); + switch ($this->getVeriant()) { case 'opnsense': $kldload = function (string $mod): Process { @@ -53,7 +59,11 @@ final class Startup extends Command case 'pfsense': default: $attach = function (string $interface): Process { - return new Process(['/usr/local/bin/php', '-r', '"pfSense_ngctl_attach(\'.\', \'' . $interface . '\';"']); + return new Process([ + '/usr/local/bin/php', + '-r', + '"pfSense_ngctl_attach(\'.\', \'' . $interface . '\';"' + ]); }; $this->logger->info('attaching interfaces to ng_ether...'); @@ -73,7 +83,9 @@ final class Startup extends Command /** * @return string */ - private function getVeriant(): string { + private function getVeriant(): string + { + // @todo detect the variant to trigger different behaviors. return 'opnsense'; } } diff --git a/src/PfattApplication.php b/src/PfattApplication.php new file mode 100644 index 0000000..dcec7b6 --- /dev/null +++ b/src/PfattApplication.php @@ -0,0 +1,11 @@ + Monitor::class, + 'startup' => Startup::class, + ]; + + public function create(): Application + { + // Lazy load command with container + $container = $this->getContainer(); + /** @var \Pfatt\PfattApplication $application */ + $application = $container->get(PfattApplication::class); + return $application; + } + + public function getContainer(): ContainerInterface + { + $file = __DIR__ . '/../cache/container.php'; + if (!file_exists($file)) { + $containerBuilder = new ContainerBuilder(); + + $containerBuilder->register(Logger::class, Logger::class) + ->setPublic(true); + $containerBuilder->setAlias(LoggerInterface::class, Logger::class); + $containerBuilder->register('logger-5268', Logger::class) + ->setPublic(true) + ->setArgument('$channel', 'pfatt-5268AC'); + $containerBuilder->register(Config::class, Config::class) + ->setPublic(true) + ->setArguments(['', '', '']); + $containerBuilder->autowire(NgController::class, NgController::class) + ->setPublic(true); + + $containerBuilder->autowire(Monitor::class, Monitor::class) + ->setPublic(true) + ->setArgument(Logger::class, new Reference('logger-5268')); + $containerBuilder->autowire(Startup::class, Startup::class) + ->setPublic(true); + + $containerBuilder->register(ContainerCommandLoader::class, ContainerCommandLoader::class) + ->setArguments([ + new Reference('service_container'), + $this->commands + ]) + ->setPublic(true); + $containerBuilder->register(PfattApplication::class, PfattApplication::class) + ->setArguments(['PfATT']) + ->addMethodCall('setCommandLoader', [new Reference(ContainerCommandLoader::class)]) + ->setPublic(true); + + $containerBuilder->compile(); + $dumper = new PhpDumper($containerBuilder); + /** + * This will always be a string because of the default options. + * @psalm-suppress MixedArgumentTypeCoercion + */ + file_put_contents($file, $dumper->dump()); + } + + require_once $file; + /** + * Tell static analysis of this dynamic class. + * @var \Symfony\Component\DependencyInjection\ContainerInterface $container + * @psalm-suppress UndefinedClass + * @phpstan-ignore-next-line + */ + $container = new \ProjectServiceContainer(); + return $container; + } + +} diff --git a/src/Config.php b/src/Service/Config.php similarity index 98% rename from src/Config.php rename to src/Service/Config.php index 80b6a63..4fd8cc7 100644 --- a/src/Config.php +++ b/src/Service/Config.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Pfatt; +namespace Pfatt\Service; /** * Config wrapper. diff --git a/src/Logger.php b/src/Service/Logger.php similarity index 92% rename from src/Logger.php rename to src/Service/Logger.php index 91f6052..bc01257 100644 --- a/src/Logger.php +++ b/src/Service/Logger.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Pfatt; +namespace Pfatt\Service; use Psr\Log\AbstractLogger; use Psr\Log\LoggerInterface; @@ -20,7 +20,7 @@ class Logger extends AbstractLogger */ private ?LoggerInterface $logger; - public function __construct(string $channel, LoggerInterface $logger = null) + public function __construct(string $channel = 'pfatt', LoggerInterface $logger = null) { $this->channel = $channel; $this->logger = $logger; diff --git a/src/NgController.php b/src/Service/NgController.php similarity index 99% rename from src/NgController.php rename to src/Service/NgController.php index a11b793..c35f189 100644 --- a/src/NgController.php +++ b/src/Service/NgController.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Pfatt; +namespace Pfatt\Service; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerInterface;