151 lines
3.8 KiB
PHP
151 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace Framework;
|
|
|
|
use DI\ContainerBuilder;
|
|
use Doctrine\Common\Cache\ApcuCache;
|
|
use Doctrine\Common\Cache\FilesystemCache;
|
|
use Framework\Middleware\CombinedMiddleware;
|
|
use Framework\Middleware\RoutePrefixedMiddleware;
|
|
use Interop\Http\ServerMiddleware\DelegateInterface;
|
|
use Interop\Http\ServerMiddleware\MiddlewareInterface;
|
|
use Psr\Container\ContainerInterface;
|
|
use Psr\Http\Message\ResponseInterface;
|
|
use Psr\Http\Message\ServerRequestInterface;
|
|
|
|
class App implements DelegateInterface
|
|
{
|
|
|
|
/**
|
|
* List of modules
|
|
* @var array
|
|
*/
|
|
private $modules = [];
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
private $definitions;
|
|
|
|
/**
|
|
* @var ContainerInterface
|
|
*/
|
|
private $container;
|
|
|
|
/**
|
|
* @var string[]
|
|
*/
|
|
private $middlewares = [];
|
|
|
|
/**
|
|
* @var int
|
|
*/
|
|
private $index = 0;
|
|
|
|
/**
|
|
* App constructor.
|
|
* @param null|string|array $definitions
|
|
*/
|
|
public function __construct($definitions = [])
|
|
{
|
|
if (is_string($definitions)) {
|
|
$definitions = [$definitions];
|
|
}
|
|
if (!$this->isSequential($definitions)) {
|
|
$definitions = [$definitions];
|
|
}
|
|
$this->definitions = $definitions;
|
|
}
|
|
|
|
/**
|
|
* Rajoute un module à l'application
|
|
*
|
|
* @param string $module
|
|
* @return App
|
|
*/
|
|
public function addModule(string $module): self
|
|
{
|
|
$this->modules[] = $module;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Ajoute un middleware
|
|
*
|
|
* @param string|callable|MiddlewareInterface $routePrefix
|
|
* @param null|string|callable|MiddlewareInterface $middleware
|
|
* @return App
|
|
*/
|
|
public function pipe($routePrefix, $middleware = null): self
|
|
{
|
|
if ($middleware === null) {
|
|
$this->middlewares[] = $routePrefix;
|
|
} else {
|
|
$this->middlewares[] = new RoutePrefixedMiddleware($this->getContainer(), $routePrefix, $middleware);
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
public function process(ServerRequestInterface $request): ResponseInterface
|
|
{
|
|
$this->index++;
|
|
if ($this->index > 1) {
|
|
throw new \Exception();
|
|
}
|
|
$middleware = new CombinedMiddleware($this->getContainer(), $this->middlewares);
|
|
return $middleware->process($request, $this);
|
|
}
|
|
|
|
public function run(ServerRequestInterface $request): ResponseInterface
|
|
{
|
|
foreach ($this->modules as $module) {
|
|
$this->getContainer()->get($module);
|
|
}
|
|
return $this->process($request);
|
|
}
|
|
|
|
/**
|
|
* @return ContainerInterface
|
|
*/
|
|
public function getContainer(): ContainerInterface
|
|
{
|
|
if ($this->container === null) {
|
|
$builder = new ContainerBuilder();
|
|
$env = getenv('ENV') ?: 'production';
|
|
if ($env === 'production') {
|
|
//$builder->setDefinitionCache(new FilesystemCache('tmp/di'));
|
|
$builder->writeProxiesToFile(true, 'tmp/proxies');
|
|
}
|
|
foreach ($this->definitions as $definition) {
|
|
$builder->addDefinitions($definition);
|
|
}
|
|
foreach ($this->modules as $module) {
|
|
if ($module::DEFINITIONS) {
|
|
$builder->addDefinitions($module::DEFINITIONS);
|
|
}
|
|
}
|
|
$builder->addDefinitions([
|
|
App::class => $this
|
|
]);
|
|
$this->container = $builder->build();
|
|
}
|
|
return $this->container;
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function getModules(): array
|
|
{
|
|
return $this->modules;
|
|
}
|
|
|
|
private function isSequential(array $array): bool
|
|
{
|
|
if (empty($array)) {
|
|
return true;
|
|
}
|
|
return array_keys($array) === range(0, count($array) - 1);
|
|
}
|
|
}
|