summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Controller.php506
-rw-r--r--src/Controller/CheckRequest.php86
-rw-r--r--src/Controller/CheckResponse.php75
-rw-r--r--src/Controller/Respond.php307
-rw-r--r--src/Controller/RouteAction.php87
-rw-r--r--src/Controller/Session.php65
-rw-r--r--src/Controller/Session/Flash.php129
-rw-r--r--src/Controller/View/Twig.php (renamed from src/View/Twig.php)0
-rw-r--r--src/Flash.php109
9 files changed, 744 insertions, 620 deletions
diff --git a/src/Controller.php b/src/Controller.php
index 9f69160..93ba38d 100644
--- a/src/Controller.php
+++ b/src/Controller.php
@@ -10,6 +10,11 @@ use Psr\Http\Message\ResponseInterface;
*/
abstract class Controller
{
+ use Controller\Respond,
+ Controller\CheckRequest,
+ Controller\CheckResponse,
+ Controller\Session;
+
/**
* Server request
* @var ServerRequestInterface
@@ -22,46 +27,18 @@ abstract class Controller
**/
protected $response = null;
- /**
- * Common input and output formats with associated MIME
- * @var array
- */
- protected $contentFormats = [
- 'text/html' => 'html',
- 'application/json' => 'json',
- 'application/xml' => 'xml',
- 'text/xml' => 'xml',
- 'text/plain' => 'text',
- 'application/javascript' => 'js',
- 'text/css' => 'css',
- 'image/png' => 'png',
- 'image/gif' => 'gif',
- 'image/jpeg' => 'jpeg',
- 'image/x-icon' => 'ico',
- 'application/x-www-form-urlencoded' => 'post',
- 'multipart/form-data' => 'post'
- ];
/**
- * Flash
- * @var Flash
- */
- protected $flash = null;
-
- /**
- * Run the controller
- *
- * @return ResponseInterface
- */
- abstract public function run();
-
- /**
* Get request, set for controller
*
* @return ServerRequestInterface
*/
- public function getRequest()
+ protected function getRequest()
{
+ if (!isset($this->request)) {
+ throw new \RuntimeException("Request not set, the controller has not been invoked");
+ }
+
return $this->request;
}
@@ -70,470 +47,47 @@ abstract class Controller
*
* @return ResponseInterface
*/
- public function getResponse()
+ protected function getResponse()
{
+ if (!isset($this->response)) {
+ throw new \RuntimeException("Response not set, the controller has not been invoked");
+ }
+
return $this->response;
}
/**
- * Run the controller as function
+ * Get response. set for controller
*
- * @param ServerRequestInterface $request
- * @param ResponseInterface $response
* @return ResponseInterface
*/
- public function __invoke(ServerRequestInterface $request, ResponseInterface $response)
+ protected function setResponse(ResponseInterface $response)
{
- $this->request = $request;
$this->response = $response;
-
- return $this->run();
- }
-
- /**
- * Set the headers with HTTP status code and content type.
- * @link http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
- *
- * Examples:
- * <code>
- * $this->responseWith(200, 'json');
- * $this->responseWith(200, 'application/json');
- * $this->responseWith(204);
- * $this->responseWith("204 Created");
- * $this->responseWith('json');
- * </code>
- *
- * @param int $code HTTP status code (may be omitted)
- * @param string|array $format Mime or content format
- * @return ResponseInterface $response
- */
- public function responseWith($code, $format = null)
- {
- $response = $this->getResponse();
-
- // Shift arguments if $code is omitted
- if (!is_int($code) && !preg_match('/^\d{3}\b/', $code)) {
- list($code, $format) = array_merge([null], func_get_args());
- }
-
- if ($code) {
- $response = $response->withStatus((int)$code);
- }
-
- if ($format) {
- $contentType = $this->getContentType($format);
- $response = $response->withHeader('Content-Type', $contentType);
- }
-
- return $response;
- }
-
- /**
- * Response with success 200 code
- *
- * @return ResponseInterface $response
- */
- public function ok()
- {
- return $this->responseWith(200);
- }
-
- /**
- * Response with created 201 code, and optionaly redirect to created location
- *
- * @param string $location Url of created resource
- * @return ResponseInterface $response
- */
- public function created($location = '')
- {
- $response = $this->responseWith(201);
-
- if ($location) {
- $response = $response->withHeader('Location', $location);
- }
-
- return $response;
- }
-
- /**
- * Response with 204 'No Content'
- *
- * @return ResponseInterface $response
- */
- public function noContent()
- {
- return $this->responseWith(204);
- }
-
- /**
- * Redirect to url
- *
- * @param string $url
- * @param int $code 301 (Moved Permanently), 303 (See Other) or 307 (Temporary Redirect)
- * @return ResponseInterface $response
- */
- public function redirect($url, $code = 303)
- {
- $response = $this->responseWith($code, 'html');
- $response = $response->withHeader('Location', $url);
- $response->getBody()->write('You are being redirected to <a href="' . $url . '">' . $url . '</a>');
-
- return $response;
- }
-
- /**
- * Redirect to previous page, or to home page
- *
- * @return ResponseInterface $response
- */
- public function back()
- {
- return $this->redirect($this->getLocalReferer() ?: '/');
- }
-
- /**
- * Route to 401
- * Note: While the 401 route is used, we don't respond with a 401 http status code.
- *
- * @return ResponseInterface $response
- */
- public function requireLogin()
- {
- return $this->redirect('/401');
- }
-
- /**
- * Alias of requireLogin
- *
- * @return ResponseInterface $response
- */
- public function requireAuth()
- {
- return $this->requireLogin();
- }
-
- /**
- * Set response to error 'Bad Request' state
- *
- * @param string $message
- * @param int $code HTTP status code
- * @return ResponseInterface $response
- */
- public function badRequest($message, $code = 400)
- {
- return $this->error($message, $code);
- }
-
- /**
- * Set response to error 'Forbidden' state
- *
- * @param string $message
- * @param int $code HTTP status code
- * @return ResponseInterface $response
- */
- public function forbidden($message, $code = 403)
- {
- return $this->error($message, $code);
- }
-
- /**
- * Set response to error 'Not Found' state
- *
- * @param string $message
- * @param int $code HTTP status code
- * @return ResponseInterface $response
- */
- public function notFound($message, $code = 404)
- {
- return $this->error($message, $code);
- }
-
- /**
- * Set response to error 'Conflict' state
- *
- * @param string $message
- * @param int $code HTTP status code
- * @return ResponseInterface $response
- */
- public function conflict($message, $code = 409)
- {
- return $this->error($message, $code);
- }
-
- /**
- * Set response to error 'Too Many Requests' state
- *
- * @param string $message
- * @param int $code HTTP status code
- * @return ResponseInterface $response
- */
- public function tooManyRequests($message, $code = 429)
- {
- return $this->error($message, $code);
- }
-
- /**
- * Set response to error state
- *
- * @param string $message
- * @param int $code HTTP status code
- * @return ResponseInterface $response
- */
- public function error($message, $code = 400)
- {
- $response = $this->getResponse();
-
- $errorResponse = $response->withStatus($code);
- $errorResponse->getBody()->write($message);
-
- return $errorResponse;
- }
-
- /**
- * Set the flash message and/or return the flash object.
- *
- * @param mixed $type flash type, eg. 'error', 'notice' or 'success'
- * @param mixed $message flash message
- * @return Flash
- */
- public function flash($type = null, $message = null)
- {
- if (!isset($this->flash)) $this->flash = new Flash();
- if ($type && $message) $this->flash->set($type, $message);
-
- return $this->flash;
- }
-
- /**
- * Check if response is 2xx succesful, or empty
- *
- * @return boolean
- */
- public function isSuccessful()
- {
- $code = $this->getResponseStatusCode();
-
- return !$code || ($code >= 200 && $code < 300);
- }
-
- /**
- * Check if response is a 3xx redirect
- *
- * @return boolean
- */
- public function isRedirection()
- {
- $code = $this->getResponseStatusCode();
-
- return $code >= 300 && $code < 400;
}
/**
- * Check if response is a 4xx client error
- *
- * @return boolean
- */
- public function isClientError()
- {
- $code = $this->getResponseStatusCode();
-
- return $code >= 400 && $code < 500;
- }
-
- /**
- * Check if response is a 5xx redirect
- *
- * @return boolean
- */
- public function isServerError()
- {
- return $this->getResponseStatusCode() >= 500;
- }
-
- /**
- * Check if response is 4xx or 5xx error
- *
- * @return boolean
- */
- public function isError()
- {
- return $this->isClientError() || $this->isServerError();
- }
-
- /**
- * Check if request is GET request
- *
- * @return boolean
- */
- public function isGetRequest()
- {
- $method = $this->getRequestMethod();
-
- return !$method || $method === 'GET';
- }
-
- /**
- * Check if request is POST request
- *
- * @return boolean
- */
- public function isPostRequest()
- {
- return $this->getRequestMethod() === 'POST';
- }
-
- /**
- * Check if request is PUT request
- *
- * @return boolean
- */
- public function isPutRequest()
- {
- return $this->getRequestMethod() === 'PUT';
- }
-
- /**
- * Check if request is DELETE request
- *
- * @return boolean
- */
- public function isDeleteRequest()
- {
- return $this->getRequestMethod() === 'DELETE';
- }
-
- /**
- * Check if request is HEAD request
- *
- * @return boolean
- */
- public function isHeadRequest()
- {
- return $this->getRequestMethod() === 'HEAD';
- }
-
- /**
- * Returns the HTTP referer if it is on the current host
- *
- * @return string
- */
- public function getLocalReferer()
- {
- $request = $this->getRequest();
- $referer = $request->getHeaderLine('HTTP_REFERER');
- $host = $request->getHeaderLine('HTTP_HOST');
-
- return $referer && parse_url($referer, PHP_URL_HOST) === $host ? $referer : '';
- }
-
- /**
- * Output result
- *
- * @param mixed $data
- * @param string $format
- * @return ResponseInterface $response
- */
- public function output($data, $format)
- {
- $response = $this->getResponse();
- $contentType = $this->getContentType($format);
- $response = $response->withHeader('Content-Type', $contentType);
- $content = is_scalar($data) ? $data : $this->encodeData($data, $format);
-
- $response->getBody()->write($content);
-
- return $response;
- }
-
- /**
- * Encode data to send to client
- *
- * @param mixed $data
- * @param string $format
- * @return string
- */
- public function encodeData($data, $format)
- {
- switch ($format) {
- case 'json': return $this->encodeDataAsJson($data);
- case 'xml': return $this->encodeDataAsXml($data);
- case 'html':
- throw new \InvalidArgumentException("To encode HTML please use a view");
- default:
- throw new \InvalidArgumentException("Can not encode data for format '$format'");
- }
- }
-
- /**
- * Encode data as xml
- *
- * @param \SimpleXMLElement $data
- * @return string
- */
- protected function encodeDataAsXml(\SimpleXMLElement $data)
- {
- return $data->asXML();
- }
-
- /**
- * Encode data as json
- *
- * @param mixed
- * @return string
- */
- protected function encodeDataAsJson($data)
- {
- $data = json_encode($data);
-
- return $this->isJsonp() ?
- $this->getRequest()->getQueryParams()['callback'] . '(' . $data . ')' :
- $data;
- }
-
- /**
- * Check if we should respond with jsonp
- *
- * @return boolean
- */
- protected function isJsonp()
- {
- $request = $this->getRequest();
-
- return $request && !empty($request->getQueryParams()['callback']);
- }
-
- /**
- * Get status code of response
+ * Run the controller
*
- * @return int
+ * @return ResponseInterface
*/
- protected function getResponseStatusCode()
- {
- $response = $this->getResponse();
-
- return $response ? $response->getStatusCode() : 0;
- }
+ abstract protected function run();
- /**
- * Get valid content type by simple word description
- *
- * @param string $format
- * @return string
- */
- protected function getContentType($format)
- {
- return array_search($format, $this->contentFormats) ?: $format;
- }
/**
- * Get method of request
+ * Run the controller as function
*
- * @return string
+ * @param ServerRequestInterface $request
+ * @param ResponseInterface $response
+ * @return ResponseInterface
*/
- protected function getRequestMethod()
+ public function __invoke(ServerRequestInterface $request, ResponseInterface $response)
{
- $request = $this->getRequest();
+ $this->request = $request;
+ $this->response = $response;
- return $request ? $request->getMethod() : '';
+ $this->useSession();
+
+ return $this->run();
}
}
diff --git a/src/Controller/CheckRequest.php b/src/Controller/CheckRequest.php
new file mode 100644
index 0000000..a63a2b7
--- /dev/null
+++ b/src/Controller/CheckRequest.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace Jasny\Controller;
+
+use Psr\Http\Message\ServerRequestInterface;
+
+/**
+ * Controller methods to check the request
+ */
+trait CheckRequest
+{
+ /**
+ * Get request, set for controller
+ *
+ * @return ServerRequestInterface
+ */
+ abstract protected function getRequest();
+
+
+ /**
+ * Check if request is GET request
+ *
+ * @return boolean
+ */
+ public function isGetRequest()
+ {
+ $method = $this->getRequest()->getMethod();
+
+ return !$method || $method === 'GET';
+ }
+
+ /**
+ * Check if request is POST request
+ *
+ * @return boolean
+ */
+ public function isPostRequest()
+ {
+ return $this->getRequest()->getMethod() === 'POST';
+ }
+
+ /**
+ * Check if request is PUT request
+ *
+ * @return boolean
+ */
+ public function isPutRequest()
+ {
+ return $this->getRequest()->getMethod() === 'PUT';
+ }
+
+ /**
+ * Check if request is DELETE request
+ *
+ * @return boolean
+ */
+ public function isDeleteRequest()
+ {
+ return $this->getRequest()->getMethod() === 'DELETE';
+ }
+
+ /**
+ * Check if request is HEAD request
+ *
+ * @return boolean
+ */
+ public function isHeadRequest()
+ {
+ return $this->getRequest()->getMethod() === 'HEAD';
+ }
+
+
+ /**
+ * Returns the HTTP referer if it is on the current host
+ *
+ * @return string
+ */
+ public function getLocalReferer()
+ {
+ $request = $this->getRequest();
+ $referer = $request->getHeaderLine('HTTP_REFERER');
+ $host = $request->getHeaderLine('HTTP_HOST');
+
+ return $referer && parse_url($referer, PHP_URL_HOST) === $host ? $referer : '';
+ }
+} \ No newline at end of file
diff --git a/src/Controller/CheckResponse.php b/src/Controller/CheckResponse.php
new file mode 100644
index 0000000..7c02d46
--- /dev/null
+++ b/src/Controller/CheckResponse.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace Jasny\Controller;
+
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Methods to check the response
+ */
+trait CheckResponse
+{
+ /**
+ * Get response. set for controller
+ *
+ * @return ResponseInterface
+ */
+ abstract protected function getResponse();
+
+
+ /**
+ * Check if response is 2xx succesful, or empty
+ *
+ * @return boolean
+ */
+ public function isSuccessful()
+ {
+ $code = $this->getResponse()->getStatusCode() ?: 200;
+
+ return !$code || ($code >= 200 && $code < 300);
+ }
+
+ /**
+ * Check if response is a 3xx redirect
+ *
+ * @return boolean
+ */
+ public function isRedirection()
+ {
+ $code = $this->getResponse()->getStatusCode() ?: 200;
+
+ return $code >= 300 && $code < 400;
+ }
+
+ /**
+ * Check if response is a 4xx client error
+ *
+ * @return boolean
+ */
+ public function isClientError()
+ {
+ $code = $this->getResponse()->getStatusCode() ?: 200;
+
+ return $code >= 400 && $code < 500;
+ }
+
+ /**
+ * Check if response is a 5xx redirect
+ *
+ * @return boolean
+ */
+ public function isServerError()
+ {
+ return $this->getResponse()->getStatusCode() ?: 200 >= 500;
+ }
+
+ /**
+ * Check if response is 4xx or 5xx error
+ *
+ * @return boolean
+ */
+ public function isError()
+ {
+ return $this->isClientError() || $this->isServerError();
+ }
+}
diff --git a/src/Controller/Respond.php b/src/Controller/Respond.php
new file mode 100644
index 0000000..02b2cfb
--- /dev/null
+++ b/src/Controller/Respond.php
@@ -0,0 +1,307 @@
+<?php
+
+namespace Jasny\Controller;
+
+use Psr\Http\Message\ResponseInterface;
+use Dflydev\ApacheMimeTypes\PhpRepository as ApacheMimeTypes;
+
+/**
+ * Methods for a controller to send a response
+ */
+trait Respond
+{
+ /**
+ * Get response. set for controller
+ *
+ * @return ResponseInterface
+ */
+ abstract protected function getResponse();
+
+ /**
+ * Get response. set for controller
+ *
+ * @return ResponseInterface
+ */
+ abstract protected function setResponse(ResponseInterface $response);
+
+ /**
+ * Returns the HTTP referer if it is on the current host
+ *
+ * @return string
+ */
+ abstract public function getLocalReferer();
+
+
+ /**
+ * Set a response header
+ *
+ * @param string $header
+ * @param string $value
+ * @param boolean $overwrite
+ */
+ public function setResponseHeader($header, $value, $overwrite = true)
+ {
+ $fn = $overwrite ? 'withHeader' : 'withAddedHeader';
+ $response = $this->getResponse()->$fn($value, $header);
+
+ $this->setResponse($response);
+ }
+
+ /**
+ * Set the headers with HTTP status code and content type.
+ * @link http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
+ *
+ * Examples:
+ * <code>
+ * $this->respondWith(200, 'json');
+ * $this->respondWith(200, 'application/json');
+ * $this->respondWith(204);
+ * $this->respondWith("204 Created");
+ * $this->respondWith('json');
+ * </code>
+ *
+ * @param int $code HTTP status code (may be omitted)
+ * @param string|array $format Mime or content format
+ */
+ public function respondWith($code, $format = null)
+ {
+ $response = $this->getResponse();
+
+ // Shift arguments if $code is omitted
+ if (!is_int($code) && !preg_match('/^\d{3}\b/', $code)) {
+ list($code, $format) = array_merge([null], func_get_args());
+ }
+
+ if ($code) {
+ $response = $response->withStatus((int)$code);
+ }
+
+ if ($format) {
+ $contentType = $this->getContentType($format);
+ $response = $response->withHeader('Content-Type', $contentType);
+ }
+
+ $this->setResponse($response);
+ }
+
+
+ /**
+ * Response with 200 OK
+ *
+ * @return ResponseInterface $response
+ */
+ public function ok()
+ {
+ $this->respondWith(200);
+ }
+
+ /**
+ * Response with created 201 code, and optionaly redirect to created location
+ *
+ * @param string $location Url of created resource
+ */
+ public function created($location = '')
+ {
+ $this->respondWith(201);
+
+ if ($location) {
+ $this->setResponseHeader('Location', $location);
+ }
+ }
+
+ /**
+ * Response with 204 No Content
+ */
+ public function noContent()
+ {
+ $this->respondWith(204);
+ }
+
+ /**
+ * Redirect to url
+ *
+ * @param string $url
+ * @param int $code 301 (Moved Permanently), 303 (See Other) or 307 (Temporary Redirect)
+ */
+ public function redirect($url, $code = 303)
+ {
+ $this->respondWith($code, 'text/html');
+ $this->setResponseHeader('Location', $url);
+
+ $urlHtml = htmlentities($url);
+ $this->output('You are being redirected to <a href="' . $urlHtml . '">' . $urlHtml . '</a>');
+ }
+
+ /**
+ * Redirect to previous page, or to home page
+ *
+ * @return ResponseInterface $response
+ */
+ public function back()
+ {
+ $this->redirect($this->getLocalReferer() ?: '/');
+ }
+
+
+ /**
+ * Respond with 400 Bad Request
+ *
+ * @param string $message
+ * @param int $code HTTP status code
+ */
+ public function badRequest($message, $code = 400)
+ {
+ $this->respondWith($code);
+ $this->output($message);
+ }
+
+ /**
+ * Respond with a 401 Unauthorized
+ */
+ public function requireAuth()
+ {
+ $this->respondWith(401);
+ }
+
+ /**
+ * Alias of requireAuth
+ * @deprecated
+ */
+ final public function requireLogin()
+ {
+ $this->requireAuth();
+ }
+
+ /**
+ * Respond with 402 Payment Required
+ *
+ * @param string $message
+ */
+ public function paymentRequired($message = "Payment required")
+ {
+ $this->respondWith(402);
+ $this->output($message);
+ }
+
+ /**
+ * Respond with 403 Forbidden
+ *
+ * @param string $message
+ */
+ public function forbidden($message = "Forbidden")
+ {
+ $this->respondWith(403);
+ $this->output($message);
+ }
+
+ /**
+ * Respond with 404 Not Found
+ *
+ * @param string $message
+ * @param int $code HTTP status code (404 or 405)
+ */
+ public function notFound($message = "Not found", $code = 404)
+ {
+ $this->respondWith($code);
+ $this->output($message);
+ }
+
+ /**
+ * Respond with 409 Conflict
+ *
+ * @param string $message
+ */
+ public function conflict($message)
+ {
+ $this->respondWith(409);
+ $this->output($message);
+ }
+
+ /**
+ * Respond with 429 Too Many Requests
+ *
+ * @param string $message
+ */
+ public function tooManyRequests($message = "Too many requests")
+ {
+ $this->respondWith(429);
+ $this->output($message);
+ }
+
+
+ /**
+ * Respond with a server error
+ *
+ * @param string $message
+ * @param int $code HTTP status code
+ */
+ public function error($message = "An unexpected error occured", $code = 500)
+ {
+ $this->respondWith($code);
+ $this->output($message);
+ }
+
+
+ /**
+ * Get MIME type for extension
+ *
+ * @param string $format
+ * @return string
+ */
+ protected function getContentType($format)
+ {
+ if (\Jasny\str_contains($format, '/')) { // Already MIME
+ return $format;
+ }
+
+ $repository = new ApacheMimeTypes();
+ $mime = $repository->findType('html');
+
+ if (!isset($mime)) {
+ throw new \UnexpectedValueException("Format $format doesn't correspond with a MIME type");
+ }
+
+ return $mime;
+ }
+
+ /**
+ * Serialize data
+ *
+ * @param mixed $data
+ * @param string $contentType
+ * @return string
+ */
+ 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)) {
+ throw new \Exception("Unable to serialize data to {$contentType}");
+ }
+
+ return $data;
+ }
+
+ /**
+ * Output result
+ *
+ * @param mixed $data
+ * @param string $format Output format as MIME or extension
+ */
+ public function output($data, $format = null)
+ {
+ if (!isset($format)) {
+ $contentType = $this->getResponse()->getHeaderLine('Content-Type') ?: 'text/html';
+ } else {
+ $contentType = $this->getContentType($format);
+ $this->setResponseHeader('Content-Type', $contentType);
+ }
+
+ $content = $this->serializeData($data, $contentType);
+
+ $this->getResponse()->getBody()->write($content);
+ }
+}
diff --git a/src/Controller/RouteAction.php b/src/Controller/RouteAction.php
index dabd501..5303f8a 100644
--- a/src/Controller/RouteAction.php
+++ b/src/Controller/RouteAction.php
@@ -15,40 +15,75 @@ trait RouteAction
*
* @return ServerRequestInterface
*/
- abstract public function getRequest();
+ abstract protected function getRequest();
- /**
+ /**
* Get response. set for controller
*
* @return ResponseInterface
*/
- abstract public function getResponse();
+ abstract protected function getResponse();
+
+ /**
+ * Respond with a server error
+ *
+ * @param string $message
+ * @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();
+
+
+ /**
+ * Called before executing the action.
+ * If the response is no longer a success statuc (>= 300), the action will not be executed.
+ *
+ * <code>
+ * protected function beforeAction()
+ * {
+ * $this->respondWith('json'); // Respond with JSON by default
+ *
+ * if ($this->auth->getUser()->getCredits() <= 0) {
+ * $this->paymentRequired();
+ * }
+ * }
+ * </code>
+ */
+ protected function beforeAction()
+ {
+ }
+
+ /**
* Run the controller
*
* @return ResponseInterface
*/
- public function run() {
- $request = $this->getRequest();
- $route = $request->getAttribute('route');
+ public function run()
+ {
+ $route = $this->getRequest()->getAttribute('route');
$method = $this->getActionMethod(isset($route->action) ? $route->action : 'default');
-
+
if (!method_exists($this, $method)) {
- return $this->setResponseError(404, 'Not Found');
+ return $this->notFound();
}
- try {
- $args = isset($route->args) ?
- $route->args :
- $this->getFunctionArgs($route, new \ReflectionMethod($this, $method));
- } catch (\RuntimeException $e) {
- return $this->setResponseError(400, 'Bad Request');
- }
+ $args = isset($route->args)
+ ? $route->args
+ : $this->getFunctionArgs($route, new \ReflectionMethod($this, $method));
- $response = call_user_func_array([$this, $method], $args);
+ $this->beforeAction();
+
+ if ($this->isSuccessful()) {
+ call_user_func_array([$this, $method], $args);
+ }
- return $response ?: $this->getResponse();
+ return $this->getResponse();
}
/**
@@ -96,22 +131,4 @@ trait RouteAction
return $args;
}
-
- /**
- * Set response to error state
- *
- * @param int $code
- * @param string $message
- * @return ResponseInterface
- */
- protected function setResponseError($code, $message)
- {
- $response = $this->getResponse();
-
- $errorResponse = $response->withStatus($code);
- $errorResponse->getBody()->write($message);
-
- return $errorResponse;
- }
}
-
diff --git a/src/Controller/Session.php b/src/Controller/Session.php
new file mode 100644
index 0000000..8dc292f
--- /dev/null
+++ b/src/Controller/Session.php
@@ -0,0 +1,65 @@
+<?php
+
+namespace Jasny\Controller;
+
+use Jasny\Controller\Session\Flash;
+
+/**
+ * Use session in the controller
+ */
+trait Session
+{
+ /**
+ * Session
+ * @var array|\ArrayObject
+ */
+ protected $session;
+
+ /**
+ * Flash message
+ * @var Flash
+ */
+ protected $flash;
+
+
+ /**
+ * Get request, set for controller
+ *
+ * @return ServerRequestInterface
+ */
+ abstract protected function getRequest();
+
+
+ /**
+ * Link the session to the session property in the controller
+ */
+ protected function useSession()
+ {
+ $this->session = $this->getRequest()->getAttribute('session');
+
+ if (!isset($this->session)) {
+ $this->session =& $_SESSION;
+ }
+ }
+
+
+ /**
+ * Get an/or set the flash message.
+ *
+ * @param mixed $type flash type, eg. 'error', 'notice' or 'success'
+ * @param mixed $message flash message
+ * @return Flash
+ */
+ public function flash($type = null, $message = null)
+ {
+ if (!isset($this->flash)) {
+ $this->flash = new Flash($this->session);
+ }
+
+ if ($type) {
+ $this->flash->set($type, $message);
+ }
+
+ return $this->flash;
+ }
+}
diff --git a/src/Controller/Session/Flash.php b/src/Controller/Session/Flash.php
new file mode 100644
index 0000000..be72e7c
--- /dev/null
+++ b/src/Controller/Session/Flash.php
@@ -0,0 +1,129 @@
+<?php
+
+namespace Jasny\Controller\Session;
+
+/**
+ * Class for the flash message
+ */
+class Flash
+{
+ /**
+ * @var array
+ */
+ protected $data;
+
+ /**
+ * @var array|\ArrayObject
+ */
+ protected $session;
+
+ /**
+ * Session key for flash
+ * @var string
+ */
+ protected $key = 'flash';
+
+
+ /**
+ * Class constructor
+ *
+ * @param array|\ArrayObject $session
+ */
+ public function __construct(&$session)
+ {
+ $this->session =& $session;
+ }
+
+ /**
+ * Check if the flash is set.
+ *
+ * @return boolean
+ */
+ public function isIssued()
+ {
+ return isset($this->session[$this->key]);
+ }
+
+ /**
+ * Set the flash.
+ *
+ * @param string $type flash type, eg. 'error', 'notice' or 'success'
+ * @param mixed $message flash message
+ */
+ public function set($type, $message)
+ {
+ if (!$type) {
+ throw new \InvalidArgumentException("Type should not be empty");
+ }
+
+ $this->session[$this->key] = compact('type', 'message');
+ }
+
+ /**
+ * Get the flash.
+ *
+ * @return object
+ */
+ public function get()
+ {
+ if (!isset($this->data) && isset($this->session[$this->key])) {
+ $this->data = $this->session[$this->key];
+ unset($this->session[$this->key]);
+ }
+
+ return (object)$this->data;
+ }
+
+ /**
+ * Reissue the flash.
+ */
+ public function reissue()
+ {
+ if (!isset($this->data) && isset($this->session[$this->key])) {
+ $this->data = $this->session[$this->key];
+ } else {
+ $this->session[$this->key] = $this->data;
+ }
+ }
+
+ /**
+ * Clear the flash.
+ */
+ public function clear()
+ {
+ $this->data = null;
+ unset($this->session[$this->key]);
+ }
+
+ /**
+ * Get the flash type
+ *
+ * @return string
+ */
+ public function getType()
+ {
+ $data = $this->get();
+ return isset($data) ? $data->type : null;
+ }
+
+ /**
+ * Get the flash message
+ *
+ * @return string
+ */
+ public function getMessage()
+ {
+ $data = $this->get();
+ return isset($data) ? $data->message : null;
+ }
+
+ /**
+ * Cast object to string
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return (string)$this->getMessage();
+ }
+}
diff --git a/src/View/Twig.php b/src/Controller/View/Twig.php
index ee5d4ce..ee5d4ce 100644
--- a/src/View/Twig.php
+++ b/src/Controller/View/Twig.php
diff --git a/src/Flash.php b/src/Flash.php
deleted file mode 100644
index ad060f9..0000000
--- a/src/Flash.php
+++ /dev/null
@@ -1,109 +0,0 @@
-<?php
-
-namespace Jasny;
-
-/**
- * Class for the flash message
- */
-class Flash
-{
- /**
- * @var object
- */
- protected static $data = null;
-
- /**
- * Check if the flash is set.
- *
- * @return boolean
- */
- public static function isIssued()
- {
- return isset($_SESSION['flash']) || isset(static::$data);
- }
-
- /**
- * Set the flash.
- *
- * @param mixed $type flash type, eg. 'error', 'notice' or 'success'
- * @param mixed $message flash message
- */
- public static function set($type, $message)
- {
- if (!$type) {
- throw new \InvalidArgumentException("Type should not be empty");
- }
-
- static::$data = (object)['type'=>$type, 'message'=>$message];
-
- $_SESSION['flash'] = static::$data;
- }
-
- /**
- * Get the flash.
- *
- * @return object
- */
- public static function get()
- {
- if (!isset(static::$data) && isset($_SESSION['flash'])) {
- static::$data = (object)$_SESSION['flash'];
- unset($_SESSION['flash']);
- }
-
- return static::$data;
- }
-
- /**
- * Reissue the flash.
- */
- public static function reissue()
- {
- if (!isset(static::$data) && isset($_SESSION['flash'])) {
- static::$data = (object)$_SESSION['flash'];
- } else {
- $_SESSION['flash'] = static::$data;
- }
- }
-
- /**
- * Clear the flash.
- */
- public static function clear()
- {
- self::$data = null;
- unset($_SESSION['flash']);
- }
-
- /**
- * Get the flash type
- *
- * @return string
- */
- public static function getType()
- {
- $data = static::get();
- return isset($data) ? $data->type : null;
- }
-
- /**
- * Get the flash message
- *
- * @return string
- */
- public static function getMessage()
- {
- $data = static::get();
- return isset($data) ? $data->message : null;
- }
-
- /**
- * Cast object to string
- *
- * @return string
- */
- public function __toString()
- {
- return (string)$this->getMessage();
- }
-}