diff options
author | Bharat Mediratta <bharat@menalto.com> | 2008-11-19 04:20:35 +0000 |
---|---|---|
committer | Bharat Mediratta <bharat@menalto.com> | 2008-11-19 04:20:35 +0000 |
commit | 5638fc5fb60823544f1944bdf40705a19b7365f1 (patch) | |
tree | 2102a8053df65dda50807c3ad67fdeb416071ed3 /core/controllers | |
parent | e0efdee8b2a2ba2ee1b86cfb2b7863a88877c00e (diff) |
Change the way that we do RESTful routing.
1) We now use __call() in REST_Controller to handle any requests to a controller
that were not already handled. In the case of RESTful controllers, this should
be the only entry point (although they're free to break the model and add other
ones.. nothing stops them).
This means that we can remove all the catch-all routes in
routes.php which greatly simplifies it.
2) Move request_method() and output_format() out of REST_Controller and into the REST
helper in core/helpers/rest.php
3) Experiment with letting the various subclasses check the output_format and deal with
it themselves. This simplifies the API, but it might be a bad idea in that it might
push too much work to the individual controllers. It's a balancing act, time will tell,
I'm willing to change it back later.
Diffstat (limited to 'core/controllers')
-rw-r--r-- | core/controllers/albums.php | 4 | ||||
-rw-r--r-- | core/controllers/items.php | 2 | ||||
-rw-r--r-- | core/controllers/photos.php | 4 | ||||
-rw-r--r-- | core/controllers/rest.php | 67 |
4 files changed, 27 insertions, 50 deletions
diff --git a/core/controllers/albums.php b/core/controllers/albums.php index ead738d9..f9e0be2c 100644 --- a/core/controllers/albums.php +++ b/core/controllers/albums.php @@ -20,9 +20,9 @@ class Albums_Controller extends Items_Controller { /** - * @see Rest_Controller::_show($resource, $output_format) + * @see Rest_Controller::_show($resource) */ - public function _show($item, $output_format) { + public function _show($item) { // @todo: these need to be pulled from the database $theme_name = "default"; $page_size = 9; diff --git a/core/controllers/items.php b/core/controllers/items.php index 6c202b30..d56ef774 100644 --- a/core/controllers/items.php +++ b/core/controllers/items.php @@ -41,7 +41,7 @@ class Items_Controller extends REST_Controller { throw new Exception("@todo Comment_Controller::_form NOT IMPLEMENTED"); } - public function _show($item, $format) { + public function _show($item) { // Redirect to the more specific resource type, since it will render // differently. We could also just delegate here, but it feels more appropriate // to have a single canonical resource mapping. diff --git a/core/controllers/photos.php b/core/controllers/photos.php index a5b75b79..1d995de8 100644 --- a/core/controllers/photos.php +++ b/core/controllers/photos.php @@ -20,9 +20,9 @@ class Photos_Controller extends Items_Controller { /** - * @see Rest_Controller::_show($resource, $output_format) + * @see Rest_Controller::_show($resource) */ - public function _show($item, $output_format) { + public function _show($item) { $template = new View("page.html"); // @todo: this needs to be data-driven diff --git a/core/controllers/rest.php b/core/controllers/rest.php index 6391c153..25f71299 100644 --- a/core/controllers/rest.php +++ b/core/controllers/rest.php @@ -28,19 +28,19 @@ * // Handle GET request to /controller * } * - * public function _show(ORM $comment, $output_format) { + * public function _show(ORM $comment) { * // Handle GET request to /comments/{comment_id} * } * - * public function _update(ORM $comment, $output_format) { + * public function _update(ORM $comment) { * // Handle PUT request to /comments/{comment_id} * } * - * public function _create(ORM $comment, $output_format) { + * public function _create(ORM $comment) { * // Handle POST request to /comments * } * - * public function _delete(ORM $comment, $output_format) { + * public function _delete(ORM $comment) { * // Handle DELETE request to /comments/{comments_id} * } * @@ -62,33 +62,42 @@ abstract class REST_Controller extends Controller { protected $resource_type = null; - public function dispatch($id) { + public function __construct() { if ($this->resource_type == null) { throw new Exception("@todo ERROR_MISSING_RESOURCE_TYPE"); } + parent::__construct(); + } - // A request on /controller gets routed to REST_Controller::dispatch(0). - if (!$id && $this->request_method() == "get") { + /** + * Handle dispatching for all REST controllers. + */ + public function __call($function, $args) { + // If no parameter was provided after the controller name (eg "/albums") then $function will + // be set to "index". Otherwise, $function is the first parameter, and $args are all + // subsequent parameters. + $request_method = rest::request_method(); + if ($function == "index" && $request_method == "get") { return $this->_index(); } // @todo this needs security checks + $id = $function; $resource = ORM::factory($this->resource_type, $id); - if (!$resource->loaded && !$this->request_method() == "post") { + if (!$resource->loaded && $request_method == "post") { return Kohana::show_404(); } - if ($this->request_method() == "get") { - $this->_show($resource, $this->output_format()); + switch ($request_method) { + case "get": + $this->_show($resource); if (Session::instance()->get("use_profiler", false)) { $profiler = new Profiler(); $profiler->render(); } return; - } - switch ($this->request_method()) { case "put": return $this->_update($resource); @@ -121,38 +130,6 @@ abstract class REST_Controller extends Controller { } /** - * We're expecting to run in an environment that only supports GET/POST, so expect to tunnel - * PUT and DELETE through POST. - * - * Returns the HTTP request method taking into consideration PUT/DELETE tunneling. - * @todo Move this to a MY_request helper? - * @return string HTTP request method - */ - protected function request_method() { - if (request::method() == "get") { - return "get"; - } else { - switch ($this->input->post("_method", $this->input->get("_method"))) { - case "put": return "put"; - case "delete": return "delete"; - default: return "post"; - } - } - } - - /** - * Choose an output format based on what the client prefers to accept. - * @return string "html", "xml" or "json" - */ - protected function output_format() { - // Pick a format, but let it be overridden. - return $this->input->get( - "_format", $this->input->post( - "_format", request::preferred_accept( - array("html", "xml", "json")))); - } - - /** * Perform a GET request on the controller root * (e.g. http://www.example.com/gallery3/comments) */ @@ -168,7 +145,7 @@ abstract class REST_Controller extends Controller { * Perform a GET request on this resource * @param ORM $resource the instance of this resource type */ - abstract public function _show($resource, $output_format); + abstract public function _show($resource); /** * Perform a PUT request on this resource |