From 320fe18654dfbde864ac9a84959059faa10b5adb Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 8 Jan 2025 22:59:29 +0000 Subject: [PATCH] Create Container interface, add DiceContainer as implementation --- bin/auth_ejabberd.php | 2 +- bin/console.php | 2 +- bin/daemon.php | 2 +- bin/jetstream.php | 2 +- bin/worker.php | 2 +- index.php | 5 +- src/Core/Container.php | 89 +----------- src/Core/DiceContainer.php | 127 ++++++++++++++++++ ...ontainerTest.php => DiceContainerTest.php} | 13 +- 9 files changed, 147 insertions(+), 97 deletions(-) create mode 100644 src/Core/DiceContainer.php rename tests/Unit/Core/{ContainerTest.php => DiceContainerTest.php} (84%) diff --git a/bin/auth_ejabberd.php b/bin/auth_ejabberd.php index 7a279b079b..bc976e61a4 100755 --- a/bin/auth_ejabberd.php +++ b/bin/auth_ejabberd.php @@ -48,7 +48,7 @@ chdir(dirname(__DIR__)); require dirname(__DIR__) . '/vendor/autoload.php'; -$container = \Friendica\Core\Container::fromBasePath(dirname(__DIR__)); +$container = \Friendica\Core\DiceContainer::fromBasePath(dirname(__DIR__)); $app = \Friendica\App::fromContainer($container); diff --git a/bin/console.php b/bin/console.php index 94738dbf8c..ad612f4363 100755 --- a/bin/console.php +++ b/bin/console.php @@ -15,7 +15,7 @@ if (php_sapi_name() !== 'cli') { require dirname(__DIR__) . '/vendor/autoload.php'; -$container = \Friendica\Core\Container::fromBasePath(dirname(__DIR__)); +$container = \Friendica\Core\DiceContainer::fromBasePath(dirname(__DIR__)); $app = \Friendica\App::fromContainer($container); diff --git a/bin/daemon.php b/bin/daemon.php index 04e00ccf0d..546f207e08 100755 --- a/bin/daemon.php +++ b/bin/daemon.php @@ -27,7 +27,7 @@ require dirname(__DIR__) . '/vendor/autoload.php'; $argv = $_SERVER['argv'] ?? []; array_splice($argv, 1, 0, "daemon"); -$container = \Friendica\Core\Container::fromBasePath(dirname(__DIR__)); +$container = \Friendica\Core\DiceContainer::fromBasePath(dirname(__DIR__)); $app = \Friendica\App::fromContainer($container); diff --git a/bin/jetstream.php b/bin/jetstream.php index 72d13c3e1f..156f961856 100755 --- a/bin/jetstream.php +++ b/bin/jetstream.php @@ -22,7 +22,7 @@ require dirname(__DIR__) . '/vendor/autoload.php'; $argv = $_SERVER['argv'] ?? []; array_splice($argv, 1, 0, "jetstream"); -$container = \Friendica\Core\Container::fromBasePath(dirname(__DIR__)); +$container = \Friendica\Core\DiceContainer::fromBasePath(dirname(__DIR__)); $app = \Friendica\App::fromContainer($container); diff --git a/bin/worker.php b/bin/worker.php index 54b36e392f..a79d8836a7 100755 --- a/bin/worker.php +++ b/bin/worker.php @@ -24,7 +24,7 @@ require dirname(__DIR__) . '/vendor/autoload.php'; $argv = $_SERVER['argv'] ?? []; array_splice($argv, 1, 0, "worker"); -$container = \Friendica\Core\Container::fromBasePath(dirname(__DIR__)); +$container = \Friendica\Core\DiceContainer::fromBasePath(dirname(__DIR__)); $app = \Friendica\App::fromContainer($container); diff --git a/index.php b/index.php index 906d91bc3c..850d9cd1c0 100644 --- a/index.php +++ b/index.php @@ -15,7 +15,8 @@ require __DIR__ . '/vendor/autoload.php'; $request = \GuzzleHttp\Psr7\ServerRequest::fromGlobals(); -$container = \Friendica\Core\Container::fromBasePath(__DIR__); -$app = \Friendica\App::fromContainer($container); +$container = \Friendica\Core\DiceContainer::fromBasePath(__DIR__); + +$app = \Friendica\App::fromContainer($container); $app->processRequest($request, $start_time); diff --git a/src/Core/Container.php b/src/Core/Container.php index 0da94935d8..f0f44f38db 100644 --- a/src/Core/Container.php +++ b/src/Core/Container.php @@ -9,46 +9,13 @@ declare(strict_types=1); namespace Friendica\Core; -use Dice\Dice; -use Friendica\Core\Addon\Capability\ICanLoadAddons; use Friendica\Core\Logger\Capability\LogChannel; -use Friendica\Core\Logger\Handler\ErrorHandler; -use Friendica\DI; -use Psr\Log\LoggerInterface; /** - * Wrapper for the Dice class to make some basic setups + * Dependency Injection Container */ -class Container +interface Container { - public static function fromBasePath(string $basePath): self - { - $path = $basePath . '/static/dependencies.config.php'; - - $dice = (new Dice())->addRules(require($path)); - - return static::fromDice($dice); - } - - private Dice $container; - - private function __construct(Dice $container) - { - $this->container = $container; - } - - /** - * Creates an instance with Dice - * - * @param Dice $container - * - * @return self - */ - public static function fromDice(Dice $container): self - { - return new self($container); - } - /** * Initialize the container with the given parameters * @@ -57,17 +24,7 @@ class Container * * @return void */ - public function setup(string $logChannel = LogChannel::DEFAULT, bool $withTemplateEngine = true) - { - $this->setupContainerForAddons(); - $this->setupContainerForLogger($logChannel); - $this->setupLegacyServiceLocator(); - $this->registerErrorHandler(); - - if ($withTemplateEngine) { - $this->registerTemplateEngine(); - } - } + public function setup(string $logChannel = LogChannel::DEFAULT, bool $withTemplateEngine = true): void; /** * Returns a fully constructed object based on $name using $args and $share as constructor arguments if supplied @@ -78,10 +35,7 @@ class Container * * @see Dice::create() */ - public function create(string $name, array $args = [], array $share = []): object - { - return $this->container->create($name, $args, $share); - } + public function create(string $name, array $args = [], array $share = []): object; /** * Add a rule $rule to the class $name @@ -90,38 +44,5 @@ class Container * * @see Dice::addRule() */ - public function addRule(string $name, array $rule): void - { - $this->container = $this->container->addRule($name, $rule); - } - - private function setupContainerForAddons(): void - { - /** @var ICanLoadAddons $addonLoader */ - $addonLoader = $this->container->create(ICanLoadAddons::class); - - $this->container = $this->container->addRules($addonLoader->getActiveAddonConfig('dependencies')); - } - - private function setupContainerForLogger(string $logChannel): void - { - $this->container = $this->container->addRule(LoggerInterface::class, [ - 'constructParams' => [$logChannel], - ]); - } - - private function setupLegacyServiceLocator(): void - { - DI::init($this->container); - } - - private function registerErrorHandler(): void - { - ErrorHandler::register($this->container->create(LoggerInterface::class)); - } - - private function registerTemplateEngine(): void - { - Renderer::registerTemplateEngine('Friendica\Render\FriendicaSmartyEngine'); - } + public function addRule(string $name, array $rule): void; } diff --git a/src/Core/DiceContainer.php b/src/Core/DiceContainer.php new file mode 100644 index 0000000000..7d8b57b14d --- /dev/null +++ b/src/Core/DiceContainer.php @@ -0,0 +1,127 @@ +addRules(require($path)); + + return static::fromDice($dice); + } + + private Dice $container; + + private function __construct(Dice $container) + { + $this->container = $container; + } + + /** + * Creates an instance with Dice + * + * @param Dice $container + * + * @return self + */ + public static function fromDice(Dice $container): self + { + return new self($container); + } + + /** + * Initialize the container with the given parameters + * + * @param string $logChannel The Log Channel of this call + * @param bool $withTemplateEngine true, if the template engine should be set too + * + * @return void + */ + public function setup(string $logChannel = LogChannel::DEFAULT, bool $withTemplateEngine = true): void + { + $this->setupContainerForAddons(); + $this->setupContainerForLogger($logChannel); + $this->setupLegacyServiceLocator(); + $this->registerErrorHandler(); + + if ($withTemplateEngine) { + $this->registerTemplateEngine(); + } + } + + /** + * Returns a fully constructed object based on $name using $args and $share as constructor arguments if supplied + * @param string $name name The name of the class to instantiate + * @param array $args An array with any additional arguments to be passed into the constructor upon instantiation + * @param array $share a list of defined in shareInstances for objects higher up the object graph, should only be used internally + * @return object A fully constructed object based on the specified input arguments + * + * @see Dice::create() + */ + public function create(string $name, array $args = [], array $share = []): object + { + return $this->container->create($name, $args, $share); + } + + /** + * Add a rule $rule to the class $name + * @param string $name The name of the class to add the rule for + * @param array $rule The container can be fully configured using rules provided by associative arrays. See {@link https://r.je/dice.html#example3} for a description of the rules. + * + * @see Dice::addRule() + */ + public function addRule(string $name, array $rule): void + { + $this->container = $this->container->addRule($name, $rule); + } + + private function setupContainerForAddons(): void + { + /** @var ICanLoadAddons $addonLoader */ + $addonLoader = $this->container->create(ICanLoadAddons::class); + + $this->container = $this->container->addRules($addonLoader->getActiveAddonConfig('dependencies')); + } + + private function setupContainerForLogger(string $logChannel): void + { + $this->container = $this->container->addRule(LoggerInterface::class, [ + 'constructParams' => [$logChannel], + ]); + } + + private function setupLegacyServiceLocator(): void + { + DI::init($this->container); + } + + private function registerErrorHandler(): void + { + ErrorHandler::register($this->container->create(LoggerInterface::class)); + } + + private function registerTemplateEngine(): void + { + Renderer::registerTemplateEngine('Friendica\Render\FriendicaSmartyEngine'); + } +} diff --git a/tests/Unit/Core/ContainerTest.php b/tests/Unit/Core/DiceContainerTest.php similarity index 84% rename from tests/Unit/Core/ContainerTest.php rename to tests/Unit/Core/DiceContainerTest.php index 5c56c696be..d18c551da1 100644 --- a/tests/Unit/Core/ContainerTest.php +++ b/tests/Unit/Core/DiceContainerTest.php @@ -11,12 +11,13 @@ namespace Core; use Dice\Dice; use Friendica\Core\Container; +use Friendica\Core\DiceContainer; use org\bovigo\vfs\vfsStream; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; -class ContainerTest extends TestCase +class DiceContainerTest extends TestCase { public function testFromBasePathReturnsContainer(): void { @@ -26,7 +27,7 @@ class ContainerTest extends TestCase ], ]); - $container = Container::fromBasePath($root->url()); + $container = DiceContainer::fromBasePath($root->url()); $this->assertInstanceOf(Container::class, $container); } @@ -45,7 +46,7 @@ class ContainerTest extends TestCase ], ]); - $container = Container::fromBasePath($root->url()); + $container = DiceContainer::fromBasePath($root->url()); $this->assertInstanceOf(NullLogger::class, $container->create(LoggerInterface::class)); } @@ -55,7 +56,7 @@ class ContainerTest extends TestCase $dice = $this->createMock(Dice::class); $dice->expects($this->never())->method('create'); - $container = Container::fromDice($dice); + $container = DiceContainer::fromDice($dice); $this->assertInstanceOf(Container::class, $container); } @@ -65,7 +66,7 @@ class ContainerTest extends TestCase $dice = $this->createMock(Dice::class); $dice->expects($this->once())->method('create')->with(LoggerInterface::class)->willReturn(new NullLogger()); - $container = Container::fromDice($dice); + $container = DiceContainer::fromDice($dice); $this->assertInstanceOf(NullLogger::class, $container->create(LoggerInterface::class)); } @@ -75,7 +76,7 @@ class ContainerTest extends TestCase $dice = $this->createMock(Dice::class); $dice->expects($this->once())->method('addRule')->with(LoggerInterface::class, ['constructParams' => ['console']])->willReturn($dice); - $container = Container::fromDice($dice); + $container = DiceContainer::fromDice($dice); $container->addRule(LoggerInterface::class, ['constructParams' => ['console']]); } }