diff --git a/src/pjdietz/WellRESTed/Handler.php b/src/pjdietz/WellRESTed/Handler.php index 912fbb6..c9f7f99 100644 --- a/src/pjdietz/WellRESTed/Handler.php +++ b/src/pjdietz/WellRESTed/Handler.php @@ -13,81 +13,23 @@ namespace pjdietz\WellRESTed; use pjdietz\WellRESTed\Interfaces\HandlerInterface; use pjdietz\WellRESTed\Interfaces\RequestInterface; use pjdietz\WellRESTed\Interfaces\ResponseInterface; -use pjdietz\WellRESTed\Interfaces\RouterInterface; /** * A Handler issues a response for a given resource. * * @property-read ResponseInterface response The Response to the request */ -abstract class Handler implements HandlerInterface +abstract class Handler extends RouteTarget implements HandlerInterface { - /** @var array Matches array from the preg_match() call used to find this Handler */ - protected $args; - /** @var RequestInterface 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; - - // ------------------------------------------------------------------------- - // Accessors - /** - * Magic function for properties - * - * @param string $propertyName - * @return mixed + * @param RequestInterface $request + * @return ResponseInterface */ - public function __get($propertyName) + public function getResponse(RequestInterface $request = null) { - $method = 'get' . ucfirst($propertyName); - if (method_exists($this, $method)) { - return $this->{$method}(); + if (!is_null($request)) { + $this->request = $request; } - return null; - } - - /** @param array $args */ - public function setArguments(array $args) - { - $this->args = $args; - } - - /** @return array */ - public function getArguments() - { - return $this->args; - } - - /** @return RequestInterface */ - public function getRequest() - { - return $this->request; - } - - /** @param RequestInterface $request */ - public function setRequest(RequestInterface $request) - { - $this->request = $request; - } - - /** @return RouterInterface */ - public function getRouter() - { - return $this->router; - } - - /** @param RouterInterface $router */ - public function setRouter(RouterInterface $router) - { - $this->router = $router; - } - - /** @return ResponseInterface */ - public function getResponse() - { $this->response = new Response(); $this->buildResponse(); return $this->response; @@ -127,15 +69,6 @@ abstract class Handler implements HandlerInterface } } - // ------------------------------------------------------------------------- - // HTTP Methods - - // Each of these methods corresponds to a standard HTTP method. Each method - // has no arguments and returns nothing, but should affect the instance's - // response member. - // - // By default, the methods will provide a 405 Method Not Allowed header. - /** * Method for handling HTTP GET requests. * diff --git a/src/pjdietz/WellRESTed/Interfaces/HandlerInterface.php b/src/pjdietz/WellRESTed/Interfaces/HandlerInterface.php index da07f57..4bd580d 100644 --- a/src/pjdietz/WellRESTed/Interfaces/HandlerInterface.php +++ b/src/pjdietz/WellRESTed/Interfaces/HandlerInterface.php @@ -14,26 +14,6 @@ namespace pjdietz\WellRESTed\Interfaces; * Interface for a creating a response in reaction to a request or arguments. * @package pjdietz\WellRESTed */ -interface HandlerInterface +interface HandlerInterface extends RouteTargetInterface { - /** @return array Associative array used to obtain a response */ - public function getArguments(); - - /** @param array $args Associative array used to obtain a response */ - public function setArguments(array $args); - - /** @return RequestInterface Request used to obtain a response */ - public function getRequest(); - - /** @param RequestInterface $request Request used to obtain a response */ - public function setRequest(RequestInterface $request); - - /** @return RouterInterface Reference to the router used to dispatch this handler */ - public function getRouter(); - - /** @param RouterInterface $router Request used to obtain a response */ - public function setRouter(RouterInterface $router); - - /** @return ResponseInterface Response obtained based on the args and request */ - public function getResponse(); } diff --git a/src/pjdietz/WellRESTed/Interfaces/RouteInterface.php b/src/pjdietz/WellRESTed/Interfaces/RouteInterface.php index 6fff10e..96d0f86 100644 --- a/src/pjdietz/WellRESTed/Interfaces/RouteInterface.php +++ b/src/pjdietz/WellRESTed/Interfaces/RouteInterface.php @@ -23,8 +23,8 @@ interface RouteInterface public function setPattern($pattern); /** @return string Fully qualified name of the class the route will dispatch. */ - public function getHandler(); + public function getTarget(); /** @param string $className Fully qualified name of the class the route will dispatch. */ - public function setHandler($className); + public function setTarget($className); } diff --git a/src/pjdietz/WellRESTed/Interfaces/RouteTargetInterface.php b/src/pjdietz/WellRESTed/Interfaces/RouteTargetInterface.php new file mode 100644 index 0000000..e476ea5 --- /dev/null +++ b/src/pjdietz/WellRESTed/Interfaces/RouteTargetInterface.php @@ -0,0 +1,44 @@ + + * @copyright Copyright 2013 by PJ Dietz + * @license MIT + */ + +namespace pjdietz\WellRESTed\Interfaces; + +/** + * The RouteTargetInterface provides a mechanism for obtaining a response given a request. + * @package pjdietz\WellRESTed + */ +interface RouteTargetInterface +{ + /** @return array Associative array used to obtain a response */ + public function getArguments(); + + /** @param array $args Associative array used to obtain a response */ + public function setArguments(array $args); + + /** @return RequestInterface Request used to obtain a response */ + public function getRequest(); + + /** @param RequestInterface $request Request used to obtain a response */ + public function setRequest(RequestInterface $request); + + /** @return RouterInterface Reference to the router used to dispatch this handler */ + public function getRouter(); + + /** @param RouterInterface $router Request used to obtain a response */ + public function setRouter(RouterInterface $router); + + /** + * Return the response for the given request. + * + * @param RequestInterface $request + * @return ResponseInterface + */ + public function getResponse(RequestInterface $request = null); +} diff --git a/src/pjdietz/WellRESTed/Interfaces/RouterInterface.php b/src/pjdietz/WellRESTed/Interfaces/RouterInterface.php index 931fe3e..6d4f954 100644 --- a/src/pjdietz/WellRESTed/Interfaces/RouterInterface.php +++ b/src/pjdietz/WellRESTed/Interfaces/RouterInterface.php @@ -14,13 +14,6 @@ namespace pjdietz\WellRESTed\Interfaces; * The RouterInterface provides a mechanism for obtaining a response given a request. * @package pjdietz\WellRESTed */ -interface RouterInterface +interface RouterInterface extends RouteTargetInterface { - /** - * Return the response for the given request. - * - * @param RequestInterface $request - * @return ResponseInterface - */ - public function getResponse(RequestInterface $request = null); -} \ No newline at end of file +} diff --git a/src/pjdietz/WellRESTed/Route.php b/src/pjdietz/WellRESTed/Route.php index 44b21f1..a51a335 100644 --- a/src/pjdietz/WellRESTed/Route.php +++ b/src/pjdietz/WellRESTed/Route.php @@ -44,36 +44,36 @@ class Route implements RouteInterface */ private $pattern; /** - * Name of the Handler class to use + * Name of the RouteTarget class to dispatch when the pattern is matched. * * @var string */ - private $handler; + private $target; /** * Create a new Route * - * @param $pattern - * @param $handler + * @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, $handler) + public function __construct($pattern, $target) { $this->pattern = $pattern; - $this->handler = $handler; + $this->target = $target; } /** * Create a new Route using a URI template to generate the pattern. * * @param string $uriTemplate - * @param string $handler + * @param string $target * @param array $variables * @throws WellRESTedException * @return Route */ static public function newFromUriTemplate( $uriTemplate, - $handler, + $target, $variables = null ) { @@ -129,26 +129,7 @@ class Route implements RouteInterface $pattern = '/^' . $pattern . '$/'; - $klass = __CLASS__; - $route = new $klass($pattern, $handler); - return $route; - - } - - /** - * @return string - */ - public function getHandler() - { - return $this->handler; - } - - /** - * @param string $handler - */ - public function setHandler($handler) - { - $this->handler = $handler; + return new self($pattern, $target); } /** @@ -167,4 +148,36 @@ class Route implements RouteInterface $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 new file mode 100644 index 0000000..74d21dd --- /dev/null +++ b/src/pjdietz/WellRESTed/RouteTarget.php @@ -0,0 +1,70 @@ + + * @copyright Copyright 2013 by PJ Dietz + * @license MIT + */ + +namespace pjdietz\WellRESTed; + +use pjdietz\WellRESTed\Interfaces\RequestInterface; +use pjdietz\WellRESTed\Interfaces\ResponseInterface; +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 RequestInterface 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 RequestInterface */ + public function getRequest() + { + return $this->request; + } + + /** @param RequestInterface $request */ + public function setRequest(RequestInterface $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 7dfea5a..2c0436c 100644 --- a/src/pjdietz/WellRESTed/Router.php +++ b/src/pjdietz/WellRESTed/Router.php @@ -15,16 +15,17 @@ use pjdietz\WellRESTed\Interfaces\RequestInterface; use pjdietz\WellRESTed\Interfaces\ResponseInterface; use pjdietz\WellRESTed\Interfaces\RouteInterface; use pjdietz\WellRESTed\Interfaces\RouterInterface; +use pjdietz\WellRESTed\Interfaces\RouteTargetInterface; /** * Router * * A Router uses a table of Routes to find the appropriate Handler for a request. */ -class Router implements RouterInterface +class Router extends RouteTarget implements RouterInterface { /** @var string Fully qualified name for the interface for handlers */ - const HANDLER_INTERFACE = '\\pjdietz\\WellRESTed\\Interfaces\\HandlerInterface'; + const ROUTE_TARGET_INTERFACE = '\\pjdietz\\WellRESTed\\Interfaces\\RouteTargetInterface'; /** @var array Array of Route objects */ private $routes; @@ -61,19 +62,36 @@ class Router implements RouterInterface foreach ($this->routes as $route) { /** @var RouteInterface $route */ if (preg_match($route->getPattern(), $path, $matches)) { - $handlerClassName = $route->getHandler(); - if (is_subclass_of($handlerClassName, self::HANDLER_INTERFACE)) { - /** @var HandlerInterface $handler */ - $handler = new $handlerClassName(); - $handler->setRequest($request); - $handler->setArguments($matches); - $handler->setRouter($this); - return $handler->getResponse(); + $targetClassName = $route->getTarget(); + if (is_subclass_of($targetClassName, self::ROUTE_TARGET_INTERFACE)) { + + /** @var RouteTargetInterface $target */ + $target = new $targetClassName(); + $target->setRequest($request); + + // If this instance already had argument, merge the matches with them. + $myArguments = $this->getArguments(); + if (!is_null($myArguments)) { + $matches = array_merge($myArguments, $matches); + } + $target->setArguments($matches); + + // If this instance already had a top-level router, pass it along. + // Otherwise, pass itself as the top-level router. + if (isset($this->router)) { + $target->setRouter($this->router); + } else { + $target->setRouter($this); + } + + return $target->getResponse(); + } else { return $this->getInternalServerErrorResponse($request); } } } + return $this->getNoRouteResponse($request); }