PHP Classes
elePHPant
Icontem

File: RestServer.class.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Diogo Souza da Silva  >  REST Server  >  RestServer.class.php  >  Download  
File: RestServer.class.php
Role: Class source
Content type: text/plain
Description: RestServer main class
Class: REST Server
Implement REST Web services servers
Author: By
Last change: big time update
Date: 4 years ago
Size: 7,108 bytes
 

Contents

Class file image Download
<?php

include_once 'RestAction.class.php';
include_once
'RestController.class.php';
include_once
'RestView.class.php';
include_once
'RestRequest.class.php';
include_once
'RestResponse.class.php';
include_once
'RestAuthenticator.class.php';

/**
* Class RestServer
* Is the front controller for mapping URL to controllers and dealing with Request/Response and Headers
* Made with Restful webservices in mind.
* By Diogo Souza da Silva <manifesto@manifesto.blog.br>
*/
class RestServer {

    private
$response ;
    private
$request ;
    private
$authenticator ;

    private
$baseUrl ;
    private
$query ;
    private
$qPart;

    private
$map ;
    private
$params ;
    private
$stack ;

   
/**
     * Contructor of RestServer
     * @param string $query Optional query to be treat as the URL
     * @return RestServer $rest;
    */
   
public function __construct($query=null) {
       
$this->request = new RestRequest($this); // Request handler
       
$this->response = new RestResponse($this); // Response holder
       
$this->authenticator = new RestAuthenticator($this); // Authenticator holder

       
if(isset($_SERVER["HTTP_HOST"])) {
           
$this->baseUrl = "http://".$_SERVER["HTTP_HOST"].dirname($_SERVER["SCRIPT_NAME"]);
        }

       
// If will use custom URI or HTTP requested URI
       
if($query===null) $this->query = $this->getRequest()->getRequestURI() ;
        else
$this->query = $query ;

       
$this->getRequest()->setURI($this->query);

       
$this->qPart = explode("/",$this->query);
    }

   
/**
    * Sets a parameter in a global scope that can be recovered at any request.
    * @param mixed $key The identifier of the parameter
    * @param mixed $value The content of the parameter
    * @return RestServer $this
    */
   
public function setParameter($key,$value) {
       
$this->params[$key] = $value ;
        return
$this ;
    }

   
/**
    * Return the specified parameter
    * @param mixed $key The parameter identifier
    * @return mixed
    */
   
public function getParameter($key) {
        return
$this->params[$key];
    }

   
/**
    * Maps a Method and URL for a Class
    * @param string $method The method to be associated
    * @param string $uri The URL to be accossiated
    * @param string $class The name of the class to be called, it must implement RestAction
    * @return RestServer $this
    */
   
public function addMap($method,$uri,$class) {
       
$this->map[$method][$uri] = $class ;
        return
$this ;
    }

   
/**
    * Set the URL to be handle or part of it
    * @param mixed $value The url
    * @param int $k the part of the url to change
    * @return RestServer $this
    */
   
public function setQuery($value,$k=null) {
        if(
$k !== null){
           
$this->qPart[$k] = $value ;
        } else {
           
$this->query = $value ;
           
$this->qPart = explode("/",$value );
           
$this->getRequest()->setURI($value);
        }
        return
$this ;
    }

   
/**
    * Get the URL or part of it, depreciated by RestRequest::getURI();
    * @param $k uri part
    * @return string
    **/
   
public function getQuery($k=null) {
        if(
$k !== null){
            if(isset(
$this->qPart[$k])) {
                return
$this->qPart[$k];
            } else {
                return
'';
            }
        }
        return
$this->query ;
    }

   
/**
    * Get the baseurl, based on website location (eg. localhost/website or website.com/);
    * @return string
    **/
   
public function getBaseUrl() {
        return
$this->baseUrl ;
    }

   
/**
    * Get the Response handler object
    * @return RestResponse
    */
   
public function getResponse() {
        return
$this->response ;
    }

   
/**
     * Get the Request handler object
    * @return RestRequest
    */
   
public function getRequest() {
        return
$this->request ;
    }

   
/**
     * Get the Authentication handler object
    * @return RestAuthenticator
    */
   
public function getAuthenticator() {
        return
$this->authenticator ;
    }

   
/**
    * Get the class for specified method and uri
    * @param string $method
    * @param string $uri
    * @return string
    */
   
public function getMap($method,$uri) {
       
$maps = $this->map[$method];
        if(
count($maps) < 1) { return false; }
        foreach(
$maps as $map=>$class) {
            if(
preg_match("%^".$map."$%",$uri) ) {
                return
$class ;
            }
        }
        return
false ;
    }

   
/**
    * Return last class name from RestServer stack trace
    * @return string
    */
   
public function lastClass() {
       
$i = count($this->stack);
        return
$this->stack[$i - 1];
    }

   
/**
    * Run the Server to handle the request and prepare the response
    * @return string $responseContent
    */
   
public function execute() {
        if(!
$this->getAuthenticator()->tryAuthenticate()) {
            return
$this->show(); // If auth is required and its not ok, response is 401
       
}

       
// This is the class name to call
       
$responseClass = $this->getMap($this->getRequest()->getMethod(),$this->getQuery()) ;
       
$responseMethod = null;

        if(!
$responseClass) { // If no class was found, response is 404
           
$this->getResponse()->cleanHeader();
           
$this->getResponse()->addHeader("HTTP/1.1 404 Not found");
           
$this->getResponse()->setResponse("HTTP/1.1 404 NOT FOUND");
            return
$this->show();
        }

       
// In case a specific method should be called
       
if(count($parts = explode("::",$responseClass)) > 1) {
           
$responseClass = $parts[0];
           
$responseMethod = $parts[1];
        }

        return
$this->call(new $responseClass,$responseMethod)->show(); // Call the class and return the response
   
}

    private function
call($class,$method=null) {
       
$this->stack[] = get_class($class) ;
        if(
$method != null) {
        } else if(
$class instanceof RestView) { // If is a view, call Show($restServer)
           
$method="show";
        } else if(
$class instanceof RestController) { //If is a controller, call execute($restServer)
           
$method="execute";
        } else {
            Throw new
Exception(get_class($class)." is not a RestAction");
        }
       
$class = $class->$method($this);

        if(
$class instanceof RestAction
           
&& get_class($class) != $this->lastClass() ) {
            return
$this->call($class); // May have another class to follow the request
       
}

        return
$this ;
    }

    private function
show() {
        if(!
$this->getResponse()->headerSent()) {
           
$this->getResponse()->showHeader(); // Call headers, if no yet
       
}
        return
$this->getResponse()->getResponse() ; // Return response content;
   
}
}

?>