summaryrefslogtreecommitdiffstats
path: root/system
diff options
context:
space:
mode:
authorDracony <draconyster@gmail.com>2012-12-26 15:13:57 +0200
committerDracony <draconyster@gmail.com>2012-12-26 15:13:57 +0200
commitdb5bd4e2a84cfbbd662a7dbd9c6fc93edfb376d1 (patch)
tree77335fecf9b3e0995323df3c9887b593cb79aedf /system
downloadPHPixie-db5bd4e2a84cfbbd662a7dbd9c6fc93edfb376d1.zip
PHPixie-db5bd4e2a84cfbbd662a7dbd9c6fc93edfb376d1.tar.gz
PHPixie-db5bd4e2a84cfbbd662a7dbd9c6fc93edfb376d1.tar.bz2
Moving to github
Diffstat (limited to 'system')
-rw-r--r--system/bootstrap.php72
-rw-r--r--system/classes/config.php51
-rw-r--r--system/classes/controller.php84
-rw-r--r--system/classes/debug.php122
-rw-r--r--system/classes/error.php99
-rw-r--r--system/classes/misc.php61
-rw-r--r--system/classes/request.php112
-rw-r--r--system/classes/response.php69
-rw-r--r--system/classes/route.php126
-rw-r--r--system/classes/session.php57
-rw-r--r--system/classes/view.php95
-rw-r--r--system/views/debug.php126
-rw-r--r--system/views/error.php94
13 files changed, 1168 insertions, 0 deletions
diff --git a/system/bootstrap.php b/system/bootstrap.php
new file mode 100644
index 0000000..2561d4e
--- /dev/null
+++ b/system/bootstrap.php
@@ -0,0 +1,72 @@
+<?php
+
+/**
+ * Bootstraps the system
+ */
+class Bootstrap{
+
+ /**
+ * Autload function. Searches for the class file and includes it.
+ *
+ * @param unknown $class Class name
+ * @return void
+ * @access public
+ * @throws Exception If the class is not found
+ * @static
+ */
+ public static function autoload($class) {
+ $file = Misc::find_file('class', $class);
+ if ($file == false)
+ throw new Exception("Class {$class} not found.");
+ require_once($file);
+ }
+
+ /**
+ * Runs the application
+ *
+ * @return void
+ * @access public
+ * @static
+ */
+ public static function run() {
+
+ /**
+ * Application folder
+ */
+ define('APPDIR', ROOTDIR.'/application/');
+
+ /**
+ * Modules folder
+ */
+ define('MODDIR', ROOTDIR.'/modules/');
+
+ /**
+ * System folder
+ */
+ define('SYSDIR', ROOTDIR.'/system/');
+
+ /**
+ * Web folder
+ */
+ define('WEBDIR', ROOTDIR.'/web/');
+ /**
+ * Helper functions
+ */
+ require_once('classes/misc.php');
+
+ /**
+ * Configuration handler
+ */
+ require_once('classes/config.php');
+
+ /**
+ * Applications configuration file
+ */
+ require_once('application/config.php');
+
+ spl_autoload_register('Bootstrap::autoload');
+ Debug::init();
+ foreach(Config::get('routes') as $route)
+ Route::add($route[0],$route[1],$route[2]);
+ }
+} \ No newline at end of file
diff --git a/system/classes/config.php b/system/classes/config.php
new file mode 100644
index 0000000..b0550b4
--- /dev/null
+++ b/system/classes/config.php
@@ -0,0 +1,51 @@
+<?php
+
+/**
+ * Handles retrieving of the configuration options.
+ * You can add any configuration values to your /application/config.php file
+ * as associative array and get those values using the get() method.
+ */
+class Config {
+
+ /**
+ * Array of configuration options
+ * @var array
+ * @access public
+ * @static
+ */
+ public static $data=array();
+
+ /**
+ * Retrieves a configuration value. You can use a dot notation
+ * to access properties in nested arrays like this:
+ * <code>
+ * Config::get('database.default.user');
+ * </code>
+ *
+ * @param string $key Configuration key to retrieve.
+ * @param string $default Default value to return if the key is not found.
+ * @return mixed Configuration value
+ * @access public
+ * @throws Exception If default value is not specified and the key is not found
+ * @static
+ */
+ public static function get() {
+ $p = func_get_args();
+ $keys = explode('.', $p[0]);
+ $group=Config::$data;
+ for ($i = 0; $i < count($keys); $i++) {
+ if ($i == count($keys) - 1) {
+ if (isset($group[$keys[$i]]))
+ return $group[$keys[$i]];
+ break;
+ }
+ $group = Misc::arr($group, $keys[$i], null);
+ if (!is_array($group))
+ break;
+ }
+ if (isset($p[1]))
+ return $p[1];
+ throw new Exception("Configuration not set for {$p[0]}.");
+ }
+
+} \ No newline at end of file
diff --git a/system/classes/controller.php b/system/classes/controller.php
new file mode 100644
index 0000000..e543942
--- /dev/null
+++ b/system/classes/controller.php
@@ -0,0 +1,84 @@
+<?php
+
+/**
+ * Base Controller class. Controlers contain the logic of your website,
+ * each action representing a reply to a prticular request, e.g. a single page.
+ */
+class Controller {
+
+ /**
+ * Request for this controller. Holds all input data.
+ * @var Request
+ * @access public
+ */
+ public $request;
+
+ /**
+ * Response for this controller. It will be updated with headers and
+ * response body during controller execution
+ * @var Response
+ * @access public
+ */
+ public $response;
+
+ /**
+ * If set to False stops controller execution
+ * @var boolean
+ * @access public
+ */
+ public $execute=true;
+
+ /**
+ * This method is called before the action.
+ * You can override it if you need to,
+ * it doesn't do anything by default.
+ *
+ * @return void
+ * @access public
+ */
+ public function before() {}
+
+ /**
+ * This method is called after the action.
+ * You can override it if you need to,
+ * it doesn't do anything by default.
+ *
+ * @return void
+ * @access public
+ */
+ public function after() { }
+
+ /**
+ * Creates new Controller
+ *
+ * @return void
+ * @access public
+ */
+ public function __construct() {
+ $this->response=new Response;
+ }
+
+ /**
+ * Runs the appropriate action.
+ * It will axecute the before() method before the action
+ * and after() method after the action finishes.
+ *
+ * @param string $action Name of the action to execute.
+ * @return void
+ * @access public
+ * @throws Exception If the specified action doesn't exist
+ */
+ public function run($action) {
+ $action = 'action_'.$action;
+ if (!method_exists($this, $action))
+ throw new Exception("Method {$action} doesn't exist in ".get_class($this));
+ $this->execute=true;
+ $this->before();
+ if($this->execute)
+ $this->$action();
+ if($this->execute)
+ $this->after();
+ }
+
+
+} \ No newline at end of file
diff --git a/system/classes/debug.php b/system/classes/debug.php
new file mode 100644
index 0000000..85a8956
--- /dev/null
+++ b/system/classes/debug.php
@@ -0,0 +1,122 @@
+<?php
+
+/**
+ * Handles error reporting and debugging
+ */
+class Debug {
+
+ /**
+ * Caught exception
+ * @var Exception
+ * @access public
+ */
+ public $exception;
+
+ /**
+ * An array of logged items
+ * @var array
+ * @access public
+ * @static
+ */
+ public static $logged=array();
+
+ /**
+ * Displays the error page
+ *
+ * @return void
+ * @access public
+ */
+ public function render() {
+ ob_end_clean();
+ $view = View::get('debug');
+ $view->exception = $this->exception;
+ $view->log = Debug::$logged;
+ header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
+ header("Status: 404 Not Found");
+ echo $view->render();
+ }
+
+ /**
+ * Catches errors and exceptions and processes them
+ *
+ * @param Exception $exception Caught exception
+ * @return void
+ * @access public
+ * @static
+ */
+ public static function onError($exception) {
+ set_exception_handler(array('Debug', 'internalException'));
+ set_error_handler ( array('Debug', 'internalError'), E_ALL);
+ $error = new Debug();
+ $error->exception = $exception;
+ $error->render();
+ }
+
+ /**
+ * Converts PHP Errors to Exceptions
+ *
+ * @param string $errno Error number
+ * @param string $errstr Error message
+ * @param string $errfile File in which the error occured
+ * @param string $errline Line at which the error occured
+ * @return void
+ * @access public
+ * @throws ErrorException Throws converted exception to be immediately caught
+ * @static
+ */
+ public static function errorHandler($errno, $errstr, $errfile, $errline) {
+ throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
+ }
+
+ /**
+ * Handles exceptions that occured while inside the error handler. Prevents recursion.
+ *
+ * @param Exception $exception Caught exception
+ * @return void
+ * @access public
+ * @static
+ */
+ public static function internalException($exception) {
+ echo $exception->getMessage().' in '.$exception->getFile().' on line '.$exception->getLine();
+ }
+
+ /**
+ * Handles errors that occured while inside the error handler. Prevents recursion.
+ *
+ * @param string $errno Error number
+ * @param string $errstr Error message
+ * @param string $errfile File in which the error occured
+ * @param string $errline Line at which the error occured
+ * @return void
+ * @access public
+ * @static
+ */
+ public static function internalError($errno, $errstr, $errfile, $errline) {
+ echo $errstr.' in '.$errfile.' on line '.$errline;
+ }
+
+ /**
+ * Initializes the error handler
+ *
+ * @return void
+ * @access public
+ * @static
+ */
+ public static function init(){
+ set_exception_handler(array('Debug', 'onError'));
+ set_error_handler ( array('Debug', 'errorHandler'), E_ALL);
+ }
+
+ /**
+ * Adds an item to the log.
+ *
+ * @param mixed $val Item to be logged
+ * @return void
+ * @access public
+ * @static
+ */
+ public static function log($val){
+ array_unshift(Debug::$logged,$val);
+ }
+
+} \ No newline at end of file
diff --git a/system/classes/error.php b/system/classes/error.php
new file mode 100644
index 0000000..6f54784
--- /dev/null
+++ b/system/classes/error.php
@@ -0,0 +1,99 @@
+<?php
+
+/**
+ * Short description for class
+ */
+class Error {
+
+ /**
+ * Description for public
+ * @var unknown
+ * @access public
+ */
+ public $exception;
+
+ /**
+ * Short description for function
+ *
+ * @return void
+ * @access public
+ */
+ public function render() {
+ ob_end_clean();
+ $view = View::get('error');
+ $view->exception = $this->exception;
+ echo $view->render();
+ }
+
+ /**
+ * Short description for function
+ *
+ * @param unknown $exception Parameter description (if any) ...
+ * @return void
+ * @access public
+ * @static
+ */
+ public static function onError($exception) {
+ set_exception_handler(array('Error', 'internalException'));
+ set_error_handler ( array('Error', 'internalError'), E_ALL);
+ $error = new Error();
+ $error->exception = $exception;
+ $error->render();
+ }
+
+ /**
+ * Short description for function
+ *
+ * @param unknown $errno Parameter description (if any) ...
+ * @param unknown $errstr Parameter description (if any) ...
+ * @param unknown $errfile Parameter description (if any) ...
+ * @param unknown $errline Parameter description (if any) ...
+ * @return void
+ * @access public
+ * @throws ErrorException Exception description (if any) ...
+ * @static
+ */
+ public static function errorHandler($errno, $errstr, $errfile, $errline) {
+ throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
+ }
+
+ /**
+ * Short description for function
+ *
+ * @param mixed $exception Parameter description (if any) ...
+ * @return void
+ * @access public
+ * @static
+ */
+ public static function internalException($exception) {
+ echo $exception->getMessage().' in '.$exception->getFile().' on line '.$exception->getLine();
+ }
+
+ /**
+ * Short description for function
+ *
+ * @param unknown $errno Parameter description (if any) ...
+ * @param string $errstr Parameter description (if any) ...
+ * @param string $errfile Parameter description (if any) ...
+ * @param string $errline Parameter description (if any) ...
+ * @return void
+ * @access public
+ * @static
+ */
+ public static function internalError($errno, $errstr, $errfile, $errline) {
+ echo $errstr.' in '.$errfile.' on line '.$errline;
+ }
+
+ /**
+ * Short description for function
+ *
+ * @return void
+ * @access public
+ * @static
+ */
+ public static function init(){
+ set_exception_handler(array('Error', 'onError'));
+ set_error_handler ( array('Error', 'errorHandler'), E_ALL);
+ }
+
+} \ No newline at end of file
diff --git a/system/classes/misc.php b/system/classes/misc.php
new file mode 100644
index 0000000..ab04b11
--- /dev/null
+++ b/system/classes/misc.php
@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * Miscellaneous useful functions
+ */
+class Misc{
+
+ /**
+ * Retrieve value from array by key, with default value support.
+ *
+ * @param array $array Input array
+ * @param string $key Key to retrieve from the array
+ * @param mixed $default Default value to return if the key is not found
+ * @return mixed An array value if it was found or default value if it is not
+ * @access public
+ * @static
+ */
+ public static function arr($array,$key,$default=null){
+ if (isset($array[$key]))
+ return $array[$key];
+ return $default;
+ }
+
+ /**
+ * Find full path to either a class or view by name.
+ * It will search in the /system folder first, then the /application folder
+ * and then in all enabled modules.
+ *
+ * @param string $type Type of the file to find. Either 'class' or 'view'
+ * @param string $name Name of the file to find
+ * @return boolean Return Full path to the file or False if it is not found
+ * @access public
+ * @static
+ */
+ public static function find_file($type, $name) {
+ $folders = array(SYSDIR, APPDIR);
+ foreach(Config::get('modules') as $module)
+ $folders[] = MODDIR.$module.'/';
+
+ if($type=='class'){
+ $subfolder = 'classes/';
+ $dirs = array_reverse(explode('_', strtolower($name)));
+ $fname = array_pop($dirs);
+ $subfolder.=implode('/',$dirs).'/';
+ }
+
+ if ($type == 'view') {
+ $subfolder = 'views/';
+ $fname=$name;
+ }
+
+ foreach($folders as $folder) {
+ $file = $folder.$subfolder.$fname.'.php';
+
+ if (file_exists($file)) {
+ return($file);
+ }
+ }
+ return false;
+ }
+} \ No newline at end of file
diff --git a/system/classes/request.php b/system/classes/request.php
new file mode 100644
index 0000000..da7cade
--- /dev/null
+++ b/system/classes/request.php
@@ -0,0 +1,112 @@
+<?php
+
+/**
+ * Handles client request.
+ */
+class Request {
+
+ /**
+ * Stores POST data
+ * @var array
+ * @access private
+ */
+ private $_post;
+
+ /**
+ * Stores GET data
+ * @var array
+ * @access private
+ */
+ private $_get;
+
+ /**
+ * Current Route
+ * @var Route
+ * @access public
+ */
+ public $route;
+
+ /**
+ * Request method
+ * @var string
+ * @access public
+ */
+ public $method;
+
+ /**
+ * Retrieves a GET parameter
+ *
+ * @param string $key Parameter key
+ * @param mixed $default Default value
+ * @return mixed Returns a value if a key is specified,
+ * or an array of GET parameters if it isn't.
+ * @access public
+ */
+ public function get($key = null, $default = null) {
+ if ($key == null)
+ return $this->_get;
+ return Misc::arr($this->_get,$key,$default);
+ }
+
+ /**
+ * Retrieves a POST parameter
+ *
+ * @param string $key Parameter key
+ * @param mixed $default Default value
+ * @return mixed Returns a value if a key is specified,
+ * or an array of POST parameters if it isn't.
+ * @access public
+ */
+ public function post($key = null, $default = null) {
+ if ($key == null)
+ return $this->_post;
+ return Misc::arr($this->_post,$key,$default);
+ }
+
+ /**
+ * Retrieves a Route parameter
+ *
+ * @param string $key Parameter key
+ * @param mixed $default Default value
+ * @return mixed Returns a value if a key is specified,
+ * or an array of Route parameters if it isn't.
+ * @access public
+ */
+ public function param($key = null, $default = null) {
+ if ($key == null)
+ return $this->route->params;
+ return Misc::arr($this->route->params,$key,$default);
+ }
+
+ /**
+ * Initializes the routed Controller and executes specified action
+ *
+ * @return Response A Response object with the body and headers set
+ * @access public
+ */
+ public function execute() {
+ $controller=$this->param('controller').'_Controller';
+ $controller = new $controller;
+ $controller->request = $this;
+ $controller->run($this->param('action'));
+ return $controller->response;
+ }
+
+ /**
+ * Initializes the Request and process the URI into a Route
+ *
+ * @return object Request
+ * @access public
+ * @static
+ */
+ public static function create(){
+ $request = new Request();
+ $request->_post = $_POST;
+ $request->_get = $_GET;
+ $url_parts = parse_url($_SERVER['REQUEST_URI']);
+ $request->route = Route::match($url_parts['path']);
+ $request->method=$_SERVER['REQUEST_METHOD'];
+ return $request;
+ }
+
+} \ No newline at end of file
diff --git a/system/classes/response.php b/system/classes/response.php
new file mode 100644
index 0000000..da8a80a
--- /dev/null
+++ b/system/classes/response.php
@@ -0,0 +1,69 @@
+<?php
+
+/**
+ * Handles the response that is sent back to the client.
+ */
+class Response {
+
+ /**
+ * Headers for the response
+ * @var array
+ * @access public
+ */
+ public $headers = array(
+ 'Content-Type: text/html; charset=utf-8'
+ );
+
+ /**
+ * Response body
+ * @var string
+ * @access public
+ */
+ public $body;
+
+ /**
+ * Add header to the response
+ *
+ * @param string $header Header content
+ * @return void
+ * @access public
+ */
+ public function add_header($header){
+ $this->headers[]=$header;
+ }
+
+ /**
+ * Add redirection header
+ *
+ * @param string $url URL to redirect the client to
+ * @return void
+ * @access public
+ */
+ public function redirect($url){
+ $this->add_header("Location: $url");
+ }
+
+ /**
+ * Sends headers to the client
+ *
+ * @return Response Same Response object, for method chaining
+ * @access public
+ */
+ public function send_headers(){
+ foreach($this->headers as $header)
+ header($header);
+ return $this;
+ }
+
+ /**
+ * Send response body to the client
+ *
+ * @return object Same Response object, for method chaining
+ * @access public
+ */
+ public function send_body(){
+ echo $this->body;
+ return $this;
+ }
+
+} \ No newline at end of file
diff --git a/system/classes/route.php b/system/classes/route.php
new file mode 100644
index 0000000..62f53fe
--- /dev/null
+++ b/system/classes/route.php
@@ -0,0 +1,126 @@
+<?php
+
+/**
+ * Routing class to extract and parse request parameters from the URL
+ */
+class Route {
+
+ /**
+ * Name of the route.
+ * @var string
+ * @access public
+ */
+ public $name;
+
+ /**
+ * Extracted parameters
+ * @var array
+ * @access public
+ */
+ public $params=array();
+
+ /**
+ * Associative array of routes.
+ * @var array
+ * @access private
+ * @static
+ */
+ private static $rules=array();
+
+ /**
+ * Ads a route
+ *
+ * @param string $name Name of the route. Routes with the same name will override one another.
+ * @param mixed $rule Either an expression to match URI against or a function that will
+ * be passed the URI and must return either an associative array of
+ * extracted parameters (if it matches) or False.
+ * @param array $defaults An associated array of default values.
+ * @return void
+ * @access public
+ * @static
+ */
+ public static function add($name, $rule, $defaults = array()) {
+ Route::$rules[$name]=array(
+ 'rule'=>$rule,
+ 'defaults'=>$defaults
+ );
+ }
+
+ /**
+ * Gets route by name
+ *
+ * @param string $name Route name
+ * @return Route
+ * @access public
+ * @throws Exception If specified route doesn't exist
+ * @static
+ */
+ public static function get($name) {
+ if (!isset(Route::$rules[$name]))
+ throw new Exception("Route {$name} not found.");
+ $route = new Route();
+ $route-> name = $name;
+ return $route;
+ }
+
+ /**
+ * Matches the URI against available routes to find the correct one.
+ *
+ * @param string $uri Request URI
+ * @return Route
+ * @access public
+ * @throws Exception If no route matches the URI
+ * @throws Exception If route matched but no Controller was defined for it
+ * @throws Exception If route matched but no action was defined for it
+ * @static
+ */
+ public static function match($uri) {
+ $matched = false;
+ foreach(Route::$rules as $name=>$rule) {
+ $rule=$rule['rule'];
+ if (is_callable($rule)) {
+ if (($data = $rule($uri)) !== FALSE) {
+ $matched = $name;
+ break;
+ }
+ }else {
+ $pattern = is_array($rule)?$rule[0]:$rule;
+ $pattern = str_replace(')', ')?', $pattern);
+
+ $pattern=preg_replace_callback('/<.*?>/',
+ function($str) use ($rule){
+ $str=$str[0];
+ $regexp='[a-zA-Z0-9\-\.]+';
+ if(is_array($rule))
+ $regexp=Misc::arr($rule[1],str_replace(array('<','>'),'',$str),$regexp);
+ return '(?P'.$str.$regexp.')';
+ },$pattern);
+
+ preg_match('#^'.$pattern.'/?$#',$uri,$match);
+ if(!empty($match[0])){
+ $matched=$name;
+ $data=array();
+ foreach($match as $k=>$v)
+ if(!is_numeric($k))
+ $data[$k]=$v;
+ break;
+ }
+ }
+ }
+ if($matched==false)
+ throw new Exception('No route matched your request');
+ $rule=Route::$rules[$matched];
+
+ $params=array_merge($rule['defaults'],$data);
+
+ if(!isset($params['controller']))
+ throw new Exception("Route {$matched} matched, but no controller was defined for this route");
+ if(!isset($params['action']))
+ throw new Exception("Route {$matched} matched with controller {$params['controller']}, but no action was defined for this route");
+
+ $route=Route::get($matched);
+ $route->params=$params;
+ return $route;
+ }
+
+} \ No newline at end of file
diff --git a/system/classes/session.php b/system/classes/session.php
new file mode 100644
index 0000000..963aa9c
--- /dev/null
+++ b/system/classes/session.php
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * Simple class for accessing session data
+ */
+class Session{
+
+ /**
+ * Flag to check if the session was already intialized
+ * @var boolean
+ * @access private
+ * @static
+ */
+ private static $initialized=false;
+
+ /**
+ * Makes sure the session is initialized
+ *
+ * @return void
+ * @access private
+ * @static
+ */
+ private static function check(){
+ if(!Session::$initialized){
+ session_start();
+ Session::$initialized=true;
+ }
+ }
+
+ /**
+ * Gets a session variable
+ *
+ * @param string $key Variable name
+ * @param mixed $default Default value
+ * @return mixed Session value
+ * @access public
+ * @static
+ */
+ public static function get($key, $default = null) {
+ Session::check();
+ return Misc::arr($_SESSION,$key,$default);
+ }
+
+ /**
+ * Sets a session variable
+ *
+ * @param string $key Variable name
+ * @param mixed $val Variable value
+ * @return void
+ * @access public
+ * @static
+ */
+ public static function set($key, $val) {
+ Session::check();
+ $_SESSION[$key]=$val;
+ }
+} \ No newline at end of file
diff --git a/system/classes/view.php b/system/classes/view.php
new file mode 100644
index 0000000..5b7b6e7
--- /dev/null
+++ b/system/classes/view.php
@@ -0,0 +1,95 @@
+<?php
+
+/**
+ * Manages passing variables to templates and rendering them
+ */
+class View{
+
+ /**
+ * Full path to template file
+ * @var string
+ * @access private
+ */
+ private $path;
+
+ /**
+ * The name of the view.
+ * @var string
+ * @access public
+ */
+ public $name;
+
+ /**
+ * Stores all the variables passed to the view
+ * @var array
+ * @access private
+ */
+ private $_data = array();
+
+ /**
+ * Manages storing the data passed to the view as properties
+ *
+ * @param string $key Property name
+ * @param string $val Property value
+ * @return void
+ * @access public
+ */
+ public function __set($key, $val) {
+ $this->_data[$key]=$val;
+ }
+
+ /**
+ * Manages accessing passed data as properties
+ *
+ * @param string $key Property name
+ * @return mixed Property value
+ * @access public
+ * @throws Exception If the property is not found
+ */
+ public function __get($key){
+ if (isset($this->_data[$key]))
+ return $this->_data[$key];
+ throw new Exception("Value {$key} not set for view {$name}");
+ }
+
+ /**
+ * Renders the template, all dynamically set properties
+ * will be available inside the view file as variables.
+ * Example:
+ * <code>
+ * $view = View::get('frontpage');
+ * $view->title = "Page title";
+ * echo $view->render();
+ * </code>
+ *
+ * @return string Rendered template
+ * @access public
+ */
+ public function render() {
+ extract($this->_data);
+ ob_start();
+ include($this->path);
+ $out = ob_get_contents();
+ ob_end_clean();
+ return $out;
+ }
+
+ /**
+ * Constructs the view
+ *
+ * @param string $name The name of the template to use
+ * @return View
+ * @access public
+ * @throws Exception If specified template is not found
+ * @static
+ */
+ public static function get($name){
+ $view = new View();
+ $view->name = $name;
+ $file = Misc::find_file('view', $name);
+ if ($file == false)
+ throw new Exception("View {$name} not found.");
+ $view->path=$file;
+ return $view;
+ }
+} \ No newline at end of file
diff --git a/system/views/debug.php b/system/views/debug.php
new file mode 100644
index 0000000..0d78601
--- /dev/null
+++ b/system/views/debug.php
@@ -0,0 +1,126 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Error</title>
+ <style>
+ html{
+ width:100%;
+ min-height:100%;
+ font-family:'Verdana';
+ font-size:14px;
+ }
+ body{
+
+ min-height:100%;
+ background: #a90329; /* Old browsers */
+ background: -moz-radial-gradient(center, ellipse cover, #a90329 0%, #6d0019 100%); /* FF3.6+ */
+ background: -webkit-radial-gradient(center, ellipse cover, #a90329 0%,#6d0019 100%); /* Chrome10+,Safari5.1+ */
+ }
+ #content{
+ width:1000px;
+ margin:auto;
+ padding:10px 0px;
+ background:#eee;
+ }
+ .file{
+ font-weight:bold;
+ }
+ .block{
+ border-bottom:1px solid #000;
+ margin:10px;
+ }
+ .code{
+
+ padding:10px;
+ }
+ .highlight{
+ background:#efecd0;
+ }
+ #exception{
+ font-size:25px;
+ font-weight:bold;
+ padding:10px;
+ }
+ #debug{
+ border-bottom: 1px solid black;
+ margin: 10px;
+ }
+ #log{
+ font-size:15px;
+ font-weight:bold;
+ padding:5px;
+ }
+ .log{
+ padding:10px;
+ border-bottom: 1px solid black;
+ }
+ .log.odd{
+
+ }
+ pre{
+ margin:0px;
+ }
+ .thick{
+ border-width:2px;
+ }
+ </style>
+ </head>
+ <body>
+ <?php
+ $rawblocks=array_merge(array(array(
+ 'file'=>$exception->getFile(),
+ 'line'=>$exception->getLine()
+ )), $exception->getTrace());
+ $blocks = array();
+ foreach($rawblocks as $block){
+ if(!isset($block['file']))
+ continue;
+ //avoid duplicates
+ if(count($blocks)>0){
+ $last=$blocks[count($blocks)-1];
+ if($block['file']==$last['file'] && $block['line']==$last['line'])
+ continue;
+ }
+ $blocks[]=$block;
+ }
+
+
+ ?>
+ <div id="content">
+ <div id="exception"><?php echo str_replace("\n",'<br/>',$exception->getMessage()); ?></div>
+ <div id="blocks">
+ <?php foreach($blocks as $bkey=>$block): ?>
+ <div class="block <?php echo (!empty($log)&&$bkey==0)?'thick':''; ?>">
+ <div class="file"><?php echo $block['file'];?></div>
+ <div class="code">
+ <?php
+ $line=$block['line']-1;
+ $code = explode("\n", file_get_contents($block['file']));
+ $start = $line - 3;
+ if ($start < 0) $start = 0;
+ $end = $line + 3;
+ if($end>=count($code)) $end=count($code)-1;
+ $code=array_slice($code,$start,$end-$start,true);
+ ?>
+
+ <?php foreach($code as $n=>$text):?>
+ <pre class="line <?php echo $n==$line?'highlight':''; ?>"><?php echo ($n+1).' '.htmlspecialchars($text); ?></pre>
+ <?php endforeach;?>
+ </div>
+ </div>
+ <?php if($bkey==0&&!empty($log)):?>
+ <div id="debug">
+ <div id="log">Logged values:</div>
+ <?php foreach($log as $key=>$val):?>
+ <div class="log <?php echo $key%2?'odd':''; ?>">
+ <pre><?php var_export($val);?></pre>
+ </div>
+ <?php endforeach;?>
+ </div>
+ <div id="log">Call stack:</div>
+ <?php endif;?>
+ <?php endforeach;?>
+ </div>
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/system/views/error.php b/system/views/error.php
new file mode 100644
index 0000000..6204f35
--- /dev/null
+++ b/system/views/error.php
@@ -0,0 +1,94 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Error</title>
+ <style>
+ html{
+ width:100%;
+ min-height:100%;
+ font-family:'Verdana';
+ font-size:14px;
+ }
+ body{
+
+ min-height:100%;
+ background: #a90329; /* Old browsers */
+ background: -moz-radial-gradient(center, ellipse cover, #a90329 0%, #6d0019 100%); /* FF3.6+ */
+ background: -webkit-radial-gradient(center, ellipse cover, #a90329 0%,#6d0019 100%); /* Chrome10+,Safari5.1+ */
+ }
+ #content{
+ width:1000px;
+ margin:auto;
+ padding:10px 0px;
+ background:#eee;
+ }
+ .file{
+ font-weight:bold;
+ }
+ .block{
+ border-bottom:1px solid #000;
+ margin:10px;
+ }
+ .code{
+
+ padding:10px;
+ }
+ .highlight{
+ background:#efecd0;
+ }
+ #exception{
+ font-size:25px;
+ font-weight:bold;
+ padding:10px;
+ }
+
+ </style>
+ </head>
+ <body>
+ <?php
+ $rawblocks=array_merge(array(array(
+ 'file'=>$exception->getFile(),
+ 'line'=>$exception->getLine()
+ )), $exception->getTrace());
+ $blocks = array();
+ foreach($rawblocks as $block){
+ if(!isset($block['file']))
+ continue;
+ //avoid duplicates
+ if(count($blocks)>0){
+ $last=$blocks[count($blocks)-1];
+ if($block['file']==$last['file'] && $block['line']==$last['line'])
+ continue;
+ }
+ $blocks[]=$block;
+ }
+
+
+ ?>
+ <div id="content">
+ <div id="exception"><?php echo str_replace("\n",'<br/>',$exception->getMessage()); ?></div>
+ <div id="blocks">
+ <?php foreach($blocks as $block): ?>
+ <div class="block">
+ <div class="file"><?php echo $block['file'];?></div>
+ <div class="code">
+ <?php
+ $line=$block['line']-1;
+ $code = explode("\n", file_get_contents($block['file']));
+ $start = $line - 3;
+ if ($start < 0) $start = 0;
+ $end = $line + 3;
+ if($end>=count($code)) $end=count($code)-1;
+ $code=array_slice($code,$start,$end-$start,true);
+ ?>
+
+ <?php foreach($code as $n=>$text):?>
+ <pre class="line <?php echo $n==$line?'highlight':''; ?>"><?php echo ($n+1).' '.htmlspecialchars($text); ?></pre>
+ <?php endforeach;?>
+ </div>
+ </div>
+ <?php endforeach;?>
+ </div>
+ </div>
+ </body>
+</html> \ No newline at end of file