Commit aa27df8b authored by Colin Viebrock's avatar Colin Viebrock

Merge remote-tracking branch 'laravel/develop' into develop

Conflicts:
	laravel/form.php
parents 8f103cde 2fe7cfd9
......@@ -113,7 +113,11 @@ return array(
'redis' => array(
'default' => array('host' => '127.0.0.1', 'port' => 6379),
'default' => array(
'host' => '127.0.0.1',
'port' => 6379,
'database' => 0
),
),
......
......@@ -36,6 +36,7 @@ return array(
"in" => "The selected :attribute is invalid.",
"integer" => "The :attribute must be an integer.",
"ip" => "The :attribute must be a valid IP address.",
"match" => "The :attribute format is invalid.",
"max" => array(
"numeric" => "The :attribute must be less than :max.",
"file" => "The :attribute must be less than :max kilobytes.",
......
......@@ -20,4 +20,8 @@ Changes for 3.1:
- Added controller::detect method.
- Added Cache::forever method.
- Controller layouts now resolved in Laravel\Controller __construct.
- Rewrote Eloquent and included in core.
\ No newline at end of file
- Rewrote Eloquent and included in core.
- Added "match" validation rule.
- Fixed table prefix bug.
- Added Form::macro method.
- Added Route::forward method.
\ No newline at end of file
......@@ -154,9 +154,9 @@ class Migrator extends Task {
// the bundle name and string migration name as an unique ID
// for the migrations, allowing us to easily identify which
// migrations have been run for each bundle.
$table->string('bundle');
$table->string('bundle', 50);
$table->string('name');
$table->string('name', 200);
// When running a migration command, we will store a batch
// ID with each of the rows on the table. This will allow
......
......@@ -89,21 +89,34 @@ abstract class Grammar {
// Since columns may be prefixed with their corresponding table
// name so as to not make them ambiguous, we will need to wrap
// the table and the column in keyword identifiers.
foreach (explode('.', $value) as $segment)
$segments = explode('.', $value);
foreach ($segments as $key => $value)
{
if ($segment == '*')
if ($key == 0 and count($segments) > 1)
{
$wrapped[] = $segment;
$wrapped[] = $this->wrap_table($value);
}
else
{
$wrapped[] = sprintf($this->wrapper, $segment);
$wrapped[] = $this->wrap_value($value);
}
}
return implode('.', $wrapped);
}
/**
* Wrap a single string value in keyword identifiers.
*
* @param string $value
* @return string
*/
protected function wrap_value($value)
{
return ($value !== '*') ? sprintf($this->wrapper, $value) : $value;
}
/**
* Create query parameters from an array of values.
*
......
......@@ -182,7 +182,7 @@ class Query {
* @param string $column2
* @return Query
*/
public function left_join($table, $column1, $operator, $column2)
public function left_join($table, $column1, $operator = null, $column2 = null)
{
return $this->join($table, $column1, $operator, $column2, 'LEFT');
}
......
......@@ -32,7 +32,22 @@ abstract class Grammar extends \Laravel\Database\Grammar {
$sql = "ALTER TABLE $table ADD CONSTRAINT $name ";
return $sql .= "FOREIGN KEY ($foreign) REFERENCES $on ($referenced)";
$sql .= "FOREIGN KEY ($foreign) REFERENCES $on ($referenced)";
// Finally we will check for any "on delete" or "on update" options for
// the foreign key. These control the behavior of the constraint when
// an update or delete statement is run against the record.
if ( ! is_null($command->on_delete))
{
$sql .= " ON DELETE {$command->on_delete}";
}
if ( ! is_null($command->on_update))
{
$sql .= " ON UPDATE {$command->on_update}";
}
return $sql;
}
/**
......
......@@ -68,6 +68,30 @@ class File {
if (static::exists($path)) @unlink($path);
}
/**
* Move a file to a new location.
*
* @param string $path
* @param string $target
* @return void
*/
public static function move($path, $target)
{
return rename($path, $target);
}
/**
* Copy a file to a new location.
*
* @param string $path
* @param string $target
* @return void
*/
public static function copy($path, $target)
{
return copy($path, $target);
}
/**
* Extract the file extension from a file path.
*
......@@ -173,6 +197,18 @@ class File {
return false;
}
/**
* Create a new directory.
*
* @param string $path
* @param int $chmod
* @return void
*/
public static function mkdir($path, $chmod = 0777)
{
return ( ! is_dir($path)) ? mkdir($path, $chmod, true) : true;
}
/**
* Move a directory from one location to another.
*
......@@ -183,7 +219,7 @@ class File {
*/
public static function mvdir($source, $destination, $options = fIterator::SKIP_DOTS)
{
static::cpdir($source, $destination, true, $options);
return static::cpdir($source, $destination, true, $options);
}
/**
......@@ -197,7 +233,7 @@ class File {
*/
public static function cpdir($source, $destination, $delete = false, $options = fIterator::SKIP_DOTS)
{
if ( ! is_dir($source)) return;
if ( ! is_dir($source)) return false;
// First we need to create the destination directory if it doesn't
// already exists. This directory hosts all of the assets we copy
......@@ -221,7 +257,7 @@ class File {
{
$path = $item->getRealPath();
static::cpdir($path, $location, $delete, $options);
if (! static::cpdir($path, $location, $delete, $options)) return false;
if ($delete) @rmdir($item->getRealPath());
}
......@@ -231,22 +267,25 @@ class File {
// files with the same name.
else
{
copy($item->getRealPath(), $location);
if(! copy($item->getRealPath(), $location)) return false;
if ($delete) @unlink($item->getRealPath());
}
}
if ($delete) rmdir($source);
return true;
}
/**
* Recursively delete a directory.
*
* @param string $directory
* @param bool $preserve
* @return void
*/
public static function rmdir($directory)
public static function rmdir($directory, $preserve = false)
{
if ( ! is_dir($directory)) return;
......@@ -267,7 +306,18 @@ class File {
}
}
@rmdir($directory);
if ( ! $preserve) @rmdir($directory);
}
/**
* Empty the specified directory of all files and folders.
*
* @param string $directory
* @return void
*/
public static function cleandir($directory)
{
return static::rmdir($directory, true);
}
/**
......
......@@ -7,7 +7,26 @@ class Form {
*
* @var array
*/
protected static $labels = array();
public static $labels = array();
/**
* The registered custom macros.
*
* @var array
*/
public static $macros = array();
/**
* Registers a custom macro.
*
* @param string $name
* @param Closure $input
* @return void
*/
public static function macro($name, $macro)
{
static::$macros[$name] = $macro;
}
/**
* Open a HTML form.
......@@ -52,8 +71,7 @@ class Form {
// Since PUT and DELETE methods are not actually supported by HTML forms,
// we'll create a hidden input element that contains the request method
// and set the actual request method to POST. Laravel will look for the
// hidden element to determine the request method.
// and set the actual request method variable to POST.
if ($method == 'PUT' or $method == 'DELETE')
{
$append = static::hidden(Request::spoofer, $method);
......@@ -541,8 +559,7 @@ class Form {
{
// If an ID has been explicitly specified in the attributes, we will
// use that ID. Otherwise, we will look for an ID in the array of
// label names as this makes it convenient to give input elements
// the same ID as their corresponding labels.
// label names so labels and their elements have the same ID.
if (array_key_exists('id', $attributes))
{
return $attributes['id'];
......@@ -554,4 +571,21 @@ class Form {
}
}
/**
* Dynamically handle calls to custom macros.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public static function __callStatic($method, $parameters)
{
if (isset(static::$macros[$method]))
{
return call_user_func_array(static::$macros[$method], $parameters);
}
throw new \Exception("Method [$method] does not exist.");
}
}
......@@ -16,6 +16,13 @@ class Redis {
*/
protected $port;
/**
* The databse number the connection selects on load.
*
* @var int
*/
protected $database;
/**
* The connection to the Redis database.
*
......@@ -35,12 +42,14 @@ class Redis {
*
* @param string $host
* @param string $port
* @param int $database
* @return void
*/
public function __construct($host, $port)
public function __construct($host, $port, $database = 0)
{
$this->host = $host;
$this->port = $port;
$this->database = $database;
}
/**
......@@ -68,7 +77,9 @@ class Redis {
throw new \Exception("Redis database [$name] is not defined.");
}
static::$databases[$name] = new static($config['host'], $config['port']);
extract($config);
static::$databases[$name] = new static($host, $port, $database);
}
return static::$databases[$name];
......@@ -95,6 +106,17 @@ class Redis {
$response = trim(fgets($this->connection, 512));
return $this->parse($response);
}
/**
* Parse and return the response from the Redis database.
*
* @param string $response
* @return mixed
*/
protected function parse($response)
{
switch (substr($response, 0, 1))
{
case '-':
......@@ -131,6 +153,8 @@ class Redis {
throw new \Exception("Error making Redis connection: {$error} - {$message}");
}
$this->select($this->database);
return $this->connection;
}
......@@ -191,18 +215,21 @@ class Redis {
list($read, $response, $size) = array(0, '', substr($head, 1));
do
if ($size > 0)
{
// 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;
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);
$response .= fread($this->connection, $block);
$read += $block;
$read += $block;
} while ($read < $size);
} 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
......@@ -225,11 +252,11 @@ class Redis {
$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.
// using the "parse" method since a multi-bulk response is just a list
// of plain old Redis database responses.
for ($i = 0; $i < $count; $i++)
{
$response[] = $this->bulk(trim(fgets($this->connection, 512)));
$response[] = $this->parse(trim(fgets($this->connection, 512)));
}
return $response;
......
......@@ -381,4 +381,16 @@ class Route {
Filter::register($name, $callback);
}
/**
* Calls the specified route and returns its response.
*
* @param string $method
* @param string $uri
* @return Response
*/
public static function forward($method, $uri)
{
return Router::route(strtoupper($method), $uri)->call();
}
}
\ No newline at end of file
......@@ -611,6 +611,18 @@ class Validator {
return preg_match('/^([-a-z0-9_-])+$/i', $value);
}
/**
* Validate that an attribute passes a regular expression check.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
protected function validate_match($attribute, $value, $parameters)
{
return preg_match($parameters[0], $value);
}
/**
* Validate the MIME type of a file upload attribute is in a set of MIME types.
*
......
......@@ -41,7 +41,7 @@ Laravel is a clean and classy framework for PHP web development. Freeing you fro
Contributions are encouraged and welcome; however, please review the Developer Certificate of Origin in the "license.txt" file included in the repository. All commits must be signed off using the "-s" switch.
git commit -s -m "thie commit will be signed off automatically!"
git commit -s -m "this commit will be signed off automatically!"
### License
......
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