diff --git a/flight/Flight.php b/flight/Flight.php
index 6657d5e..326be9a 100644
--- a/flight/Flight.php
+++ b/flight/Flight.php
@@ -45,7 +45,7 @@ class Flight {
* Handles calls to static methods.
*
* @param string $name Method name
- * @param array $args Method parameters
+ * @param array $params Method parameters
*/
public static function __callStatic($name, $params) {
$callback = self::$dispatcher->get($name);
@@ -65,59 +65,54 @@ class Flight {
* Initializes the framework.
*/
public static function init() {
- static $initialized = false;
-
- if (!$initialized) {
- // Handle errors internally
- set_error_handler(array(__CLASS__, 'handleError'));
-
- // Handle exceptions internally
- set_exception_handler(array(__CLASS__, 'handleException'));
-
- // Fix magic quotes
- if (get_magic_quotes_gpc()) {
- $func = function ($value) use (&$func) {
- return is_array($value) ? array_map($func, $value) : stripslashes($value);
- };
- $_GET = array_map($func, $_GET);
- $_POST = array_map($func, $_POST);
- $_COOKIE = array_map($func, $_COOKIE);
- }
+ // Handle errors internally
+ set_error_handler(array(__CLASS__, 'handleError'));
+
+ // Handle exceptions internally
+ set_exception_handler(array(__CLASS__, 'handleException'));
- // Load core components
+ // Load core components
+ if (self::$loader == null) {
self::$loader = new \flight\core\Loader();
- self::$dispatcher = new \flight\core\Dispatcher();
+ self::$loader->start();
+ }
+ else {
+ self::$loader->reset();
+ }
- // Initialize autoloading
- self::$loader->init();
- self::$loader->addDirectory(dirname(__DIR__));
-
- // Register default components
- self::$loader->register('request', '\flight\net\Request');
- self::$loader->register('response', '\flight\net\Response');
- self::$loader->register('router', '\flight\net\Router');
- self::$loader->register('view', '\flight\template\View', array(), function($view){
- $view->path = Flight::get('flight.views.path');
- });
-
- // Register framework methods
- $methods = array(
- 'start','stop','route','halt','error','notFound',
- 'render','redirect','etag','lastModified','json'
- );
- foreach ($methods as $name) {
- self::$dispatcher->set($name, array(__CLASS__, '_'.$name));
- }
+ if (self::$dispatcher == null) {
+ self::$dispatcher = new \flight\core\Dispatcher();
+ }
+ else {
+ self::$dispatcher->reset();
+ }
- // Default settings
- self::set('flight.views.path', './views');
- self::set('flight.log_errors', false);
+ // Register framework directory
+ self::$loader->addDirectory(dirname(__DIR__));
+
+ // Register default components
+ self::$loader->register('request', '\flight\net\Request');
+ self::$loader->register('response', '\flight\net\Response');
+ self::$loader->register('router', '\flight\net\Router');
+ self::$loader->register('view', '\flight\template\View', array(), function($view){
+ $view->path = Flight::get('flight.views.path');
+ });
+
+ // Register framework methods
+ $methods = array(
+ 'start','stop','route','halt','error','notFound',
+ 'render','redirect','etag','lastModified','json'
+ );
+ foreach ($methods as $name) {
+ self::$dispatcher->set($name, array(__CLASS__, '_'.$name));
+ }
- // Enable output buffering
- ob_start();
+ // Default settings
+ self::set('flight.views.path', './views');
+ self::set('flight.log_errors', false);
- $initialized = true;
- }
+ // Enable output buffering
+ ob_start();
}
/**
@@ -137,7 +132,7 @@ class Flight {
/**
* Custom exception handler. Logs exceptions.
*
- * @param object $e Exception
+ * @param Exception $e Thrown exception
*/
public static function handleException(Exception $e) {
if (self::get('flight.log_errors')) {
@@ -151,6 +146,7 @@ class Flight {
*
* @param string $name Method name
* @param callback $callback Callback function
+ * @throws Exception If trying to map over a framework method
*/
public static function map($name, $callback) {
if (method_exists(__CLASS__, $name)) {
@@ -167,6 +163,7 @@ class Flight {
* @param string $class Class name
* @param array $params Class initialization parameters
* @param callback $callback Function to call after object instantiation
+ * @throws Exception If trying to map over a framework method
*/
public static function register($name, $class, array $params = array(), $callback = null) {
if (method_exists(__CLASS__, $name)) {
@@ -301,7 +298,7 @@ class Flight {
* Stops processing and returns a given response.
*
* @param int $code HTTP status code
- * @param int $message Response message
+ * @param string $message Response message
*/
public static function _halt($code = 200, $message = '') {
self::response(false)
@@ -314,7 +311,7 @@ class Flight {
/**
* Sends an HTTP 500 response for any errors.
*
- * @param object $e Exception
+ * @param \Exception Thrown exception
*/
public static function _error(Exception $e) {
$msg = sprintf('
500 Internal Server Error
'.
@@ -364,6 +361,7 @@ class Flight {
* Redirects the current request to another URL.
*
* @param string $url URL
+ * @param int $code HTTP status code
*/
public static function _redirect($url, $code = 303) {
$base = self::request()->base;
@@ -418,8 +416,7 @@ class Flight {
self::response()->header('ETag', $id);
- if (isset($_SERVER['HTTP_IF_NONE_MATCH']) &&
- $_SERVER['HTTP_IF_NONE_MATCH'] === $id) {
+ if ($id === getenv('HTTP_IF_NONE_MATCH')) {
self::halt(304);
}
}
@@ -432,8 +429,7 @@ class Flight {
public static function _lastModified($time) {
self::response()->header('Last-Modified', date(DATE_RFC1123, $time));
- if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) &&
- strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) === $time) {
+ if ($time === strtotime(getenv('HTTP_IF_MODIFIED_SINCE'))) {
self::halt(304);
}
}
diff --git a/flight/core/Dispatcher.php b/flight/core/Dispatcher.php
index 0d5eb32..82de9d1 100644
--- a/flight/core/Dispatcher.php
+++ b/flight/core/Dispatcher.php
@@ -34,6 +34,7 @@ class Dispatcher {
*
* @param string $name Event name
* @param array $params Callback parameters
+ * @return string Output of callback
*/
public function run($name, $params) {
$output = '';
@@ -68,7 +69,7 @@ class Dispatcher {
* Gets an assigned callback.
*
* @param string $name Event name
- * @param callback $callback Callback function
+ * @return callback $callback Callback function
*/
public function get($name) {
return isset($this->events[$name]) ? $this->events[$name] : null;
@@ -104,7 +105,7 @@ class Dispatcher {
/**
* Hooks a callback to an event.
*
- * @param string $event Event name
+ * @param string $name Event name
* @param string $type Filter type
* @param callback $callback Callback function
*/
@@ -116,8 +117,8 @@ class Dispatcher {
* Executes a chain of method filters.
*
* @param array $filters Chain of filters
- * @param reference $params Method parameters
- * @param reference $output Method output
+ * @param object $params Method parameters
+ * @param object $output Method output
*/
public function filter($filters, &$params, &$output) {
$args = array(&$params, &$output);
@@ -140,13 +141,15 @@ class Dispatcher {
self::invokeMethod($callback, $params) :
self::callFunction($callback, $params);
}
+ return null;
}
/**
* Calls a function.
*
* @param string $func Name of function to call
- * @param array $params Function parameters
+ * @param array $params Function parameters
+ * @return mixed Function results
*/
public static function callFunction($func, array &$params = array()) {
switch (count($params)) {
@@ -172,6 +175,7 @@ class Dispatcher {
*
* @param mixed $func Class method
* @param array $params Class method parameters
+ * @return mixed Function results
*/
public static function invokeMethod($func, array &$params = array()) {
list($class, $method) = $func;
@@ -180,20 +184,40 @@ class Dispatcher {
switch (count($params)) {
case 0:
- return ($instance) ? $class->$method() : $class::$method();
+ return ($instance) ?
+ $class->$method() :
+ $class::$method();
case 1:
- return ($instance) ? $class->$method($params[0]) : $class::$method($params[0]);
+ return ($instance) ?
+ $class->$method($params[0]) :
+ $class::$method($params[0]);
case 2:
- return ($instance) ? $class->$method($params[0], $params[1]) : $class::$method($params[0], $params[1]);
+ return ($instance) ?
+ $class->$method($params[0], $params[1]) :
+ $class::$method($params[0], $params[1]);
case 3:
- return ($instance) ? $class->$method($params[0], $params[1], $params[2]) : $class::$method($params[0], $params[1], $params[2]);
+ return ($instance) ?
+ $class->$method($params[0], $params[1], $params[2]) :
+ $class::$method($params[0], $params[1], $params[2]);
case 4:
- return ($instance) ? $class->$method($params[0], $params[1], $params[2], $params[3]) : $class::$method($params[0], $params[1], $params[2], $params[3]);
+ return ($instance) ?
+ $class->$method($params[0], $params[1], $params[2], $params[3]) :
+ $class::$method($params[0], $params[1], $params[2], $params[3]);
case 5:
- return ($instance) ? $class->$method($params[0], $params[1], $params[2], $params[3], $params[4]) : $class::$method($params[0], $params[1], $params[2], $params[3], $params[4]);
+ return ($instance) ?
+ $class->$method($params[0], $params[1], $params[2], $params[3], $params[4]) :
+ $class::$method($params[0], $params[1], $params[2], $params[3], $params[4]);
default:
return call_user_func_array($func, $params);
}
}
+
+ /**
+ * Resets the object to the initial state.
+ */
+ public function reset() {
+ $this->events = array();
+ $this->filters = array();
+ }
}
-?>
+?>
\ No newline at end of file
diff --git a/flight/core/Loader.php b/flight/core/Loader.php
index 32de4c5..7ecfd75 100644
--- a/flight/core/Loader.php
+++ b/flight/core/Loader.php
@@ -34,7 +34,7 @@ class Loader {
*
* @var array
*/
- protected $dirs = array('.', __DIR__);
+ protected $dirs = array();
/**
* Registers a class.
@@ -64,6 +64,7 @@ class Loader {
*
* @param string $name Method name
* @param bool $shared Shared instance
+ * @return object Class instance
*/
public function load($name, $shared = true) {
if (isset($this->classes[$name])) {
@@ -107,6 +108,7 @@ class Loader {
*
* @param string $class Class name
* @param array $params Class initialization parameters
+ * @return object Class instance
*/
public function newInstance($class, array $params = array()) {
switch (count($params)) {
@@ -123,7 +125,7 @@ class Loader {
case 5:
return new $class($params[0], $params[1], $params[2], $params[3], $params[4]);
default:
- $refClass = new ReflectionClass($class);
+ $refClass = new \ReflectionClass($class);
return $refClass->newInstanceArgs($params);
}
}
@@ -145,22 +147,24 @@ class Loader {
}
/**
- * Initializes the autoloader.
+ * Starts autoloader.
*/
- public function init() {
- static $initialized = false;
-
- if (!$initialized) {
- spl_autoload_register(array(__CLASS__, 'autoload'));
+ public function start() {
+ spl_autoload_register(array($this, 'autoload'));
+ }
- $initialized = true;
- }
+ /**
+ * Stops autoloading.
+ */
+ public function stop() {
+ spl_autoload_unregister(array($this, 'autoload'));
}
/**
* Autoloads classes.
*
* @param string $class Class name
+ * @throws \Exception If class not found
*/
public function autoload($class) {
$class_file = str_replace('\\', '/', str_replace('_', '/', $class)).'.php';
@@ -177,8 +181,17 @@ class Loader {
$loaders = spl_autoload_functions();
$loader = array_pop($loaders);
if (is_array($loader) && $loader[0] == __CLASS__ && $loader[1] == __FUNCTION__) {
- throw new Exception('Unable to load file: '.$class_file);
+ throw new \Exception('Unable to load file: '.$class_file);
}
}
+
+ /**
+ * Resets the object to the initial state.
+ */
+ public function reset() {
+ $this->classes = array();
+ $this->instances = array();
+ $this->dirs = array();
+ }
}
-?>
+?>
\ No newline at end of file
diff --git a/flight/net/Request.php b/flight/net/Request.php
index a8eca09..0db3b33 100644
--- a/flight/net/Request.php
+++ b/flight/net/Request.php
@@ -42,17 +42,17 @@ class Request {
// Default properties
if (empty($config)) {
$config = array(
- 'url' => $_SERVER['REQUEST_URI'],
- 'base' => str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME'])),
- 'method' => $_SERVER['REQUEST_METHOD'],
- 'referrer' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '',
+ 'url' => getenv('REQUEST_URI') ?: '/',
+ 'base' => str_replace('\\', '/', dirname(getenv('SCRIPT_NAME'))),
+ 'method' => getenv('REQUEST_METHOD') ?: 'GET',
+ 'referrer' => getenv('HTTP_REFERER') ?: '',
'ip' => $this->getIpAddress(),
- 'ajax' => isset($_SERVER['HTTP_X_REQUESTED_WITH']) ? ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') : false,
- 'scheme' => $_SERVER['SERVER_PROTOCOL'],
- 'user_agent' => $_SERVER['HTTP_USER_AGENT'],
+ 'ajax' => getenv('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest',
+ 'scheme' => getenv('SERVER_PROTOCOL') ?: 'HTTP/1.1',
+ 'user_agent' => getenv('HTTP_USER_AGENT') ?: '',
'body' => file_get_contents('php://input'),
- 'type' => isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : '',
- 'length' => isset($_SERVER['CONTENT_LENGTH']) ? $_SERVER['CONTENT_LENGTH'] : 0,
+ 'type' => getenv('CONTENT_TYPE') ?: '',
+ 'length' => getenv('CONTENT_LENGTH') ?: 0,
'query' => new Collection($_GET),
'data' => new Collection($_POST),
'cookies' => new Collection($_COOKIE),
@@ -73,7 +73,7 @@ class Request {
$this->$name = $value;
}
- if ($this->base != '/' && strpos($this->url, $this->base) === 0) {
+ if ($this->base != '/' && strlen($this->base) > 0 && strpos($this->url, $this->base) === 0) {
$this->url = substr($this->url, strlen($this->base));
}
@@ -129,6 +129,8 @@ class Request {
}
}
}
+
+ return '';
}
}
?>
diff --git a/flight/net/Response.php b/flight/net/Response.php
index df2c333..400757b 100644
--- a/flight/net/Response.php
+++ b/flight/net/Response.php
@@ -65,6 +65,8 @@ class Response {
* Sets the HTTP status of the response.
*
* @param int $code HTTP status code.
+ * @return object Self reference
+ * @throws \Exception If invalid status code
*/
public function status($code) {
if (array_key_exists($code, self::$codes)) {
@@ -82,7 +84,7 @@ class Response {
header(
sprintf(
'%s %d %s',
- (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1'),
+ getenv('SERVER_PROTOCOL') ?: 'HTTP/1.1',
$code,
self::$codes[$code]),
true,
@@ -100,8 +102,9 @@ class Response {
/**
* Adds a header to the response.
*
- * @param string|array $key Header name or array of names and values
+ * @param string|array $name Header name or array of names and values
* @param string $value Header value
+ * @return object Self reference
*/
public function header($name, $value = null) {
if (is_array($name)) {
@@ -120,6 +123,7 @@ class Response {
* Writes content to the response body.
*
* @param string $str Response content
+ * @return object Self reference
*/
public function write($str) {
$this->body .= $str;
@@ -129,6 +133,8 @@ class Response {
/**
* Clears the response.
+ *
+ * @return object Self reference
*/
public function clear() {
$this->headers = array();
@@ -142,6 +148,7 @@ class Response {
* Sets caching headers for the response.
*
* @param int|string $expires Expiration time
+ * @return object Self reference
*/
public function cache($expires) {
if ($expires === false) {
diff --git a/flight/net/Router.php b/flight/net/Router.php
index 014b0a9..d6e7519 100644
--- a/flight/net/Router.php
+++ b/flight/net/Router.php
@@ -75,6 +75,7 @@ class Router {
*
* @param string $pattern URL pattern
* @param string $url Requested URL
+ * @return boolean Match status
*/
public function match($pattern, $url) {
$ids = array();
@@ -116,8 +117,8 @@ class Router {
/**
* Routes the current request.
*
- * @param object $request Request object
- * @return callable Matched callback function
+ * @param Request $request Request object
+ * @return callable|boolean Matched callback function or false if not found
*/
public function route(Request $request) {
$this->matched = null;
diff --git a/flight/template/View.php b/flight/template/View.php
index df10078..d3d83f9 100644
--- a/flight/template/View.php
+++ b/flight/template/View.php
@@ -41,10 +41,10 @@ class View {
* Gets a template variable.
*
* @param string $key Key
- * @return mixed
+ * @return mixed Value
*/
public function get($key) {
- return $this->vars[$key];
+ return isset($this->vars[$key]) ? $this->vars[$key] : null;
}
/**
@@ -68,6 +68,7 @@ class View {
* Checks if a template variable is set.
*
* @param string $key Key
+ * @return boolean If key exists
*/
public function has($key) {
return isset($this->vars[$key]);
@@ -92,6 +93,7 @@ class View {
*
* @param string $file Template file
* @param array $data Template data
+ * @throws \Exception If template not found
*/
public function render($file, $data = null) {
$template = $this->getTemplate($file);
@@ -114,6 +116,7 @@ class View {
*
* @param string $file Template file
* @param array $data Template data
+ * @return string Output of template
*/
public function fetch($file, $data = null) {
ob_start();