<?php
/**
* Controller handles HTTP requests, selects and executes appropriate resource. Afterwards sends out output generated by the View to the browser, and the execution halts: application waits for another request.
* Implemented as a frontal controller: it is the only point of entry to the application.
* It is an abstract class for sub-classing. An application Controller should extend the framework Controller and call the parent::process() to handle requests.
* @package diy-framework
* @subpackage controller
* @author Martynas Jusevicius <hide@address.com>
* @link http://www.xml.lt
*/
abstract class Controller implements Singleton
{
protected $resource = null;
protected $view = null;
/**
* Constructs a new Controller.
* Is private because of the Singleton pattern.
*/
private function __construct() {}
private function __clone() {}
/**
* Extracts and returns the full URI (including both host and resource URIs) of the current Request, by striping the query string.
* @param Request $request Request to extract the URI from
* @return string URI
*/
private static function getFullURI(Request $request)
{
$host = $request->getHeader("HTTP_HOST");
//if ($request->getHeader("HTTP_X_FORWARDED_HOST") != null) $host = $request->getHeader("HTTP_X_FORWARDED_HOST");
$URI = "http://".$host."/".self::getPath($request);
return $URI;
}
/**
* Extracts and returns the path of the current Request, by striping the query string.
* @param Request $request Request to extract the path from
* @return string path
*/
private static function getPath(Request $request)
{
$path = $request->getRequestURI();
//$path = $request->getPathInfo(); // wrong URL encoding
if ($pos = strpos($path, "?")) $path = substr($path, 0, $pos); // strip the query string
$path = substr($path, 1); // strip the leading slash
return $path;
}
/**
* Sets HTTP response headers and writes out the buffer.
* @param Response $response Response to write out and to send to the client
*/
protected static function output(Response $response)
{
header("HTTP/1.1 ".$response->getStatus());
if ($response->getContentType() != null && $response->getCharacterEncoding() != null) header("Content-Type: ".$response->getContentType()."; charset=".$response->getCharacterEncoding());
if ($response->getBuffer() != null) print $response->getBuffer();
// exit
}
/**
* Processes the HTTP Request. Finds an appropriate Resource, passes the control to it, and displays the resulting View.
* @param Request $request Request to process
* @param Response $response Response to process
*/
protected function process(Request $request, Response $response, ResourceMapping $mapping)
{
$uri = $this->getFullURI($request);
$path = substr($uri, strlen($mapping->getHost()));
$request->setAttribute("URI", $path);
$this->resource = $mapping->findByURI($path);
$this->view = null;
if ($this->resource != null)
switch ($request->getMethod())
{
case "GET":
$this->view = $this->resource->doGet($request, $response);
break;
case "POST":
$this->view = $this->resource->doPost($request, $response);
break;
case "PUT":
$this->view = $this->resource->doPut($request, $response);
break;
case "DELETE":
$this->view = $this->resource->doDelete($request, $response);
break;
default:
$response->setStatus(Response::SC_METHOD_NOT_ALLOWED);
break;
}
}
}
?>