Update AppFactory and HttpFactory to support long-running services like Roadrunner.
This commit is contained in:
parent
8b15a55bad
commit
4e669ab20f
|
@ -6,8 +6,7 @@ namespace App;
|
|||
|
||||
use App\Console\Application;
|
||||
use App\Enums\SupportedLocales;
|
||||
use App\Http\Factory\ResponseFactory;
|
||||
use App\Http\Factory\ServerRequestFactory;
|
||||
use App\Http\HttpFactory;
|
||||
use App\Utilities\Logger as AppLogger;
|
||||
use DI;
|
||||
use Monolog\ErrorHandler;
|
||||
|
@ -21,34 +20,37 @@ use Slim\Handlers\Strategies\RequestResponse;
|
|||
final class AppFactory
|
||||
{
|
||||
public static function createApp(
|
||||
array $appEnvironment = [],
|
||||
array $diDefinitions = []
|
||||
array $appEnvironment = []
|
||||
): App {
|
||||
$di = self::buildContainer($appEnvironment, $diDefinitions);
|
||||
$environment = self::buildEnvironment($appEnvironment);
|
||||
$diBuilder = self::createContainerBuilder($environment);
|
||||
$di = self::buildContainer($diBuilder);
|
||||
return self::buildAppFromContainer($di);
|
||||
}
|
||||
|
||||
public static function createCli(
|
||||
array $appEnvironment = [],
|
||||
array $diDefinitions = []
|
||||
array $appEnvironment = []
|
||||
): Application {
|
||||
$di = self::buildContainer($appEnvironment, $diDefinitions);
|
||||
self::buildAppFromContainer($di);
|
||||
$environment = self::buildEnvironment($appEnvironment);
|
||||
$diBuilder = self::createContainerBuilder($environment);
|
||||
$di = self::buildContainer($diBuilder);
|
||||
|
||||
$env = $di->get(Environment::class);
|
||||
|
||||
SupportedLocales::createForCli($env);
|
||||
SupportedLocales::createForCli($environment);
|
||||
|
||||
return $di->get(Application::class);
|
||||
}
|
||||
|
||||
public static function buildAppFromContainer(DI\Container $container): App
|
||||
{
|
||||
public static function buildAppFromContainer(
|
||||
DI\Container $container,
|
||||
?HttpFactory $httpFactory = null
|
||||
): App {
|
||||
$httpFactory ??= new HttpFactory();
|
||||
|
||||
ServerRequestCreatorFactory::setSlimHttpDecoratorsAutomaticDetection(false);
|
||||
ServerRequestCreatorFactory::setServerRequestCreator(new ServerRequestFactory());
|
||||
ServerRequestCreatorFactory::setServerRequestCreator($httpFactory);
|
||||
|
||||
$app = new App(
|
||||
responseFactory: new ResponseFactory(),
|
||||
responseFactory: $httpFactory,
|
||||
container: $container,
|
||||
);
|
||||
$container->set(App::class, $app);
|
||||
|
@ -67,18 +69,19 @@ final class AppFactory
|
|||
return $app;
|
||||
}
|
||||
|
||||
public static function buildContainer(
|
||||
array $appEnvironment = [],
|
||||
array $diDefinitions = []
|
||||
): DI\Container {
|
||||
$environment = self::buildEnvironment($appEnvironment);
|
||||
/**
|
||||
* @return DI\ContainerBuilder<DI\Container>
|
||||
*/
|
||||
public static function createContainerBuilder(
|
||||
Environment $environment
|
||||
): DI\ContainerBuilder {
|
||||
$diDefinitions = [
|
||||
Environment::class => $environment,
|
||||
];
|
||||
|
||||
Environment::setInstance($environment);
|
||||
|
||||
self::applyPhpSettings($environment);
|
||||
|
||||
// Override DI definitions for settings.
|
||||
$diDefinitions[Environment::class] = $environment;
|
||||
|
||||
$plugins = new Plugins($environment->getBaseDirectory() . '/plugins');
|
||||
|
||||
$diDefinitions[Plugins::class] = $plugins;
|
||||
|
@ -96,6 +99,16 @@ final class AppFactory
|
|||
|
||||
$containerBuilder->addDefinitions(dirname(__DIR__) . '/config/services.php');
|
||||
|
||||
return $containerBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DI\ContainerBuilder<DI\Container> $containerBuilder
|
||||
* @return DI\Container
|
||||
*/
|
||||
public static function buildContainer(
|
||||
DI\ContainerBuilder $containerBuilder
|
||||
): DI\Container {
|
||||
$di = $containerBuilder->build();
|
||||
|
||||
// Monolog setup
|
||||
|
@ -109,14 +122,17 @@ final class AppFactory
|
|||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $environment
|
||||
* @param array<string, mixed> $rawEnvironment
|
||||
*/
|
||||
public static function buildEnvironment(array $environment = []): Environment
|
||||
public static function buildEnvironment(array $rawEnvironment = []): Environment
|
||||
{
|
||||
$_ENV = getenv();
|
||||
$environment = array_merge(array_filter($_ENV), $environment);
|
||||
$rawEnvironment = array_merge(array_filter($_ENV), $rawEnvironment);
|
||||
$environment = new Environment($rawEnvironment);
|
||||
|
||||
return new Environment($environment);
|
||||
self::applyPhpSettings($environment);
|
||||
|
||||
return $environment;
|
||||
}
|
||||
|
||||
private static function applyPhpSettings(Environment $environment): void
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Factory;
|
||||
|
||||
use App\Http\Response;
|
||||
use GuzzleHttp\Psr7\HttpFactory;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Slim\Http\Factory\DecoratedResponseFactory;
|
||||
|
||||
final class ResponseFactory extends DecoratedResponseFactory
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$httpFactory = new HttpFactory();
|
||||
parent::__construct($httpFactory, $httpFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new response.
|
||||
*
|
||||
* @param int $code HTTP status code; defaults to 200
|
||||
* @param string $reasonPhrase Reason phrase to associate with status code
|
||||
* in generated response; if none is provided implementations MAY use
|
||||
* the defaults as suggested in the HTTP specification.
|
||||
*/
|
||||
public function createResponse(int $code = 200, string $reasonPhrase = ''): ResponseInterface
|
||||
{
|
||||
$response = $this->responseFactory->createResponse($code, $reasonPhrase);
|
||||
return new Response($response, $this->streamFactory);
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Factory;
|
||||
|
||||
use App\Http\ServerRequest;
|
||||
use GuzzleHttp\Psr7\HttpFactory;
|
||||
use GuzzleHttp\Psr7\ServerRequest as GuzzleServerRequest;
|
||||
use Psr\Http\Message\ServerRequestFactoryInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Slim\Interfaces\ServerRequestCreatorInterface;
|
||||
|
||||
final class ServerRequestFactory implements ServerRequestFactoryInterface, ServerRequestCreatorInterface
|
||||
{
|
||||
public function createServerRequest(string $method, $uri, array $serverParams = []): ServerRequestInterface
|
||||
{
|
||||
$serverRequest = (new HttpFactory())->createServerRequest($method, $uri, $serverParams);
|
||||
return $this->decorateServerRequest($serverRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
*/
|
||||
public function decorateServerRequest(ServerRequestInterface $request): ServerRequestInterface
|
||||
{
|
||||
return new ServerRequest($request);
|
||||
}
|
||||
|
||||
public function createServerRequestFromGlobals(): ServerRequestInterface
|
||||
{
|
||||
return $this->decorateServerRequest(GuzzleServerRequest::fromGlobals());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use GuzzleHttp\Psr7\HttpFactory as GuzzleHttpFactory;
|
||||
use GuzzleHttp\Psr7\ServerRequest as GuzzleServerRequest;
|
||||
use Psr\Http\Message\RequestFactoryInterface;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseFactoryInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestFactoryInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\StreamFactoryInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use Psr\Http\Message\UploadedFileFactoryInterface;
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
use Psr\Http\Message\UriFactoryInterface;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
use Slim\Interfaces\ServerRequestCreatorInterface;
|
||||
|
||||
final class HttpFactory implements
|
||||
RequestFactoryInterface,
|
||||
ResponseFactoryInterface,
|
||||
ServerRequestFactoryInterface,
|
||||
StreamFactoryInterface,
|
||||
UploadedFileFactoryInterface,
|
||||
UriFactoryInterface,
|
||||
ServerRequestCreatorInterface
|
||||
{
|
||||
private readonly GuzzleHttpFactory $httpFactory;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->httpFactory = new GuzzleHttpFactory();
|
||||
}
|
||||
|
||||
public function createUploadedFile(...$args): UploadedFileInterface
|
||||
{
|
||||
return $this->httpFactory->createUploadedFile(...$args);
|
||||
}
|
||||
|
||||
public function createStream(string $content = ''): StreamInterface
|
||||
{
|
||||
return $this->httpFactory->createStream($content);
|
||||
}
|
||||
|
||||
public function createStreamFromFile(...$args): StreamInterface
|
||||
{
|
||||
return $this->httpFactory->createStreamFromFile(...$args);
|
||||
}
|
||||
|
||||
public function createStreamFromResource($resource): StreamInterface
|
||||
{
|
||||
return $this->httpFactory->createStreamFromResource($resource);
|
||||
}
|
||||
|
||||
public function createServerRequest(...$args): ServerRequestInterface
|
||||
{
|
||||
$serverRequest = $this->httpFactory->createServerRequest(...$args);
|
||||
return $this->decorateServerRequest($serverRequest);
|
||||
}
|
||||
|
||||
public function createServerRequestFromGlobals(): ServerRequestInterface
|
||||
{
|
||||
return $this->decorateServerRequest(GuzzleServerRequest::fromGlobals());
|
||||
}
|
||||
|
||||
private function decorateServerRequest(ServerRequestInterface $request): ServerRequestInterface
|
||||
{
|
||||
return new ServerRequest($request);
|
||||
}
|
||||
|
||||
public function createResponse(int $code = 200, string $reasonPhrase = ''): ResponseInterface
|
||||
{
|
||||
$response = $this->httpFactory->createResponse($code, $reasonPhrase);
|
||||
return new Response($response, $this->httpFactory);
|
||||
}
|
||||
|
||||
public function createRequest(string $method, $uri): RequestInterface
|
||||
{
|
||||
return $this->httpFactory->createRequest($method, $uri);
|
||||
}
|
||||
|
||||
public function createUri(string $uri = ''): UriInterface
|
||||
{
|
||||
return $this->httpFactory->createUri($uri);
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace App\Tests;
|
||||
|
||||
use App\Http\Factory\ServerRequestFactory;
|
||||
use App\Http\HttpFactory;
|
||||
use Codeception\Lib\Connector\Shared\PhpSuperGlobalsConverter;
|
||||
use Slim\App;
|
||||
use Symfony\Component\BrowserKit\AbstractBrowser;
|
||||
|
@ -53,7 +53,7 @@ class Connector extends AbstractBrowser
|
|||
$_SERVER['REQUEST_METHOD'] = strtoupper($request->getMethod());
|
||||
$_SERVER['REQUEST_URI'] = $uri;
|
||||
|
||||
$request = (new ServerRequestFactory())->createServerRequestFromGlobals();
|
||||
$request = (new HttpFactory())->createServerRequestFromGlobals();
|
||||
|
||||
$slimResponse = $this->app->handle($request);
|
||||
|
||||
|
|
|
@ -10,9 +10,10 @@ require dirname(__DIR__) . '/vendor/autoload.php';
|
|||
|
||||
$tempDir = sys_get_temp_dir();
|
||||
|
||||
$ci = App\AppFactory::buildContainer([
|
||||
$app = App\AppFactory::createApp([
|
||||
App\Environment::TEMP_DIR => $tempDir,
|
||||
App\Environment::UPLOADS_DIR => $tempDir,
|
||||
]);
|
||||
$di = $app->getContainer();
|
||||
|
||||
return $ci->get(Doctrine\ORM\EntityManagerInterface::class);
|
||||
return $di->get(Doctrine\ORM\EntityManagerInterface::class);
|
||||
|
|
|
@ -8,14 +8,12 @@ use Psr\Log\LogLevel;
|
|||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
$di = App\AppFactory::buildContainer(
|
||||
$app = App\AppFactory::createApp(
|
||||
[
|
||||
App\Environment::BASE_DIR => dirname(__DIR__),
|
||||
App\Environment::LOG_LEVEL => LogLevel::DEBUG,
|
||||
]
|
||||
);
|
||||
|
||||
$app = App\AppFactory::buildAppFromContainer($di);
|
||||
$di = $app->getContainer();
|
||||
|
||||
$env = $di->get(Environment::class);
|
||||
App\Enums\SupportedLocales::createForCli($env);
|
||||
|
|
Loading…
Reference in New Issue