Browse Source

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

Chris Berthe 12 years ago
parent
commit
b325e954e3

+ 14 - 1
application/config/application.php

@@ -84,7 +84,7 @@ return array(
 
 	/*
 	|--------------------------------------------------------------------------
-	| Application Language
+	| Default Application Language
 	|--------------------------------------------------------------------------
 	|
 	| The default language of your application. This language will be used by
@@ -94,6 +94,19 @@ return array(
 
 	'language' => 'en',
 
+	/*
+	|--------------------------------------------------------------------------
+	| Supported Languages
+	|--------------------------------------------------------------------------
+	|
+	| These languages may also be supported by your application. If a request
+	| enters your application with a URI beginning with one of these values
+	| the default language will automatically be set to that language.
+	|
+	*/
+
+	'languages' => array(),
+
 	/*
 	|--------------------------------------------------------------------------
 	| SSL Link Generation

+ 19 - 0
application/language/bg/pagination.php

@@ -0,0 +1,19 @@
+<?php 
+
+return array(
+
+	/*
+	|--------------------------------------------------------------------------
+	| Pagination Language Lines
+	|--------------------------------------------------------------------------
+	|
+	| The following language lines are used by the paginator library to build
+	| the pagination links. You're free to change them to anything you want.
+	| If you come up with something more exciting, let us know.
+	|
+	*/
+
+	'previous' => '&laquo; Назад',
+	'next'     => 'Напред &raquo;',
+
+);

+ 99 - 0
application/language/bg/validation.php

@@ -0,0 +1,99 @@
+<?php 
+
+return array(
+
+	/*
+	|--------------------------------------------------------------------------
+	| Validation Language Lines
+	|--------------------------------------------------------------------------
+	|
+	| The following language lines contain the default error messages used
+	| by the validator class. Some of the rules contain multiple versions,
+	| such as the size (max, min, between) rules. These versions are used
+	| for different input types such as strings and files.
+	|
+	| These language lines may be easily changed to provide custom error
+	| messages in your application. Error messages for custom validation
+	| rules may also be added to this file.
+	|
+	*/
+
+	"accepted"       => "Трябва да приемете :attribute.",
+	"active_url"     => "Полето :attribute не е валиден URL адрес.",
+	"after"          => "Полето :attribute трябва да бъде дата след :date.",
+	"alpha"          => "Полето :attribute трябва да съдържа само букви.",
+	"alpha_dash"     => "Полето :attribute трябва да съдържа само букви, цифри, долна черта и тире.",
+	"alpha_num"      => "Полето :attribute трябва да съдържа само букви и цифри.",
+	"before"         => "Полето :attribute трябва да бъде дата преди :date.",
+	"between"        => array(
+		"numeric" => "Полето :attribute трябва да бъде между :min и :max.",
+		"file"    => "Полето :attribute трябва да бъде между :min и :max килобайта.",
+		"string"  => "Полето :attribute трябва да бъде между :min и :max знака.",
+	),
+	"confirmed"      => "Полето :attribute не е потвърдено.",
+	"different"      => "Полетата :attribute и :other трябва да са различни.",
+	"email"          => "Полето :attribute е с невалиден формат.",
+	"exists"         => "Избраната стойност на :attribute вече съществува.",
+	"image"          => "Полето :attribute трябва да бъде изображение.",
+	"in"             => "Стойността на :attribute е невалидна.",
+	"integer"        => "Полето :attribute трябва да бъде цяло число.",
+	"ip"             => "Полето :attribute трябва да бъде IP адрес.",
+	"match"          => "Полето :attribute е с невалиден формат.",
+	"max"            => array(
+		"numeric" => "Полето :attribute трябва да бъде по-малко от :max.",
+		"file"    => "Полето :attribute трябва да бъде по-малко от :max килобайта.",
+		"string"  => "Полето :attribute трябва да бъде по-малко от :max знака.",
+	),
+	"mimes"          => "Полето :attribute трябва да бъде файл от тип: :values.",
+	"min"            => array(
+		"numeric" => "Полето :attribute трябва да бъде минимум :min.",
+		"file"    => "Полето :attribute трябва да бъде минимум :min килобайта.",
+		"string"  => "Полето :attribute трябва да бъде минимум :min знака.",
+	),
+	"not_in"         => "Стойността на :attribute е невалидна.",
+	"numeric"        => "Полето :attribute трябва да бъде число.",
+	"required"       => "Полето :attribute е задължително.",
+	"same"           => "Стойностите на :attribute и :other трябва да съвпадат.",
+	"size"           => array(
+		"numeric" => "Полето :attribute трябва да бъде :size.",
+		"file"    => "Полето :attribute трябва да бъде :size килобайта.",
+		"string"  => "Полето :attribute трябва да бъде :size знака.",
+	),
+	"unique"         => "Стойността на :attribute вече съществува.",
+	"url"            => "Полето :attribute е с невалиден формат.",
+
+	/*
+	|--------------------------------------------------------------------------
+	| Custom Validation Language Lines
+	|--------------------------------------------------------------------------
+	|
+	| Here you may specify custom validation messages for attributes using the
+	| convention "attribute_rule" to name the lines. This helps keep your
+	| custom validation clean and tidy.
+	|
+	| So, say you want to use a custom validation message when validating that
+	| the "email" attribute is unique. Just add "email_unique" to this array
+	| with your custom message. The Validator will handle the rest!
+	|
+	*/
+
+	'custom' => array(),
+
+	/*
+	|--------------------------------------------------------------------------
+	| Validation Attributes
+	|--------------------------------------------------------------------------
+	|
+	| The following language lines are used to swap attribute place-holders
+	| with something more reader friendly such as "E-Mail Address" instead
+	| of "email". Your users will thank you.
+	|
+	| The Validator class will automatically search this array of lines it
+	| is attempting to replace the :attribute place-holder in messages.
+	| It's pretty slick. We think you'll like it.
+	|
+	*/
+
+	'attributes' => array(),
+
+);

+ 19 - 0
application/language/he/pagination.php

@@ -0,0 +1,19 @@
+<?php 
+
+return array(
+
+	/*
+	|--------------------------------------------------------------------------
+	| Pagination Language Lines
+	|--------------------------------------------------------------------------
+	|
+	| The following language lines are used by the paginator library to build
+	| the pagination links. You're free to change them to anything you want.
+	| If you come up with something more exciting, let us know.
+	|
+	*/
+
+	'previous' => '&rarr; אחורה',
+	'next'     => 'קדימה &larr;',
+
+);

+ 102 - 0
application/language/he/validation.php

@@ -0,0 +1,102 @@
+<?php 
+
+return array(
+
+	/*
+	|--------------------------------------------------------------------------
+	| Validation Language Lines
+	|--------------------------------------------------------------------------
+	|
+	| The following language lines contain the default error messages used
+	| by the validator class. Some of the rules contain multiple versions,
+	| such as the size (max, min, between) rules. These versions are used
+	| for different input types such as strings and files.
+	|
+	| These language lines may be easily changed to provide custom error
+	| messages in your application. Error messages for custom validation
+	| rules may also be added to this file.
+	|
+	| Hebrew Translation:
+	| Nir Lahad - www.nirlah.com
+	|
+	*/
+
+	"accepted"       => "חובה להסכים ל-:attribute.",
+	"active_url"     => "הערך :attribute חייב להכיל כתובת אינטרנט פעילה.",
+	"after"          => "הערך :attribute חייב להכיל תאריך אחרי :date.",
+	"alpha"          => "הערך :attribute יכול להכיל רק אותיות.",
+	"alpha_dash"     => "הערך :attribute יכול להכיל רק אותיות, מספרים ומקפים.",
+	"alpha_num"      => "הערך :attribute יכול להכיל רק אותיות ומספרים.",
+	"before"         => "הערך :attribute חייב להכיל תאריך לפני :date.",
+	"between"        => array(
+		"numeric" => "הערך :attribute חייב להיות בין :min ל-:max.",
+		"file"    => "הערך :attribute חייב לשקול בין :min ל-:max ק&quot;ב.",
+		"string"  => "הערך :attribute חייב להכיל בין :min ל-:max תווים.",
+	),
+	"confirmed"      => "הערכים של :attribute חייבים להיות זהים.",
+	"different"      => "הערכים של :attribute ו-:other חייבים להיות שונים.",
+	"email"          => "הערך :attribute חייב להכיל כתובת אימייל תקינה.",
+	"exists"         => "הערך :attribute לא קיים.",
+	"image"          => "הערך :attribute חייב להיות תמונה.",
+	"in"             => "הערך :attribute חייב להיות ברשימה המאשרת.",
+	"integer"        => "הערך :attribute חייב להיות מספר שלם.",
+	"ip"             => "הערך :attribute חייב להיות כתובת IP תקינה.",
+	"match"          => "התבנית של הערך :attribute אינה תקינה.",
+	"max"            => array(
+		"numeric" => "הערך :attribute חייב להיות פחות מ-:max.",
+		"file"    => "הערך :attribute חייב לשקול פחות מ-:max ק&quotב.",
+		"string"  => "הערך :attribute חייב להכיל פחות מ-:max תווים.",
+	),
+	"mimes"          => "הערך :attribute חייב להיות קובץ מסוג: :values.",
+	"min"            => array(
+		"numeric" => "הערך :attribute חייב להיות לפחות :min.",
+		"file"    => "הערך :attribute חייב לשקול לפחות :min ק&quot;ב.",
+		"string"  => "הערך :attribute חייב להכיל לפחות :min תווים.",
+	),
+	"not_in"         => "הערך :attribute נמצא ברשימה השחורה.",
+	"numeric"        => "הערך :attribute חייב להיות מספר.",
+	"required"       => "חובה למלא את הערך :attribute.",
+	"same"           => "הערכים :attribute ו-:other חייבים להיות זהים.",
+	"size"           => array(
+		"numeric" => "הערך :attribute חייב להיות :size.",
+		"file"    => "הערך :attribute חייב לשקול :size ק&quot;ב.",
+		"string"  => "הערך :attribute חייב להכיל :size תווים.",
+	),
+	"unique"         => "הערך :attribute כבר קיים.",
+	"url"            => "הערך :attribute חייב להכיל כתובת אינטרנט תקינה.",
+
+	/*
+	|--------------------------------------------------------------------------
+	| Custom Validation Language Lines
+	|--------------------------------------------------------------------------
+	|
+	| Here you may specify custom validation messages for attributes using the
+	| convention "attribute_rule" to name the lines. This helps keep your
+	| custom validation clean and tidy.
+	|
+	| So, say you want to use a custom validation message when validating that
+	| the "email" attribute is unique. Just add "email_unique" to this array
+	| with your custom message. The Validator will handle the rest!
+	|
+	*/
+
+	'custom' => array(),
+
+	/*
+	|--------------------------------------------------------------------------
+	| Validation Attributes
+	|--------------------------------------------------------------------------
+	|
+	| The following language lines are used to swap attribute place-holders
+	| with something more reader friendly such as "E-Mail Address" instead
+	| of "email". Your users will thank you.
+	|
+	| The Validator class will automatically search this array of lines it
+	| is attempting to replace the :attribute place-holder in messages.
+	| It's pretty slick. We think you'll like it.
+	|
+	*/
+
+	'attributes' => array(),
+
+);

+ 19 - 0
application/language/pl/pagination.php

@@ -0,0 +1,19 @@
+<?php
+
+return array(
+
+    /*
+    |--------------------------------------------------------------------------
+    | Pagination Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used by the paginator library to build
+    | the pagination links. You're free to change them to anything you want.
+    | If you come up with something more exciting, let us know.
+    |
+    */
+
+    'previous' => '&laquo; Poprzednia',
+    'next'     => 'Następna &raquo;',
+
+);

+ 99 - 0
application/language/pl/validation.php

@@ -0,0 +1,99 @@
+<?php
+
+return array(
+
+    /*
+    |--------------------------------------------------------------------------
+    | Validation Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines contain the default error messages used
+    | by the validator class. Some of the rules contain multiple versions,
+    | such as the size (max, min, between) rules. These versions are used
+    | for different input types such as strings and files.
+    |
+    | These language lines may be easily changed to provide custom error
+    | messages in your application. Error messages for custom validation
+    | rules may also be added to this file.
+    |
+    */
+
+    "accepted"       => ":attribute musi zostać zaakceptowane.",
+    "active_url"     => ":attribute nie jest prawidłowym adresem URL.",
+    "after"          => ":attribute musi zawierać datę, która jest po :date.",
+    "alpha"          => ":attribute może zawierać jedynie litery.",
+    "alpha_dash"     => ":attribute może zawierać jedynie litery, cyfry i myślniki.",
+    "alpha_num"      => ":attribute może zawierać jedynie litery i cyfry.",
+    "before"         => ":attribute musi zawierać datę, która jest przed :date.",
+    "between"        => array(
+        "numeric" => ":ttribute musi mieścić się w granicach :min - :max.",
+        "file"    => ":attribute musi mieć :min - :max kilobajtów.",
+        "string"  => ":attribute musi mieć :min - :max znaków.",
+    ),
+    "confirmed"      => "Potwierdzenie :attribute się nie zgadza.",
+    "different"      => ":attribute i :other muszą się od siebie różnić.",
+    "email"          => "The :attribute format is invalid.",
+    "exists"         => "Zaznaczona opcja :attribute jest nieprawidłowa.",
+    "image"          => ":attribute musi być obrazkiem.",
+    "in"             => "Zaznaczona opcja :attribute jest nieprawidłowa.",
+    "integer"        => ":attribute musi być liczbą całkowitą.",
+    "ip"             => ":attribute musi być prawidłowym adresem IP.",
+    "match"          => "Format :attribute jest nieprawidłowy.",
+    "max"            => array(
+        "numeric" => ":attribute musi być poniżej :max.",
+        "file"    => ":attribute musi mieć poniżej :max kilobajtów.",
+        "string"  => ":attribute musi mieć poniżej :max znaków.",
+    ),
+    "mimes"          => ":attribute musi być plikiem rodzaju :values.",
+    "min"            => array(
+        "numeric" => ":attribute musi być co najmniej :min.",
+        "file"    => "Plik :attribute musi mieć co najmniej :min kilobajtów.",
+        "string"  => ":attribute musi mieć co najmniej :min znaków.",
+    ),
+    "not_in"         => "Zaznaczona opcja :attribute jest nieprawidłowa.",
+    "numeric"        => ":attribute musi być numeryczne.",
+    "required"       => "Pole :attribute jest wymagane.",
+    "same"           => ":attribute i :other muszą być takie same.",
+    "size"           => array(
+        "numeric" => ":attribute musi mieć rozmiary :size.",
+        "file"    => ":attribute musi mieć :size kilobajtów.",
+        "string"  => ":attribute musi mieć :size znaków.",
+    ),
+    "unique"         => ":attribute zostało już użyte.",
+    "url"            => "Format pola :attribute jest nieprawidłowy.",
+
+    /*
+    |--------------------------------------------------------------------------
+    | Custom Validation Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | Here you may specify custom validation messages for attributes using the
+    | convention "attribute_rule" to name the lines. This helps keep your
+    | custom validation clean and tidy.
+    |
+    | So, say you want to use a custom validation message when validating that
+    | the "email" attribute is unique. Just add "email_unique" to this array
+    | with your custom message. The Validator will handle the rest!
+    |
+    */
+
+    'custom' => array(),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Validation Attributes
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used to swap attribute place-holders
+    | with something more reader friendly such as "E-Mail Address" instead
+    | of "email". Your users will thank you.
+    |
+    | The Validator class will automatically search this array of lines it
+    | is attempting to replace the :attribute place-holder in messages.
+    | It's pretty slick. We think you'll like it.
+    |
+    */
+
+    'attributes' => array(),
+
+);

+ 4 - 0
laravel/cli/tasks/test/runner.php

@@ -80,6 +80,10 @@ class Runner extends Task {
 		// pointing to our temporary configuration file. This allows
 		// us to flexibly run tests for any setup.
 		$path = path('base').'phpunit.xml';
+		
+		// fix the spaced directories problem when using the command line
+		// strings with spaces inside should be wrapped in quotes.
+		$path = escapeshellarg($path)
 
 		passthru('phpunit --configuration '.$path);
 

+ 7 - 5
laravel/database/eloquent/model.php

@@ -218,9 +218,11 @@ abstract class Model {
 	{
 		$model = new static(array(), true);
 
-		if (static::$timestamps) $attributes['updated_at'] = new \DateTime;
+		$model->fill($attributes);
 
-		return $model->query()->where($model->key(), '=', $id)->update($attributes);
+		if (static::$timestamps) $model->timestamp();
+
+		return $model->query()->where($model->key(), '=', $id)->update($model->attributes);
 	}
 
 	/**
@@ -500,7 +502,7 @@ abstract class Model {
 	 */
 	public function changed($attribute)
 	{
-		return array_get($this->attributes, $attribute) !== array_get($this->original, $attribute);
+		return array_get($this->attributes, $attribute) != array_get($this->original, $attribute);
 	}
 
 	/**
@@ -536,7 +538,7 @@ abstract class Model {
 
 		foreach ($this->attributes as $key => $value)
 		{
-			if ( ! isset($this->original[$key]) or $value !== $this->original[$key])
+			if ( ! array_key_exists($key, $this->original) or $value !== $this->original[$key])
 			{
 				$dirty[$key] = $value;
 			}
@@ -725,7 +727,7 @@ abstract class Model {
 	{
 		foreach (array('attributes', 'relationships') as $source)
 		{
-			if (array_key_exists($key, $this->$source)) return true;
+			if (array_key_exists($key, $this->$source)) return !is_null($this->$source[$key]);
 		}
 		
 		if (method_exists($this, $key)) return true;

+ 3 - 20
laravel/database/query.php

@@ -140,7 +140,7 @@ class Query {
 	 */
 	public function select($columns = array('*'))
 	{
-		$this->selects = (array) $columns;
+		$this->selects = is_array($columns) ? $columns : array($columns);
 		return $this;
 	}
 
@@ -395,7 +395,7 @@ class Query {
 	}
 
 	/**
-	 * Add a nested where condition to the query.
+	 * Add nested constraints to the query.
 	 *
 	 * @param  Closure  $callback
 	 * @param  string   $connector
@@ -403,24 +403,7 @@ class Query {
 	 */
 	public function where_nested($callback, $connector = 'AND')
 	{
-		$type = 'where_nested';
-
-		// To handle a nested where statement, we will actually instantiate a new
-		// Query instance and run the callback over that instance, which will
-		// allow the developer to have a fresh query instance
-		$query = new Query($this->connection, $this->grammar, $this->from);
-
-		call_user_func($callback, $query);
-
-		// Once the callback has been run on the query, we will store the nested
-		// query instance on the where clause array so that it's passed to the
-		// query's query grammar instance when building.
-		if ($query->wheres !== null)
-		{
-			$this->wheres[] = compact('type', 'query', 'connector');
-		}
-
-		$this->bindings = array_merge($this->bindings, $query->bindings);
+		call_user_func($callback, $this);
 
 		return $this;
 	}

+ 1 - 1
laravel/database/schema/grammars/mysql.php

@@ -99,7 +99,7 @@ class MySQL extends Grammar {
 	 */
 	protected function unsigned(Table $table, Fluent $column)
 	{
-		if ($column->type == 'integer' && $column->unsigned)
+		if ($column->type == 'integer' && ($column->unsigned || $column->increment))
 		{
 			return ' UNSIGNED';
 		}

+ 2 - 0
laravel/documentation/changes.md

@@ -37,6 +37,8 @@
 ## Laravel 3.2.4
 
 - Speed up many to many eager loading mapping.
+- Tweak the Eloquent::changed() method.
+- Added support for locales in the URI.
 
 <a name="upgrade-3.2.3"></a>
 ## Upgrading From 3.2.3

+ 1 - 1
laravel/documentation/contents.md

@@ -4,7 +4,7 @@
 - [Installation & Setup](/docs/install)
 	- [Requirements](/docs/install#requirements)
 	- [Installation](/docs/install#installation)
-	- [Server Configuration: Why Public?](/docs/install#server-configuration)
+	- [Server Configuration](/docs/install#server-configuration)
 	- [Basic Configuration](/docs/install#basic-configuration)
 	- [Environments](/docs/install#environments)
 	- [Cleaner URLs](/docs/install#cleaner-urls)

+ 26 - 0
laravel/documentation/database/eloquent.md

@@ -318,6 +318,10 @@ However, you may often only want to insert a new record into the intermediate ta
 
 	$user->roles()->attach($role_id);
 
+It's also possible to attach data for fields in the intermediate table (pivot table), to do this add a second array variable to the attach command containing the data you want to attach:
+	
+	$user->roles()->attach($role_id, array('expires' => $expires));
+
 <a name="sync-method"></a>
 Alternatively, you can use the `sync` method, which accepts an array of IDs to "sync" with the intermediate table. After this operation is complete, only the IDs in the array will be on the intermediate table.
 
@@ -406,6 +410,28 @@ You may even eager load nested relationships. For example, let's assume our **Au
 
 	$books = Book::with(array('author', 'author.contacts'))->get();
 
+If you find yourself eager loading the same models often, you may want to use **$includes** in the model.
+
+	class Book extends Eloquent {
+
+	     public $includes = array('author');
+	     
+	     public function author()
+	     {
+	          return $this->belongs_to('Author');
+	     }
+
+	}
+	
+**$includes** takes the same arguments that **with** takes. The following is now eagerly loaded.
+
+	foreach (Book::all() as $book)
+	{
+	     echo $book->author->name;
+	}
+
+> **Note:** Using **with** will override a models **$includes**.
+
 <a name="constraining-eager-loads"></a>
 ## Constraining Eager Loads
 

+ 7 - 9
laravel/documentation/install.md

@@ -4,7 +4,7 @@
 
 - [Requirements](#requirements)
 - [Installation](#installation)
-- [Server Configuration: Why Public?](#server-configuration)
+- [Server Configuration](#server-configuration)
 - [Basic Configuration](#basic-configuration)
 - [Environments](#environments)
 - [Cleaner URLs](#cleaner-urls)
@@ -23,7 +23,8 @@
 1. [Download Laravel](http://laravel.com/download)
 2. Extract the Laravel archive and upload the contents to your web server.
 3. Set the value of the **key** option in the **config/application.php** file to a random, 32 character string.
-4. Navigate to your application in a web browser.
+4. Verify that the `storage/views` directory is writable.
+5. Navigate to your application in a web browser.
 
 If all is well, you should see a pretty Laravel splash page. Get ready, there is lots more to learn!
 
@@ -43,9 +44,9 @@ If you are having problems installing, try the following:
 - Verify that your storage folder and the folders within are writable by your web server.
 
 <a name="server-configuration"></a>
-## Server Configuration: Why Public?
+## Server Configuration
 
-Like most web-development frameworks, Laravel is designed to protect your application code, bundles, and local storage by placing only files that are necessarily public in the web server's DocumentRoot. This prevents some types of server misconfiguration from making your code (including database passwords and other configuration data) accessible through the web server. It's best to be safe.
+Like most web-development frameworks, Laravel is designed to protect your application code, bundles, and local storage by placing only files that are necessarily public in the web server's DocumentRoot. This prevents some types of server misconfiguration from making your code (including database passwords and other configuration data) accessible through the web server. It's best to be safe. 
 
 In this example let's imagine that we installed Laravel to the directory **/Users/JonSnow/Sites/MySite**.
 
@@ -53,15 +54,12 @@ A very basic example of an Apache VirtualHost configuration for MySite might loo
 
 	<VirtualHost *:80>
 		DocumentRoot /Users/JonSnow/Sites/MySite/public
-		ServerName mysite.local
+		ServerName mysite.dev
 	</VirtualHost>
 
 Notice that while we installed to **/Users/JonSnow/Sites/MySite** our DocumentRoot points to **/Users/JonSnow/Sites/MySite/public**.
 
-Pointing the DocumentRoot to the public folder is a commonly used best-practice. However, you may need to use Laravel on a host that does not allow you to update your DocumentRoot. This is possible, but before resigning to this option it's best to contact your host and verify that you are unable to change your DocumentRoot to increase the security of your application.
-
-More information about how to use the public folder can be found on the [Laravel Forums](http://forums.laravel.com/viewtopic.php?pid=10023#p10023).
-
+While pointing the DocumentRoot to the public folder is a commonly used best-practice, it's possible that you may need to use Laravel on a host that does not allow you to update your DocumentRoot. A collection of algorithms to circumvent this need can be found [on the Laravel forums.](http://forums.laravel.com/viewtopic.php?id=1258)
 
 <a name="basic-configuration"></a>
 ## Basic Configuration

+ 1 - 1
laravel/documentation/localization.md

@@ -33,7 +33,7 @@ Next, you should create a corresponding **marketing.php** file within the **appl
 
 Nice! Now you know how to get started setting up your language files and directories. Let's keep localizing!
 
-<a name="basics"></a>
+<a name="get"></a>
 ## Retrieving A Language Line
 
 #### Retrieving a language line:

+ 9 - 0
laravel/documentation/routing.md

@@ -152,6 +152,15 @@ Sometimes you may want to attach a filter to all requests that begin with a give
 
 	Route::filter('pattern: admin/*', 'auth');
 
+Optionally you can register filters directly when attaching filters to a given URI by supplying an array with the name of the filter and a callback.
+
+#### Defining a filter and URI pattern based filter in one:
+
+    Route::filter('pattern: admin/*', array('name' => 'auth', function()
+    {
+        // 
+    }));
+
 <a name="global-filters"></a>
 ## Global Filters
 

+ 3 - 0
laravel/documentation/validation.md

@@ -63,6 +63,9 @@ Now you are familiar with the basic usage of the Validator class. You're ready t
 
 	'name' => 'required'
 
+#### Validate that an attribute is present, when another attribute is present:
+	'last_name' => 'required_with:first_name'
+
 <a name="rule-alpha"></a>
 ### Alpha, Alpha Numeric, & Alpha Dash
 

+ 1 - 1
laravel/input.php

@@ -205,7 +205,7 @@ class Input {
 	 */
 	public static function has_file($key)
 	{
-		return ! is_null(static::file("{$key}.tmp_name"));
+		return strlen(static::file("{$key}.tmp_name", "")) > 0;
 	}
 
 	/**

+ 40 - 2
laravel/laravel.php

@@ -107,6 +107,46 @@ Routing\Router::register('*', '(:all)', function()
 	return Event::first('404');
 });
 
+/*
+|--------------------------------------------------------------------------
+| Gather The URI And Locales
+|--------------------------------------------------------------------------
+|
+| When routing, we'll need to grab the URI and the supported locales for
+| the route so we can properly set the language and route the request
+| to the proper end-point in the application.
+|
+*/
+
+$uri = URI::current();
+
+$locales = Config::get('application.languages', array());
+
+$locales[] = Config::get('application.language');
+
+/*
+|--------------------------------------------------------------------------
+| Set The Locale Based On Route
+|--------------------------------------------------------------------------
+|
+| If the URI starts with one of the supported languages, we will set
+| the default language to match that URI segment and shorten the
+| URI we'll pass to the router to not include the lang segment.
+|
+*/
+
+foreach ($locales as $locale)
+{
+	if (starts_with($uri, $locale))
+	{
+		Config::set('application.language', $locale);
+
+		$uri = trim(substr($uri, strlen($locale)), '/'); break;
+	}
+}
+
+if ($uri === '') $uri = '/';
+
 /*
 |--------------------------------------------------------------------------
 | Route The Incoming Request
@@ -118,8 +158,6 @@ Routing\Router::register('*', '(:all)', function()
 |
 */
 
-$uri = URI::current();
-
 Request::$route = Routing\Router::route(Request::method(), $uri);
 
 $response = Request::$route->call();

+ 2 - 2
laravel/response.php

@@ -93,7 +93,7 @@ class Response {
 	 */
 	public static function json($data, $status = 200, $headers = array())
 	{
-		$headers['Content-Type'] = 'application/json';
+		$headers['Content-Type'] = 'application/json; charset=utf-8';
 
 		return new static(json_encode($data), $status, $headers);
 	}
@@ -113,7 +113,7 @@ class Response {
 	 */
 	public static function eloquent($data, $status = 200, $headers = array())
 	{
-		$headers['Content-Type'] = 'application/json';
+		$headers['Content-Type'] = 'application/json; charset=utf-8';
 
 		return new static(eloquent_to_json($data), $status, $headers);
 	}

+ 9 - 0
laravel/routing/route.php

@@ -213,6 +213,15 @@ class Route {
 		{
 			if (Str::is($pattern, $this->uri))
 			{
+				// If the filter provided is an array then we need to register
+				// the filter before we can assign it to the route.
+				if (is_array($filter))
+				{
+					list($filter, $callback) = array_values($filter);
+
+					Filter::register($filter, $callback);
+				}
+
 				$filters[] = $filter;
 			}
 		}

+ 13 - 0
laravel/url.php

@@ -107,6 +107,14 @@ class URL {
 
 		$root = static::base().'/'.Config::get('application.index');
 
+		// If multiple languages are being supported via URIs, we will append current
+		// language to the URI so all redirects and URLs generated include the
+		// current language so it is not lost on further requests.
+		if (count(Config::get('application.languages')) > 0)
+		{
+			$root .= '/'.Config::get('application.language');
+		}
+
 		// Since SSL is not often used while developing the application, we allow the
 		// developer to disable SSL on all framework generated links to make it more
 		// convenient to work with the site while developing locally.
@@ -242,6 +250,11 @@ class URL {
 			$url = str_replace($index.'/', '', $url);
 		}
 
+		if (count(Config::get('application.languages')) > 0)
+		{
+			$url = str_replace(Config::get('application.language').'/', '', $url);
+		}
+
 		return $url;
 	}
 

+ 22 - 1
laravel/validator.php

@@ -214,7 +214,7 @@ class Validator {
 	 */
 	protected function implicit($rule)
 	{
-		return $rule == 'required' or $rule == 'accepted';
+		return $rule == 'required' or $rule == 'accepted' or $rule == 'required_with';
 	}
 
 	/**
@@ -257,6 +257,27 @@ class Validator {
 		return true;
 	}
 
+	/**
+	 * Validate that an attribute exists in the attributes array, if another
+	 * attribute exists in the attributes array.
+	 *
+	 * @param  string  $attribute
+	 * @param  mixed   $value
+	 * @param  array   $parameters
+	 * @return bool
+	 */
+	protected function validate_required_with($attribute, $value, $parameters)
+	{
+		$other = $parameters[0];
+
+		if ($this->validate_required($other, $this->attributes[$other]))
+		{
+			return $this->validate_required($attribute, $value);
+		}
+
+		return true;
+	}
+
 	/**
 	 * Validate that an attribute has a matching confirmation attribute.
 	 *

+ 16 - 0
laravel/view.php

@@ -551,4 +551,20 @@ class View implements ArrayAccess {
 		return $this->render();
 	}
 
+	/**
+	 * Magic Method for handling dynamic functions.
+	 *
+	 * This method handles calls to dynamic with helpers.
+	 */
+	public function __call($method, $parameters)
+	{
+		if (strpos($method, 'with_') === 0)
+		{
+			$key = substr($method, 5);
+			return $this->with($key, $parameters[0]);
+		}
+
+		throw new \Exception("Method [$method] is not defined on the View class.");
+	}
+
 }