diff options
-rw-r--r-- | src/Controller/Output.php | 26 | ||||
-rw-r--r-- | src/Controller/RouteAction.php | 54 | ||||
-rw-r--r-- | src/Controller/Session/Flash.php | 2 | ||||
-rw-r--r-- | src/Controller/View/Twig.php | 2 | ||||
-rw-r--r-- | tests/Controller/RouteActionTest.php | 39 |
5 files changed, 88 insertions, 35 deletions
diff --git a/src/Controller/Output.php b/src/Controller/Output.php index ff0ed80..8eecc8b 100644 --- a/src/Controller/Output.php +++ b/src/Controller/Output.php @@ -290,7 +290,8 @@ trait Output */ protected function getContentType($format) { - if (\Jasny\str_contains($format, '/')) { // Already MIME + // Check if it's already MIME + if (\Jasny\str_contains($format, '/')) { return $format; } @@ -376,12 +377,12 @@ trait Output } /** - * Output result - * - * @param mixed $data - * @param string $format Output format as MIME or extension + * Set the content type for the output + * + * @param string $format + * @return string */ - public function output($data, $format = null) + protected function outputContentType($format) { if (!isset($format)) { $contentType = $this->getResponse()->getHeaderLine('Content-Type'); @@ -395,6 +396,19 @@ trait Output $contentType = $this->getContentType($format); $this->setResponseHeader('Content-Type', $contentType); } + + return $contentType; + } + + /** + * Output result + * + * @param mixed $data + * @param string $format Output format as MIME or extension + */ + public function output($data, $format = null) + { + $contentType = $this->outputContentType($format); try { $content = $this->serializeData($data, $contentType); diff --git a/src/Controller/RouteAction.php b/src/Controller/RouteAction.php index 32da273..e8937b0 100644 --- a/src/Controller/RouteAction.php +++ b/src/Controller/RouteAction.php @@ -11,6 +11,12 @@ use Psr\Http\Message\ResponseInterface; trait RouteAction { /** + * @var boolean + */ + protected $actionCancelled = false; + + + /** * Get request, set for controller * * @return ServerRequestInterface @@ -31,15 +37,8 @@ trait RouteAction * @param int $code HTTP status code */ abstract public function notFound($message = '', $code = 404); - - /** - * Check if response is 2xx succesful, or empty - * - * @return boolean - */ - abstract public function isSuccessful(); - + /** * Get the route * @@ -78,7 +77,7 @@ trait RouteAction /** * Called before executing the action. - * If the response is no longer a success statuc (>= 300), the action will not be executed. + * @codeCoverageIgnore * * <code> * protected function beforeAction() @@ -91,11 +90,37 @@ trait RouteAction * } * </code> */ - protected function beforeActionRun() + protected function before() { } /** + * Called before executing the action. + * @codeCoverageIgnore + */ + protected function after() + { + } + + /** + * Cancel the action + */ + public function cancel() + { + $this->actionCancelled = true; + } + + /** + * Check if the action is cancelled + * + * @return boolean + */ + public function isCancelled() + { + return $this->actionCancelled; + } + + /** * Run the controller * * @return ResponseInterface @@ -109,20 +134,22 @@ trait RouteAction return $this->notFound(); } - $this->beforeActionRun(); + $this->before(); - if ($this->isSuccessful()) { + if (!$this->isCancelled()) { $args = isset($route->args) ? $route->args : $this->getFunctionArgs($route, new \ReflectionMethod($this, $method)); call_user_func_array([$this, $method], $args); } + + $this->after(); } /** * Get the arguments for a function from a route using reflection * - * @param object $route + * @param \stdClass $route * @param \ReflectionFunctionAbstract $refl * @return array */ @@ -151,3 +178,4 @@ trait RouteAction return $args; } } + diff --git a/src/Controller/Session/Flash.php b/src/Controller/Session/Flash.php index 7b158e8..0a7fe0f 100644 --- a/src/Controller/Session/Flash.php +++ b/src/Controller/Session/Flash.php @@ -8,7 +8,7 @@ namespace Jasny\Controller\Session; class Flash { /** - * @var array + * @var array|null */ protected $data; diff --git a/src/Controller/View/Twig.php b/src/Controller/View/Twig.php index 38e97d0..f74c05a 100644 --- a/src/Controller/View/Twig.php +++ b/src/Controller/View/Twig.php @@ -18,6 +18,7 @@ trait Twig /** * Get server request + * * @return ServerRequestInterface */ abstract public function getRequest(); @@ -27,6 +28,7 @@ trait Twig * * @param mixed $data * @param string $format Output format as MIME or extension + * @return void */ abstract public function output($data, $format = null); diff --git a/tests/Controller/RouteActionTest.php b/tests/Controller/RouteActionTest.php index 49d71f5..fcab3ed 100644 --- a/tests/Controller/RouteActionTest.php +++ b/tests/Controller/RouteActionTest.php @@ -30,7 +30,7 @@ class RouteActionTest extends \PHPUnit_Framework_TestCase protected function getController($methods = array(), $className = null) { return $this->_getController( - array_merge($methods, ['getRequest', 'defaultAction', 'runTestAction', 'notFound', 'isSuccessful']), + array_merge($methods, ['getRequest', 'defaultAction', 'runTestAction', 'notFound', 'before', 'after']), $className ); } @@ -40,9 +40,9 @@ class RouteActionTest extends \PHPUnit_Framework_TestCase public function actionProvider() { return [ - [(object)['args' => [1]], 'defaultAction', [1]], - [(object)['action' => 'test-run'], 'testRunAction', []], - [(object)['action' => 'non-existent'], 'notFound', []] + [(object)['args' => ['woo']], 'defaultAction', ['woo']], + [(object)['action' => 'test-run'], 'testRunAction'], + [(object)['action' => 'non-existent'], 'notFound'] ]; } @@ -54,7 +54,7 @@ class RouteActionTest extends \PHPUnit_Framework_TestCase * @param string $method * @param array $args */ - public function testRunAction($route, $method, array $args) + public function testRunAction($route, $method, array $args = []) { $request = $this->createMock(ServerRequestInterface::class); $request->method('getAttribute')->with('route')->willReturn($route); @@ -63,10 +63,14 @@ class RouteActionTest extends \PHPUnit_Framework_TestCase $controller = $this->getController(); $controller->expects($this->any())->method('getRequest')->willReturn($request); - $controller->expects($method !== 'notFound' ? $this->once() : $this->never())->method('isSuccessful') - ->willReturn(true); - $controller->expects($this->once())->method($method)->with(...$args); + if ($method === 'notFound') { + $controller->expects($this->once())->method($method)->with(...$args); + } else { + $controller->expects($this->once())->method('before')->id('before'); + $controller->expects($this->once())->method($method)->id('action')->after('before')->with(...$args); + $controller->expects($this->once())->method('after')->after('action'); + } foreach (['defaultAction', 'runTestAction', 'notFound'] as $fn) { if ($fn !== $method) { @@ -108,8 +112,7 @@ class RouteActionTest extends \PHPUnit_Framework_TestCase $controller = $this->getController(); $controller->expects($this->any())->method('getRequest')->willReturn($request); - $controller->expects($this->once())->method('isSuccessful')->willReturn(true); - + $controller->expects($this->once())->method('defaultAction')->with(...$expect); $controller->expects($this->never())->method('runTestAction'); $controller->expects($this->never())->method('notFound'); @@ -158,20 +161,26 @@ class RouteActionTest extends \PHPUnit_Framework_TestCase $controller = $this->getController([], 'RunMissingArgumentController'); $controller->expects($this->any())->method('getRequest')->willReturn($request); - $controller->expects($this->once())->method('isSuccessful')->willReturn(true); $controller->run(); } - public function testSkipActionIfNotSuccessful() + public function testCancel() { $request = $this->createMock(ServerRequestInterface::class); $request->method('getAttribute')->with('route')->willReturn((object)[]); $controller = $this->getController(); - $controller->expects($this->any())->method('getRequest')->willReturn($request); - $controller->expects($this->once())->method('isSuccessful')->willReturn(false); - + $controller->method('getRequest')->willReturn($request); + + $controller->expects($this->once())->method('before')->willReturnCallback(\Closure::bind(function() { + $this->cancel(); + }, $controller)); + + $controller->expects($this->never())->method('defaultAction'); + + $controller->expects($this->once())->method('after'); + $controller->run(); } } |