Browse Source

various refactorings.

Taylor Otwell 12 years ago
parent
commit
9caf239f6b

+ 2 - 2
application/composers.php

@@ -13,8 +13,8 @@ return array(
 	|
 	|		'home.index' => array('name' => 'home')
 	|
-	| Now, you can create an instance of that view using the expressive View::of
-	| dynamic method. Take a look at this example:
+	| Now, you can create an instance of that view using the very expressive
+	| View::of dynamic method. Take a look at this example:
 	|
 	|		return View::of_home();
 	|

+ 29 - 22
application/config/error.php

@@ -7,12 +7,12 @@ return array(
 	| Error Detail
 	|--------------------------------------------------------------------------
 	|
-	| Detailed error messages contain information about the file in which
-	| an error occurs, a stack trace, and a snapshot of the source code
-	| in which the error occured.
+	| Detailed error messages contain information about the file in which an
+	| error occurs, as well as a PHP stack trace containing the call stack.
 	|
 	| If your application is in production, consider turning off error details
-	| for enhanced security and user experience.
+	| for enhanced security and user experience. The error stack trace could
+	| contain sensitive information that should not be publicly visible.
 	|
 	*/
 
@@ -23,9 +23,9 @@ return array(
 	| Error Logging
 	|--------------------------------------------------------------------------
 	|
-	| Error Logging will use the "logger" function defined below to log error
-	| messages, which gives you complete freedom to determine how error
-	| messages are logged. Enjoy the flexibility.
+	| When error logging is enabled, the "logger" Closure defined below will
+	| be called for every error in your application. You are free to log the
+	| errors however you want. Enjoy the flexibility.
 	|
 	*/
 
@@ -37,23 +37,28 @@ return array(
 	|--------------------------------------------------------------------------
 	|
 	| Because of the various ways of managing error logging, you get complete
-	| flexibility in Laravel to manage error logging as you see fit.
+	| flexibility in Laravel to manage all error logging as you see fit.
 	|
 	| This function will be called when an error occurs in your application.
-	| You are free to handle the exception any way your heart desires.
-	|
-	| The error "severity" passed to the method is a human-readable severity
-	| level such as "Parsing Error" or "Fatal Error".
+	| You are free to handle the exception any way you want. The severity
+	| will be a human-readable severity level such as "Parsing Error".
 	|
 	*/
 
 	'handler' => function($exception, $severity, $message, $config)
 	{
-		$data = compact('exception', 'severity', 'message');
+		if ($config['detail'])
+		{
+			$data = compact('exception', 'severity', 'message');
 
-		$data['detailed'] = $config['detail'];
+			$response = Response::view('error.exception', $data)->status(500);
+		}
+		else
+		{
+			$response = Response::error('500');
+		}
 
-		Response::error('500', $data)->send();
+		$response->send();
 	},
 
 	/*
@@ -62,19 +67,21 @@ return array(
 	|--------------------------------------------------------------------------
 	|
 	| Because of the various ways of managing error logging, you get complete
-	| flexibility to manage error logging as you see fit.
-	|
-	| This function will be called when an error occurs in your application
-	| and error loggins is enabled. You can log the error however you like.
+	| flexibility to manage error logging as you see fit. This function will
+	| be called anytime an error occurs within your application and error
+	| logging is enabled. 
 	|
-	| A simple logging system has been setup for you. By default, all errors
-	| will be logged to the storage/log.txt file.
+	| You may log the error message however you like; however, a simple logging
+	| solution has been setup for you which will log all error messages to a
+	| single text file within the application storage directory.
 	|
 	*/
 
 	'logger' => function($exception, $severity, $message, $config)
 	{
-		File::append(STORAGE_PATH.'log.txt', date('Y-m-d H:i:s').' '.$severity.' - '.$message.PHP_EOL);
+		$message = date('Y-m-d H:i:s').' '.$severity.' - '.$message.PHP_EOL;
+
+		File::append(STORAGE_PATH.'log.txt', $message);
 	}
 
 );

+ 3 - 3
application/filters.php

@@ -50,19 +50,19 @@ return array(
 
 	'after' => function($response)
 	{
-		if (Config::get('session.driver') !== '') Input::flash();
+		Input::flash();
 	},
 
 
 	'auth' => function()
 	{
-		if ( ! Auth::check()) return Redirect::to_login();
+		if (Auth::guest()) return Redirect::to_login();
 	},
 
 
 	'csrf' => function()
 	{
-		if (Input::get('csrf_token') !== Form::raw_token()) return Response::error('500');
+		if (Request::forged()) return Response::error('500');
 	},
 
 );

+ 3 - 3
application/routes.php

@@ -10,9 +10,9 @@ return array(
 	| Here is the public API of your application. To add functionality to your
 	| application, you just add to the array of routes located in this file.
 	|
-	| Simply tell Laravel the HTTP verbs and URIs it should respond to. It is a
-	| breeze to create beautiful applications using the simplicity and elegance
-	| of Laravel's RESTful routing.
+	| Simply tell Laravel the HTTP verbs and URIs it should respond to. It's a
+	| piece of cake to create beautiful applications using the elegant RESTful
+	| routing available in Laravel.
 	|
 	| Let's respond to a simple GET request to http://example.com/hello:
 	|

+ 2 - 2
laravel/bootstrap/core.php

@@ -78,8 +78,8 @@ IoC::bootstrap();
 spl_autoload_register(array('Laravel\\Autoloader', 'load'));
 
 /**
- * Define a few convenient functions to make our lives as
- * developers a little more easy and enjoyable.
+ * Define a few global convenience functions to make our lives
+ * as Laravel PHP developers a little more easy and enjoyable.
  */
 function e($value)
 {

+ 2 - 9
laravel/bootstrap/errors.php

@@ -39,16 +39,9 @@ $severity = function($e)
 		E_STRICT           => 'Runtime Notice',
 	);
 
-	if (array_key_exists($e->getCode(), $levels))
-	{
-		$level = $levels[$e->getCode()];
-	}
-	else
-	{
-		$level = $e->getCode();
-	}
+	$code = $e->getCode();
 
-	return $level;
+	return (array_key_exists($code, $levels)) ? $levels[$code] : $code;
 };
 
 /**

+ 4 - 1
laravel/cache/drivers/apc.php

@@ -39,7 +39,10 @@ class APC extends Driver {
 	 */
 	protected function retrieve($key)
 	{
-		if ( ! is_null($cache = apc_fetch($this->key.$key))) return $cache;
+		if ( ! is_null($cache = apc_fetch($this->key.$key)))
+		{
+			return $cache;
+		}
 	}
 
 	/**

+ 4 - 1
laravel/cache/drivers/memcached.php

@@ -47,7 +47,10 @@ class Memcached extends Driver {
 	 */
 	protected function retrieve($key)
 	{
-		if (($cache = $this->memcache->get($this->key.$key)) !== false) return $cache;
+		if (($cache = $this->memcache->get($this->key.$key)) !== false)
+		{
+			return $cache;
+		}
 	}
 
 	/**

+ 2 - 2
laravel/cache/manager.php

@@ -32,12 +32,12 @@ class Manager {
 
 		if ( ! array_key_exists($driver, static::$drivers))
 		{
-			if ( ! IoC::container()->registered('laravel.cache.'.$driver))
+			if ( ! IoC::container()->registered("laravel.cache.{$driver}"))
 			{
 				throw new \Exception("Cache driver [$driver] is not supported.");
 			}
 
-			return static::$drivers[$driver] = IoC::container()->core('cache.'.$driver);
+			return static::$drivers[$driver] = IoC::container()->core("cache.{$driver}");
 		}
 
 		return static::$drivers[$driver];

+ 6 - 0
laravel/config/container.php

@@ -2,6 +2,12 @@
 
 return array(
 
+	'laravel.view.composers' => array('singleton' => true, 'resolver' => function()
+	{
+		return require APP_PATH.'composers'.EXT;
+	}),
+
+
 	'laravel.routing.router' => array('singleton' => true, 'resolver' => function($c)
 	{
 		return new Routing\Router($c->core('routing.loader'), CONTROLLER_PATH);

+ 35 - 29
laravel/database/connection.php

@@ -3,32 +3,32 @@
 class Connection {
 
 	/**
-	 * The connection configuration array.
+	 * The raw PDO connection instance.
 	 *
-	 * @var array
+	 * @var PDO
 	 */
-	protected $config;
+	public $pdo;
 
 	/**
-	 * The query grammar instance for the connection.
+	 * All of the queries that have been executed on the connection.
 	 *
-	 * @var Grammars\Grammar
+	 * @var array
 	 */
-	protected $grammar;
+	public $queries = array();
 
 	/**
-	 * The raw PDO connection instance.
+	 * The connection configuration array.
 	 *
-	 * @var PDO
+	 * @var array
 	 */
-	public $pdo;
+	protected $config;
 
 	/**
-	 * All of the queries that have been executed on the connection.
+	 * The query grammar instance for the connection.
 	 *
-	 * @var array
+	 * @var Grammars\Grammar
 	 */
-	public $queries = array();
+	protected $grammar;
 
 	/**
 	 * Create a new database connection instance.
@@ -112,7 +112,10 @@ class Connection {
 	 */
 	public function first($sql, $bindings = array())
 	{
-		if (count($results = $this->query($sql, $bindings)) > 0) return $results[0];
+		if (count($results = $this->query($sql, $bindings)) > 0)
+		{
+			return $results[0];
+		}
 	}
 
 	/**
@@ -144,7 +147,7 @@ class Connection {
 			if ($value instanceof Expression) unset($bindings[$key]);
 		}
 
-		$sql = $this->transform(trim($sql), $bindings);
+		$sql = $this->transform($sql, $bindings);
 
 		$this->queries[] = compact('sql', 'bindings');
 
@@ -164,23 +167,24 @@ class Connection {
 	 */
 	protected function transform($sql, $bindings)
 	{
-		if (strpos($sql, '(...)') === false) return $sql;
-
-		for ($i = 0; $i < count($bindings); $i++)
+		if (strpos($sql, '(...)') !== false)
 		{
-			// If the binding is an array, we can assume it is being used to fill
-			// a "where in" condition, so we will replace the next place-holder
-			// in the query with the correct number of parameters based on the
-			// number of elements in this binding.
-			if (is_array($bindings[$i]))
+			for ($i = 0; $i < count($bindings); $i++)
 			{
-				$parameters = implode(', ', array_fill(0, count($bindings[$i]), '?'));
-
-				$sql = preg_replace('~\(\.\.\.\)~', "({$parameters})", $sql, 1);
-			}
+				// If the binding is an array, we can assume it is being used to fill
+				// a "where in" condition, so we will replace the next place-holder
+				// in the query with the correct number of parameters based on the
+				// number of elements in this binding.
+				if (is_array($bindings[$i]))
+				{
+					$parameters = implode(', ', array_fill(0, count($bindings[$i]), '?'));
+
+					$sql = preg_replace('~\(\.\.\.\)~', "({$parameters})", $sql, 1);
+				}
+			}			
 		}
 
-		return $sql;
+		return trim($sql);
 	}
 
 	/**
@@ -204,8 +208,10 @@ class Connection {
 		{
 			return $statement->rowCount();
 		}
-
-		return $result;
+		else
+		{
+			return $result;
+		}
 	}
 
 	/**

+ 4 - 0
laravel/database/connectors/sqlite.php

@@ -30,6 +30,10 @@ class SQLite extends Connector {
 	{
 		$options = $this->options($config);
 
+		// SQLite provides supported for "in-memory" databases, which exist only for the
+		// lifetime of the request. Any given in-memory database may only have one PDO
+		// connection open to it at a time. Generally, these databases are use for
+		// testing and development purposes, not in production scenarios.
 		if ($config['database'] == ':memory:')
 		{
 			return new PDO('sqlite::memory:', null, null, $options);

+ 20 - 5
laravel/database/grammars/grammar.php

@@ -84,7 +84,9 @@ class Grammar {
 	 */
 	protected function aggregate(Query $query)
 	{
-		return 'SELECT '.$query->aggregate['aggregator'].'('.$this->wrap($query->aggregate['column']).')';
+		$column = $this->wrap($query->aggregate['column']);
+
+		return 'SELECT '.$query->aggregate['aggregator'].'('.$column.')';
 	}
 
 	/**
@@ -332,7 +334,7 @@ class Grammar {
 	 * @param  array   $columns
 	 * @return string
 	 */
-	public function columnize($columns)
+	final public function columnize($columns)
 	{
 		return implode(', ', array_map(array($this, 'wrap'), $columns));
 	}
@@ -349,16 +351,29 @@ class Grammar {
 	 */
 	public function wrap($value)
 	{
-		if (strpos(strtolower($value), ' as ') !== false) return $this->alias($value);
+		// If the value being wrapped contains a column alias, we need to wrap
+		// it a little differently since each segment must be wrapped and not
+		// the entire string.
+		if (strpos(strtolower($value), ' as ') !== false)
+		{
+			return $this->alias($value);
+		}
 
 		// Expressions should be injected into the query as raw strings, so we
 		// do not want to wrap them in any way. We will just return the string
-		// value from the expression.
+		// value from the expression to be included in the query.
 		if ($value instanceof Expression) return $value->get();
 
 		foreach (explode('.', $value) as $segment)
 		{
-			$wrapped[] = ($segment !== '*') ? $this->wrapper.$segment.$this->wrapper : $segment;
+			if ($segment === '*')
+			{
+				$wrapped[] = $segment;
+			}
+			else
+			{
+				$wrapped[] = $this->wrapper.$segment.$this->wrapper;
+			}
 		}
 
 		return implode('.', $wrapped);

+ 5 - 0
laravel/database/manager.php

@@ -55,6 +55,11 @@ class Manager {
 	 */
 	protected static function connect($config)
 	{
+		// We allow the developer to place a "connector" option in the database
+		// configuration, which should have a Closure value. If the connector
+		// is present, we will use the Closure to retrieve the PDO connection
+		// to the database. This allows the flexiblity to connect to database
+		// systems that are not officially supported by the the framework.
 		if (isset($config['connector']))
 		{
 			return call_user_func($config['connector'], $config);

+ 1 - 16
laravel/form.php

@@ -144,22 +144,7 @@ class Form {
 	 */
 	public static function token()
 	{
-		return static::input('hidden', 'csrf_token', static::raw_token());
-	}
-
-	/**
-	 * Get the CSRF token for the current session.
-	 *
-	 * @return string
-	 */
-	public static function raw_token()
-	{
-		if (Config::get('session.driver') == '')
-		{
-			throw new \Exception("A session driver must be specified before using CSRF tokens.");			
-		}
-
-		return Session::get('csrf_token');
+		return static::input('hidden', 'csrf_token', Session::token());
 	}
 
 	/**

+ 4 - 1
laravel/input.php

@@ -70,7 +70,10 @@ class Input {
 	 */
 	public static function flash()
 	{
-		Session::flash(Input::old_input, static::get());
+		if (Config::$items['session']['driver'] !== '')
+		{
+			Session::flash(Input::old_input, static::get());			
+		}
 	}
 
 	/**

+ 1 - 1
laravel/laravel.php

@@ -74,7 +74,7 @@ switch (Request::method())
 
 /**
  * The spoofed request method is removed from the input so it is
- * not unexpectedly included in Input::all() or Input::get().s
+ * not unexpectedly included in Input::all() or Input::get().
  */
 unset($input[Request::spoofer]);
 

+ 12 - 0
laravel/request.php

@@ -145,6 +145,18 @@ class Request {
 		return isset($_SERVER['HTTPS']) and strtolower($_SERVER['HTTPS']) !== 'off';
 	}
 
+	/**
+	 * Determine if the request has been forged.
+	 *
+	 * The session CSRF token will be compared to the CSRF token in the request input.
+	 *
+	 * @return bool
+	 */
+	public static function forged()
+	{
+		return Input::get('csrf_token') !== Session::token();
+	}
+
 	/**
 	 * Determine if the current request is an AJAX request.
 	 *

+ 3 - 1
laravel/response.php

@@ -258,7 +258,9 @@ class Response {
 	{
 		if ( ! isset($this->headers['Content-Type']))
 		{
-			$this->header('Content-Type', 'text/html; charset='.Config::$items['application']['encoding']);
+			$encoding = Config::$items['application']['encoding'];
+
+			$this->header('Content-Type', "text/html; charset={$encoding}");
 		}
 
 		header(Request::protocol().' '.$this->status.' '.$this->statuses[$this->status]);

+ 13 - 1
laravel/security/auth.php

@@ -29,7 +29,19 @@ class Auth {
 	const remember_key = 'laravel_remember';
 
 	/**
-	 * Determine if the current user of the application is authenticated.
+	 * Determine if the user of the application is not logged in.
+	 *
+	 * This method is the inverse of the "check" method.
+	 *
+	 * @return bool
+	 */
+	public static function guest()
+	{
+		return ! static::check();
+	}
+
+	/**
+	 * Determine if the user of the application is logged in.
 	 *
 	 * @return bool
 	 */

+ 7 - 5
laravel/security/hasher.php

@@ -43,17 +43,19 @@ class Hasher {
 	/**
 	 * Get a salt for use during Bcrypt hashing.
 	 *
-	 * Bcrypt expects salts to be 22 alpha-numeric characters including
-	 * dots and forward slashes. OpenSSL will be used if available and
-	 * the Str::random method will be used if it isn't.
-	 *
 	 * @return string
 	 */
 	protected static function salt()
 	{
+		// Bcrypt expects the salt to be 22 base64 encoded characters, including dots
+		// and slashes. We will get rid of the plus signs included in the base64 data
+		// and replace them with dots. OpenSSL will be used if available, since it is
+		// more random, otherwise we will fallback on Str::random.
 		if (function_exists('openssl_random_pseudo_bytes'))
 		{
-			return substr(strtr(base64_encode(openssl_random_pseudo_bytes(16)), '+', '.'), 0 , 22);
+			$bytes = openssl_random_pseudo_bytes(16);
+
+			return substr(strtr(base64_encode($bytes), '+', '.'), 0 , 22);
 		}
 
 		return substr(str_replace('+', '.', base64_encode(Str::random(40))), 0, 22);

+ 10 - 3
laravel/session.php

@@ -182,6 +182,16 @@ class Session {
 		static::$exists = false;
 	}
 
+	/**
+	 * Get the CSRF token that is stored in the session data.
+	 *
+	 * @return string
+	 */
+	public static function token()
+	{
+		return static::get('csrf_token');
+	}
+
 	/**
 	 * Store the session payload in storage.
 	 *
@@ -196,9 +206,6 @@ class Session {
 
 		$config = Config::$items['session'];
 
-		// To keep the session persistence code clean, session drivers are
-		// responsible for the storage of the session array to the various
-		// available persistent storage mechanisms.
 		$driver->save(static::$session, $config, static::$exists);
 
 		static::cookie();

+ 0 - 7
laravel/validation/messages.php

@@ -24,13 +24,6 @@ class Messages {
 	/**
 	 * Add a message to the collector.
 	 *
-	 * Duplicate messages will not be added.
-	 *
-	 * <code>
-	 *		// Add a message to the collector for the "email" attribute
-	 *		$messages->add('email', 'The e-mail address is invalid.');
-	 * </code>
-	 *
 	 * @param  string  $key
 	 * @param  string  $message
 	 * @return void

+ 14 - 7
laravel/validation/validator.php

@@ -2,8 +2,8 @@
 
 use Closure;
 use Laravel\Arr;
-use Laravel\IoC;
 use Laravel\Str;
+use Laravel\File;
 use Laravel\Lang;
 use Laravel\Input;
 use Laravel\Database\Manager as DB;
@@ -200,7 +200,9 @@ class Validator {
 	 */
 	protected function error($attribute, $rule, $parameters)
 	{
-		$message = $this->replace($this->message($attribute, $rule), $attribute, $rule, $parameters);
+		$message = $this->message($attribute, $rule);
+
+		$message = $this->replace($message, $attribute, $rule, $parameters);
 
 		$this->errors->add($attribute, $message);
 	}
@@ -226,9 +228,11 @@ class Validator {
 	 */
 	protected function validate_confirmed($attribute, $value)
 	{
-		$confirmation = $this->attributes[$attribute.'_confirmation'];
+		$confirmed = $attribute.'_confirmation';
+
+		$confirmation = $this->attributes[$confirmed];
 
-		return array_key_exists($attribute.'_confirmation', $this->attributes) and $value == $confirmation;
+		return array_key_exists($confirmed, $this->attributes) and $value == $confirmation;
 	}
 
 	/**
@@ -493,7 +497,10 @@ class Validator {
 	{
 		foreach ($parameters as $extension)
 		{
-			if (File::is($extension, $this->attributes[$attribute]['tmp_name'])) return true;
+			if (File::is($extension, $this->attributes[$attribute]['tmp_name']))
+			{
+				return true;
+			}
 		}
 
 		return false;
@@ -527,7 +534,7 @@ class Validator {
 		// If the rule being validated is a "size" rule and the attribute is not
 		// a number, we will need to gather the specific size message for the
 		// type of attribute being validated, either a file or a string.
-		elseif (in_array($rule, $this->size_rules) and ! $this->has_rule($attribute, $this->numeric_rules))
+		elseif (isset($this->size_rules[$rule]) and ! $this->has_rule($attribute, $this->numeric_rules))
 		{
 			$line = (array_key_exists($attribute, Input::file())) ? "file" : "string";
 
@@ -560,7 +567,7 @@ class Validator {
 		{
 			// Even though every size rule will not have a place-holder for min,
 			// max, and size, we will go ahead and make replacements for all of
-			// them just for convenience. Except for "between" every replacement
+			// them just for convenience. Except for "between", every replacement
 			// should be the first parameter.
 			$max = ($rule == 'between') ? $parameters[1] : $parameters[0];
 

+ 37 - 5
laravel/view.php

@@ -1,4 +1,7 @@
-<?php namespace Laravel; use Closure;
+<?php namespace Laravel;
+
+use Closure;
+use Laravel\Validation\Messages;
 
 class View {
 
@@ -42,6 +45,20 @@ class View {
 		$this->view = $view;
 		$this->data = $data;
 		$this->path = $this->path($view);
+
+		// If a session driver has been specified, we will bind an instance of
+		// the validation error message container to every view. If an errors
+		// instance exists in the session, we will use that instance.
+		//
+		// This makes the implementation of the Post/Redirect/Get pattern very
+		// convenient since each view can assume it has a message container.
+		if (Config::$items['session']['driver'] !== '')
+		{
+			$this->data['errors'] = Session::get('errors', function()
+			{
+				return new Messages;
+			});
+		}
 	}
 
 	/**
@@ -117,7 +134,10 @@ class View {
 	 */
 	public static function of($name, $data = array())
 	{
-		if ( ! is_null($view = static::name($name))) return static::make($view, $data);
+		if ( ! is_null($view = static::name($name)))
+		{
+			return static::make($view, $data);
+		}
 
 		throw new \Exception("Named view [$name] is not defined.");
 	}
@@ -134,11 +154,11 @@ class View {
 	 */
 	protected static function name($name)
 	{
-		if (is_null(static::$composers)) static::$composers = require APP_PATH.'composers'.EXT;
+		static::composers();
 
 		foreach (static::$composers as $key => $value)
 		{
-			if ($name === $value or (is_array($value) and $name === Arr::get($value, 'name')))
+			if ($name === $value or $name === Arr::get((array) $value, 'name'))
 			{
 				return $key;
 			}
@@ -153,7 +173,7 @@ class View {
 	 */
 	protected static function compose(View $view)
 	{
-		if (is_null(static::$composers)) static::$composers = require APP_PATH.'composers'.EXT;
+		static::composers();
 
 		if (isset(static::$composers[$view->view]))
 		{
@@ -164,6 +184,18 @@ class View {
 		}
 	}
 
+	/**
+	 * Load the view composers for the application.
+	 *
+	 * For better testing flexiblity, we load the composers from the IoC container.
+	 *
+	 * @return void
+	 */
+	protected static function composers()
+	{
+		static::$composers = IoC::container()->core('view.composers');
+	}
+
 	/**
 	 * Get the evaluated string content of the view.
 	 *

+ 3 - 2
laravel/views/error/404.php

@@ -22,8 +22,9 @@
 			<h3>What does this mean?</h3>
 
 			<p>
-				We couldn't find the page you requested on our servers. We're really sorry about that.
-				It's our fault, not yours. We'll work hard to get this page back online as soon as possible.
+				We couldn't find the page you requested on our servers. We're really sorry
+				about that. It's our fault, not yours. We'll work hard to get this page
+				back online as soon as possible.
 			</p>
 
 			<p>

+ 0 - 18
laravel/views/error/500.php

@@ -30,24 +30,6 @@
 			<p>
 				Perhaps you would like to go to our <?php echo HTML::link('/', 'home page'); ?>?
 			</p>
-
-			<?php if (isset($detailed) and $detailed): ?>
-				<h3>Error Message:</h3>
-
-				<pre style="word-wrap: break-word;"><?php echo $message; ?></pre>
-
-				<h3>Stack Trace:</h3>
-
-				<?php
-					$search = array(APP_PATH, SYS_PATH);
-
-					$replace = array('APP_PATH/', 'SYS_PATH/');
-
-					$trace = str_replace($search, $replace, $exception->getTraceAsString()); 
-				?>
-
-				<pre style="word-wrap: break-word;"><?php echo $trace; ?></pre>
-			<?php endif; ?>
 		</div>
 	</body>
 </html>

+ 41 - 0
laravel/views/error/exception.php

@@ -0,0 +1,41 @@
+<!doctype html>
+<html>
+	<head>
+		<meta charset="utf-8">
+
+		<title><?php echo $severity; ?></title>
+
+		<style>
+			<?php echo file_get_contents(PUBLIC_PATH.'css/laravel.css'); ?>
+		</style>
+
+		<style>
+			pre {
+				word-wrap: break-word;
+			}
+		</style>
+	</head>
+	<body>
+		<div id="main">
+			<img src="http://laravel.com/img/splash/error.png" class="marker">
+
+			<h1><?php echo $severity; ?></h1>
+
+			<h3>Error Message:</h3>
+
+			<pre><?php echo $message; ?></pre>
+
+			<h3>Stack Trace:</h3>
+
+			<?php
+				$search  = array(APP_PATH, SYS_PATH);
+
+				$replace = array('APP_PATH/', 'SYS_PATH/');
+
+				$trace   = str_replace($search, $replace, $exception->getTraceAsString());
+			?>
+
+			<pre style="word-wrap: break-word;"><?php echo $trace; ?></pre>
+		</div>
+	</body>
+</html>

+ 7 - 3
public/index.php

@@ -8,6 +8,8 @@
  * @link     http://laravel.com
  */
 
+define('LARAVEL_START', microtime(true));
+
 // --------------------------------------------------------------
 // The path to the application directory.
 // --------------------------------------------------------------
@@ -16,14 +18,16 @@ $application = '../application';
 // --------------------------------------------------------------
 // The path to the Laravel directory.
 // --------------------------------------------------------------
-$laravel     = '../laravel';
+$laravel = '../laravel';
 
 // --------------------------------------------------------------
 // The path to the public directory.
 // --------------------------------------------------------------
-$public      = __DIR__;
+$public = __DIR__;
 
 // --------------------------------------------------------------
 // Launch Laravel.
 // --------------------------------------------------------------
-require $laravel.'/laravel.php';
+require $laravel.'/laravel.php';
+
+echo (microtime(true) - LARAVEL_START) * 1000;