From 5cbafdb6af1f67f58824b888d94127e5357da5a6 Mon Sep 17 00:00:00 2001 From: Kekalainen Date: Sun, 27 Nov 2022 18:56:17 +0200 Subject: [PATCH] Initial commit --- .gitignore | 2 + LICENSE | 21 +++++++++ README.md | 33 ++++++++++++++ composer.json | 20 +++++++++ src/AdvancedCallableResolverProxy.php | 64 +++++++++++++++++++++++++++ 5 files changed, 140 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 composer.json create mode 100644 src/AdvancedCallableResolverProxy.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..de4a392 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/vendor +/composer.lock diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..735070a --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Kekalainen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..c7adc3c --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +# Slim Illuminate autowire + +Autowire class dependencies using the Laravel/Illuminate [service container](https://laravel.com/docs/9.x/container) by proxying Slim's [callable resolver](https://www.slimframework.com/docs/v4/objects/routing.html#container-resolution). + +## Usage + +```php +use Illuminate\Container\Container; +use Illuminate\Contracts\Container\Container as ContainerContract; +use Kekalainen\SlimIlluminateAutowire\AdvancedCallableResolverProxy; +use Slim\CallableResolver; +use Slim\Factory\AppFactory; +use Slim\Interfaces\AdvancedCallableResolverInterface; + +// Instantiate the Illuminate container. +$container = new Container(); + +// Bind the container instance into the container. +$container->instance(ContainerContract::class, $container); + +// Bind a concrete advanced callable resolver to be proxied. +$container->bind(AdvancedCallableResolverInterface::class, CallableResolver::class); + +// Resolve the proxied callable resolver. +$callableResolver = $container->make(AdvancedCallableResolverProxy::class); + +// Set the static properties of the Slim App factory. +AppFactory::setContainer($container); +AppFactory::setCallableResolver($callableResolver); + +// Instantiate the Slim App. +$app = AppFactory::create(); +``` diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..f8efb15 --- /dev/null +++ b/composer.json @@ -0,0 +1,20 @@ +{ + "name": "kekalainen/slim-illuminate-autowire", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Kekalainen", + "email": "git@kekalainen.me" + } + ], + "autoload": { + "psr-4": { + "Kekalainen\\SlimIlluminateAutowire\\": "src/" + } + }, + "require": { + "illuminate/container": ">=4.0", + "slim/slim": ">=4.0" + } +} diff --git a/src/AdvancedCallableResolverProxy.php b/src/AdvancedCallableResolverProxy.php new file mode 100644 index 0000000..78ba246 --- /dev/null +++ b/src/AdvancedCallableResolverProxy.php @@ -0,0 +1,64 @@ +container = $container; + $this->callableResolver = $callableResolver; + } + + /** + * Prepare $toResolve for container resolution. + */ + protected function prepareToResolve($toResolve): void + { + if (!is_string($toResolve)) + return; + + // Extract the class name from Slim notation. + [$class] = explode(':', $toResolve); + + if ( + $this->container->has($class) || + !class_exists($class) + ) + return; + + // Resolve the class instance (including any type-hinted dependencies) and bind it into the container. + $this->container->instance($class, $this->container->make($class)); + } + + public function resolve($toResolve): callable + { + $this->prepareToResolve($toResolve); + return $this->callableResolver->resolve($toResolve); + } + + public function resolveRoute($toResolve): callable + { + $this->prepareToResolve($toResolve); + return $this->callableResolver->resolveRoute($toResolve); + } + + public function resolveMiddleware($toResolve): callable + { + $this->prepareToResolve($toResolve); + return $this->callableResolver->resolveMiddleware($toResolve); + } +}