diff options
author | Arnold Daniels <arnold@jasny.net> | 2016-11-18 18:28:24 +0100 |
---|---|---|
committer | Arnold Daniels <arnold@jasny.net> | 2016-11-18 18:28:24 +0100 |
commit | 43c6d835943b322c036e9ee47800d694cb6bb5de (patch) | |
tree | f56809890b4e65c2f4790fbd8be9593a3538a72c /src/Controller | |
parent | 934b380f473b4e85e807f07d6bf516f4e227e112 (diff) | |
download | controller-43c6d835943b322c036e9ee47800d694cb6bb5de.zip controller-43c6d835943b322c036e9ee47800d694cb6bb5de.tar.gz controller-43c6d835943b322c036e9ee47800d694cb6bb5de.tar.bz2 |
Refactored CheckRequest and CheckResponse traits
WIP Controller\Output
Restructuring the tests (one test per trait)
Diffstat (limited to 'src/Controller')
-rw-r--r-- | src/Controller/CheckResponse.php | 23 | ||||
-rw-r--r-- | src/Controller/Input.php | 13 | ||||
-rw-r--r-- | src/Controller/Output.php (renamed from src/Controller/Respond.php) | 125 |
3 files changed, 135 insertions, 26 deletions
diff --git a/src/Controller/CheckResponse.php b/src/Controller/CheckResponse.php index 7c02d46..7509778 100644 --- a/src/Controller/CheckResponse.php +++ b/src/Controller/CheckResponse.php @@ -18,6 +18,17 @@ trait CheckResponse /** + * Check if response is a 1xx informational + * + * @return boolean + */ + public function isInformational() + { + $code = $this->getResponse()->getStatusCode() ?: 200; + return $code >= 100 && $code < 200; + } + + /** * Check if response is 2xx succesful, or empty * * @return boolean @@ -25,8 +36,7 @@ trait CheckResponse public function isSuccessful() { $code = $this->getResponse()->getStatusCode() ?: 200; - - return !$code || ($code >= 200 && $code < 300); + return $code >= 200 && $code < 300; } /** @@ -37,7 +47,6 @@ trait CheckResponse public function isRedirection() { $code = $this->getResponse()->getStatusCode() ?: 200; - return $code >= 300 && $code < 400; } @@ -49,7 +58,6 @@ trait CheckResponse public function isClientError() { $code = $this->getResponse()->getStatusCode() ?: 200; - return $code >= 400 && $code < 500; } @@ -60,8 +68,9 @@ trait CheckResponse */ public function isServerError() { - return $this->getResponse()->getStatusCode() ?: 200 >= 500; - } + $code = $this->getResponse()->getStatusCode() ?: 200; + return $code >= 500 && $code < 600; + } /** * Check if response is 4xx or 5xx error @@ -71,5 +80,5 @@ trait CheckResponse public function isError() { return $this->isClientError() || $this->isServerError(); - } + } } diff --git a/src/Controller/Input.php b/src/Controller/Input.php new file mode 100644 index 0000000..7f5ce35 --- /dev/null +++ b/src/Controller/Input.php @@ -0,0 +1,13 @@ +<?php + +namespace Jasny\Controller; + +use Psr\Http\Message\ServerRequestInterface; + +/** + * Methods for a controller to read from the request + */ +trait Input +{ + +} diff --git a/src/Controller/Respond.php b/src/Controller/Output.php index 02b2cfb..a6160f1 100644 --- a/src/Controller/Respond.php +++ b/src/Controller/Output.php @@ -8,9 +8,14 @@ use Dflydev\ApacheMimeTypes\PhpRepository as ApacheMimeTypes; /** * Methods for a controller to send a response */ -trait Respond +trait Output { /** + * @var string + */ + protected $defaultFormat; + + /** * Get response. set for controller * * @return ResponseInterface @@ -33,6 +38,17 @@ trait Respond /** + * If a non scalar value is passed without an format, use this format + * + * @param string $format Format by extention or MIME + */ + public function byDefaultSerializeTo($format) + { + $this->defaultFormat = $format; + } + + + /** * Set a response header * * @param string $header @@ -96,40 +112,66 @@ trait Respond } /** - * Response with created 201 code, and optionaly redirect to created location + * Response with created 201 code, and optionally the created location * * @param string $location Url of created resource */ - public function created($location = '') + public function created($location = null) { $this->respondWith(201); - if ($location) { + if (!empty($location)) { $this->setResponseHeader('Location', $location); } } /** + * Response with 203 Accepted + */ + public function accepted() + { + $this->respondWith(202); + } + + /** * Response with 204 No Content + * + * @param int $code 204 (No Content) or 205 (Reset Content) */ - public function noContent() + public function noContent($code = 204) { - $this->respondWith(204); + $this->respondWith($code); + } + + /** + * Respond with a 206 Partial content with `Content-Range` header + * + * @param int $rangeFrom Beginning of the range in bytes + * @param int $rangeTo End of the range in bytes + * @param int $totalSize Total size in bytes + */ + public function partialContent($rangeFrom, $rangeTo, $totalSize) + { + $this->respondWith(206); + + $this->setResponseHeader('Content-Range', "bytes {$rangeFrom}-{$rangeTo}/{$totalSize}"); + $this->setResponseHeader('Content-Length', $rangeTo - $rangeFrom); } + /** - * Redirect to url + * Redirect to url and output a short message with the link * * @param string $url - * @param int $code 301 (Moved Permanently), 303 (See Other) or 307 (Temporary Redirect) + * @param int $code 301 (Moved Permanently), 302 (Found), 303 (See Other) or 307 (Temporary Redirect) */ public function redirect($url, $code = 303) { - $this->respondWith($code, 'text/html'); + $this->respondWith($code); $this->setResponseHeader('Location', $url); $urlHtml = htmlentities($url); - $this->output('You are being redirected to <a href="' . $urlHtml . '">' . $urlHtml . '</a>'); + $this->output('You are being redirected to <a href="' . $urlHtml . '">' . $urlHtml . '</a>', 'text/html'); } /** @@ -141,6 +183,14 @@ trait Respond { $this->redirect($this->getLocalReferer() ?: '/'); } + + /** + * Respond with 304 Not Modified + */ + public function notModified() + { + $this->respondWith(304); + } /** @@ -188,7 +238,7 @@ trait Respond * * @param string $message */ - public function forbidden($message = "Forbidden") + public function forbidden($message = "Access denied") { $this->respondWith(403); $this->output($message); @@ -198,7 +248,7 @@ trait Respond * Respond with 404 Not Found * * @param string $message - * @param int $code HTTP status code (404 or 405) + * @param int $code 404 (Not Found), 405 (Method not allowed) or 410 (Gone) */ public function notFound($message = "Not found", $code = 404) { @@ -273,16 +323,53 @@ trait Respond */ protected function serializeData($data, $contentType) { - if ($contentType == 'json') { - return (is_string($data) && (json_decode($data) !== null || !json_last_error())) - ? $data : json_encode($data); + if (is_scalar($data)) { + return (string)$data; + } + + $format = preg_replace('~^.+/~', '', $contentType); + $method = 'serializeDataTo' . $format; + + if (method_exists($this, $method)) { + return $this->$method($data); + } + + if (is_object($data) && method_exists($data, '__toString')) { + return (string)$data; + } + + throw new \Exception("Unable to serialize data to $format"); + } + + /** + * Serialize data to JSON + * + * @param mixed $data + * @return string + */ + private function serializeDataToJson($data) + { + return json_encode($data); + } + + /** + * Serialize data to XML + * + * @param mixed $data + * @return string + */ + private function serializeDataToXml($data) + { + if ($data instanceof \SimpleXMLElement) { + return $data->asXML(); } - if (!is_scalar($data)) { - throw new \Exception("Unable to serialize data to {$contentType}"); + if ($data instanceof \DOMNode) { + return $data->ownerDocument->saveXML($data); } - return $data; + $type = (is_object($data) ? get_class($data) . ' ' : '') . gettype($data); + throw new \Exception("Unable to serialize $type to XML"); } /** @@ -300,7 +387,7 @@ trait Respond $this->setResponseHeader('Content-Type', $contentType); } - $content = $this->serializeData($data, $contentType); + $content = $this->serializeData($data, $format); $this->getResponse()->getBody()->write($content); } |