Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial commit

  • Loading branch information...
commit 0e33a7bcdd62c1a12e35c9ce639494211ddb1cb0 0 parents
@jaytaph authored
0  README.markup
No changes.
17 controllers/defaultController.php
@@ -0,0 +1,17 @@
+<?php
+
+class defaultController extends ji_restController {
+
+ function handleRetrieveCollection() {
+ $response = $this->getResponse();
+ $response->setBody("COLLECTION STATUS IS UP AND RUNNING");
+ }
+
+ function handleRetrieveResource() {
+ $request = $this->getRequest();
+ $resource = $request->resource;
+
+ $response = $this->getResponse();
+ $response->setBody("RESOURCE STATUS IS UP AND RUNNING");
+ }
+}
17 controllers/event/talk/commentController.php
@@ -0,0 +1,17 @@
+<?php
+
+class event_talk_commentController extends ji_restController {
+
+ function handleRetrieveResource() {
+ $response = $this->getResponse();
+ $response->setBody("EVENT_TALK_COMMENT_CONTROLLER IS CALLED!!! WHOOHOO");
+ }
+
+ function handleRetrieveCollection() {
+ $response = $this->getResponse();
+
+ $a = array(1,2,3,4,5);
+ $response->setBody($a);
+ }
+
+}
8 controllers/event/talkController.php
@@ -0,0 +1,8 @@
+<?php
+
+class event_talkController extends ji_restController {
+
+ function passThrough($resource) {
+ return true;
+ }
+}
7 controllers/eventController.php
@@ -0,0 +1,7 @@
+<?php
+
+class eventController extends ji_restController {
+ function passThrough($resource) {
+ return ($resource == 2);
+ }
+}
4 controllers/talkController.php
@@ -0,0 +1,4 @@
+<?php
+
+class talkController extends ji_restController {
+}
4 controllers/userController.php
@@ -0,0 +1,4 @@
+<?php
+
+class userController extends ji_restController {
+}
153 library/ji/request.php
@@ -0,0 +1,153 @@
+<?php
+
+class ji_request {
+ protected $_resource;
+ protected $_accept;
+ protected $_host;
+ protected $_parameters;
+ protected $_verb;
+ protected $_url_elements;
+
+ /**
+ * Constructs a request. Can be populate form server variables if needed
+ *
+ * @param array|null $server_vars
+ */
+ function __construct(array $server_vars = null) {
+ if (is_array($server_vars)) {
+ $this->_populate($server_vars);
+ }
+ }
+
+ /**
+ * Populates the request. Accepts apache server variables
+ *
+ * @return ji_request
+ */
+ protected function _populate($server_vars) {
+ // Collect headers
+ $this->setVerb($server_vars['REQUEST_METHOD']);
+ $this->setAccept($server_vars['HTTP_ACCEPT']);
+ $this->setHost($server_vars['HTTP_HOST']);
+
+ // collect URL info and sets the url elements.
+ if(isset($server_vars['PATH_INFO'])) {
+ $items = explode('/',$server_vars['PATH_INFO']);
+ array_shift($items);
+
+ // Default default to default..
+ if (count($items) == 0) $items[] = "default";
+
+ /* Resources have an even number of items on the path. Collections don't:
+ * Resource: /event/3/talk/5
+ * Collection: /event/4/talks
+ */
+ $this->setResource((count($items) & 1) != 1);
+
+ // Map serialized url data into key value pairs
+ $path = "";
+ while (count($items)) {
+ $k = array_shift($items);
+ if (strlen($k) == 0) continue;
+ $this->addUrlElement($k, array_shift($items), $path);
+
+ // Holds the "hiearchy" for finding deeper controllers
+ $path .= $k."_";
+ }
+ }
+
+ // Parse query string and set (default) values
+ parse_str($server_vars['QUERY_STRING'], $parameters);
+ $parameters['resultsperpage'] = isset($parameters['resultsperpage']) ? $parameters['resultsperpage'] : 20;
+ $parameters['page'] = isset($parameters['page']) ? $parameters['page'] : 1;
+ $this->setParameters($parameters);
+ }
+
+
+ public function addUrlElement($element, $resource, $path) {
+ $this->_url_elements[] = array(
+ 'element' => $element,
+ 'resource' => $resource,
+ 'path' => $path
+ );
+ }
+
+ public function getUrlElements() {
+ return $this->_url_elements;
+ }
+
+ /**
+ * Returns parent elements.
+ *
+ * Returns event/5 and talk/3 url element pairs from the url:
+ * /event/5/talk/3/comment/5
+ *
+ * @return array
+ */
+ public function getParentElements() {
+ return array_splice($this->_url_elements, 0, count($this->_url_elements)-1);
+ }
+
+ /**
+ * Returns main element or rest end-point if you will.
+ *
+ * Returns comment/5 url element pairs from the url:
+ * /event/5/talk/3/comment/5
+ *
+ * @return array
+ */
+ public function getMainElement() {
+ return $this->_url_elements[count($this->_url_elements)-1];
+ }
+
+ public function setAccept($accept)
+ {
+ $this->_accept = $accept;
+ }
+
+ public function getAccept()
+ {
+ return $this->_accept;
+ }
+
+ public function setHost($host)
+ {
+ $this->_host = $host;
+ }
+
+ public function getHost()
+ {
+ return $this->_host;
+ }
+
+ public function setParameters($parameters)
+ {
+ $this->_parameters = $parameters;
+ }
+
+ public function getParameters()
+ {
+ return $this->_parameters;
+ }
+
+ public function setResource($resource)
+ {
+ $this->_resource = $resource;
+ }
+
+ public function isResource()
+ {
+ return $this->_resource;
+ }
+
+ public function setVerb($verb)
+ {
+ $this->_verb = $verb;
+ }
+
+ public function getVerb()
+ {
+ return $this->_verb;
+ }
+
+}
37 library/ji/response.php
@@ -0,0 +1,37 @@
+<?php
+
+class ji_response {
+ protected $_httpCode = 200;
+ protected $_httpStatus = "Ok";
+ protected $_body = "";
+
+ function __construct() {
+ }
+
+ function setHttpCode($httpCode) {
+ $this->_httpCode = $httpCode;
+ }
+
+ function getHttpCode() {
+ return $this->_httpCode = $httpCode;
+ }
+
+ public function setBody($body) {
+ $this->_body = $body;
+ }
+
+ public function getBody() {
+ return $this->_body;
+ }
+
+ public function setHttpStatus($httpStatus)
+ {
+ $this->_httpStatus = $httpStatus;
+ }
+
+ public function getHttpStatus()
+ {
+ return $this->_httpStatus;
+ }
+
+}
162 library/ji/restController.php
@@ -0,0 +1,162 @@
+<?php
+
+abstract class ji_restController {
+ /**
+ * @var ji_request
+ */
+ protected $_request = null;
+
+ /**
+ * @var ji_response
+ */
+ protected $_response = null;
+
+ /**
+ *
+ */
+ function __construct() {
+ }
+
+
+ /**
+ * Global REST handler
+ *
+ * @param stdClass $request
+ * @return null
+ */
+ function handle(ji_request $request) {
+ $this->setRequest($request);
+ if ($this->getResponse() == null) {
+ $this->setResponse(new ji_response());
+ }
+
+ /**
+ * HTTP PUT and POST are pretty much interchangeable. Can be configured here
+ */
+ switch (strtolower($request->getVerb())) {
+ case "delete" :
+ // Delete is always delete
+ $crudMethod = "Delete";
+ break;
+ case "put" :
+ // PUT is create or update, depending on resource or collection
+ $crudMethod = ($entity == "Resource") ? "Update" : "Create";
+ break;
+ case "post" :
+ // POST is create or update, depending on resource or collection
+ $crudMethod = ($entity == "Resource") ? "Update" : "Create";
+ break;
+ case "get" :
+ default :
+ // Default and GET are retrievals
+ $crudMethod = "Retrieve";
+ break;
+ }
+
+ // Check if we need to call resource or collection
+ $entity = $request->isResource() ? "Resource" : "Collection";
+
+ // Call function
+ $handleFunc = "handle".$crudMethod.$entity;
+ $this->$handleFunc();
+
+ // Return response
+ return $this->getResponse();
+ }
+
+ /**
+ * @param ji_request $request
+ * @return void
+ */
+ function setRequest(ji_request $request) {
+ $this->_request = $request;
+ }
+
+ /**
+ * @return ji_request|null
+ */
+ function getRequest() {
+ return $this->_request;
+ }
+
+ /**
+ * @param ji_response $response
+ * @return void
+ */
+ function setResponse(ji_response $response) {
+ $this->_response = $response;
+ }
+
+ /**
+ * @return ji_response|null
+ */
+ function getResponse() {
+ return $this->_response;
+ }
+
+ /**
+ * Error creator. Just an easy way to fill the response for error outputting
+ */
+ function createError($http_code, $http_status, $body = "") {
+ $response = $this->getResponse();
+ $response->setHttpCode($http_code);
+ $response->setHttpStatus($http_status);
+ $response->setBody($body);
+ }
+
+
+ /**
+ * 8 default handle functions. Will handle CRUD operations for both resources and collections.
+ * By default they will return a 501 status since they are not defined.
+ */
+ function handleCreateCollection() {
+ $this->createError(501, "Not implemented");
+ }
+
+ function handleUpdateCollection() {
+ $this->createError(501, "Not implemented");
+ }
+
+ function handleRetrieveCollection() {
+ $this->createError(501, "Not implemented");
+ }
+
+ function handleDeleteCollection() {
+ $this->createError(501, "Not implemented");
+ }
+
+ function handleCreateResource() {
+ $this->createError(501, "Not implemented");
+ }
+
+ function handleCUpdateResource() {
+ $this->createError(501, "Not implemented");
+ }
+
+ function handleRetrieveResource() {
+ return $this->createError(501, "Not implemented");
+ }
+
+ function handleDeleteResource() {
+ return $this->createError(501, "Not implemented");
+ }
+
+ /**
+ * Called when this controller is a parent of another controller. Checks if the item exists or not.
+ * For example:
+ *
+ * GET event/5/talk/3/comment/1 (get first comment from 3rd talk from event 5).
+ *
+ * will call
+ * + eventController::passthrough(5),
+ * + event_talkController::passthrough(3)
+ * + event_talk_commentController::retrieveResource(1)
+ *
+ * @param $resource
+ * @return boolean true|false
+ */
+ function passThrough($resource) {
+ return false;
+ }
+
+}
8 public/.htaccess
@@ -0,0 +1,8 @@
+<IfModule mod_rewrite.c>
+ RewriteEngine On
+ RewriteBase /
+
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteRule ^(.*)$ index.php/$1 [L]
+</IfModule>
0  public/Favicon.ico
No changes.
135 public/index.php
@@ -0,0 +1,135 @@
+<?php
+
+print "<pre>";
+
+// Full error reporting
+error_reporting(-1);
+ini_set('display_errors', true);
+
+// Setup
+set_exception_handler('handle_exception');
+setupDb();
+$request = new ji_request($_SERVER);
+
+// Pass through parent controllers if needed (in case of /event/%d/talk/%d/comment/%d)
+foreach ($request->getParentElements() as $element) {
+ print "PARENT ELEMENTS! ".print_r($element,true);
+ $tmp = findController($element['element']);
+ if (! $tmp) die ("Cannot find controller: ".$element['element']);
+
+ $controllerClass = $element['path'].$tmp."Controller";
+ print "Controller: ".$controllerClass." : ";
+
+ // Check if we are allowed to continue
+ $controller = new $controllerClass();
+ if ($controller->passThrough($element['resource'])) {
+ print "Continue; <br>\n";
+ // This is ok, continue with the next element form the URL
+ } else {
+ print "No continue; <br>\n";
+ // Do something, like returning a 404
+ }
+}
+
+// Call the actual endpoint controller (we call handle(), not passthrough() and we call without resource)
+$element = $request->getMainElement();
+$tmp = findController($element['element']);
+if (! $tmp) die ("Cannot find controller ".$element['element']);
+$controllerClass = $element['path'].$tmp."Controller";
+$controller = new $controllerClass();
+$response = $controller->handle($request);
+
+// Response is populated. Do something with it, like output depending on the response values (which media format etc)
+var_dump ($response);
+exit;
+
+
+/**
+ * Not used. Output thingie.
+ */
+function output(ji_response $response) {
+ // Output
+ header("Status ".$response->getHttpCode()." ".$response->getHttpStatus());
+
+ // Output additional headers
+ foreach ($response->getHeaders() as $header) {
+ header($header);
+ }
+
+ return $response->body;
+}
+
+
+/**
+ * Controller mapper. This makes it possible to map certain uri-elements to controllers.
+ * For instance: "/events/%d" to the event-controller, but also "/children" to the
+ * child-controller if needed.
+ *
+ * It means we have to map each URL element for now, but I prefer this over auto-detection
+ * for the time being.
+ */
+function findController($name) {
+ $mappers = array(
+ 'event' => 'event', 'events' => 'event',
+ 'talk' => 'talk', 'talks' => 'talk',
+ 'user' => 'user', 'users' => 'user',
+ 'comment' => 'comment', 'comments' => 'comment',
+ 'default' => 'default'
+ );
+ return isset ($mappers[$name]) ? $mappers[$name] : false;
+}
+
+
+/**
+ * Add exception handler
+ */
+function handle_exception($e) {
+ // TODO pass this through the output handlers
+ echo "BADNESS<pre>";
+ var_dump($e);
+ error_log('Exception Handled: ' . $e->getMessage());
+}
+
+/**
+ * autoloader
+ */
+function __autoload($classname) {
+ // We use directory separators in our classes.
+ $classname = str_replace('_', '/', $classname);
+
+ if(false !== strpos($classname, '.')) {
+ // this was a filename, don't bother
+ return;
+ }
+
+ if(preg_match('/^ji\//',$classname)) {
+ // Check ji_* classes inside the library
+ include('../library/' . $classname . '.php');
+ return true;
+ } elseif(preg_match('/[a-zA-Z]+Controller$/',$classname)) {
+ include('../controllers/' . $classname . '.php');
+ return true;
+ } elseif(preg_match('/[a-zA-Z]+Model$/',$classname)) {
+ include('../models/' . $classname . '.php');
+ return true;
+ } elseif(preg_match('/[a-zA-Z]+View$/',$classname)) {
+ include('../views/' . $classname . '.php');
+ return true;
+ }
+}
+
+
+/**
+ * @return void
+ */
+function setupDb() {
+ // config setup
+ define('BASEPATH', '.');
+
+ // Assumes that here we find CodeIgnited database config...
+ require_once('../../system/application/config/database.php');
+ $ji_db = new PDO('mysql:host=' . $db['default']['hostname'] .
+ ';dbname=' . $db['default']['database'],
+ $db['default']['username'],
+ $db['default']['password']);
+}
Please sign in to comment.
Something went wrong with that request. Please try again.