Refactor for better PSR compliance. Still need to finish with samples.

This commit is contained in:
PJ Dietz 2013-01-24 21:27:57 -05:00
parent 3ff2371edd
commit 8597b9be06
19 changed files with 415 additions and 333 deletions

6
.gitignore vendored
View File

@ -0,0 +1,6 @@
# Composer
vendor/
# PhpStorm
workspace.xml

View File

@ -5,46 +5,54 @@ namespace apisample;
use pjdietz\WellRESTed\Router;
use pjdietz\WellRESTed\Route;
require_once(dirname(__FILE__) . '/../../Router.php');
// TODO Revise with autoload required.
/**
* Loads and instantiates handlers based on URI.
*/
class ApiSampleRouter extends Router {
public function __construct() {
class ApiSampleRouter extends Router
{
public function __construct()
{
parent::__construct();
$this->addTemplate('/articles/',
'ArticleCollectionHandler',
'ArticleCollectionHandler.php');
$this->addTemplate(
'/articles/',
'ArticleCollectionHandler',
'ArticleCollectionHandler.php'
);
$this->addTemplate('/articles/{id}',
'ArticleItemHandler',
'ArticleItemHandler.inc.php',
array('id' => Route::RE_NUM));
$this->addTemplate(
'/articles/{id}',
'ArticleItemHandler',
'ArticleItemHandler.inc.php',
array('id' => Route::RE_NUM)
);
$this->addTemplate('/articles/{slug}',
'ArticleItemHandler',
'ArticleItemHandler.inc.php',
array('slug' => Route::RE_SLUG));
$this->addTemplate(
'/articles/{slug}',
'ArticleItemHandler',
'ArticleItemHandler.inc.php',
array('slug' => Route::RE_SLUG)
);
}
public function addTemplate($template, $handlerClassName, $handlerFilePath, $variables=null) {
public function addTemplate($template, $handlerClassName, $handlerFilePath, $variables = null)
{
// Customize as needed based on your server.
$template = '/wellrested/samples/apisample' . $template;
$handlerClassName = '\apisample\handlers\\' . $handlerClassName;
$handlerFilePath = dirname(__FILE__) . '/handlers/' . $handlerFilePath;
$this->addRoute(Route::newFromUriTemplate(
$template, $handlerClassName, $handlerFilePath, $variables));
$this->addRoute(
Route::newFromUriTemplate(
$template,
$handlerClassName,
$handlerFilePath,
$variables
)
);
}
}
?>

View File

@ -5,60 +5,57 @@ namespace apisample;
/**
* Simple class for reading and writing articles to a text file.
*/
class ArticlesController {
class ArticlesController
{
public $data;
protected $path;
public function __construct() {
public function __construct()
{
$this->path = dirname(__FILE__) . '/data/articles.json';
$this->load();
}
public function load() {
public function load()
{
if (file_exists($this->path)) {
$data = file_get_contents($this->path);
$this->data = json_decode($data, true);
}
}
public function save() {
public function save()
{
if (is_writable($this->path)) {
$data = json_encode($this->data);
return file_put_contents($this->path, $data);
}
return false;
}
public function getArticleById($id) {
public function getArticleById($id)
{
foreach ($this->data as $article) {
if ($article['articleId'] == $id) {
return $article;
}
}
return false;
}
public function getArticleBySlug($slug) {
public function getArticleBySlug($slug)
{
foreach ($this->data as $article) {
if ($article['slug'] == $slug) {
return $article;
}
}
return false;
}
public function addArticle($newArticle) {
public function addArticle($newArticle)
{
$validatedArticle = array(
'articleId' => $this->getNewId(),
'slug' => $newArticle['slug'],
@ -69,11 +66,10 @@ class ArticlesController {
$this->data[] = $validatedArticle;
return $validatedArticle;
}
public function updateArticle($newArticle) {
public function updateArticle($newArticle)
{
foreach ($this->data as &$oldArticle) {
if ($oldArticle['articleId'] == $newArticle['articleId']) {
@ -86,11 +82,10 @@ class ArticlesController {
}
return false;
}
public function removeArticle($id) {
public function removeArticle($id)
{
foreach ($this->data as $index => $article) {
if ($article['articleId'] == $id) {
unset($this->data[$index]);
@ -99,12 +94,10 @@ class ArticlesController {
}
return false;
}
protected function getNewId() {
protected function getNewId()
{
$maxId = 0;
foreach ($this->data as $article) {
@ -112,9 +105,6 @@ class ArticlesController {
}
return $maxId + 1;
}
}
?>

View File

@ -1,12 +1,9 @@
The apisample directory contains a mini API project that demonstrates the
main features of Well RESTEd.
The apisample directory contains a mini API project that demonstrates the main features of Well RESTEd.
Resources
---------
For this sample project, the only resources
are "articles", which are kind of like little mini blog posts or news feed
items. Each article contains the following fields:
For this sample project, the only resources are "articles", which are kind of like little mini blog posts or news feed items. Each article contains the following fields:
articleId: Numeric unique identifier for the article
slug: A human readable unique identifier for the article

View File

@ -2,18 +2,19 @@
namespace apisample\handlers;
require_once(dirname(__FILE__) . '/../../../Handler.php');
require_once(dirname(__FILE__) . '/../ArticlesController.php');
use \pjdietz\WellRESTed\Handler;
/**
* Handler class for a list of articles.
*/
class ArticleCollectionHandler extends \pjdietz\WellRESTed\Handler {
class ArticleCollectionHandler extends Handler
{
/**
* Respond to a GET request.
*/
protected function get() {
protected function get()
{
// Display the list of articles.
$articles = new \apisample\ArticlesController();
@ -37,7 +38,8 @@ class ArticleCollectionHandler extends \pjdietz\WellRESTed\Handler {
/**
* Respond to a POST request.
*/
protected function post() {
protected function post()
{
// Read the request body, and ensure it is in the proper format.
$article = json_decode($this->request->body, true);
@ -100,5 +102,3 @@ class ArticleCollectionHandler extends \pjdietz\WellRESTed\Handler {
}
}
?>

View File

@ -2,8 +2,7 @@
namespace apisample\handlers;
require_once(dirname(__FILE__) . '/../../../Handler.php');
require_once(dirname(__FILE__) . '/../ArticlesController.php');
use \pjdietz\WellRESTed\Handler;
/**
* Handler class for one specific article.
@ -11,12 +10,14 @@ require_once(dirname(__FILE__) . '/../ArticlesController.php');
* When instantiated by the Router, this class should receive an id or slug
* argument to identify the article.
*/
class ArticleItemHandler extends \pjdietz\WellRESTed\Handler {
class ArticleItemHandler extends Handler
{
/**
* Respond to a GET request.
*/
protected function get() {
protected function get()
{
// Read the list of articles.
$articles = new \apisample\ArticlesController();
@ -53,7 +54,8 @@ class ArticleItemHandler extends \pjdietz\WellRESTed\Handler {
/**
* Respond to a PUT request.
*/
protected function put() {
protected function put()
{
// Read the request body, and ensure it is in the proper format.
$article = json_decode($this->request->body, true);
@ -156,7 +158,8 @@ class ArticleItemHandler extends \pjdietz\WellRESTed\Handler {
/**
* Respond to a DELETE request.
*/
protected function delete() {
protected function delete()
{
// Read the list of articles.
$articles = new \apisample\ArticlesController();
@ -199,5 +202,3 @@ class ArticleItemHandler extends \pjdietz\WellRESTed\Handler {
}
}
?>

View File

@ -1,10 +1,8 @@
<?php
require_once('ApiSampleRouter.php');
require_once('../../vendor/autoload.php');
$router = new \apisample\ApiSampleRouter();
$response = $router->getResponse();
$response->respond();
exit;
?>

View File

@ -9,12 +9,15 @@
* Please modify samples/client-side-endpoint.php to see results.
*/
// Include the Well RESTed Request and Response class files.
require_once('../Request.php');
require_once('../Response.php');
// Include the autoload script.
require_once('../vendor/autoload.php');
use \pjdietz\WellRESTed\Request;
use \pjdietz\WellRESTed\Response;
use \pjdietz\WellRESTed\Exceptions\CurlException;
// Make a custom request to talk to the server.
$rqst = new \pjdietz\WellRESTed\Request();
$rqst = new Request();
// Use the client-site-endpoint.php script
$rqst->hostname = $_SERVER['HTTP_HOST'];
@ -23,10 +26,10 @@ $rqst->path = '/wellrested/samples/server-side-response.php';
// Issue the request, and read the response returned by the server.
try {
$resp = $rqst->request();
} catch (\wellrested\exceptions\CurlException $e) {
} catch (CurlException $e) {
// Explain the cURL error and provide an error status code.
$myResponse = new \wellrested\Response();
$myResponse = new Response();
$myResponse->statusCode = 500;
$myResponse->setHeader('Content-Type', 'text/plain');
$myResponse->body = 'Message: ' .$e->getMessage() ."\n";
@ -37,7 +40,7 @@ try {
}
// Create new response to send to output to the browser.
$myResponse = new \wellrested\Response();
$myResponse = new Response();
$myResponse->statusCode = 200;
$myResponse->setHeader('Content-Type', 'application/json');
@ -50,5 +53,3 @@ $myResponse->body = json_encode($json);
$myResponse->respond();
exit;
?>

View File

@ -4,11 +4,13 @@
* This script will make a request to google and output the response.
*/
// Include the Well RESTed Request and Response class files.
require_once('../Request.php');
// Include the autoload script.
require_once('../vendor/autoload.php');
use \pjdietz\WellRESTed\Request;
// Make a requst to Google in one line:
$rqst = new \pjdietz\WellRESTed\Request();
$rqst = new Request();
$rqst->uri = 'https://www.google.com/search?q=my+search+terms';
// You could also set the members individually, like this:
@ -23,5 +25,3 @@ $resp = $rqst->request();
// Output the response body and exit.
print $resp->body;
exit;
?>

View File

@ -7,15 +7,17 @@
* with JSON descrition of the original request.
*/
// Include the Well RESTed Request and Response class files.
require_once('../Request.php');
require_once('../Response.php');
// Include the autoload script.
require_once('../vendor/autoload.php');
use \pjdietz\WellRESTed\Request;
use \pjdietz\WellRESTed\Response;
// Read the request sent to the server as the singleton instance.
$rqst = \pjdietz\WellRESTed\Request::getRequest();
$rqst = Request::getRequest();
// Alternatively, you can create a new Request and call readHttpRequest().
// $rqst = new \wellrested\Request();
// $rqst = new Request();
// $rqst->readHttpRequest();
// Read some info from the request and store it to an associative array.
@ -28,7 +30,7 @@ $rtn = array(
);
// Create a new Response instance.
$resp = new \wellrested\Response();
$resp = new Response();
// Set the status code to 200 OK.
$resp->statusCode = 200;
@ -42,5 +44,3 @@ $resp->body = json_encode($rtn);
// Output the response.
$resp->respond();
?>

View File

@ -4,14 +4,15 @@
* Create and output a response from the server.
*/
require_once('../Response.php');
// Include the autoload script.
require_once('../vendor/autoload.php');
use \pjdietz\WellRESTed\Response;
// Create a new Response instance.
$resp = new \pjdietz\WellRESTed\Response();
$resp = new Response();
$resp->statusCode = 200;
$resp->setHeader('Content-Type', 'text/plain');
$resp->body = 'This is a response.';
$resp->respond();
exit;
?>

View File

@ -2,9 +2,6 @@
namespace pjdietz\WellRESTed;
require_once(dirname(__FILE__) . '/Request.php');
require_once(dirname(__FILE__) . '/Response.php');
/*******************************************************************************
* Handler
*
@ -17,22 +14,26 @@ require_once(dirname(__FILE__) . '/Response.php');
/**
* @property Response response The Response to the request
*/
class Handler {
class Handler
{
/**
* The HTTP request to respond to.
*
* @var Request
*/
protected $request;
/**
* The HTTP response to send based on the request.
*
* @var Response
*/
protected $response;
/**
* Matches array from the preg_match() call used to find this Handler.
*
* @var array
*/
protected $args;
@ -43,8 +44,8 @@ class Handler {
* @param Request $request
* @param array $args
*/
public function __construct($request, $args=null) {
public function __construct($request, $args = null)
{
$this->request = $request;
if (is_null($args)) {
@ -54,7 +55,6 @@ class Handler {
$this->response = new Response();
$this->buildResponse();
}
// -------------------------------------------------------------------------
@ -65,21 +65,21 @@ class Handler {
* @return Response
* @throws \Exception
*/
public function __get($name) {
public function __get($name)
{
switch ($name) {
case 'response':
return $this->getResponse();
default:
throw new \Exception('Property ' . $name . ' does not exist.');
case 'response':
return $this->getResponse();
default:
throw new \Exception('Property ' . $name . ' does not exist.');
}
}
/**
* @return Response
*/
public function getResponse() {
public function getResponse()
{
return $this->response;
}
@ -88,40 +88,39 @@ class Handler {
* repond to any non-standard HTTP methods. Otherwise, override the
* get, post, put, etc. methods.
*/
protected function buildResponse() {
protected function buildResponse()
{
switch ($this->request->method) {
case 'GET':
$this->get();
break;
case 'GET':
$this->get();
break;
case 'HEAD':
$this->head();
break;
case 'HEAD':
$this->head();
break;
case 'POST':
$this->post();
break;
case 'POST':
$this->post();
break;
case 'PUT':
$this->put();
break;
case 'PUT':
$this->put();
break;
case 'DELETE':
$this->delete();
break;
case 'DELETE':
$this->delete();
break;
case 'PATCH':
$this->patch();
break;
case 'PATCH':
$this->patch();
break;
case 'OPTIONS':
$this->options();
break;
case 'OPTIONS':
$this->options();
break;
}
}
// -------------------------------------------------------------------------
@ -136,15 +135,16 @@ class Handler {
/**
* Method for handling HTTP GET requests.
*/
protected function get() {
protected function get()
{
$this->response->statusCode = 405;
}
/**
* Method for handling HTTP HEAD requests.
*/
protected function head() {
protected function head()
{
// The default function calls the instance's get() method, then sets
// the resonse's body member to an empty string.
@ -153,44 +153,46 @@ class Handler {
if ($this->response->statusCode == 200) {
$this->response->setBody('', false);
}
}
/**
* Method for handling HTTP POST requests.
*/
protected function post() {
protected function post()
{
$this->response->statusCode = 405;
}
/**
* Method for handling HTTP PUT requests.
*/
protected function put() {
protected function put()
{
$this->response->statusCode = 405;
}
/**
* Method for handling HTTP DELETE requests.
*/
protected function delete() {
protected function delete()
{
$this->response->statusCode = 405;
}
/**
* Method for handling HTTP PATCH requests.
*/
protected function patch() {
protected function patch()
{
$this->response->statusCode = 405;
}
/**
* Method for handling HTTP OPTION requests.
*/
protected function options() {
protected function options()
{
$this->response->statusCode = 405;
}
}
?>

View File

@ -8,8 +8,8 @@ namespace pjdietz\WellRESTed;
* @property string body Entity body of the message
* @property array headers Associative array of HTTP headers
*/
abstract class Message {
abstract class Message
{
/**
* Entity body of the message
*
@ -35,12 +35,14 @@ abstract class Message {
/**
* Name of the protocol to use.
*
* @var string
*/
protected $protocol = 'HTTP';
/**
* Version of the protocol to use.
*
* @var string
*/
protected $protocolVersion = '1.1';
@ -53,8 +55,8 @@ abstract class Message {
* @return array|string
* @throws \Exception
*/
public function __get($name) {
public function __get($name)
{
switch ($name) {
case 'body':
return $this->getBody();
@ -67,7 +69,6 @@ abstract class Message {
default:
throw new \Exception('Property ' . $name . ' does not exist.');
}
}
/**
@ -75,8 +76,8 @@ abstract class Message {
* @param $value
* @throws \Exception
*/
public function __set($name, $value) {
public function __set($name, $value)
{
switch ($name) {
case 'body':
$this->setBody($value);
@ -90,7 +91,6 @@ abstract class Message {
default:
throw new \Exception('Property ' . $name . 'does not exist or is read-only.');
}
}
/**
@ -98,7 +98,8 @@ abstract class Message {
*
* @return string
*/
public function getBody() {
public function getBody()
{
return $this->body;
}
@ -107,7 +108,8 @@ abstract class Message {
*
* @param string $body
*/
public function setBody($body) {
public function setBody($body)
{
$this->body = $body;
}
@ -116,7 +118,8 @@ abstract class Message {
*
* @return array
*/
public function getHeaders() {
public function getHeaders()
{
return $this->headers;
}
@ -126,8 +129,8 @@ abstract class Message {
* @param string $name
* @return string|bool
*/
public function getHeader($name) {
public function getHeader($name)
{
$lowerName = strtolower($name);
if (isset($this->headerLookup[$lowerName])) {
@ -141,7 +144,6 @@ abstract class Message {
}
return false;
}
/**
@ -151,17 +153,16 @@ abstract class Message {
* @param $value
* @param string $value
*/
public function setHeader($name, $value) {
public function setHeader($name, $value)
{
$lowerName = strtolower($name);
// Check if a mapping already exists for this header.
// Remove it, if needed.
if (isset($this->headerLookup[$lowerName])
&& $this->headerLookup[$lowerName] !== $name) {
&& $this->headerLookup[$lowerName] !== $name
) {
unset($this->headers[$this->headerLookup[$lowerName]]);
}
// Store the actual header.
@ -169,7 +170,6 @@ abstract class Message {
// Store a mapping to the user's prefered case.
$this->headerLookup[$lowerName] = $name;
}
/**
@ -178,7 +178,8 @@ abstract class Message {
* @param $name
* @return bool
*/
public function hasHeader($name) {
public function hasHeader($name)
{
$lowerName = strtolower($name);
return isset($this->headerLookup[$lowerName]);
}
@ -188,8 +189,8 @@ abstract class Message {
*
* @param string $name
*/
public function unsetHeader($name) {
public function unsetHeader($name)
{
$lowerName = strtolower($name);
if (isset($this->headerLookup[$lowerName])) {
@ -203,43 +204,42 @@ abstract class Message {
unset($this->headerLookup[$lowerName]);
}
}
/**
* @return string
*/
public function getProtocol() {
public function getProtocol()
{
return $this->protocol;
}
/**
* @param $protocol
*/
public function setProtocol($protocol) {
public function setProtocol($protocol)
{
if (strpos($protocol, '/') === false) {
list($this->protocol, $this->protocolVersion) = explode('/', $protocol, 2);
} else {
$this->protocol = $protocol;
}
}
/**
* @return string
*/
public function getProtocolVersion() {
public function getProtocolVersion()
{
return $this->protocolVersion;
}
/**
* @param string $protocolVersion
*/
public function setProtocolVersion($protocolVersion) {
public function setProtocolVersion($protocolVersion)
{
$this->protocolVersion = $protocolVersion;
}
}
?>

View File

@ -2,10 +2,6 @@
namespace pjdietz\WellRESTed;
require_once(dirname(__FILE__) . '/Message.php');
require_once(dirname(__FILE__) . '/Response.php');
require_once(dirname(__FILE__) . '/exceptions/CurlException.php');
// TODO: Include port in the URI
/**
@ -27,8 +23,8 @@ require_once(dirname(__FILE__) . '/exceptions/CurlException.php');
*
* @package WellRESTed
*/
class Request extends Message {
class Request extends Message
{
/**
* The Hostname for the request (e.g., www.google.com)
*
@ -80,8 +76,8 @@ class Request extends Message {
* @return array|string
* @throws \Exception
*/
public function __get($name) {
public function __get($name)
{
switch ($name) {
case 'hostname':
return $this->getHostname();
@ -98,7 +94,6 @@ class Request extends Message {
default:
return parent::__get($name);
}
}
/**
@ -106,8 +101,8 @@ class Request extends Message {
* @param mixed $value
* @throws \Exception
*/
public function __set($name, $value) {
public function __set($name, $value)
{
switch ($name) {
case 'hostname':
$this->setHostname($value);
@ -127,34 +122,37 @@ class Request extends Message {
default:
parent::__set($name, $value);
}
}
/**
* @return string
*/
public function getHostname() {
public function getHostname()
{
return $this->hostname;
}
/**
* @param string $hostname
*/
public function setHostname($hostname) {
public function setHostname($hostname)
{
$this->hostname = $hostname;
}
/**
* @return string
*/
public function getMethod() {
public function getMethod()
{
return $this->method;
}
/**
* @param string $method
*/
public function setMethod($method) {
public function setMethod($method)
{
$this->method = $method;
}
@ -163,7 +161,8 @@ class Request extends Message {
*
* @return string
*/
public function getPath() {
public function getPath()
{
return $this->path;
}
@ -172,7 +171,8 @@ class Request extends Message {
*
* @param string $path
*/
public function setPath($path) {
public function setPath($path)
{
$this->path = $path;
$this->pathParts = explode('/', substr($path, 1));
}
@ -182,7 +182,8 @@ class Request extends Message {
*
* @return array
*/
public function getPathParts() {
public function getPathParts()
{
return $this->pathParts;
}
@ -191,7 +192,8 @@ class Request extends Message {
*
* @return array
*/
public function getQuery() {
public function getQuery()
{
return $this->query;
}
@ -202,8 +204,8 @@ class Request extends Message {
* @param string|array $query
* @throws \InvalidArgumentException
*/
public function setQuery($query) {
public function setQuery($query)
{
if (is_string($query)) {
$qs = $query;
parse_str($qs, $query);
@ -214,7 +216,6 @@ class Request extends Message {
} else {
throw new \InvalidArgumentException('Unable to parse query string.');
}
}
/**
@ -222,8 +223,8 @@ class Request extends Message {
*
* @return array
*/
public function getUri() {
public function getUri()
{
$uri = strtolower($this->protocol) . '://' . $this->hostname . $this->path;
if ($this->query) {
@ -231,7 +232,6 @@ class Request extends Message {
}
return $uri;
}
/**
@ -240,8 +240,8 @@ class Request extends Message {
*
* @param string $uri
*/
public function setUri($uri) {
public function setUri($uri)
{
$parsed = parse_url($uri);
$host = isset($parsed['host']) ? $parsed['host'] : '';
@ -252,7 +252,6 @@ class Request extends Message {
$query = isset($parsed['query']) ? $parsed['query'] : '';
$this->setQuery($query);
}
// -------------------------------------------------------------------------
@ -263,8 +262,8 @@ class Request extends Message {
* @return Response
* @throws exceptions\CurlException
*/
public function request() {
public function request()
{
$ch = curl_init();
// Set the URL.
@ -333,14 +332,13 @@ class Request extends Message {
curl_close($ch);
return $resp;
}
/**
* Set instance members based on the HTTP request sent to the server.
*/
public function readHttpRequest() {
public function readHttpRequest()
{
$this->setBody(file_get_contents("php://input"), false);
$this->headers = apache_request_headers();
@ -352,7 +350,6 @@ class Request extends Message {
$this->method = $_SERVER['REQUEST_METHOD'];
$this->uri = $_SERVER['REQUEST_URI'];
$this->hostname = $_SERVER['HTTP_HOST'];
}
/**
@ -362,8 +359,8 @@ class Request extends Message {
* @return Request
* @static
*/
public static function getRequest() {
public static function getRequest()
{
if (!isset(self::$theRequest)) {
$klass = __CLASS__;
@ -375,9 +372,6 @@ class Request extends Message {
}
return self::$theRequest;
}
}
?>

View File

@ -2,8 +2,6 @@
namespace pjdietz\WellRESTed;
require_once(dirname(__FILE__) . '/Message.php');
/*******************************************************************************
* Response
*
@ -19,7 +17,8 @@ require_once(dirname(__FILE__) . '/Message.php');
* @property int statusCode HTTP status code
* @property string statusLine HTTP status line, e.g. "HTTP/1.1 200 OK"
*/
class Response extends Message {
class Response extends Message
{
/**
* Text explanation of the HTTP Status Code. You only need to set this if
@ -32,6 +31,7 @@ class Response extends Message {
/**
* HTTP status code
*
* @var int
*/
protected $statusCode;
@ -46,14 +46,14 @@ class Response extends Message {
* @param string $body
* @param array $headers
*/
public function __construct($statusCode=500, $body=null, $headers=null) {
public function __construct($statusCode = 500, $body = null, $headers = null)
{
$this->statusCode = $statusCode;
if (is_array($headers)) {
$this->headers = $headers;
} else {
$this->headers = array();
$this->headers = array();
}
if (!is_null($body)) {
@ -76,8 +76,8 @@ class Response extends Message {
* @return array|string
* @throws \Exception
*/
public function __get($name) {
public function __get($name)
{
switch ($name) {
case 'reasonPhrase':
return $this->getReasonPhrase();
@ -88,7 +88,6 @@ class Response extends Message {
default:
return parent::__get($name);
}
}
/**
@ -96,8 +95,8 @@ class Response extends Message {
* @param mixed $value
* @throws \Exception
*/
public function __set($name, $value) {
public function __set($name, $value)
{
switch ($name) {
case 'reasonPhrase':
$this->setReasonPhrase($value);
@ -108,7 +107,6 @@ class Response extends Message {
default:
parent::__set($name, $value);
}
}
/**
@ -119,34 +117,36 @@ class Response extends Message {
* @param string $value
* @param bool $setContentLength Automatically add a Content-length header
*/
public function setBody($value, $setContentLength=true) {
public function setBody($value, $setContentLength = true)
{
$this->body = $value;
if ($setContentLength === true) {
$this->setHeader('Content-Length', strlen($value));
}
}
/**
* @return string
*/
public function getReasonPhrase() {
public function getReasonPhrase()
{
return $this->reasonPhrase;
}
/**
* @param string $statusCodeMessage
*/
public function setReasonPhrase($statusCodeMessage) {
public function setReasonPhrase($statusCodeMessage)
{
$this->reasonPhrase = $statusCodeMessage;
}
/**
* @return int
*/
public function getStatusCode() {
public function getStatusCode()
{
return $this->statusCode;
}
@ -156,51 +156,127 @@ class Response extends Message {
* @throws \InvalidArgumentException
* @return void
*/
public function setStatusCode($statusCode, $reasonPhrase=null) {
$this->statusCode = (int) $statusCode;
public function setStatusCode($statusCode, $reasonPhrase = null)
{
$this->statusCode = (int)$statusCode;
if (is_null($reasonPhrase)) {
switch ($this->statusCode) {
case 100: $text = 'Continue'; break;
case 101: $text = 'Switching Protocols'; break;
case 200: $text = 'OK'; break;
case 201: $text = 'Created'; break;
case 202: $text = 'Accepted'; break;
case 203: $text = 'Non-Authoritative Information'; break;
case 204: $text = 'No Content'; break;
case 205: $text = 'Reset Content'; break;
case 206: $text = 'Partial Content'; break;
case 300: $text = 'Multiple Choices'; break;
case 301: $text = 'Moved Permanently'; break;
case 302: $text = 'Moved Temporarily'; break;
case 303: $text = 'See Other'; break;
case 304: $text = 'Not Modified'; break;
case 305: $text = 'Use Proxy'; break;
case 400: $text = 'Bad Request'; break;
case 401: $text = 'Unauthorized'; break;
case 402: $text = 'Payment Required'; break;
case 403: $text = 'Forbidden'; break;
case 404: $text = 'Not Found'; break;
case 405: $text = 'Method Not Allowed'; break;
case 406: $text = 'Not Acceptable'; break;
case 407: $text = 'Proxy Authentication Required'; break;
case 408: $text = 'Request Time-out'; break;
case 409: $text = 'Conflict'; break;
case 410: $text = 'Gone'; break;
case 411: $text = 'Length Required'; break;
case 412: $text = 'Precondition Failed'; break;
case 413: $text = 'Request Entity Too Large'; break;
case 414: $text = 'Request-URI Too Large'; break;
case 415: $text = 'Unsupported Media Type'; break;
case 500: $text = 'Internal Server Error'; break;
case 501: $text = 'Not Implemented'; break;
case 502: $text = 'Bad Gateway'; break;
case 503: $text = 'Service Unavailable'; break;
case 504: $text = 'Gateway Time-out'; break;
case 505: $text = 'HTTP Version not supported'; break;
default: $text = 'Nonstandard'; break;
case 100:
$text = 'Continue';
break;
case 101:
$text = 'Switching Protocols';
break;
case 200:
$text = 'OK';
break;
case 201:
$text = 'Created';
break;
case 202:
$text = 'Accepted';
break;
case 203:
$text = 'Non-Authoritative Information';
break;
case 204:
$text = 'No Content';
break;
case 205:
$text = 'Reset Content';
break;
case 206:
$text = 'Partial Content';
break;
case 300:
$text = 'Multiple Choices';
break;
case 301:
$text = 'Moved Permanently';
break;
case 302:
$text = 'Moved Temporarily';
break;
case 303:
$text = 'See Other';
break;
case 304:
$text = 'Not Modified';
break;
case 305:
$text = 'Use Proxy';
break;
case 400:
$text = 'Bad Request';
break;
case 401:
$text = 'Unauthorized';
break;
case 402:
$text = 'Payment Required';
break;
case 403:
$text = 'Forbidden';
break;
case 404:
$text = 'Not Found';
break;
case 405:
$text = 'Method Not Allowed';
break;
case 406:
$text = 'Not Acceptable';
break;
case 407:
$text = 'Proxy Authentication Required';
break;
case 408:
$text = 'Request Time-out';
break;
case 409:
$text = 'Conflict';
break;
case 410:
$text = 'Gone';
break;
case 411:
$text = 'Length Required';
break;
case 412:
$text = 'Precondition Failed';
break;
case 413:
$text = 'Request Entity Too Large';
break;
case 414:
$text = 'Request-URI Too Large';
break;
case 415:
$text = 'Unsupported Media Type';
break;
case 500:
$text = 'Internal Server Error';
break;
case 501:
$text = 'Not Implemented';
break;
case 502:
$text = 'Bad Gateway';
break;
case 503:
$text = 'Service Unavailable';
break;
case 504:
$text = 'Gateway Time-out';
break;
case 505:
$text = 'HTTP Version not supported';
break;
default:
$text = 'Nonstandard';
break;
}
$this->reasonPhrase = $text;
@ -222,12 +298,15 @@ class Response extends Message {
*
* @return string
*/
protected function getStatusLine() {
return sprintf('%s/%s %s %s',
strtoupper($this->protocol),
$this->protocolVersion,
$this->statusCode,
$this->reasonPhrase);
protected function getStatusLine()
{
return sprintf(
'%s/%s %s %s',
strtoupper($this->protocol),
$this->protocolVersion,
$this->statusCode,
$this->reasonPhrase
);
}
// -------------------------------------------------------------------------
@ -237,8 +316,8 @@ class Response extends Message {
*
* @param bool $headersOnly Do not include the body, only the headers.
*/
public function respond($headersOnly=false) {
public function respond($headersOnly = false)
{
// Output the HTTP status code.
header($this->statusLine);
@ -251,9 +330,6 @@ class Response extends Message {
if (!$headersOnly && isset($this->body)) {
print $this->body;
}
}
}
?>

View File

@ -9,8 +9,8 @@ namespace pjdietz\WellRESTed;
*
******************************************************************************/
class Route {
class Route
{
const RE_SLUG = '[0-9a-zA-Z\-_]+';
const RE_NUM = '[0-9]+';
const RE_ALPHA = '[a-zA-Z]+';
@ -20,24 +20,28 @@ class Route {
/**
* Regular Expression to use to validate a template variable.
*
* @var string
*/
static public $defaultVariablePattern = self::RE_SLUG;
/**
* Regular expression used to match a Request URI path component
*
* @var string
*/
public $pattern;
/**
* Name of the Handler class to use
*
* @var string
*/
public $handler;
/**
* The path to the source file defing the handler class.
*
* @var string
*/
public $handlerPath;
@ -47,13 +51,12 @@ class Route {
* @param $handler
* @param $handlerPath
*/
public function __construct($pattern, $handler, $handlerPath=null) {
public function __construct($pattern, $handler, $handlerPath = null)
{
$this->pattern = $pattern;
$this->handler = $handler;
$this->handlerPath = $handlerPath;
} // __construct
}
/**
* Create a new Route using a URI template to generate the pattern.
@ -65,9 +68,12 @@ class Route {
* @throws \Exception
* @return Route
*/
static public function newFromUriTemplate($uriTemplate, $handler,
$handlerPath=null,
$variables=null) {
static public function newFromUriTemplate(
$uriTemplate,
$handler,
$handlerPath = null,
$variables = null
) {
$pattern = '';
@ -83,8 +89,12 @@ class Route {
$pattern .= '\/';
// Is this part an expression or a literal?
if (preg_match(self::URI_TEMPLATE_EXPRESSION_RE,
$part, $matches)) {
if (preg_match(
self::URI_TEMPLATE_EXPRESSION_RE,
$part,
$matches
)
) {
// This part of the path is an expresion.
@ -102,8 +112,11 @@ class Route {
$variablePattern = self::$defaultVariablePattern;
}
$pattern .= sprintf('(?<%s>%s)', $variableName,
$variablePattern);
$pattern .= sprintf(
'(?<%s>%s)',
$variableName,
$variablePattern
);
} else {
// Not sure why this would happen.
@ -126,5 +139,3 @@ class Route {
}
}
?>

View File

@ -2,10 +2,6 @@
namespace pjdietz\WellRESTed;
require_once(dirname(__FILE__) . '/Request.php');
require_once(dirname(__FILE__) . '/Response.php');
require_once(dirname(__FILE__) . '/Route.php');
/*******************************************************************************
* Router
*
@ -16,31 +12,38 @@ require_once(dirname(__FILE__) . '/Route.php');
*
******************************************************************************/
class Router {
class Router
{
/**
* Array of \WellRESTed\Route objects
* @var array
*/
protected $routes;
/**
* Create a new Router.
*/
public function __construct() {
public function __construct()
{
$this->routes = array();
}
/**
* Append a new Route instance to the Router's route table.
*
* @param $route
*/
public function addRoute(Route $route) {
public function addRoute(Route $route)
{
$this->routes[] = $route;
} // addRoute()
}
/**
* @param Request $request
* @return Response
*/
public function getResponse($request=null) {
public function getResponse($request = null)
{
if (is_null($request)) {
$request = Request::getRequest();
}
@ -54,7 +57,7 @@ class Router {
$klass = $route->handler;
// Autoload, if needed.
if (!class_exists($klass) && is_string($route->handlerPath)) {
if (is_string($route->handlerPath) && !class_exists($klass)) {
require_once($route->handlerPath);
}
@ -66,21 +69,17 @@ class Router {
}
return $this->getNoRouteResponse($request);
} // getRequestHandler()
}
/**
* @param Request $request
* @return Response
*/
protected function getNoRouteResponse(Request $request) {
protected function getNoRouteResponse(Request $request)
{
$response = new Response(404);
$response->body = 'No resource at ' . $request->uri;
return $response;
}
}
?>

View File

@ -1,8 +1,6 @@
<?php
namespace pjdietz\WellRESTed\exceptions;
require_once(dirname(__FILE__) . '/WellrestedException.php');
namespace pjdietz\WellRESTed\Exceptions;
/**
* Exception related to a cURL operation. The message and code should correspond

View File

@ -1,6 +1,6 @@
<?php
namespace pjdietz\WellRESTed\exceptions;
namespace pjdietz\WellRESTed\Exceptions;
/**
* Top level class for custom exceptions thrown by Well RESTed.