Skip to content

Commit

Permalink
BC: Remove dependencies between application context and request conte…
Browse files Browse the repository at this point in the history
…xt. This was a bad design, use dependency injection instead (see examples)
  • Loading branch information
phpbg committed Jan 25, 2019
1 parent 787836d commit 49836a9
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 75 deletions.
11 changes: 9 additions & 2 deletions example/api/Tasks.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@
/**
* This is a sample tasks management class.
*/
class Tasks extends \PhpBg\MiniHttpd\Controller\AbstractController
final class Tasks extends \PhpBg\MiniHttpd\Controller\AbstractController
{
use \PhpBg\MiniHttpd\Middleware\ContextTrait;

// Initial tasks
public $tasks = ['task1', 'task2'];

private $loop;

public function __construct(\React\EventLoop\LoopInterface $loop)
{
$this->loop = $loop;
}

/**
* Simple add task example
*/
Expand All @@ -30,7 +37,7 @@ public function add(\Psr\Http\Message\ServerRequestInterface $request)
public function addAsync(\Psr\Http\Message\ServerRequestInterface $request)
{
return new React\Promise\Promise(function($resolve, $reject) use ($request) {
$this->getContext($request)->applicationContext->loop->addTimer(2, function() use ($resolve, $reject, $request) {
$this->loop->addTimer(2, function() use ($resolve, $reject, $request) {
try {
$task = $this->getFromPost($request, 'task', null, new \Zend\Validator\NotEmpty());
} catch (\PhpBg\MiniHttpd\Model\ValidateException $e) {
Expand Down
1 change: 1 addition & 0 deletions example/bare-minimal-json-server.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// Application context will be accessible everywhere
// @See \PhpBg\MiniHttpd\Middleware\ContextTrait to retrieve it easily
$applicationContext = new \PhpBg\MiniHttpd\Model\ApplicationContext();
$applicationContext->loop = $loop;

// Default renderer
$applicationContext->defaultRenderer = new \PhpBg\MiniHttpd\Renderer\Json();
Expand Down
4 changes: 1 addition & 3 deletions example/full-featured-server.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

$loop = React\EventLoop\Factory::create();
$jsonRenderer = new \PhpBg\MiniHttpd\Renderer\Json();
$taskController = new Tasks();
$taskController = new Tasks($loop);
$routes = [
// Redirection example
'/' => new \PhpBg\MiniHttpd\Model\Route(function () {
Expand Down Expand Up @@ -43,8 +43,6 @@
// You may require loop for async tasks
$applicationContext->loop = $loop;

// You can put your configuration directives in options
$applicationContext->options = [];
$applicationContext->routes = $routes;

// Public path is where static files are served from (optional)
Expand Down
61 changes: 34 additions & 27 deletions src/Middleware/AutoPhtml.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,36 +43,43 @@ public function __invoke(ServerRequestInterface $request, callable $next)
$result = $next($request);
$context = $this->getContext($request);
$renderer = $context->getRenderer();
if ($renderer instanceof Phtml && is_object($context->route->handler)) {
$rc = new \ReflectionClass(get_class($context->route->handler));
$controllerFilePath = $rc->getFileName();
$controllerFilePathinfo = pathinfo($controllerFilePath);
if (! isset($renderer)) {
return $result;
}
if (! $renderer instanceof Phtml) {
return $result;
}
if (! is_object($context->route->handler)) {
return $result;
}
$rc = new \ReflectionClass(get_class($context->route->handler));
$controllerFilePath = $rc->getFileName();
$controllerFilePathinfo = pathinfo($controllerFilePath);

// PHTML view file
$phtmlFile = "{$controllerFilePathinfo['dirname']}/{$controllerFilePathinfo['filename']}.phtml";
if (!array_key_exists('viewFilePath', $context->renderOptions)) {
$context->renderOptions['viewFilePath'] = $phtmlFile;
}
// PHTML view file
$phtmlFile = "{$controllerFilePathinfo['dirname']}/{$controllerFilePathinfo['filename']}.phtml";
if (!array_key_exists('viewFilePath', $context->renderOptions)) {
$context->renderOptions['viewFilePath'] = $phtmlFile;
}

// JS file
$jsFile = "{$controllerFilePathinfo['dirname']}/{$controllerFilePathinfo['filename']}.js";
if (!isset($context->renderOptions['inlineScripts'])) {
$context->renderOptions['inlineScripts'] = [];
}
if (is_file($jsFile)) {
//TODO async file get contents?
$context->renderOptions['inlineScripts'][] = file_get_contents($jsFile);
}
// JS file
$jsFile = "{$controllerFilePathinfo['dirname']}/{$controllerFilePathinfo['filename']}.js";
if (!isset($context->renderOptions['inlineScripts'])) {
$context->renderOptions['inlineScripts'] = [];
}
if (is_file($jsFile)) {
//TODO async file get contents?
$context->renderOptions['inlineScripts'][] = file_get_contents($jsFile);
}

// CSS file
$cssFile = "{$controllerFilePathinfo['dirname']}/{$controllerFilePathinfo['filename']}.css";
if (!isset($context->renderOptions['inlineCss'])) {
$context->renderOptions['inlineCss'] = [];
}
if (is_file($cssFile)) {
//TODO async file get contents?
$context->renderOptions['inlineCss'][] = file_get_contents($cssFile);
}
// CSS file
$cssFile = "{$controllerFilePathinfo['dirname']}/{$controllerFilePathinfo['filename']}.css";
if (!isset($context->renderOptions['inlineCss'])) {
$context->renderOptions['inlineCss'] = [];
}
if (is_file($cssFile)) {
//TODO async file get contents?
$context->renderOptions['inlineCss'][] = file_get_contents($cssFile);
}

return $result;
Expand Down
11 changes: 1 addition & 10 deletions src/Middleware/Context.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

namespace PhpBg\MiniHttpd\Middleware;

use PhpBg\MiniHttpd\Model\ApplicationContext;
use PhpBg\MiniHttpd\Model\RequestContext;
use Psr\Http\Message\ServerRequestInterface;

Expand All @@ -39,17 +38,9 @@ class Context

protected $applicationContext;

/**
* @param ApplicationContext $applicationContext
*/
public function __construct(ApplicationContext $applicationContext)
{
$this->applicationContext = $applicationContext;
}

public function __invoke(ServerRequestInterface $request, callable $next)
{
$context = new RequestContext($this->applicationContext);
$context = new RequestContext();
$request = $this->setContext($request, $context);
return $next($request);
}
Expand Down
3 changes: 2 additions & 1 deletion src/Middleware/Render.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ protected function doRenderException(ServerRequestInterface $request, \Exception
protected function getRenderer(ServerRequestInterface $request): RendererInterface
{
$context = $this->getContext($request);
return $context->getRenderer();
$renderer = $context->getRenderer();
return $renderer ?? $this->defaultRenderer;
}
}
14 changes: 10 additions & 4 deletions src/Middleware/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,22 @@ class Route
{
use ContextTrait;

protected $routes;

public function __construct(array $routes)
{
$this->routes = $routes;
}

public function __invoke(ServerRequestInterface $request, callable $next)
{
$pathDecoded = $this->getContext($request)->uriPathDecoded;
$routes = $this->getContext($request)->applicationContext->routes;
if (isset($routes[$pathDecoded])) {
if (!$routes[$pathDecoded] instanceof \PhpBg\MiniHttpd\Model\Route) {
if (isset($this->routes[$pathDecoded])) {
if (!$this->routes[$pathDecoded] instanceof \PhpBg\MiniHttpd\Model\Route) {
throw new \RuntimeException("Route $pathDecoded does not extend " . \PhpBg\MiniHttpd\Model\Route::class);
}

$this->getContext($request)->route = $routes[$pathDecoded];
$this->getContext($request)->route = $this->routes[$pathDecoded];
}

return $next($request);
Expand Down
12 changes: 6 additions & 6 deletions src/Model/ApplicationContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,6 @@ class ApplicationContext
*/
public $loop;

/**
* This is where you can put your application configuration
* @var mixed
*/
public $options;

/**
* Array of <uri paths> => <Route>
* @var Route[]
Expand All @@ -59,6 +53,12 @@ class ApplicationContext
*/
public $publicPath;

/**
* Root path of the application
* @var string
*/
public $rootPath;

/**
* @var LoggerInterface
*/
Expand Down
22 changes: 3 additions & 19 deletions src/Model/RequestContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@
*/
class RequestContext
{
/**
* @var ApplicationContext
*/
public $applicationContext;

/**
* @var ResponseInterface
*/
Expand Down Expand Up @@ -67,11 +62,6 @@ class RequestContext
*/
public $renderOptions = [];

public function __construct(ApplicationContext $context)
{
$this->applicationContext = $context;
}

/**
* Return the response that will be returned
* Remember that because of PSR-7, responses are immutable so @see RequestContext::setResponse()
Expand Down Expand Up @@ -99,16 +89,10 @@ public function setResponse(ResponseInterface $response): ResponseInterface
/**
* Return renderer instance to use
*
* @return RendererInterface
* @return RendererInterface | null
*/
public function getRenderer(): RendererInterface
public function getRenderer()
{
// Use route renderer if any
if (isset($this->route->renderer)) {
return $this->route->renderer;
}

// Otherwise use default renderer
return $this->applicationContext->defaultRenderer;
return $this->route->renderer ?? null;
}
}
6 changes: 3 additions & 3 deletions src/ServerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ public static function createDefaultStack(ApplicationContext $applicationContext
// Log all incoming requests
$middlewares[] = new LogRequest($applicationContext->logger);

// Make application context and request context available to all middlewares. Allow data exchanging between middlewares
$middlewares[] = new Context($applicationContext);
// Make request context available to all middlewares. Allow data exchanging between middlewares
$middlewares[] = new Context();

// Decode once uri path
$middlewares[] = new UriPath();
Expand Down Expand Up @@ -90,7 +90,7 @@ public static function createDefaultStack(ApplicationContext $applicationContext
$middlewares[] = new LogError($applicationContext->logger);

// Calculate route to be run
$middlewares[] = new Route();
$middlewares[] = new Route($applicationContext->routes);

// Auto render PHTML files
$middlewares[] = new AutoPhtml();
Expand Down

0 comments on commit 49836a9

Please sign in to comment.