Commit: 80d76020c7ff106416cc60e77591b6beaaea1f84
Author: Nate Abele | Date: 2009-07-03 18:23:06 -0400
diff --git a/.gitignore b/.gitignore
index e69de29..496ee2c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+.DS_Store
\ No newline at end of file
diff --git a/exceptions/NotFoundException.php b/exceptions/NotFoundException.php
new file mode 100644
index 0000000..3e43237
--- /dev/null
+++ b/exceptions/NotFoundException.php
@@ -0,0 +1,8 @@
+<?php
+
+namespace slice\exceptions;
+
+class NotFoundException extends \Exception {
+}
+
+?>
\ No newline at end of file
diff --git a/extensions/http/Dispatcher.php b/extensions/http/Dispatcher.php
new file mode 100644
index 0000000..474c3f4
--- /dev/null
+++ b/extensions/http/Dispatcher.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace slice\extensions\http;
+
+class Dispatcher extends \cake\http\Dispatcher {
+
+ protected static $_classes = array(
+ 'request' => '\slice\extensions\http\Request',
+ 'router' => '\slice\extensions\http\Router'
+ );
+
+ public static function run($request, $options = array(), $methods = array()) {
+ if (is_array($request) && is_callable(current($request))) {
+ $methods = $request;
+ $options['methods'] = $methods;
+ $request = null;
+ }
+ $router = static::$_classes['router'];
+ $router::connect(array_keys($methods));
+ $result = parent::run($request, $options);
+
+ var_dump($result);
+ static::_stop();
+ }
+
+ protected static function _callable($request, $params, $options) {
+ if (!isset($params['route']) || !isset($options['methods'])) {
+ return null;
+ }
+ return $options['methods'][$params['route']];
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/extensions/http/Request.php b/extensions/http/Request.php
new file mode 100644
index 0000000..1118a68
--- /dev/null
+++ b/extensions/http/Request.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace slice\extensions\http;
+
+class Request extends \cake\http\Request {
+
+ public function __get($key) {
+ return isset($this->params[$key]) ? $this->params[$key] : $this->env($key);
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/extensions/http/Router.php b/extensions/http/Router.php
new file mode 100644
index 0000000..7afbc89
--- /dev/null
+++ b/extensions/http/Router.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace slice\extensions\http;
+
+class Router extends \cake\http\Router {
+
+ protected static $_configuration = array();
+
+ public static function connect($routes) {
+ static::$_configuration = $routes;
+ }
+
+ public static function parse($request) {
+ $requestMethod = strtolower($request->env('REQUEST_METHOD'));
+ $class = static::$_classes['route'];
+
+ foreach (static::$_configuration as $route) {
+ list($method, $template) = explode(' ', $route, 2);
+
+ if ($method != $requestMethod) {
+ continue;
+ }
+ $routeObject = new $class(compact('template'));
+ $routeObject->compile();
+
+ if ($match = $routeObject->parse($request)) {
+ return compact('route') + $match;
+ }
+ }
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/readme b/readme
new file mode 100644
index 0000000..4d01e71
--- /dev/null
+++ b/readme
@@ -0,0 +1,46 @@
+## Slice: The Lightweight Request Dispatch Framework for CakePHP
+
+Slice is a plugin which allows you to implement micro-applications or application services using the CakePHP framework. Slice is ideally suited to serving small requests, such as APIs or Ajax queries, where speed is of the essence.
+
+To use Slice in your application, simply install it in your `plugins` directory and include it by adding the following to `config/bootstrap.php` or `webroot/index.php`:
+
+{{{
+\cake\core\Libraries::add('plugin', 'slice');
+}}}
+
+You can then implement Slice services by calling the `run()` method of `slice\extensions\http\Dispatcher`, and passing it an array where the keys are Slice-formatted routes and the values are closures which define how requests matching the corresponding route should be handled.
+
+{{{
+
+use \Exception;
+use \app\models\Post;
+use \slice\exceptions\NotFoundException;
+use \slice\extensions\http\Dispatcher;
+
+echo Dispatcher::run(array(
+ 'get /posts/{:id:\d+}.json' => function($request) {
+ try {
+ return array(
+ 'status' => 200,
+ 'type' => 'application/json',
+ 'content' => Post::find($request->id)->to('json')
+ );
+ } catch (Exception $e) {
+ throw new NotFoundException();
+ }
+ }
+));
+
+}}}
+
+### Routing
+
+The syntax for declaring routes in Slice is similar to that of Cake 3.0 standard routes, except that Slice routes are prefixed with an HTTP request method name, followed by a space. Routes can then include standard parameters, with optional regular expression match patterns, as in the example.
+
+### Handling requests
+
+Closures used to handle requests in Slice take a single parameter, an instance of the `Request` object, which encapsulates the request details. Slice extends the default CakePHP `Request` object so that route parameters are accessible as properties (i.e. `$request->id`), as seen in the example.
+
+In order to successfully handle requests, closures must _either_ return an array containing (at a minimum) `'status'`, `'type'`, and `'content'` keys, and optionally, a `'headers'` key containing an array with additional headers, _or_ an instance of `cake\http\Response` containing a fully-formed response.
+
+Alternatively, closures can throw exceptions in case of error, or ignore the request, simply by returning null. If a request is ignored, it simply "falls through", out of the scope of Slice. This is useful if you are declaring a Slice service inside of `webroot/index.php`, and wish for requests ignored by Slice to be handled by your application.
\ No newline at end of file