Login   Register  
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;
    
}
}

?>