Skip to content

Instantly share code, notes, and snippets.

@jiripudil
Created May 9, 2017 07:42
Show Gist options
  • Save jiripudil/3a7c8b8571c0217192f0e96064647655 to your computer and use it in GitHub Desktop.
Save jiripudil/3a7c8b8571c0217192f0e96064647655 to your computer and use it in GitHub Desktop.
Slim + Nette DI
<?php
declare(strict_types = 1);
namespace App\Application;
use Slim\App;
interface ApplicationConfigurator
{
public function configureApplication(App $application): void;
}
<?php
declare(strict_types = 1);
namespace App\Application;
use Psr\Container\ContainerInterface;
use Slim\App;
class ApplicationFactory
{
/**
* @var ContainerInterface
*/
private $container;
/**
* @var ApplicationConfigurator
*/
private $configurator;
public function __construct(ContainerInterface $container, ApplicationConfigurator $configurator)
{
$this->container = $container;
$this->configurator = $configurator;
}
public function createApplication(): App
{
$app = new App($this->container);
$this->configurator->configureApplication($app);
return $app;
}
}
<?php
declare(strict_types = 1);
namespace App\Authentication;
use App\Application\ApplicationConfigurator;
use Slim\App;
class AuthenticationApplicationConfigurator implements ApplicationConfigurator
{
/**
* @var AuthenticationMiddleware
*/
private $middleware;
public function __construct(AuthenticationMiddleware $middleware)
{
$this->middleware = $middleware;
}
public function configureApplication(App $app): void
{
$app->add($this->middleware);
}
}
<?php
declare(strict_types = 1);
return call_user_func(function (): Nette\DI\Container {
require_once __DIR__ . '/vendor/autoload.php';
$configurator = new Nette\Configurator();
$configurator->setTempDirectory(__DIR__ . '/temp');
$configurator->enableDebugger(__DIR__ . '/log');
$configurator->addConfig(__DIR__ . '/config/config.neon');
return $configurator->createContainer();
});
<?php
declare(strict_types = 1);
namespace App\Application;
use Slim\App;
final class ChainApplicationConfigurator implements ApplicationConfigurator
{
/**
* @var ApplicationConfigurator[]
*/
private $configurators = [];
public function addConfigurator(ApplicationConfigurator $configurator): void
{
$this->configurators[] = $configurator;
}
public function configureApplication(App $application): void
{
foreach ($this->configurators as $configurator) {
$configurator->configureApplication($application);
}
}
}
{
"require": {
"php": ">= 7.1.0",
"nette/di": "^2.4",
"nette/utils": "^2.4",
"slim/slim": "^3.0",
"arachne/container-adapter": "dev-master"
}
}
extensions:
- Arachne\ContainerAdapter\DI\ContainerAdapterExtension
slim: App\DI\SlimExtension(%debugMode%)
slim:
configurators:
- @App\Authentication\AuthenticationApplicationConfigurator
services:
- App\Authentication\Authenticator
- App\Authentication\AuthenticationApplicationConfigurator
- App\Authentication\AuthenticationMiddleware
<?php
declare(strict_types = 1);
namespace App\Http;
use Slim\Http\Headers;
use Slim\Http\Response;
/**
* @internal used by {@see App\DI\SlimExtension}
*/
class DefaultResponseFactory
{
public static function createResponse(string $protocolVersion): Response
{
$headers = new Headers(['Content-Type' => 'text/html; charset=UTF-8']);
$response = new Response(200, $headers);
return $response->withProtocolVersion($protocolVersion);
}
}
<?php
/** @var Nette\DI\Container $container */
$container = require_once __DIR__ . '/../bootstrap.php';
$container->getByType(Slim\App::class)->run();
<?php
declare(strict_types = 1);
namespace App\DI;
use Nette\DI\CompilerExtension;
use Nette\PhpGenerator\PhpLiteral;
use Nette\Utils\ArrayHash;
use App\Application\ApplicationFactory;
use App\Application\ChainApplicationConfigurator;
use App\Http\DefaultResponseFactory;
use Psr\Container\ContainerInterface;
use Psr\Http;
use Slim;
class SlimExtension extends CompilerExtension
{
private $defaults = [
'settings' => [
'httpVersion' => '1.1',
'responseChunkSize' => 4096,
'outputBuffering' => 'append',
'determineRouteBeforeAppMiddleware' => FALSE,
'displayErrorDetails' => NULL,
'addContentLengthHeader' => TRUE,
'routerCacheFile' => FALSE,
],
'configurators' => [],
];
public function __construct(bool $debugMode)
{
$this->defaults['settings']['displayErrorDetails'] = $debugMode;
}
public function loadConfiguration()
{
$builder = $this->getContainerBuilder();
$config = $this->validateConfig($this->defaults);
$chainConfigurator = $builder->addDefinition($this->prefix('configurator'))
->setClass(ChainApplicationConfigurator::class);
foreach ($config['configurators'] as $configurator) {
$chainConfigurator->addSetup('addConfigurator', [$configurator]);
}
$builder->addDefinition($this->prefix('applicationFactory'))
->setClass(ApplicationFactory::class, ['@' . ContainerInterface::class, $chainConfigurator]);
$builder->addDefinition($this->prefix('application'))
->setClass(Slim\App::class)
->setFactory('@' . ApplicationFactory::class . '::createApplication');
/**
* SERVICES REQUIRED BY SLIM FRAMEWORK
* {@see Slim\DefaultServicesProvider}
*/
$builder->addDefinition('settings')
->setClass(ArrayHash::class)
->setFactory(ArrayHash::class . '::from', [$config['settings']]);
$builder->addDefinition('environment')
->setClass(Slim\Interfaces\Http\EnvironmentInterface::class)
->setFactory(Slim\Http\Environment::class . '::mock', new PhpLiteral('$_SERVER'));
$builder->addDefinition('request')
->setClass(Http\Message\ServerRequestInterface::class)
->setFactory(Slim\Http\Request::class . '::createFromEnvironment', ['@environment']);
$builder->addDefinition('response')
->setClass(Http\Message\ResponseInterface::class)
->setFactory(DefaultResponseFactory::class . '::createResponse', [$config['settings']['httpVersion']]);
$builder->addDefinition('router')
->setClass(Slim\Interfaces\RouterInterface::class)
->setFactory(Slim\Router::class)
->addSetup('setCacheFile', [$config['settings']['routerCacheFile']])
->addSetup('setContainer', ['@' . ContainerInterface::class]);
$builder->addDefinition('foundHandler')
->setClass(Slim\Interfaces\InvocationStrategyInterface::class)
->setFactory(Slim\Handlers\Strategies\RequestResponse::class);
$builder->addDefinition('phpErrorHandler')->setClass(Slim\Handlers\PhpError::class, [$config['settings']['displayErrorDetails']]);
$builder->addDefinition('errorHandler')->setClass(Slim\Handlers\Error::class, [$config['settings']['displayErrorDetails']]);
$builder->addDefinition('notFoundHandler')->setClass(Slim\Handlers\NotFound::class);
$builder->addDefinition('notAllowedHandler')->setClass(Slim\Handlers\NotAllowed::class);
$builder->addDefinition('callableResolver')
->setClass(Slim\Interfaces\CallableResolverInterface::class)
->setFactory(Slim\CallableResolver::class);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment