From 2eecbd43eb2f84f34831ff2538856118b10ffd35 Mon Sep 17 00:00:00 2001 From: Victor Welling Date: Thu, 1 Feb 2018 15:43:29 +0100 Subject: [PATCH] Context is now interfaced, in preparation of Shoot/Http --- CHANGELOG.md | 4 ++++ README.md | 2 +- composer.json | 5 ++++- src/Context.php | 10 +-------- src/ContextInterface.php | 30 ++++---------------------- src/Pipeline.php | 45 +++++++++++++++++++-------------------- src/PipelineInterface.php | 17 +++++++++++++++ tests/ContextTest.php | 8 ------- tests/PipelineTest.php | 3 ++- 9 files changed, 55 insertions(+), 69 deletions(-) create mode 100644 src/PipelineInterface.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b8cb02..d9f85f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog All notable changes to Shoot will be documented in this file. +## [0.3.0] - 2018-02-01 +- Context is now interfaced, in preparation of the Shoot/Http package. This package will make use of Shoot in an HTTP +context (PSR-7 and PSR-15) easier. + ## [0.2.1] - 2018-01-16 - Shoot handles embedded templates by passing through all variables from the parent template. diff --git a/README.md b/README.md index 1add044..190113d 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ available to all middleware and presenters. You'll see how it's used further dow ```php $app->get('/posts/{post_id}', function ($request, $response) { - $context = [ServerRequestInterface::class => $request]; + $context = new Context([ServerRequestInterface::class => $request]); return $this ->get(Pipeline::class) diff --git a/composer.json b/composer.json index 99d9d1f..38a7188 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "shoot/shoot", - "description": "Shoot extends Twig with presentation models, presenters and a middleware interface", + "description": "Shoot brings inversion of control to loading template data for Twig", "type": "library", "keywords": [ "twig", @@ -32,6 +32,9 @@ "require-dev": { "phpunit/phpunit": "^6.5" }, + "suggest": { + "shoot/http": "Makes use of Shoot in an HTTP context more convenient" + }, "autoload": { "psr-4": { "Shoot\\Shoot\\": "src/" diff --git a/src/Context.php b/src/Context.php index e8a2046..4ac6e97 100644 --- a/src/Context.php +++ b/src/Context.php @@ -6,7 +6,7 @@ /** * Provides the context in which middleware processes a view. */ -final class Context +final class Context implements ContextInterface { /** @var mixed[] */ private $attributes; @@ -29,12 +29,4 @@ public function getAttribute(string $name, $default = null) { return $this->attributes[$name] ?? $default; } - - /** - * @return mixed[] All attributes available in the context. - */ - public function getAttributes(): array - { - return $this->attributes; - } } diff --git a/src/ContextInterface.php b/src/ContextInterface.php index ee2738d..7dd6acc 100644 --- a/src/ContextInterface.php +++ b/src/ContextInterface.php @@ -3,35 +3,13 @@ namespace Shoot\Shoot; -/** - * Provides an interface to apply a context to the pipeline as it processes a view. - */ interface ContextInterface { /** - * Apply the given context attributes to the pipeline. + * @param string $name The name of the attribute. + * @param mixed $default A default value is the attribute does not exist. * - * @param mixed[] $context - * - * @return void - */ - public function applyContext(array $context); - - /** - * Clear the current context. - * - * @return void - */ - public function clearContext(); - - /** - * Applies the given context to the pipeline, executes the given callback, and clears the context. This method - * exists merely for convenience. - * - * @param mixed[] $context - * @param callable $callback - * - * @return mixed The result as returned by the callback (if any). + * @return mixed The value of the attribute, or the default if it does not exist. */ - public function withContext(array $context, callable $callback); + public function getAttribute(string $name, $default = null); } diff --git a/src/Pipeline.php b/src/Pipeline.php index 31b0e1a..6a9f8aa 100644 --- a/src/Pipeline.php +++ b/src/Pipeline.php @@ -12,7 +12,7 @@ use Twig_Test as TwigTest; use Twig_TokenParserInterface as TokenParserInterface; -final class Pipeline implements ContextInterface, ExtensionInterface +final class Pipeline implements ExtensionInterface, PipelineInterface { /** @var Context */ private $context; @@ -53,45 +53,44 @@ private function chainMiddleware(array $middleware): callable } /** - * Apply the given context attributes to the pipeline. + * Applies the given context to the pipeline, executes the given callback, and clears the context. * - * @param mixed[] $context + * @param ContextInterface $context + * @param callable $callback * - * @return void + * @return mixed The result as returned by the callback (if any). */ - public function applyContext(array $context) + public function withContext(ContextInterface $context, callable $callback) { - $this->context = new Context($context); + try { + $this->applyContext($context); + + return $callback(); + } finally { + $this->clearContext(); + } } /** - * Clear the current context. + * Apply the given context attributes to the pipeline. + * + * @param ContextInterface $context * * @return void */ - public function clearContext() + private function applyContext(ContextInterface $context) { - $this->applyContext([]); + $this->context = $context; } /** - * Applies the given context to the pipeline, executes the given callback, and clears the context. This method - * exists merely for convenience. - * - * @param mixed[] $context - * @param callable $callback + * Clear the current context. * - * @return mixed The result as returned by the callback (if any). + * @return void */ - public function withContext(array $context, callable $callback) + private function clearContext() { - try { - $this->applyContext($context); - - return $callback(); - } finally { - $this->clearContext(); - } + $this->applyContext(new Context()); } /** diff --git a/src/PipelineInterface.php b/src/PipelineInterface.php new file mode 100644 index 0000000..88491cf --- /dev/null +++ b/src/PipelineInterface.php @@ -0,0 +1,17 @@ +assertSame('default', $this->context->getAttribute('non_existing_attribute', 'default')); } - /** - * @return void - */ - public function testGetAttributesShouldReturnAllAttributes() - { - $this->assertCount(2, $this->context->getAttributes()); - } - /** * @return void */ diff --git a/tests/PipelineTest.php b/tests/PipelineTest.php index 63b6050..96bc387 100644 --- a/tests/PipelineTest.php +++ b/tests/PipelineTest.php @@ -67,8 +67,9 @@ public function testWithContextShouldClearContext() }); $pipeline = new Pipeline([$middleware]); + $context = new Context(['string_attribute' => 'value']); - $pipeline->withContext(['string_attribute' => 'value'], function () use ($pipeline, $view) { + $pipeline->withContext($context, function () use ($pipeline, $view) { $pipeline->process($view); });