Refactor DispatcherInterface to HandlerInterface

Update file doc blocks
Code inspection
This commit is contained in:
PJ Dietz 2014-06-29 10:43:39 -04:00
parent 3718e03c78
commit aa06181e40
16 changed files with 125 additions and 107 deletions

View File

@ -4,7 +4,7 @@
* pjdietz\WellRESTed\Exceptions\CurlException
*
* @author PJ Dietz <pj@pjdietz.com>
* @copyright Copyright 2013 by PJ Dietz
* @copyright Copyright 2014 by PJ Dietz
* @license MIT
*/

View File

@ -0,0 +1,18 @@
<?php
/**
* pjdietz\WellRESTed\Exceptions\ParseException
*
* @author PJ Dietz <pj@pjdietz.com>
* @copyright Copyright 2014 by PJ Dietz
* @license MIT
*/
namespace pjdietz\WellRESTed\Exceptions;
/**
* Exception related to a parsing data.
*/
class ParseException extends WellRESTedException
{
}

View File

@ -4,36 +4,41 @@
* pjdietz\WellRESTed\Handler
*
* @author PJ Dietz <pj@pjdietz.com>
* @copyright Copyright 2013 by PJ Dietz
* @copyright Copyright 2014 by PJ Dietz
* @license MIT
*/
namespace pjdietz\WellRESTed;
use pjdietz\WellRESTed\Interfaces\DispatcherInterface;
use pjdietz\WellRESTed\Interfaces\HandlerInterface;
use pjdietz\WellRESTed\Interfaces\ResponseInterface;
use pjdietz\WellRESTed\Interfaces\RoutableInterface;
use pjdietz\WellRESTed\Interfaces\RequestInterface;
/**
* A Handler issues a response for a given resource.
* Responds to a request based on the HTTP method.
*
* @property-read ResponseInterface response The Response to the request
* To use Handler, create a subclass and implement the methods for any HTTP
* verbs you would like to support. (get() for GET, post() for POST, etc).
*
* - Access the request via the protected member $this->request
* - Access a map of arguments via $this->args (e.g., URI path variables)
* - Modify $this->response to provide the response the instance will return
*/
abstract class Handler implements DispatcherInterface
abstract class Handler implements HandlerInterface
{
/** @var array Matches array from the preg_match() call used to find this Handler */
/** @var array Map of variables to suppliement the request, usually path variables. */
protected $args;
/** @var RoutableInterface The HTTP request to respond to. */
/** @var RequestInterface The HTTP request to respond to. */
protected $request;
/** @var ResponseInterface The HTTP response to send based on the request. */
protected $response;
/**
* @param RoutableInterface $request
* @param RequestInterface $request
* @param array|null $args
* @return ResponseInterface
*/
public function getResponse(RoutableInterface $request = null, $args = null)
public function getResponse(RequestInterface $request, array $args = null)
{
$this->request = $request;
$this->args = $args;
@ -95,9 +100,7 @@ abstract class Handler implements DispatcherInterface
{
// The default function calls the instance's get() method, then sets
// the resonse's body member to an empty string.
$this->get();
if ($this->response->getStatusCode() == 200) {
$this->response->setBody('', false);
}

View File

@ -1,18 +0,0 @@
<?php
namespace pjdietz\WellRESTed\Interfaces;
/**
* Provides a mechanism for obtaining a response given a request.
* @package pjdietz\WellRESTed\Interfaces
*/
interface DispatcherInterface {
/**
* @param RoutableInterface $request The request to build a responce for.
* @param array|null $args Optional associate array of arguments.
* @return ResponseInterface|null
*/
public function getResponse(RoutableInterface $request, $args = null);
}

View File

@ -0,0 +1,26 @@
<?php
/**
* pjdietz\WellRESTed\Interfaces\HandlerInterface
*
* @author PJ Dietz <pj@pjdietz.com>
* @copyright Copyright 2014 by PJ Dietz
* @license MIT
*/
namespace pjdietz\WellRESTed\Interfaces;
/**
* Provides a mechanism for obtaining a response given a request.
* @package pjdietz\WellRESTed
*/
interface HandlerInterface {
/**
* @param RequestInterface $request The request to build a responce for.
* @param array|null $args Optional associate array of arguments.
* @return ResponseInterface|null
*/
public function getResponse(RequestInterface $request, array $args = null);
}

View File

@ -4,7 +4,7 @@
* pjdietz\WellRESTed\Interfaces\RequestInterface
*
* @author PJ Dietz <pj@pjdietz.com>
* @copyright Copyright 2013 by PJ Dietz
* @copyright Copyright 2014 by PJ Dietz
* @license MIT
*/

View File

@ -4,7 +4,7 @@
* pjdietz\WellRESTed\Interfaces\ResponseInterface
*
* @author PJ Dietz <pj@pjdietz.com>
* @copyright Copyright 2013 by PJ Dietz
* @copyright Copyright 2014 by PJ Dietz
* @license MIT
*/

View File

@ -1,12 +0,0 @@
<?php
namespace pjdietz\WellRESTed\Interfaces;
interface RoutableInterface extends RequestInterface
{
/** @return int The number of times a router has dispatched this Routable */
public function getRouteDepth();
/** Increase the instance's internal count of its depth in nested route tables */
public function incrementRouteDepth();
}

View File

@ -4,7 +4,7 @@
* pjdietz\WellRESTed\Message
*
* @author PJ Dietz <pj@pjdietz.com>
* @copyright Copyright 2013 by PJ Dietz
* @copyright Copyright 2014 by PJ Dietz
* @license MIT
*/
@ -12,12 +12,6 @@ namespace pjdietz\WellRESTed;
/**
* Common base class for the Request and Response classes.
*
* @property string body Entity body of the message
* @property-read array headers Associative array of HTTP headers
* @property-read array headerLines Numeric array of HTTP headers
* @property string protocol The protocol, e.g. HTTP
* @property string protocolVersion The version of the protocol
*/
abstract class Message
{

View File

@ -4,14 +4,14 @@
* pjdietz\WellRESTed\Request
*
* @author PJ Dietz <pj@pjdietz.com>
* @copyright Copyright 2013 by PJ Dietz
* @copyright Copyright 2014 by PJ Dietz
* @license MIT
*/
namespace pjdietz\WellRESTed;
use pjdietz\WellRESTed\Exceptions\CurlException;
use pjdietz\WellRESTed\Interfaces\RoutableInterface;
use pjdietz\WellRESTed\Interfaces\RequestInterface;
/**
* A Request instance represents an HTTP request. This class has two main uses:
@ -22,15 +22,8 @@ use pjdietz\WellRESTed\Interfaces\RoutableInterface;
*
* Second, you can create a custom Request and use it to obtain a Response
* from a server through cURL.
*
* @property string hostname Hostname part of the URI
* @property string method HTTP method (GET, POST, PUT, DELETE, etc.)
* @property string path Path component of the URI for the request
* @property-read string pathParts Fragments of the path, delimited by slashes
* @property array query Associative array of query parameters
* @property array uri Full URI (protocol, hostname, path, etc.)
*/
class Request extends Message implements RoutableInterface
class Request extends Message implements RequestInterface
{
/**
* Singleton instance derived from reading info from Apache.
@ -65,11 +58,9 @@ class Request extends Message implements RoutableInterface
public function __construct($uri = null, $method = 'GET')
{
parent::__construct();
if (!is_null($uri)) {
$this->setUri($uri);
}
$this->method = $method;
}
@ -89,7 +80,6 @@ class Request extends Message implements RoutableInterface
$request->readHttpRequest();
self::$theRequest = $request;
}
return self::$theRequest;
}
@ -398,7 +388,7 @@ class Request extends Message implements RoutableInterface
// Make a reponse to populate and return with data obtained via cURL.
$resp = new Response();
$resp->statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$resp->setStatusCode(curl_getinfo($ch, CURLINFO_HTTP_CODE));
// Split the result into headers and body.
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);

View File

@ -4,7 +4,7 @@
* pjdietz\WellRESTed\Response
*
* @author PJ Dietz <pj@pjdietz.com>
* @copyright Copyright 2013 by PJ Dietz
* @copyright Copyright 2014 by PJ Dietz
* @license MIT
*/
@ -16,11 +16,6 @@ use pjdietz\WellRESTed\Interfaces\ResponseInterface;
/**
* A Response instance allows you to build an HTTP response and send it when
* finished.
*
* @property string reasonPhrase Text explanation of status code.
* @property int statusCode HTTP status code
* @property-read string statusLine HTTP status line, e.g. "HTTP/1.1 200 OK"
* @property-read bool success True if the status code is 2xx
*/
class Response extends Message implements ResponseInterface
{

View File

@ -1,21 +1,39 @@
<?php
/**
* pjdietz\WellRESTed\RouteBuilder
*
* @author PJ Dietz <pj@pjdietz.com>
* @copyright Copyright 2014 by PJ Dietz
* @license MIT
*/
namespace pjdietz\WellRESTed;
use pjdietz\WellRESTed\Interfaces\DispatcherInterface;
use pjdietz\WellRESTed\Exceptions\ParseException;
use pjdietz\WellRESTed\Interfaces\HandlerInterface;
use pjdietz\WellRESTed\Routes\RegexRoute;
use pjdietz\WellRESTed\Routes\StaticRoute;
use pjdietz\WellRESTed\Routes\TemplateRoute;
use stdClass;
use UnexpectedValueException;
/**
* Class for facilitating constructing Routers.
*/
class RouteBuilder
{
private $handlerNamespace;
private $templateVariablePatterns;
private $defaultVariablePattern;
public function getRoutes($data)
/**
* Contruct and return an array of routes.
*
* @param $data
* @return array
* @throws Exceptions\ParseException
*/
public function buildRoutes($data)
{
// Locate the list of routes. This should be one of these:
// - If $data is an object, $data->routes
@ -26,7 +44,7 @@ class RouteBuilder
$dataRoutes = $data->routes;
$this->readConfiguration($data);
} else {
throw new UnexpectedValueException("Unable to parse. Missing array of routes.");
throw new ParseException("Unable to parse. Missing array of routes.");
}
// Build a route instance and append it to the list.
@ -37,10 +55,14 @@ class RouteBuilder
return $routes;
}
public function buildRoutesFromJson($json) {
return $this->buildRoutes(json_decode($json));
}
/**
* @param stdClass|array $item
* @return DispatcherInterface
* @throws \UnexpectedValueException Parse error
* @return HandlerInterface
* @throws Exceptions\ParseException
*/
protected function buildRoute($item)
{
@ -51,7 +73,7 @@ class RouteBuilder
$handler = $this->getHandlerNamespace() . "\\" . $handler;
}
} else {
throw new UnexpectedValueException("Unable to parse. Route is missing a handler.");
throw new ParseException("Unable to parse. Route is missing a handler.");
}
// Static Route

View File

@ -4,22 +4,22 @@
* pjdietz\WellRESTed\Router
*
* @author PJ Dietz <pj@pjdietz.com>
* @copyright Copyright 2013 by PJ Dietz
* @copyright Copyright 2014 by PJ Dietz
* @license MIT
*/
namespace pjdietz\WellRESTed;
use pjdietz\WellRESTed\Interfaces\DispatcherInterface;
use pjdietz\WellRESTed\Interfaces\HandlerInterface;
use pjdietz\WellRESTed\Interfaces\ResponseInterface;
use pjdietz\WellRESTed\Interfaces\RoutableInterface;
use pjdietz\WellRESTed\Interfaces\RequestInterface;
/**
* Router
*
* A Router uses a table of Routes to find the appropriate Handler for a request.
*/
class Router implements DispatcherInterface
class Router implements HandlerInterface
{
/** @var array Array of Route objects */
private $routes;
@ -33,11 +33,11 @@ class Router implements DispatcherInterface
/**
* Return the response built by the handler based on the request
*
* @param RoutableInterface $request
* @param null $args
* @param RequestInterface $request
* @param array|null $args
* @return ResponseInterface
*/
public function getResponse(RoutableInterface $request, $args = null)
public function getResponse(RequestInterface $request, array $args = null)
{
// Use the singleton if the caller did not pass a request.
if (is_null($request)) {
@ -45,7 +45,7 @@ class Router implements DispatcherInterface
}
foreach ($this->routes as $route) {
/** @var DispatcherInterface $route */
/** @var HandlerInterface $route */
$responce = $route->getResponse($request, $args);
if ($responce) {
return $responce;
@ -58,9 +58,9 @@ class Router implements DispatcherInterface
/**
* Append a new route to the route route table.
*
* @param DispatcherInterface $route
* @param HandlerInterface $route
*/
public function addRoute(DispatcherInterface $route)
public function addRoute(HandlerInterface $route)
{
$this->routes[] = $route;
}
@ -68,12 +68,12 @@ class Router implements DispatcherInterface
/**
* Append a series of routes.
*
* @param array $routes List array of DispatcherInterface instances
* @param array $routes List array of HandlerInterface instances
*/
public function addRoutes(array $routes)
{
foreach ($routes as $route) {
if ($route instanceof DispatcherInterface) {
if ($route instanceof HandlerInterface) {
$this->addRoute($route);
}
}
@ -87,10 +87,10 @@ class Router implements DispatcherInterface
/**
* Prepare a resonse indicating a 404 Not Found error
*
* @param RoutableInterface $request
* @param RequestInterface $request
* @return ResponseInterface
*/
protected function getNoRouteResponse(RoutableInterface $request)
protected function getNoRouteResponse(RequestInterface $request)
{
$response = new Response(404);
$response->setBody('No resource at ' . $request->getPath());
@ -100,11 +100,11 @@ class Router implements DispatcherInterface
/**
* Prepare a response indicating a 500 Internal Server Error
*
* @param RoutableInterface $request
* @param RequestInterface $request
* @param string $message Optional additional message.
* @return ResponseInterface
*/
protected function getInternalServerErrorResponse(RoutableInterface $request, $message = '')
protected function getInternalServerErrorResponse(RequestInterface $request, $message = '')
{
$response = new Response(500);
$response->setBody('Server error at ' . $request->getPath() . "\n" . $message);

View File

@ -2,16 +2,16 @@
namespace pjdietz\WellRESTed\Routes;
use pjdietz\WellRESTed\Interfaces\DispatcherInterface;
use pjdietz\WellRESTed\Interfaces\HandlerInterface;
/**
* Base class for Routes.
* @package pjdietz\WellRESTed\Routes
*/
abstract class BaseRoute implements DispatcherInterface
abstract class BaseRoute implements HandlerInterface
{
/** @var string Fully qualified name for the interface for handlers */
const DISPATCHER_INTERFACE = '\\pjdietz\\WellRESTed\\Interfaces\\DispatcherInterface';
const DISPATCHER_INTERFACE = '\\pjdietz\\WellRESTed\\Interfaces\\HandlerInterface';
/** @var string */
private $targetClassName;
@ -25,17 +25,17 @@ abstract class BaseRoute implements DispatcherInterface
}
/**
* @return DispatcherInterface
* @return HandlerInterface
* @throws \UnexpectedValueException
*/
protected function getTarget()
{
if (is_subclass_of($this->targetClassName, self::DISPATCHER_INTERFACE)) {
/** @var DispatcherInterface $target */
/** @var HandlerInterface $target */
$target = new $this->targetClassName();
return $target;
} else {
throw new \UnexpectedValueException("Target class must implement DispatcherInterface");
throw new \UnexpectedValueException("Target class must implement HandlerInterface");
}
}

View File

@ -2,7 +2,7 @@
namespace pjdietz\WellRESTed\Routes;
use pjdietz\WellRESTed\Interfaces\RoutableInterface;
use pjdietz\WellRESTed\Interfaces\RequestInterface;
class RegexRoute extends BaseRoute
{
@ -19,9 +19,9 @@ class RegexRoute extends BaseRoute
}
// ------------------------------------------------------------------------
/* DispatcherInterface */
/* HandlerInterface */
public function getResponse(RoutableInterface $request, $args = null)
public function getResponse(RequestInterface $request, array $args = null)
{
if (preg_match($this->getPattern(), $request->getPath(), $matches)) {
$target = $this->getTarget();

View File

@ -3,7 +3,7 @@
namespace pjdietz\WellRESTed\Routes;
use InvalidArgumentException;
use pjdietz\WellRESTed\Interfaces\RoutableInterface;
use pjdietz\WellRESTed\Interfaces\RequestInterface;
/**
* Class StaticRoute
@ -31,9 +31,9 @@ class StaticRoute extends BaseRoute
}
// ------------------------------------------------------------------------
/* DispatcherInterface */
/* HandlerInterface */
public function getResponse(RoutableInterface $request, $args = null)
public function getResponse(RequestInterface $request, array $args = null)
{
$requestPath = $request->getPath();
foreach ($this->paths as $path) {