Commit 14186a00 authored by Taylor Otwell's avatar Taylor Otwell

refactoring and bug fixes.

parent 2eeb6361
...@@ -59,6 +59,6 @@ return array( ...@@ -59,6 +59,6 @@ return array(
| |
*/ */
'logout' => function($id) {} 'logout' => function($user) {}
); );
\ No newline at end of file
...@@ -40,23 +40,15 @@ return array( ...@@ -40,23 +40,15 @@ return array(
| flexibility in Laravel to manage error logging as you see fit. | flexibility in Laravel to manage error logging as you see fit.
| |
| This function will be called when an error occurs in your application. | This function will be called when an error occurs in your application.
| You can log the error however you like. | You are free to handle the exception any way your heart desires.
| |
| The error "severity" passed to the method is a human-readable severity | The error "severity" passed to the method is a human-readable severity
| level such as "Parsing Error" or "Fatal Error". | level such as "Parsing Error" or "Fatal Error".
| |
| A simple logging system has been setup for you. By default, all errors
| will be logged to the storage/log.txt file.
|
*/ */
'handler' => function($exception, $severity, $message, $config) 'handler' => function($exception, $severity, $message, $config)
{ {
if ($config['log'])
{
call_user_func($config['logger'], $severity, $message);
}
if ($config['detail']) if ($config['detail'])
{ {
$data = compact('exception', 'severity', 'message'); $data = compact('exception', 'severity', 'message');
...@@ -69,8 +61,6 @@ return array( ...@@ -69,8 +61,6 @@ return array(
} }
$response->send(); $response->send();
exit(1);
}, },
/* /*
...@@ -81,18 +71,15 @@ return array( ...@@ -81,18 +71,15 @@ return array(
| Because of the various ways of managing error logging, you get complete | Because of the various ways of managing error logging, you get complete
| flexibility to manage error logging as you see fit. | flexibility to manage error logging as you see fit.
| |
| This function will be called when an error occurs in your application. | This function will be called when an error occurs in your application
| You can log the error however you like. | and error loggins is enabled. You can log the error however you like.
|
| The error "severity" passed to the method is a human-readable severity
| level such as "Parsing Error" or "Fatal Error".
| |
| A simple logging system has been setup for you. By default, all errors | A simple logging system has been setup for you. By default, all errors
| will be logged to the storage/log.txt file. | will be logged to the storage/log.txt file.
| |
*/ */
'logger' => function($severity, $message) 'logger' => function($exception, $severity, $message, $config)
{ {
File::append(STORAGE_PATH.'log.txt', date('Y-m-d H:i:s').' '.$severity.' - '.$message.PHP_EOL); File::append(STORAGE_PATH.'log.txt', date('Y-m-d H:i:s').' '.$severity.' - '.$message.PHP_EOL);
} }
......
...@@ -56,13 +56,13 @@ return array( ...@@ -56,13 +56,13 @@ return array(
'auth' => function() 'auth' => function()
{ {
return ( ! Auth::check()) ? Redirect::to('login') : null; if ( ! Auth::check()) return Redirect::to('login');
}, },
'csrf' => function() 'csrf' => function()
{ {
return (Input::get('csrf_token') !== Form::raw_token()) ? Response::error('500') : null; if (Input::get('csrf_token') !== Form::raw_token()) return Response::error('500');
}, },
); );
\ No newline at end of file
...@@ -26,8 +26,9 @@ define('EXT', '.php'); ...@@ -26,8 +26,9 @@ define('EXT', '.php');
define('BLADE_EXT', '.blade.php'); define('BLADE_EXT', '.blade.php');
/** /**
* Load the classes that can't be resolved through the auto-loader. These are typically classes * Load the classes that can't be resolved through the auto-loader.
* that are used by the auto-loader or configuration classes, and therefore cannot be auto-loaded. * These are typically classes that are used by the auto-loader or
* configuration classes, and therefore cannot be auto-loaded.
*/ */
require SYS_PATH.'facades'.EXT; require SYS_PATH.'facades'.EXT;
require SYS_PATH.'config'.EXT; require SYS_PATH.'config'.EXT;
...@@ -35,9 +36,10 @@ require SYS_PATH.'loader'.EXT; ...@@ -35,9 +36,10 @@ require SYS_PATH.'loader'.EXT;
require SYS_PATH.'arr'.EXT; require SYS_PATH.'arr'.EXT;
/** /**
* Bootstrap the application inversion of control (IoC) container. The container provides the * Bootstrap the application inversion of control (IoC) container.
* convenient resolution of objects and their dependencies, allowing for flexibility and * The container provides the convenient resolution of objects and
* testability within the framework and application. * their dependencies, allowing for flexibility and testability
* within the framework and application.
*/ */
require SYS_PATH.'container'.EXT; require SYS_PATH.'container'.EXT;
...@@ -46,25 +48,13 @@ $container = new Container(Config::get('container')); ...@@ -46,25 +48,13 @@ $container = new Container(Config::get('container'));
IoC::$container = $container; IoC::$container = $container;
/** /**
* Register the application auto-loader. The auto-loader is responsible for the lazy-loading * Register the application auto-loader. The auto-loader is responsible
* of all of the Laravel core classes, as well as the developer created libraries and models. * for the lazy-loading of all of the Laravel core classes, as well as
* the developer created libraries and models.
*/ */
spl_autoload_register(array($container->resolve('laravel.loader'), 'load')); spl_autoload_register(array($container->resolve('laravel.loader'), 'load'));
/** /**
* Define a few convenient global functions. * Define a few convenient global functions.
*/ */
function e($value) require 'functions'.EXT;
{ \ No newline at end of file
return HTML::entities($value);
}
function __($key, $replacements = array(), $language = null)
{
return Lang::line($key, $replacements, $language);
}
function fe($function)
{
return function_exists($function);
}
\ No newline at end of file
<?php namespace Laravel; <?php namespace Laravel;
/** /**
* Create the exception formatter closure. This function will format the exception * Create the exception formatter closure. This function will format
* message and severity for display and return the two formatted strings in an array. * the exception message and severity for display and return the two
* formatted strings in an array.
*/ */
$formatter = function($e) $formatter = function($e)
{ {
...@@ -32,20 +33,30 @@ $formatter = function($e) ...@@ -32,20 +33,30 @@ $formatter = function($e)
}; };
/** /**
* Create the exception handler function. All of the handlers registered with PHP * Create the exception handler function. All of the handlers
* will call this handler when an error occurs so the code stays D.R.Y. * registered with PHP will call this handler when an error
* occurs so the code stays D.R.Y.
*/ */
$handler = function($e) use ($formatter) $handler = function($e) use ($formatter)
{ {
list($severity, $message) = $formatter($e); list($severity, $message) = $formatter($e);
call_user_func(Config::get('error.handler'), $e, $severity, $message, Config::get('error')); $config = Config::get('error');
if ($config['log'])
{
call_user_func($config['logger'], $e, $severity, $message, $config);
}
call_user_func($config['handler'], $e, $severity, $message, $config);
exit(1);
}; };
/** /**
* Register the exception, error, and shutdown error handlers. These handlers will * Register the exception, error, and shutdown error handlers.
* catch all PHP exceptions and errors and pass the exceptions into the common * These handlers will catch all PHP exceptions and errors and
* Laravel error handler. * pass the exceptions into the common Laravel error handler.
*/ */
set_exception_handler(function($e) use ($handler) set_exception_handler(function($e) use ($handler)
{ {
...@@ -66,8 +77,9 @@ register_shutdown_function(function() use ($handler) ...@@ -66,8 +77,9 @@ register_shutdown_function(function() use ($handler)
}); });
/** /**
* Set the error reporting and display levels. Since the framework will be displaying * Set the error reporting and display levels. Since the framework
* the exception messages, we don't want PHP to display any error information. * will be displaying the exception messages, we don't want PHP to
* display any error information.
*/ */
error_reporting(-1); error_reporting(-1);
......
<?php
function fe($function)
{
return function_exists($function);
}
function e($value)
{
return HTML::entities($value);
}
function __($key, $replacements = array(), $language = null)
{
return Lang::line($key, $replacements, $language);
}
\ No newline at end of file
...@@ -44,25 +44,25 @@ class Connection { ...@@ -44,25 +44,25 @@ class Connection {
} }
/** /**
* Execute a SQL query against the connection and return a scalar result. * Execute a SQL query against the connection and return a single column result.
* *
* <code> * <code>
* // Get the total number of rows on a table * // Get the total number of rows on a table
* $count = DB::connection()->scalar('select count(*) from users'); * $count = DB::connection()->only('select count(*) from users');
* *
* // Get the sum of payment amounts from a table * // Get the sum of payment amounts from a table
* $sum = DB::connection()->scalar('select sum(amount) from payments') * $sum = DB::connection()->only('select sum(amount) from payments')
* </code> * </code>
* *
* @param string $sql * @param string $sql
* @param array $bindings * @param array $bindings
* @return float * @return mixed
*/ */
public function scalar($sql, $bindings = array()) public function only($sql, $bindings = array())
{ {
$result = (array) $this->first($sql, $bindings); $result = (array) $this->first($sql, $bindings);
return (float) reset($result); return reset($result);
} }
/** /**
......
...@@ -113,7 +113,7 @@ class Grammar { ...@@ -113,7 +113,7 @@ class Grammar {
// //
// The only exception to this rule are "raw" where clauses, which are simply // The only exception to this rule are "raw" where clauses, which are simply
// appended to the query as-is, without any further compiling. // appended to the query as-is, without any further compiling.
foreach ($wheres as $where) foreach ($query->wheres as $where)
{ {
$sql[] = ($where['type'] == 'raw') ? $where['sql'] : $where['connector'].' '.$this->{$where['type']}($where); $sql[] = ($where['type'] == 'raw') ? $where['sql'] : $where['connector'].' '.$this->{$where['type']}($where);
} }
......
...@@ -456,23 +456,16 @@ class Query { ...@@ -456,23 +456,16 @@ class Query {
} }
/** /**
* Get an aggregate value. * Execute the query as a SELECT statement and return a single column.
* *
* @param string $aggregate
* @param string $column * @param string $column
* @return mixed * @return mixed
*/ */
private function aggregate($aggregator, $column) public function only($column)
{ {
$this->aggregate = compact('aggregator', 'column'); $this->select(array($column));
$result = $this->connection->scalar($this->grammar->select($this), $this->bindings);
// Reset the aggregate so more queries can be performed using the same instance.
// This is helpful for getting aggregates and then getting actual results.
$this->aggregate = null;
return $result; return $this->connection->only($this->grammar->select($this), $this->bindings);
} }
/** /**
...@@ -487,16 +480,7 @@ class Query { ...@@ -487,16 +480,7 @@ class Query {
{ {
$columns = (array) $columns; $columns = (array) $columns;
$results = (count($results = $this->take(1)->get($columns)) > 0) ? $results[0] : null; return (count($results = $this->take(1)->get($columns)) > 0) ? $results[0] : null;
// If we have results and only a single column was selected from the database,
// we will simply return the value of that column for convenience.
if ( ! is_null($results) and count($columns) == 1 and $columns[0] !== '*')
{
return $results->{$columns[0]};
}
return $results;
} }
/** /**
...@@ -518,6 +502,26 @@ class Query { ...@@ -518,6 +502,26 @@ class Query {
return $results; return $results;
} }
/**
* Get an aggregate value.
*
* @param string $aggregate
* @param string $column
* @return mixed
*/
private function aggregate($aggregator, $column)
{
$this->aggregate = compact('aggregator', 'column');
$result = $this->connection->only($this->grammar->select($this), $this->bindings);
// Reset the aggregate so more queries can be performed using the same instance.
// This is helpful for getting aggregates and then getting actual results.
$this->aggregate = null;
return $result;
}
/** /**
* Insert an array of values into the database table. * Insert an array of values into the database table.
* *
......
...@@ -2,11 +2,12 @@ ...@@ -2,11 +2,12 @@
return array( return array(
/* /**
|-------------------------------------------------------------------------- * The validation error messages.
| Validation Error Messages *
|-------------------------------------------------------------------------- * These error messages will be used by the Validator class if no
*/ * other messages are provided by the developer.
*/
"accepted" => "The :attribute must be accepted.", "accepted" => "The :attribute must be accepted.",
"active_url" => "The :attribute does not exist.", "active_url" => "The :attribute does not exist.",
...@@ -29,12 +30,11 @@ return array( ...@@ -29,12 +30,11 @@ return array(
"unique" => "The :attribute has already been taken.", "unique" => "The :attribute has already been taken.",
"url" => "The :attribute format is invalid.", "url" => "The :attribute format is invalid.",
/* /**
|-------------------------------------------------------------------------- * The following words are appended to the "size" messages when
| The following words are appended to the "size" messages when applicable, * applicable, such as when validating string lengths or the
| such as when validating string lengths or the size of file uploads. * size of file uploads.
|-------------------------------------------------------------------------- */
*/
"characters" => "characters", "characters" => "characters",
"kilobytes" => "kilobytes", "kilobytes" => "kilobytes",
......
<?php namespace Laravel; <?php namespace Laravel;
/** /**
* Bootstrap the core framework components like the IoC container, configuration * Bootstrap the core framework components like the IoC container,
* class, and the class auto-loader. Once this file has run, the framework is * configuration class, and the class auto-loader. Once this file
* essentially ready for use. * has run, the framework is essentially ready for use.
*/ */
require 'bootstrap/core.php'; require 'bootstrap/core.php';
/** /**
* Register the framework error handling methods and set the error_reporting levels. * Register the framework error handling methods and set the
* This file will register handlers for exceptions, errors, and shutdown. * error_reporting levels. This file will register handlers
* for exceptions, errors, and shutdown.
*/ */
require SYS_PATH.'bootstrap/errors'.EXT; require SYS_PATH.'bootstrap/errors'.EXT;
...@@ -19,9 +20,9 @@ require SYS_PATH.'bootstrap/errors'.EXT; ...@@ -19,9 +20,9 @@ require SYS_PATH.'bootstrap/errors'.EXT;
date_default_timezone_set(Config::get('application.timezone')); date_default_timezone_set(Config::get('application.timezone'));
/** /**
* Load the session and session manager instance. The session payload will be * Load the session and session manager instance. The session
* registered in the IoC container as an instance so it can be retrieved easily * payload will be registered in the IoC container as an instance
* throughout the application. * so it can be retrieved easily throughout the application.
*/ */
if (Config::get('session.driver') !== '') if (Config::get('session.driver') !== '')
{ {
...@@ -31,11 +32,18 @@ if (Config::get('session.driver') !== '') ...@@ -31,11 +32,18 @@ if (Config::get('session.driver') !== '')
} }
/** /**
* Resolve the incoming request instance from the IoC container and route the * Resolve the incoming request instance from the IoC container
* request to the proper route in the application. If a route is found, the route * and route the request to the proper route in the application.
* will be called with the current requst instance. If no route is found, the 404 * If a route is found, the route will be called with the current
* response will be returned to the browser. * requst instance. If no route is found, the 404 response will
* be returned to the browser.
*/ */
require SYS_PATH.'request'.EXT;
require SYS_PATH.'routing/route'.EXT;
require SYS_PATH.'routing/router'.EXT;
require SYS_PATH.'routing/loader'.EXT;
require SYS_PATH.'routing/caller'.EXT;
$request = $container->core('request'); $request = $container->core('request');
list($method, $uri) = array($request->method(), $request->uri()); list($method, $uri) = array($request->method(), $request->uri());
...@@ -52,16 +60,18 @@ else ...@@ -52,16 +60,18 @@ else
} }
/** /**
* Stringify the response. We need to force the response to be stringed before * Stringify the response. We need to force the response to be
* closing the session, since the developer may be using the session within their * stringed before closing the session, since the developer may
* views, so we cannot age the session data until the view is rendered. * be using the session within their views, so we cannot age
* the session data until the view is rendered.
*/ */
$response->content = $response->render(); $response->content = $response->render();
/** /**
* Close the session and write the active payload to persistent storage. The input * Close the session and write the active payload to persistent
* for the current request is also flashed to the session so it will be available * storage. The input for the current request is also flashed
* for the next request via the Input::old method. * to the session so it will be available for the next request
* via the Input::old method.
*/ */
if (isset($session)) if (isset($session))
{ {
......
<?php namespace Laravel\Security; <?php namespace Laravel\Security;
use Laravel\Config; use Laravel\Config;
use Laravel\Session\Driver; use Laravel\Session\Payload;
class Auth { class Auth {
...@@ -13,9 +13,9 @@ class Auth { ...@@ -13,9 +13,9 @@ class Auth {
protected $user; protected $user;
/** /**
* The session driver instance. * The session payload instance.
* *
* @var Session\Driver * @var Session\Payload
*/ */
protected $session; protected $session;
...@@ -29,10 +29,10 @@ class Auth { ...@@ -29,10 +29,10 @@ class Auth {
/** /**
* Create a new authenticator instance. * Create a new authenticator instance.
* *
* @param Session\Driver $session * @param Session\Payload $session
* @return void * @return void
*/ */
public function __construct(Driver $session) public function __construct(Payload $session)
{ {
$this->session = $session; $this->session = $session;
} }
...@@ -105,7 +105,7 @@ class Auth { ...@@ -105,7 +105,7 @@ class Auth {
*/ */
public function logout() public function logout()
{ {
call_user_func(Config::get('auth.logout'), $this->user()->id); call_user_func(Config::get('auth.logout'), $this->user());
$this->user = null; $this->user = null;
......
...@@ -42,9 +42,10 @@ class APC implements Driver { ...@@ -42,9 +42,10 @@ class APC implements Driver {
* *
* @param array $session * @param array $session
* @param array $config * @param array $config
* @param bool $exists
* @return void * @return void
*/ */
public function save($session, $config) public function save($session, $config, $exists)
{ {
$this->apc->put($session['id'], $session, $config['lifetime']); $this->apc->put($session['id'], $session, $config['lifetime']);
} }
......
...@@ -56,9 +56,10 @@ class Cookie implements Driver { ...@@ -56,9 +56,10 @@ class Cookie implements Driver {
* *
* @param array $session * @param array $session
* @param array $config * @param array $config
* @param bool $exists
* @return void * @return void
*/ */
public function save($session, $config) public function save($session, $config, $exists)
{ {
extract($config); extract($config);
......
...@@ -50,17 +50,26 @@ class Database implements Driver, Sweeper { ...@@ -50,17 +50,26 @@ class Database implements Driver, Sweeper {
* *
* @param array $session * @param array $session
* @param array $config * @param array $config
* @param bool $exists
* @return void * @return void
*/ */
public function save($session, $config) public function save($session, $config, $exists)
{ {
$this->delete($session['id']); if ($exists)
{
$this->table()->insert(array( $this->table()->where('id', '=', $session['id'])->update(array(
'id' => $session['id'], 'last_activity' => $session['last_activity'],
'last_activity' => $session['last_activity'], 'data' => serialize($session['data']),
'data' => serialize($session['data']) ));
)); }
else
{
$this->table()->insert(array(
'id' => $session['id'],
'last_activity' => $session['last_activity'],
'data' => serialize($session['data'])
));
}
} }
/** /**
......
...@@ -17,9 +17,10 @@ interface Driver { ...@@ -17,9 +17,10 @@ interface Driver {
* *
* @param array $session * @param array $session
* @param array $config * @param array $config
* @param bool $exists
* @return void * @return void
*/ */
public function save($session, $config); public function save($session, $config, $exists);
/** /**
* Delete a session from storage by a given ID. * Delete a session from storage by a given ID.
......
...@@ -40,9 +40,10 @@ class File implements Driver, Sweeper { ...@@ -40,9 +40,10 @@ class File implements Driver, Sweeper {
* *
* @param array $session * @param array $session
* @param array $config * @param array $config
* @param bool $exists
* @return void * @return void
*/ */
public function save($session, $config) public function save($session, $config, $exists)
{ {
F::put($this->path.$session['id'], serialize($session), LOCK_EX); F::put($this->path.$session['id'], serialize($session), LOCK_EX);
} }
......
...@@ -38,9 +38,10 @@ class Memcached implements Driver { ...@@ -38,9 +38,10 @@ class Memcached implements Driver {
* *
* @param array $session * @param array $session
* @param array $config * @param array $config
* @param bool $exists
* @return void * @return void
*/ */
public function save($session, $config) public function save($session, $config, $exists)
{ {
$this->memcached->put($session['id'], $session, $config['lifetime']); $this->memcached->put($session['id'], $session, $config['lifetime']);
} }
......
...@@ -28,6 +28,13 @@ class Manager { ...@@ -28,6 +28,13 @@ class Manager {
*/ */
private $payload; private $payload;
/**
* Indicates if the session exists in persistent storage.
*
* @var bool
*/
private $exists = true;
/** /**
* Create a new session manager instance. * Create a new session manager instance.
* *
...@@ -56,6 +63,8 @@ class Manager { ...@@ -56,6 +63,8 @@ class Manager {
// string ID to uniquely identify it among the application's current users. // string ID to uniquely identify it among the application's current users.
if (is_null($session) or $this->expired($session, $config)) if (is_null($session) or $this->expired($session, $config))
{ {
$this->exists = false;
$session = array('id' => Str::random(40), 'data' => array()); $session = array('id' => Str::random(40), 'data' => array());
} }
...@@ -96,12 +105,19 @@ class Manager { ...@@ -96,12 +105,19 @@ class Manager {
*/ */
public function close(Payload $payload, $config, $flash = array()) public function close(Payload $payload, $config, $flash = array())
{ {
// If the session ID has been regenerated, we will need to inform the session driver
// that the session will need to be persisted to the data store as a new session.
if ($payload->regenerated)
{
$this->exists = false;
}
foreach ($flash as $key => $value) foreach ($flash as $key => $value)
{ {
$this->driver->flash($key, $value); $payload->flash($key, $value);
} }
$this->driver->save($payload->age(), $config); $this->driver->save($payload->age(), $config, $this->exists);
$this->transporter->put($payload->session['id'], $config); $this->transporter->put($payload->session['id'], $config);
......
...@@ -12,6 +12,13 @@ class Payload { ...@@ -12,6 +12,13 @@ class Payload {
*/ */
public $session = array(); public $session = array();
/**
* Indicates if the session ID has been regenerated.
*
* @var bool
*/
public $regenerated = false;
/** /**
* Create a new session container instance. * Create a new session container instance.
* *
...@@ -144,6 +151,8 @@ class Payload { ...@@ -144,6 +151,8 @@ class Payload {
public function regenerate() public function regenerate()
{ {
$this->session['id'] = Str::random(40); $this->session['id'] = Str::random(40);
$this->regenerated = true;
} }
/** /**
......
...@@ -535,7 +535,7 @@ class Validator { ...@@ -535,7 +535,7 @@ class Validator {
* @param string $language * @param string $language
* @return Validator * @return Validator
*/ */
public function lang($language) public function speaks($language)
{ {
$this->language = $language; $this->language = $language;
return $this; return $this;
......
...@@ -43,4 +43,6 @@ $public = __DIR__; ...@@ -43,4 +43,6 @@ $public = __DIR__;
| 3... 2... 1... Lift-off! | 3... 2... 1... Lift-off!
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
*/ */
require $laravel.'/laravel.php'; require $laravel.'/laravel.php';
\ No newline at end of file
echo number_format((microtime(true) - START_TIME) * 1000, 2);
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment