various refactorings.

This commit is contained in:
Taylor Otwell
2011-11-02 21:27:43 -05:00
parent 128984facb
commit 9caf239f6b
29 changed files with 275 additions and 150 deletions

View File

@@ -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)
{

View File

@@ -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;
};
/**

View File

@@ -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;
}
}
/**

View File

@@ -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;
}
}
/**

View File

@@ -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];

View File

@@ -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);

View File

@@ -2,20 +2,6 @@
class Connection {
/**
* The connection configuration array.
*
* @var array
*/
protected $config;
/**
* The query grammar instance for the connection.
*
* @var Grammars\Grammar
*/
protected $grammar;
/**
* The raw PDO connection instance.
*
@@ -30,6 +16,20 @@ class Connection {
*/
public $queries = array();
/**
* The connection configuration array.
*
* @var array
*/
protected $config;
/**
* The query grammar instance for the connection.
*
* @var Grammars\Grammar
*/
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]), '?'));
// 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);
}
$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;
}
}
/**

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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());
}
/**

View File

@@ -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());
}
}
/**

View File

@@ -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]);

View File

@@ -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.
*

View File

@@ -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]);

View File

@@ -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
*/

View File

@@ -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);

View File

@@ -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();

View File

@@ -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

View File

@@ -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';
return array_key_exists($attribute.'_confirmation', $this->attributes) and $value == $confirmation;
$confirmation = $this->attributes[$confirmed];
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];

View File

@@ -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.
*

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>