Skip to content

Instantly share code, notes, and snippets.

@mishak87
Created May 24, 2012 12:01
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mishak87/2781069 to your computer and use it in GitHub Desktop.
Save mishak87/2781069 to your computer and use it in GitHub Desktop.
Router for API REST like methods
<?php
namespace ApiModule;
use Nette,
Nette\Application\Request;
class Router extends Nette\Object implements Nette\Application\IRouter
{
const FORMAT_KEY = 'format';
const METHOD_KEY = 'method';
const FORMAT_JSON = 'json';
private $defaults = array(
self::FORMAT_KEY => self::FORMAT_JSON,
'id' => NULL,
);
function getFormats()
{
return array(
self::FORMAT_JSON
);
}
function getMethods()
{
return array(
'GET',
'PUT',
'POST',
'PARTIAL',
'DELETE',
);
}
/**
* /api/(<namespace>/)*resource(/<id>)?(.<format json|xml...>)
*/
function match(Nette\Http\IRequest $httpRequest)
{
$presenter = NULL;
$method = NULL;
$id = NULL;
$match = preg_match('~^api/(?P<resource>[a-z]+(/[a-z]+)*)(/(?P<id>[1-9][0-9]*))?(.(?P<format>json))?$~i', $httpRequest->getUrl()->getPathInfo(), $matches);
if (!$match) {
return NULL;
}
$matches += array(
'format' => self::FORMAT_JSON,
'user' => '',
'id' => '',
);
$params = array();
if ($matches['id'] !== '') {
$params['id'] = $matches['id'];
}
if ($matches['user'] !== '') {
$params['user'] = $matches['user'];
}
$slugs = explode('/', $matches['resource'], 2);
$first = array_shift($slugs);
if (!$slugs) {
array_push($slugs, 'default');
} else {
$last = array_pop($slugs);
$last = strtr(ucwords($last), '/', '');
array_push($slugs, $last);
}
array_unshift($slugs, 'api');
array_unshift($slugs, $first);
$presenter = ucwords(implode(':', $slugs));
unset($params['resource']);
$method = $httpRequest->getMethod();
if (in_array($method, array('POST', 'PARTIAL', 'PUT'))) {
if ($httpRequest->getHeader('Content-Type') === 'application/json') {
$recieved = (array) json_decode(file_get_contents('php://input'), TRUE);
} else {
$recieved = $httpRequest->getPost();
}
} else {
$recieved = array();
}
$params = $params + $httpRequest->getQuery() + $recieved + $this->defaults;
if (isset($params[self::METHOD_KEY])) {
$method = strtoupper($params[self::METHOD_KEY]);
$this->validateMethod($method);
unset($params[self::METHOD_KEY]);
}
$params[self::FORMAT_KEY] = strtolower($params[self::FORMAT_KEY]);
$this->validateFormat($params[self::FORMAT_KEY]);
return new Request(
$presenter,
$method,
$params,
$httpRequest->getPost(),
$httpRequest->getFiles(),
array(Request::SECURED => $httpRequest->isSecured())
);
}
private function validateFormat($format)
{
if (!in_array($format, $this->getFormats(), TRUE)) {
throw new Nette\InvalidStateException("Invalid format '$format' supported formats: " . implode(', ', $this->getFormats()) . ".");
}
}
private function validateMethod($method)
{
if (!in_array($method, $this->getMethods(), TRUE)) {
throw new Nette\InvalidStateException("Invalid method '$method' supported methods: " . implode(', ', $this->getMethods()) . ".");
}
}
function constructUrl(Request $appRequest, Nette\Http\Url $refUrl)
{
return NULL;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment