From 8f99b88d0927aa5bd9b0e06759dd355143d53b2a Mon Sep 17 00:00:00 2001 From: PJ Dietz Date: Sat, 28 Jun 2014 19:42:05 -0400 Subject: [PATCH] Reduce number of interfaces and classes Remove RouterInterface, Route, and RouteTarget Change signature of DispatcherInterface::getResponse() to include args Update classes to match new DispatcherInterface::getResponse() This update simplifies the API significantly with most classes now simply needing to implement DispatcherInterface --- src/pjdietz/WellRESTed/Handler.php | 19 +- .../Interfaces/DispatcherInterface.php | 3 +- .../WellRESTed/Interfaces/RouterInterface.php | 19 -- src/pjdietz/WellRESTed/Route.php | 183 ------------------ src/pjdietz/WellRESTed/RouteTarget.php | 70 ------- src/pjdietz/WellRESTed/Router.php | 44 ++--- src/pjdietz/WellRESTed/Routes/BaseRoute.php | 10 +- src/pjdietz/WellRESTed/Routes/RegexRoute.php | 11 +- src/pjdietz/WellRESTed/Routes/StaticRoute.php | 8 +- 9 files changed, 46 insertions(+), 321 deletions(-) delete mode 100644 src/pjdietz/WellRESTed/Interfaces/RouterInterface.php delete mode 100644 src/pjdietz/WellRESTed/Route.php delete mode 100644 src/pjdietz/WellRESTed/RouteTarget.php diff --git a/src/pjdietz/WellRESTed/Handler.php b/src/pjdietz/WellRESTed/Handler.php index 317c838..79be1f7 100644 --- a/src/pjdietz/WellRESTed/Handler.php +++ b/src/pjdietz/WellRESTed/Handler.php @@ -10,7 +10,7 @@ namespace pjdietz\WellRESTed; -use pjdietz\WellRESTed\Interfaces\HandlerInterface; +use pjdietz\WellRESTed\Interfaces\DispatcherInterface; use pjdietz\WellRESTed\Interfaces\ResponseInterface; use pjdietz\WellRESTed\Interfaces\RoutableInterface; @@ -19,17 +19,24 @@ use pjdietz\WellRESTed\Interfaces\RoutableInterface; * * @property-read ResponseInterface response The Response to the request */ -abstract class Handler extends RouteTarget implements HandlerInterface +abstract class Handler implements DispatcherInterface { + /** @var array Matches array from the preg_match() call used to find this Handler */ + protected $args; + /** @var RoutableInterface 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 array|null $args * @return ResponseInterface */ - public function getResponse(RoutableInterface $request = null) + public function getResponse(RoutableInterface $request = null, $args = null) { - if (!is_null($request)) { - $this->request = $request; - } + $this->request = $request; + $this->args = $args; $this->response = new Response(); $this->buildResponse(); return $this->response; diff --git a/src/pjdietz/WellRESTed/Interfaces/DispatcherInterface.php b/src/pjdietz/WellRESTed/Interfaces/DispatcherInterface.php index 659d617..ec218bc 100644 --- a/src/pjdietz/WellRESTed/Interfaces/DispatcherInterface.php +++ b/src/pjdietz/WellRESTed/Interfaces/DispatcherInterface.php @@ -10,8 +10,9 @@ 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); + public function getResponse(RoutableInterface $request, $args = null); } diff --git a/src/pjdietz/WellRESTed/Interfaces/RouterInterface.php b/src/pjdietz/WellRESTed/Interfaces/RouterInterface.php deleted file mode 100644 index 6d4f954..0000000 --- a/src/pjdietz/WellRESTed/Interfaces/RouterInterface.php +++ /dev/null @@ -1,19 +0,0 @@ - - * @copyright Copyright 2013 by PJ Dietz - * @license MIT - */ - -namespace pjdietz\WellRESTed\Interfaces; - -/** - * The RouterInterface provides a mechanism for obtaining a response given a request. - * @package pjdietz\WellRESTed - */ -interface RouterInterface extends RouteTargetInterface -{ -} diff --git a/src/pjdietz/WellRESTed/Route.php b/src/pjdietz/WellRESTed/Route.php deleted file mode 100644 index a51a335..0000000 --- a/src/pjdietz/WellRESTed/Route.php +++ /dev/null @@ -1,183 +0,0 @@ - - * @copyright Copyright 2013 by PJ Dietz - * @license MIT - */ - -namespace pjdietz\WellRESTed; - -use pjdietz\WellRESTed\Exceptions\WellRESTedException; -use pjdietz\WellRESTed\Interfaces\RouteInterface; - -/** - * A Route connects a URI pattern to a Handler. - */ -class Route implements RouteInterface -{ - /** - * Regular expression matching URL friendly characters (i.e., letters, - * digits, hyphen and underscore) - */ - const RE_SLUG = '[0-9a-zA-Z\-_]+'; - /** Regular expression matching digitis */ - const RE_NUM = '[0-9]+'; - /** Regular expression matching letters */ - const RE_ALPHA = '[a-zA-Z]+'; - /** Regular expression matching letters and digits */ - const RE_ALPHANUM = '[0-9a-zA-Z]+'; - /** Regular expression matching a URI template variable (e.g., {id}) */ - const URI_TEMPLATE_EXPRESSION_RE = '/{([a-zA-Z]+)}/'; - /** - * Default regular expression used to match template variable - * - * @property string - */ - static public $defaultVariablePattern = self::RE_SLUG; - /** - * Regular expression used to match a Request URI path component - * - * @var string - */ - private $pattern; - /** - * Name of the RouteTarget class to dispatch when the pattern is matched. - * - * @var string - */ - private $target; - - /** - * Create a new Route - * - * @param string $pattern Regex string to match against the request path - * @param string $target String name of the RouteTargetInterface to dispatch - */ - public function __construct($pattern, $target) - { - $this->pattern = $pattern; - $this->target = $target; - } - - /** - * Create a new Route using a URI template to generate the pattern. - * - * @param string $uriTemplate - * @param string $target - * @param array $variables - * @throws WellRESTedException - * @return Route - */ - static public function newFromUriTemplate( - $uriTemplate, - $target, - $variables = null - ) { - - $pattern = ''; - - // Explode the template into an array of path segments. - if ($uriTemplate[0] === '/') { - $parts = explode('/', substr($uriTemplate, 1)); - } else { - $parts = explode('/', $uriTemplate); - } - - foreach ($parts as $part) { - - $pattern .= '\/'; - - // Is this part an expression or a literal? - if (preg_match(self::URI_TEMPLATE_EXPRESSION_RE, $part, $matches)) { - - // This part of the path is an expresion. - - if (count($matches) === 2) { - - // Locate the name for the variable from the template. - $variableName = $matches[1]; - - // If the caller passed an array with this variable name - // as a key, use its value for the pattern here. - // Otherwise, use the class's current default. - if (isset($variables[$variableName])) { - $variablePattern = $variables[$variableName]; - } else { - $variablePattern = self::$defaultVariablePattern; - } - - $pattern .= sprintf( - '(?<%s>%s)', - $variableName, - $variablePattern - ); - - } else { - // Not sure why this would happen. - throw new WellRESTedException('Invalid URI Template.'); - } - - } else { - // This part is a literal. - $pattern .= $part; - } - - } - - $pattern = '/^' . $pattern . '$/'; - - return new self($pattern, $target); - } - - /** - * @return string - */ - public function getPattern() - { - return $this->pattern; - } - - /** - * @param string $pattern - */ - public function setPattern($pattern) - { - $this->pattern = $pattern; - } - - /** @return string fully qualified name of the RouteTargetInterface to dispatch */ - public function getTarget() - { - return $this->target; - } - - /** @param string $target fully qualified name of the RouteTargetInterface to dispatch */ - public function setTarget($target) - { - $this->target = $target; - } - - /** - * @return string - * @deprecated 1.3.0 - * @see \pjdietz\WellRESTed\Route::getTarget() - */ - public function getHandler() - { - return $this->getTarget(); - } - - /** - * @param string $handler - * @deprecated 1.3.0 - * @see \pjdietz\WellRESTed\Route::setTarget() - */ - public function setHandler($handler) - { - $this->setTarget($handler); - } - -} diff --git a/src/pjdietz/WellRESTed/RouteTarget.php b/src/pjdietz/WellRESTed/RouteTarget.php deleted file mode 100644 index 131b2a3..0000000 --- a/src/pjdietz/WellRESTed/RouteTarget.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Copyright 2013 by PJ Dietz - * @license MIT - */ - -namespace pjdietz\WellRESTed; - -use pjdietz\WellRESTed\Interfaces\ResponseInterface; -use pjdietz\WellRESTed\Interfaces\RoutableInterface; -use pjdietz\WellRESTed\Interfaces\RouterInterface; -use pjdietz\WellRESTed\Interfaces\RouteTargetInterface; - -/** - * RouteTarget - * - * RouteTarget defines the basic functionality for an instance dispatched when a Route pattern - * is matched. - */ -abstract class RouteTarget implements RouteTargetInterface -{ - /** @var array Matches array from the preg_match() call used to find this Handler */ - protected $args; - /** @var RoutableInterface The HTTP request to respond to. */ - protected $request; - /** @var ResponseInterface The HTTP response to send based on the request. */ - protected $response; - /** @var RouterInterface The router that dispatched this handler */ - protected $router; - - /** @param array $args */ - public function setArguments(array $args) - { - $this->args = $args; - } - - /** @return array */ - public function getArguments() - { - return $this->args; - } - - /** @return RoutableInterface */ - public function getRequest() - { - return $this->request; - } - - /** @param RoutableInterface $request */ - public function setRequest(RoutableInterface $request) - { - $this->request = $request; - } - - /** @return RouterInterface */ - public function getRouter() - { - return $this->router; - } - - /** @param RouterInterface $router */ - public function setRouter(RouterInterface $router) - { - $this->router = $router; - } -} diff --git a/src/pjdietz/WellRESTed/Router.php b/src/pjdietz/WellRESTed/Router.php index 544824e..5a1c882 100644 --- a/src/pjdietz/WellRESTed/Router.php +++ b/src/pjdietz/WellRESTed/Router.php @@ -10,10 +10,9 @@ namespace pjdietz\WellRESTed; +use pjdietz\WellRESTed\Interfaces\DispatcherInterface; use pjdietz\WellRESTed\Interfaces\ResponseInterface; use pjdietz\WellRESTed\Interfaces\RoutableInterface; -use pjdietz\WellRESTed\Interfaces\RouteInterface; -use pjdietz\WellRESTed\Interfaces\RouterInterface; use pjdietz\WellRESTed\Interfaces\RouteTargetInterface; /** @@ -21,14 +20,8 @@ use pjdietz\WellRESTed\Interfaces\RouteTargetInterface; * * A Router uses a table of Routes to find the appropriate Handler for a request. */ -class Router extends RouteTarget implements RouterInterface +class Router extends RouteTarget implements DispatcherInterface { - /** @var string Fully qualified name for the interface for handlers */ - const ROUTE_TARGET_INTERFACE = '\\pjdietz\\WellRESTed\\Interfaces\\RouteTargetInterface'; - /** @var int Default maximum number of levels of routing. */ - const MAX_DEPTH = 10; - /** @var int maximum levels of routing before the router raises an error. */ - protected $maxDepth = self::MAX_DEPTH; /** @var array Array of Route objects */ private $routes; @@ -38,24 +31,6 @@ class Router extends RouteTarget implements RouterInterface $this->routes = array(); } - /** - * Append a new Route instance to the Router's route table. - * - * @param RouteInterface $route - */ - public function addRoute(RouteInterface $route) - { - $this->routes[] = $route; - } - - /** - * @return int maximum levels of routing before the router raises an error. - */ - public function getMaxDepth() - { - return $this->maxDepth; - } - /** * Return the response built by the handler based on the request * @@ -64,14 +39,19 @@ class Router extends RouteTarget implements RouterInterface */ public function getResponse(RoutableInterface $request = null) { + // Use the singleton if the caller did not pass a request. + if (is_null($reqs)) + // Set the instance's request, if the called passed one. if (!is_null($request)) { $this->request = $request; } + // If the instance does not have a request, use the singleton. if (is_null($this->request)) { $this->request = Request::getRequest(); } + // Reference the request and path. $request = $this->request; $request->incrementRouteDepth(); @@ -117,6 +97,16 @@ class Router extends RouteTarget implements RouterInterface return $this->getNoRouteResponse($request); } + /** + * Append a new Route instance to the Router's route table. + * + * @param RouteInterface $route + */ + public function addRoute(DispatcherInterface $route) + { + $this->routes[] = $route; + } + /** * Prepare a resonse indicating a 404 Not Found error * diff --git a/src/pjdietz/WellRESTed/Routes/BaseRoute.php b/src/pjdietz/WellRESTed/Routes/BaseRoute.php index 8769ca1..4c49bdb 100644 --- a/src/pjdietz/WellRESTed/Routes/BaseRoute.php +++ b/src/pjdietz/WellRESTed/Routes/BaseRoute.php @@ -13,7 +13,7 @@ use pjdietz\WellRESTed\Interfaces\RouteTargetInterface; abstract class BaseRoute implements DispatcherInterface { /** @var string Fully qualified name for the interface for handlers */ - const ROUTE_TARGET_INTERFACE = '\\pjdietz\\WellRESTed\\Interfaces\\RouteTargetInterface'; + const DISPATCHER_INTERFACE = '\\pjdietz\\WellRESTed\\Interfaces\\DispatcherInterface'; /** @var string */ private $targetClassName; @@ -26,15 +26,15 @@ abstract class BaseRoute implements DispatcherInterface $this->targetClassName = $targetClassName; } - protected function getTarget(RoutableInterface $routable) + protected function getTarget() { - if (is_subclass_of($this->targetClassName, self::ROUTE_TARGET_INTERFACE)) { + if (is_subclass_of($this->targetClassName, self::DISPATCHER_INTERFACE)) { /** @var RouteTargetInterface $target */ $target = new $this->targetClassName(); - $target->setRequest($routable); return $target; + } else { + throw new \UnexpectedValueException("Target class must implement DispatcherInterface"); } - return null; } } diff --git a/src/pjdietz/WellRESTed/Routes/RegexRoute.php b/src/pjdietz/WellRESTed/Routes/RegexRoute.php index 2fcaa61..42f345d 100644 --- a/src/pjdietz/WellRESTed/Routes/RegexRoute.php +++ b/src/pjdietz/WellRESTed/Routes/RegexRoute.php @@ -21,14 +21,15 @@ class RegexRoute extends BaseRoute // ------------------------------------------------------------------------ /* DispatcherInterface */ - public function getResponse(RoutableInterface $request) + public function getResponse(RoutableInterface $request, $args = null) { if (preg_match($this->getPattern(), $request->getPath(), $matches)) { - $target = $this->getTarget($request); - if ($target) { - $target->setArguments($matches); - return $target->getResponse($request); + $target = $this->getTarget(); + if (is_null($args)) { + $args = array(); } + $args = array_merge($args, $matches); + return $target->getResponse($request, $args); } return null; } diff --git a/src/pjdietz/WellRESTed/Routes/StaticRoute.php b/src/pjdietz/WellRESTed/Routes/StaticRoute.php index a35ac2f..2cc8121 100644 --- a/src/pjdietz/WellRESTed/Routes/StaticRoute.php +++ b/src/pjdietz/WellRESTed/Routes/StaticRoute.php @@ -33,15 +33,13 @@ class StaticRoute extends BaseRoute // ------------------------------------------------------------------------ /* DispatcherInterface */ - public function getResponse(RoutableInterface $request) + public function getResponse(RoutableInterface $request, $args = null) { $requestPath = $request->getPath(); foreach ($this->paths as $path) { if ($path === $requestPath) { - $target = $this->getTarget($request); - if ($target) { - return $target->getResponse($request); - } + $target = $this->getTarget(); + return $target->getResponse($request, $args); } } return null;