Skip to content

Instantly share code, notes, and snippets.

@dkobia
Created May 23, 2012 20:21
Show Gist options
  • Save dkobia/2777540 to your computer and use it in GitHub Desktop.
Save dkobia/2777540 to your computer and use it in GitHub Desktop.
Base Class for a RESTful Kohana
<?php defined('SYSPATH') OR die('No direct access allowed.');
class Controller_API extends Controller
{
/**
* @var Object Request Payload
*/
protected $_request_payload = NULL;
/**
* @var Object Response Payload
*/
protected $_response_payload = NULL;
/**
* @var array Map of HTTP methods -> actions
*/
protected $_action_map = array
(
Http_Request::POST => 'post', // Typically Create..
Http_Request::GET => 'get',
Http_Request::PUT => 'put', // Typically Update..
Http_Request::DELETE => 'delete',
);
/**
* @var array List of HTTP methods which support body content
*/
protected $_methods_with_body_content = array
(
Http_Request::POST,
Http_Request::PUT,
);
/**
* @var array List of HTTP methods which may be cached
*/
protected $_cacheable_methods = array
(
Http_Request::GET,
);
public function before()
{
parent::before();
$this->_parse_request();
}
public function after()
{
$this->_prepare_response();
parent::after();
}
/**
* Parse the request...
*/
protected function _parse_request()
{
// Override the method if needed.
$this->request->method(Arr::get(
$_SERVER,
'HTTP_X_HTTP_METHOD_OVERRIDE',
$this->request->method()
));
// Is that a valid method?
if ( ! isset($this->_action_map[$this->request->method()]))
{
// TODO .. add to the if (maybe??) .. method_exists($this, 'action_'.$this->request->method())
throw new Http_Exception_405(array_keys($this->_action_map),
'The :method method is not supported. Supported methods are :allowed_methods', array(
':method' => $method,
':allowed_methods' => implode(', ', array_keys($this->_action_map)),
));
}
// Get the basic verb based action..
$action = $this->_action_map[$this->request->method()];
// If this is a custom action, lets make sure we use it.
if ($this->request->action() != '_none')
{
$action .= '_'.$this->request->action();
}
// If we are acting on a collection, append _collection to the action name.
if ($this->request->param('id', FALSE) === FALSE)
{
$action .= '_collection';
}
// Override the action
$this->request->action($action);
// Are we be expecting body content as part of the request?
if (in_array($this->request->method(), $this->_methods_with_body_content))
{
$this->_parse_request_body();
}
}
/**
* @todo Support more than just JSON
*/
protected function _parse_request_body()
{
try
{
$this->_response_payload = json_decode($this->request->body(), TRUE);
if ( ! is_array($this->_response_payload) AND ! is_object($this->_response_payload))
throw new Http_Exception_400('Invalid json supplied. \':json\'', array(
':json' => $this->request->body(),
));
}
catch (Exception $e)
{
throw new Http_Exception_400('Invalid json supplied. \':json\'', array(
':json' => $this->request->body(),
));
}
}
protected function _prepare_response()
{
// Should we prevent this request from being cached?
if ( ! in_array($this->request->method(), $this->_cacheable_methods))
{
$this->response->headers('cache-control', 'no-cache, no-store, max-age=0, must-revalidate');
}
// Set the correct content-type header
$this->response->headers('Content-Type', 'application/json');
$this->_prepare_response_body();
}
/**
* @todo Support more than just JSON
*/
protected function _prepare_response_body()
{
try
{
// Format the reponse as JSON
$this->response->body(json_encode($this->_response_payload));
}
catch (Exception $e)
{
throw new Http_Exception_500('Error while formatting response');
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment