diff --git a/application/config/application.php b/application/config/application.php
index d91711c2..1aa3abd7 100644
--- a/application/config/application.php
+++ b/application/config/application.php
@@ -131,7 +131,6 @@
*/
'aliases' => array(
- 'Arr' => 'Laravel\\Arr',
'Asset' => 'Laravel\\Asset',
'Auth' => 'Laravel\\Security\\Auth',
'Benchmark' => 'Laravel\\Benchmark',
@@ -150,12 +149,9 @@
'Input' => 'Laravel\\Input',
'IoC' => 'Laravel\\IoC',
'Lang' => 'Laravel\\Lang',
- 'Loader' => 'Laravel\\Loader',
- 'Messages' => 'Laravel\\Validation\\Messages',
- 'Package' => 'Laravel\\Facades\\Package',
- 'URI' => 'Laravel\\URI',
'URL' => 'Laravel\\URL',
'Redirect' => 'Laravel\\Redirect',
+ 'Redis' => 'Laravel\\Redis',
'Request' => 'Laravel\\Request',
'Response' => 'Laravel\\Response',
'Session' => 'Laravel\\Session\\Manager',
diff --git a/application/config/cache.php b/application/config/cache.php
index c0435988..abd07eec 100644
--- a/application/config/cache.php
+++ b/application/config/cache.php
@@ -12,7 +12,7 @@
| Caching can be used to increase the performance of your application
| by storing commonly accessed data in memory or in a file.
|
- | Supported Drivers: 'file', 'memcached', 'apc'.
+ | Supported Drivers: 'file', 'memcached', 'apc', 'redis'.
|
*/
diff --git a/application/config/database.php b/application/config/database.php
index d8109118..ebcac4d9 100644
--- a/application/config/database.php
+++ b/application/config/database.php
@@ -70,4 +70,25 @@
),
+ /*
+ |--------------------------------------------------------------------------
+ | Redis Databases
+ |--------------------------------------------------------------------------
+ |
+ | Redis is an open source, fast, and advanced key-value store. However, it
+ | provides a richer set of commands than a typical key-value store such as
+ | APC or memcached.
+ |
+ | Here you may specify the hosts and ports for your Redis databases.
+ |
+ | For more information regarding Redis, check out: http://redis.io
+ |
+ */
+
+ 'redis' => array(
+
+ 'default' => array('host' => '127.0.0.1', 'port' => 6379),
+
+ ),
+
);
\ No newline at end of file
diff --git a/application/config/session.php b/application/config/session.php
index 58e1cf88..abd74fa8 100644
--- a/application/config/session.php
+++ b/application/config/session.php
@@ -12,7 +12,7 @@
| Since HTTP is stateless, sessions are used to maintain "state" across
| multiple requests from the same user of your application.
|
- | Supported Drivers: 'cookie', 'file', 'database', 'memcached', 'apc'.
+ | Supported Drivers: 'cookie', 'file', 'database', 'memcached', 'apc', 'redis'.
|
*/
diff --git a/laravel/bootstrap/constants.php b/laravel/bootstrap/constants.php
index 475804bf..6b7bdefc 100644
--- a/laravel/bootstrap/constants.php
+++ b/laravel/bootstrap/constants.php
@@ -5,7 +5,7 @@
define('EXT', '.php');
/**
- * Define a function that registers an array of constants if they
+ * Define a function that registers an array of constants if they haven't
* haven't already been registered. This allows the constants to
* be changed from their default values when unit testing.
*/
diff --git a/laravel/bootstrap/errors.php b/laravel/bootstrap/errors.php
index 488c8e6a..f61b406d 100644
--- a/laravel/bootstrap/errors.php
+++ b/laravel/bootstrap/errors.php
@@ -101,7 +101,6 @@
{
if ( ! is_null($error = error_get_last()))
{
- die('here');
extract($error, EXTR_SKIP);
$handler(new \ErrorException($message, $type, 0, $file, $line));
diff --git a/laravel/cache/drivers/file.php b/laravel/cache/drivers/file.php
index 0be234a5..6bf7c6e0 100644
--- a/laravel/cache/drivers/file.php
+++ b/laravel/cache/drivers/file.php
@@ -68,7 +68,9 @@ protected function retrieve($key)
*/
public function put($key, $value, $minutes)
{
- file_put_contents($this->path.$key, (time() + ($minutes * 60)).serialize($value), LOCK_EX);
+ $value = (time() + ($minutes * 60)).serialize($value);
+
+ file_put_contents($this->path.$key, $value, LOCK_EX);
}
/**
diff --git a/laravel/cache/drivers/redis.php b/laravel/cache/drivers/redis.php
new file mode 100644
index 00000000..cc3c621c
--- /dev/null
+++ b/laravel/cache/drivers/redis.php
@@ -0,0 +1,79 @@
+redis = $redis;
+ }
+
+ /**
+ * Determine if an item exists in the cache.
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function has($key)
+ {
+ return ( ! is_null($this->redis->get($key)));
+ }
+
+ /**
+ * Retrieve an item from the cache driver.
+ *
+ * @param string $key
+ * @return mixed
+ */
+ protected function retrieve($key)
+ {
+ if ( ! is_null($cache = $this->redis->get($key)))
+ {
+ return unserialize($cache);
+ }
+ }
+
+ /**
+ * Write an item to the cache for a given number of minutes.
+ *
+ *
+ * // Put an item in the cache for 15 minutes
+ * Cache::put('name', 'Taylor', 15);
+ *
+ *
+ * @param string $key
+ * @param mixed $value
+ * @param int $minutes
+ * @return void
+ */
+ public function put($key, $value, $minutes)
+ {
+ $this->redis->set($key, serialize($value));
+
+ $this->redis->expire($key, $minutes * 60);
+ }
+
+ /**
+ * Delete an item from the cache.
+ *
+ * @param string $key
+ * @return void
+ */
+ public function forget($key)
+ {
+ $this->redis->del($key);
+ }
+
+}
\ No newline at end of file
diff --git a/laravel/config/container.php b/laravel/config/container.php
index 72dbc35e..a0284e0e 100644
--- a/laravel/config/container.php
+++ b/laravel/config/container.php
@@ -71,11 +71,9 @@
| Laravel Caching Components
|--------------------------------------------------------------------------
|
- | The following components are used by the wonderfully, simple Laravel
- | caching system. Each driver is resolved through the container.
- |
- | New cache drivers may be added to the framework by simply registering
- | them into the container.
+ | The following components are used by the wonderfully simple Laravel cache
+ | system. Each driver is resolved through the container, so new drivers may
+ | be added by simply registering them in the container.
|
*/
@@ -91,6 +89,12 @@
}),
+ 'laravel.cache.redis' => array('resolver' => function()
+ {
+ return new Cache\Drivers\Redis(Redis::db());
+ }),
+
+
'laravel.cache.memcached' => array('resolver' => function($c)
{
return new Cache\Drivers\Memcached($c->core('cache.memcache.connection'), Config::get('cache.key'));
@@ -130,10 +134,6 @@
| from the session driver, as well as examining the payload validitiy
| and things like the CSRF token.
|
- | Like the caching components, each session driver is resolved via the
- | container and new drivers may be added by registering them into the
- | container. Several session drivers are "driven" by the cache drivers.
- |
*/
'laravel.session.transporter' => array('resolver' => function($c)
@@ -166,6 +166,12 @@
}),
+ 'laravel.session.redis' => array('resolver' => function($c)
+ {
+ return new Session\Drivers\Redis($c->core('cache.redis'));
+ }),
+
+
'laravel.session.memcached' => array('resolver' => function($c)
{
return new Session\Drivers\Memcached($c->core('cache.memcached'));
diff --git a/laravel/database/manager.php b/laravel/database/manager.php
index f50f3411..a4a12329 100644
--- a/laravel/database/manager.php
+++ b/laravel/database/manager.php
@@ -17,8 +17,6 @@ class Manager {
*
* If no database name is specified, the default connection will be returned.
*
- * Note: Database connections are managed as singletons.
- *
*
* // Get the default database connection for the application
* $connection = DB::connection();
diff --git a/laravel/database/query.php b/laravel/database/query.php
index 3fedcaf4..c05ca07e 100644
--- a/laravel/database/query.php
+++ b/laravel/database/query.php
@@ -611,7 +611,9 @@ public function decrement($column, $amount = 1)
*/
protected function adjust($column, $amount, $operator)
{
- return $this->update(array($column => Manager::raw($this->grammar->wrap($column).$operator.$amount)));
+ $value = Manager::raw($this->grammar->wrap($column).$operator.$amount);
+
+ return $this->update(array($column => $value));
}
/**
diff --git a/laravel/laravel.php b/laravel/laravel.php
index 7823d9be..289a173d 100644
--- a/laravel/laravel.php
+++ b/laravel/laravel.php
@@ -91,9 +91,9 @@
*/
Routing\Filter::register(require APP_PATH.'filters'.EXT);
-list($uri, $method) = array(Request::uri()->get(), Request::method());
+list($uri, $method, $format) = array(Request::uri()->get(), Request::method(), Request::format());
-$route = IoC::container()->core('routing.router')->route($method, $uri);
+$route = IoC::container()->core('routing.router')->route($method, $uri, $format);
if ( ! is_null($route))
{
diff --git a/laravel/redis.php b/laravel/redis.php
index 749bfafb..d0c25d74 100644
--- a/laravel/redis.php
+++ b/laravel/redis.php
@@ -3,92 +3,87 @@
class Redis {
/**
- * The name of the Redis connection.
+ * The address for the Redis host.
*
* @var string
*/
- public $name;
+ protected $host;
/**
- * The configuration array for the Redis connection.
+ * The port on which Redis can be accessed on the host.
*
- * @var array
+ * @var int
*/
- public $config = array();
+ protected $port;
/**
* The connection to the Redis database.
*
* @var resource
*/
- protected static $connection;
+ protected $connection;
+
+ /**
+ * The active Redis database instances.
+ *
+ * @var array
+ */
+ protected static $databases = array();
/**
* Create a new Redis connection instance.
*
- * @param string $name
- * @param array $config
+ * @param string $host
+ * @param string $port
* @return void
*/
- public function __construct($name, $config)
+ public function __construct($host, $port)
{
- $this->name = $name;
- $this->config = $config;
+ $this->host = $host;
+ $this->port = $port;
}
/**
- * Create a new Redis connection instance.
+ * Get a Redis database connection instance.
*
- * @param string $connection
- * @param array $config
+ * The given name should correspond to a Redis database in the configuration file.
+ *
+ *
+ * // Get the default Redis database instance
+ * $redis = Redis::db();
+ *
+ * // Get a specified Redis database instance
+ * $reids = Redis::db('redis_2');
+ *
+ *
+ * @param string $name
* @return Redis
*/
- public static function make($name, $config)
+ public static function db($name = 'default')
{
- return new static($name, $config);
- }
-
- /**
- * Create a new Redis connection instance.
- *
- * The Redis connection is managed as a singleton, so if the connection has
- * already been established, that same connection instance will be returned
- * on subsequent requests for the connection.
- *
- * @param string $connection
- * @return Redis
- */
- public static function connection()
- {
- if (is_null(static::$connection))
+ if (is_null(static::$databases[$name]))
{
- static::$connection = static::make($name, Config::get('database.redis'))->connect();
+ if (is_null($config = Config::get("database.redis.{$name}")))
+ {
+ throw new \Exception("Redis database [$name] is not defined.");
+ }
+
+ static::$databases[$name] = new static($config['host'], $config['port']);
}
- return static::$connection;
+ return static::$databases[$name];
}
/**
- * Connect to the Redis database.
+ * Execute a command against the Redis database.
*
- * The Redis instance itself will be returned by the method.
+ *
+ * // Execute the GET command for the "name" key
+ * $name = Redis::db()->run('get', array('name'));
*
- * @return Redis
- */
- public function connect()
- {
- static::$connection = @fsockopen($this->config['host'], $this->config['port'], $error, $message);
-
- if (static::$connection === false)
- {
- throw new \Exception("Error establishing Redis connection [{$this->name}]: {$error} - {$message}");
- }
-
- return $this;
- }
-
- /**
- * Execute a command agaisnt the Redis database.
+ * // Execute the LRANGE command for the "list" key
+ * $list = Redis::db()->run('lrange', array(0, 5));
+ *
*
* @param string $method
* @param array $parameters
@@ -96,21 +91,74 @@ public function connect()
*/
public function run($method, $parameters)
{
- fwrite(static::$connection, $this->command($method, $parameters));
+ fwrite($this->connect(), $this->command($method, (array) $parameters));
- $reply = trim(fgets(static::$connection, 512));
+ $ersponse = trim(fgets($this->connection, 512));
+
+ switch (substr($ersponse, 0, 1))
+ {
+ case '-':
+ throw new \Exception('Redis error: '.substr(trim($ersponse), 4));
+
+ case '+':
+ case ':':
+ return $this->inline($ersponse);
+
+ case '$':
+ return $this->bulk($ersponse);
+
+ case '*':
+ return $this->multibulk($ersponse);
+
+ default:
+ throw new \Exception("Unknown response from Redis server: ".substr($ersponse, 0, 1));
+ }
+ }
+
+ /**
+ * Establish the connection to the Redis database.
+ *
+ * @return resource
+ */
+ protected function connect()
+ {
+ if ( ! is_null($this->connection)) return $this->connection;
+
+ $this->connection = @fsockopen($this->host, $this->port, $error, $message);
+
+ if ($this->connection === false)
+ {
+ throw new \Exception("Error making Redis connection: {$error} - {$message}");
+ }
+
+ return $this->connection;
}
/**
* Build the Redis command based from a given method and parameters.
*
+ * Redis protocol states that a command should conform to the following format:
+ *
+ * * CR LF
+ * $ CR LF
+ * CR LF
+ * ...
+ * $ CR LF
+ * CR LF
+ *
+ * More information regarding the Redis protocol: http://redis.io/topics/protocol
+ *
* @param string $method
* @param array $parameters
* @return string
*/
protected function command($method, $parameters)
{
- $command = '*'.(count($parameters) + 1).CRLF.'$'.strlen($method).CRLF.strtoupper($method).CRLF;
+ $command = '*'.(count($parameters) + 1).CRLF;
+
+ $command .= '$'.strlen($method).CRLF;
+
+ $command .= strtoupper($method).CRLF;
foreach ($parameters as $parameter)
{
@@ -120,6 +168,73 @@ protected function command($method, $parameters)
return $command;
}
+ /**
+ * Parse and handle an inline response from the Redis database.
+ *
+ * @param string $response
+ * @return string
+ */
+ protected function inline($response)
+ {
+ return substr(trim($response), 1);
+ }
+
+ /**
+ * Parse and handle a bulk response from the Redis database.
+ *
+ * @param string $head
+ * @return string
+ */
+ protected function bulk($head)
+ {
+ if ($head == '$-1') return;
+
+ list($read, $response, $size) = array(0, '', substr($head, 1));
+
+ do
+ {
+ // Calculate and read the appropriate bytes off of the Redis response.
+ // We'll read off the response in 1024 byte chunks until the entire
+ // response has been read from the database.
+ $block = (($remaining = $size - $read) < 1024) ? $remaining : 1024;
+
+ $response .= fread($this->connection, $block);
+
+ $read += $block;
+
+ } while ($read < $size);
+
+ // The response ends with a trailing CRLF. So, we need to read that off
+ // of the end of the file stream to get it out of the way of the next
+ // command that is issued to the database.
+ fread($this->connection, 2);
+
+ return $response;
+ }
+
+ /**
+ * Parse and handle a multi-bulk reply from the Redis database.
+ *
+ * @param string $head
+ * @return array
+ */
+ protected function multibulk($head)
+ {
+ if (($count = substr($head, 1)) == '-1') return;
+
+ $response = array();
+
+ // Iterate through each bulk response in the multi-bulk and parse it out
+ // using the "bulk" method since a multi-bulk response is just a list of
+ // plain old bulk responses.
+ for ($i = 0; $i < $count; $i++)
+ {
+ $response[] = $this->bulk(trim(fgets($this->connection, 512)));
+ }
+
+ return $response;
+ }
+
/**
* Dynamically make calls to the Redis database.
*/
@@ -128,6 +243,14 @@ public function __call($method, $parameters)
return $this->run($method, $parameters);
}
+ /**
+ * Dynamically pass static method calls to the Redis instance.
+ */
+ public static function __callStatic($method, $parameters)
+ {
+ return static::db()->run($method, $parameters);
+ }
+
/**
* Close the connection to the Redis database.
*
@@ -135,7 +258,7 @@ public function __call($method, $parameters)
*/
public function __destruct()
{
- fclose(static::$connection);
+ fclose($this->connection);
}
}
\ No newline at end of file
diff --git a/laravel/routing/route.php b/laravel/routing/route.php
index 0642d142..d36c9e96 100644
--- a/laravel/routing/route.php
+++ b/laravel/routing/route.php
@@ -150,15 +150,15 @@ protected function response()
{
return call_user_func_array($this->callback, $this->parameters);
}
- // If the route is an array we will return the first value with a
- // key of "delegate", or the first instance of a Closure. If the
- // value is a string, the route is delegating the responsibility
+ // If the route is an array, we will return the first value with a
+ // key of "uses", or the first instance of a Closure. If the value
+ // is a string, the route is delegating the responsibility for
// for handling the request to a controller.
elseif (is_array($this->callback))
{
$callback = Arr::first($this->callback, function($key, $value)
{
- return $key == 'delegate' or $value instanceof Closure;
+ return $key == 'uses' or $value instanceof Closure;
});
if ($callback instanceof Closure)
diff --git a/laravel/routing/router.php b/laravel/routing/router.php
index 8b1c92df..35c3e27f 100644
--- a/laravel/routing/router.php
+++ b/laravel/routing/router.php
@@ -51,8 +51,8 @@ class Router {
* @var array
*/
protected $patterns = array(
- '(:num)' => '[0-9]+',
- '(:any)' => '[a-zA-Z0-9\.\-_]+',
+ '(:num)' => '([0-9]+)',
+ '(:any)' => '([a-zA-Z0-9\.\-_]+)',
);
/**
@@ -104,9 +104,10 @@ public function find($name)
*
* @param string $method
* @param string $uri
+ * @param string $format
* @return Route
*/
- public function route($method, $uri)
+ public function route($method, $uri, $format)
{
$routes = $this->loader->load($uri);
@@ -122,19 +123,18 @@ public function route($method, $uri)
foreach ($routes as $keys => $callback)
{
- // Formats are appended to the route key as a regular expression.
- // It will look something like: "(\.(json|xml|html))?"
- $formats = $this->provides($callback);
+ // We need to make sure that the requested format is provided by the
+ // route. If it isn't, there is no need to continue evaluating it.
+ if ( ! in_array($format, $this->provides($callback))) continue;
- // Only check routes that have multiple URIs or wildcards since other
+ // Only check routes having multiple URIs or wildcards since other
// routes would have been caught by the check for literal matches.
- // We also need to check routes with "provides" clauses.
- if ($this->fuzzy($keys) or ! is_null($formats))
+ if (strpos($keys, '(') !== false or strpos($keys, ',') !== false)
{
- if ( ! is_null($route = $this->match($destination, $keys, $callback, $formats)))
+ if ( ! is_null($route = $this->match($destination, $keys, $callback, $format)))
{
return Request::$route = $route;
- }
+ }
}
}
@@ -142,18 +142,19 @@ public function route($method, $uri)
}
/**
- * Determine if the route contains elements that forbid literal matches.
+ * Get the request formats for which the route provides responses.
*
- * Any route key containing a regular expression, wildcard, or multiple
- * URIs cannot be matched using a literal string check, but must be
- * checked using regular expressions.
- *
- * @param string $keys
- * @return bool
+ * @param mixed $callback
+ * @return array
*/
- protected function fuzzy($keys)
+ protected function provides($callback)
{
- return strpos($keys, '(') !== false or strpos($keys, ',') !== false;
+ if (is_array($callback) and isset($callback['provides']))
+ {
+ return (is_string($provides = $callback['provides'])) ? explode('|', $provides) : $provides;
+ }
+
+ return array();
}
/**
@@ -166,18 +167,19 @@ protected function fuzzy($keys)
* @param string $destination
* @param array $keys
* @param mixed $callback
- * @param array $formats
+ * @param string $format
* @return mixed
*/
- protected function match($destination, $keys, $callback, $formats)
+ protected function match($destination, $keys, $callback, $format)
{
- // Append the provided formats to the route as an optional regular expression.
- // This should make the route look something like: "user(\.(json|xml|html))?"
- $formats = ( ! is_null($formats)) ? '(\.('.implode('|', $formats).'))?' : '';
+ // We need to remove the format from the route since formats are
+ // not specified in the route URI directly, but rather through
+ // the "provides" keyword on the route array.
+ $destination = str_replace('.'.$format, '', $destination);
foreach (explode(', ', $keys) as $key)
{
- if (preg_match('#^'.$this->wildcards($key).$formats.'$#', $destination))
+ if (preg_match('#^'.$this->wildcards($key).'$#', $destination))
{
return new Route($keys, $callback, $this->parameters($destination, $key));
}
@@ -241,20 +243,6 @@ protected function controller_key($segments)
}
}
- /**
- * Get the request formats for which the route provides responses.
- *
- * @param mixed $callback
- * @return array
- */
- protected function provides($callback)
- {
- if (is_array($callback) and isset($callback['provides']))
- {
- return (is_string($provides = $callback['provides'])) ? explode('|', $provides) : $provides;
- }
- }
-
/**
* Translate route URI wildcards into actual regular expressions.
*
@@ -272,8 +260,6 @@ protected function wildcards($key)
$key .= ($replacements > 0) ? str_repeat(')?', $replacements) : '';
- // After replacing all of the optional wildcards, we can replace all
- // of the "regular" wildcards and return the fully regexed string.
return str_replace(array_keys($this->patterns), array_values($this->patterns), $key);
}
@@ -288,6 +274,11 @@ protected function wildcards($key)
*/
protected function parameters($uri, $route)
{
+ // When gathering the parameters, we need to get the request format out
+ // of the destination, otherwise it could be passed in as a parameter
+ // to the route closure or controller, which we don't want.
+ $uri = str_replace('.'.Request::format(), '', $uri);
+
list($uri, $route) = array(explode('/', $uri), explode('/', $route));
$count = count($route);
diff --git a/laravel/session/drivers/redis.php b/laravel/session/drivers/redis.php
new file mode 100644
index 00000000..a45b9a16
--- /dev/null
+++ b/laravel/session/drivers/redis.php
@@ -0,0 +1,60 @@
+redis = $redis;
+ }
+
+ /**
+ * Load a session from storage by a given ID.
+ *
+ * If no session is found for the ID, null will be returned.
+ *
+ * @param string $id
+ * @return array
+ */
+ public function load($id)
+ {
+ return $this->redis->get($id);
+ }
+
+ /**
+ * Save a given session to storage.
+ *
+ * @param array $session
+ * @param array $config
+ * @param bool $exists
+ * @return void
+ */
+ public function save($session, $config, $exists)
+ {
+ $this->redis->put($session['id'], $session, $config['lifetime']);
+ }
+
+ /**
+ * Delete a session from storage by a given ID.
+ *
+ * @param string $id
+ * @return void
+ */
+ public function delete($id)
+ {
+ $this->redis->forget($id);
+ }
+
+}
\ No newline at end of file
diff --git a/laravel/uri.php b/laravel/uri.php
index 563bc020..ed283269 100644
--- a/laravel/uri.php
+++ b/laravel/uri.php
@@ -41,9 +41,7 @@ public function get()
{
if ( ! is_null($this->uri)) return $this->uri;
- $uri = parse_url($this->server['REQUEST_URI'], PHP_URL_PATH);
-
- return $this->uri = $this->format($this->clean($uri));
+ return $this->uri = $this->format($this->clean($this->parse($this->server['REQUEST_URI'])));
}
/**
@@ -54,14 +52,24 @@ public function get()
*/
protected function clean($uri)
{
- $uri = $this->remove($uri, parse_url(Config::$items['application']['url'], PHP_URL_PATH));
+ $uri = $this->remove($uri, $this->parse(Config::$items['application']['url']));
if (($index = '/'.Config::$items['application']['index']) !== '/')
{
$uri = $this->remove($uri, $index);
}
- return rtrim($uri, '.'.Request::format($uri));
+ return $uri;
+ }
+
+ /**
+ * Parse a given string URI using PHP_URL_PATH to remove the domain.
+ *
+ * @return string
+ */
+ protected function parse($uri)
+ {
+ return parse_url($uri, PHP_URL_PATH);
}
/**
diff --git a/laravel/validation/messages.php b/laravel/validation/messages.php
index 4e5c61cb..899ce845 100644
--- a/laravel/validation/messages.php
+++ b/laravel/validation/messages.php
@@ -37,10 +37,19 @@ public function __construct($messages = array())
*/
public function add($key, $message)
{
- if ( ! isset($this->messages[$key]) or array_search($message, $this->messages[$key]) === false)
- {
- $this->messages[$key][] = $message;
- }
+ if ($this->unique($key, $message)) $this->messages[$key][] = $message;
+ }
+
+ /**
+ * Determine if a key and message combination already exists.
+ *
+ * @param string $key
+ * @param string $message
+ * @return bool
+ */
+ protected function unique($key, $message)
+ {
+ return ! isset($this->messages[$key]) or array_search($message, $this->messages[$key]) === false;
}
/**
diff --git a/laravel/view.php b/laravel/view.php
index 6497e49d..4527ade9 100644
--- a/laravel/view.php
+++ b/laravel/view.php
@@ -188,7 +188,7 @@ public function render()
// use the regular path to the view.
$view = (strpos($this->path, BLADE_EXT) !== false) ? $this->compile() : $this->path;
- try { include $view; } catch (Exception $e) { ob_get_clean(); throw $e; }
+ try { include $view; } catch (\Exception $e) { ob_get_clean(); throw $e; }
return ob_get_clean();
}