Browse Source

Merge branch 'staging'

Taylor Otwell 12 years ago
parent
commit
ae5331b312

+ 1 - 1
artisan

@@ -4,7 +4,7 @@
  * Laravel - A PHP Framework For Web Artisans
  * Laravel - A PHP Framework For Web Artisans
  *
  *
  * @package  Laravel
  * @package  Laravel
- * @version  3.2.8
+ * @version  3.2.9
  * @author   Taylor Otwell <taylorotwell@gmail.com>
  * @author   Taylor Otwell <taylorotwell@gmail.com>
  * @link     http://laravel.com
  * @link     http://laravel.com
  */
  */

+ 2 - 0
laravel/auth/drivers/driver.php

@@ -127,6 +127,8 @@ abstract class Driver {
 		$this->cookie($this->recaller(), null, -2000);
 		$this->cookie($this->recaller(), null, -2000);
 
 
 		Session::forget($this->token());
 		Session::forget($this->token());
+
+    $this->token = null;
 	}
 	}
 
 
 	/**
 	/**

+ 3 - 3
laravel/database/eloquent/model.php

@@ -528,7 +528,7 @@ abstract class Model {
 
 
 		foreach ($this->attributes as $key => $value)
 		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;
 				$dirty[$key] = $value;
 			}
 			}
@@ -544,7 +544,7 @@ abstract class Model {
 	 */
 	 */
 	public function get_key()
 	public function get_key()
 	{
 	{
-		return $this->get_attribute(static::$key);
+		return array_get($this->original, static::$key);
 	}
 	}
 
 
 	/**
 	/**
@@ -721,7 +721,7 @@ abstract class Model {
 		{
 		{
 			if (array_key_exists($key, $this->$source)) return true;
 			if (array_key_exists($key, $this->$source)) return true;
 		}
 		}
-		
+
 		if (method_exists($this, $key)) return true;
 		if (method_exists($this, $key)) return true;
 	}
 	}
 
 

+ 13 - 0
laravel/documentation/changes.md

@@ -2,6 +2,8 @@
 
 
 ## Contents
 ## Contents
 
 
+- [Laravel 3.2.9](#3.2.9)
+- [Upgrading From 3.2.8](#upgrade-3.2.9)
 - [Laravel 3.2.8](#3.2.8)
 - [Laravel 3.2.8](#3.2.8)
 - [Upgrading From 3.2.7](#upgrade-3.2.8)
 - [Upgrading From 3.2.7](#upgrade-3.2.8)
 - [Laravel 3.2.7](#3.2.7)
 - [Laravel 3.2.7](#3.2.7)
@@ -41,6 +43,17 @@
 - [Laravel 3.1](#3.1)
 - [Laravel 3.1](#3.1)
 - [Upgrading From 3.0](#upgrade-3.1)
 - [Upgrading From 3.0](#upgrade-3.1)
 
 
+<a name="3.2.9"></a>
+## Laravel 3.2.9
+
+- Always log exceptions even when there are "logger" event listeners.
+- Fix nasty view exception messages.
+
+<a name="upgrade-3.2.9"></a>
+### Upgrading From 3.2.8
+
+- Replace the **laravel** folder.
+
 <a name="3.2.8"></a>
 <a name="3.2.8"></a>
 ## Laravel 3.2.8
 ## Laravel 3.2.8
 
 

+ 14 - 2
laravel/error.php

@@ -15,6 +15,18 @@ class Error {
 
 
 		ob_get_level() and ob_end_clean();
 		ob_get_level() and ob_end_clean();
 
 
+		$message = $exception->getMessage();
+
+		// For Laravel view errors we want to show a prettier error:
+		$file = $exception->getFile();
+
+		if (str_contains($exception->getFile(), 'eval()') and str_contains($exception->getFile(), 'laravel/view.php'))
+		{
+			$message = 'Error rendering view: ['.View::$last['name'].']'.PHP_EOL.PHP_EOL.$message;
+
+			$file = View::$last['path'];
+		}
+
 		// If detailed errors are enabled, we'll just format the exception into
 		// If detailed errors are enabled, we'll just format the exception into
 		// a simple error message and display it on the screen. We don't use a
 		// a simple error message and display it on the screen. We don't use a
 		// View in case the problem is in the View class.
 		// View in case the problem is in the View class.
@@ -22,9 +34,9 @@ class Error {
 		{
 		{
 			echo "<html><h2>Unhandled Exception</h2>
 			echo "<html><h2>Unhandled Exception</h2>
 				  <h3>Message:</h3>
 				  <h3>Message:</h3>
-				  <pre>".$exception->getMessage()."</pre>
+				  <pre>".$message."</pre>
 				  <h3>Location:</h3>
 				  <h3>Location:</h3>
-				  <pre>".$exception->getFile()." on line ".$exception->getLine()."</pre>";
+				  <pre>".$file." on line ".$exception->getLine()."</pre>";
 
 
 			if ($trace)
 			if ($trace)
 			{
 			{

+ 1 - 1
laravel/laravel.php

@@ -137,7 +137,7 @@ $languages[] = Config::get('application.language');
 
 
 foreach ($languages as $language)
 foreach ($languages as $language)
 {
 {
-	if (starts_with($uri, $language))
+	if (preg_match("#^{$language}(?:$|/)#i", $uri))
 	{
 	{
 		Config::set('application.language', $language);
 		Config::set('application.language', $language);
 
 

+ 2 - 8
laravel/log.php

@@ -49,15 +49,9 @@ class Log {
 			Event::fire('laravel.log', array($type, $message));
 			Event::fire('laravel.log', array($type, $message));
 		}
 		}
 
 
-		// If there aren't listeners on the log event, we'll just write to the
-		// log files using the default conventions, writing one log file per
-		// day so the files don't get too crowded.
-		else
-		{
-			$message = static::format($type, $message);
+		$message = static::format($type, $message);
 
 
-			File::append(path('storage').'logs/'.date('Y-m-d').'.log', $message);
-		}
+		File::append(path('storage').'logs/'.date('Y-m-d').'.log', $message);
 	}
 	}
 
 
 	/**
 	/**

+ 16 - 11
laravel/str.php

@@ -9,17 +9,22 @@ class Str {
 	 */
 	 */
 	public static $pluralizer;
 	public static $pluralizer;
 
 
-	/**
-	 * Get the default string encoding for the application.
-	 *
-	 * This method is simply a short-cut to Config::get('application.encoding').
-	 *
-	 * @return string
-	 */
-	public static function encoding()
-	{
-		return Config::get('application.encoding');
-	}
+    /**
+     * Cache application encoding locally to save expensive calls to Config::get().
+     *
+     * @var string
+     */
+    public static $encoding = null;
+
+    /**
+     * Get the appliction.encoding without needing to request it from Config::get() each time.
+     *
+     * @return string
+     */
+    protected static function encoding()
+    {
+        return static::$encoding ?: static::$encoding = Config::get('application.encoding');
+    }
 
 
 	/**
 	/**
 	 * Get the length of a string.
 	 * Get the length of a string.

+ 15 - 0
laravel/tests/application/models/model.php

@@ -0,0 +1,15 @@
+<?php
+
+class Model extends Laravel\Database\Eloquent\Model {
+
+	public function set_setter($setter)
+	{
+		$this->set_attribute('setter', 'setter: '.$setter);
+	}
+
+	public function get_getter()
+	{
+		return 'getter: '.$this->get_attribute('getter');
+	}
+
+}

+ 0 - 3
laravel/tests/cases/auth.test.php

@@ -294,9 +294,6 @@ class AuthTest extends PHPUnit_Framework_TestCase {
 
 
 		Auth::logout();
 		Auth::logout();
 
 
-		// A workaround since Cookie will is only stored in memory, until Response class is called.
-		Auth::driver()->token = null;
-
 		$this->assertNull(Auth::user());
 		$this->assertNull(Auth::user());
 
 
 		$this->assertFalse(isset(Session::$instance->session['data']['laravel_auth_drivers_fluent_login']));
 		$this->assertFalse(isset(Session::$instance->session['data']['laravel_auth_drivers_fluent_login']));

+ 292 - 0
laravel/tests/cases/eloquent.test.php

@@ -0,0 +1,292 @@
+<?php
+
+class EloquentTest extends PHPUnit_Framework_TestCase {
+
+	/**
+	 * Test the Model constructor.
+	 *
+	 * @group laravel
+	 */
+	public function testAttributesAreSetByConstructor()
+	{
+		$array = array('name' => 'Taylor', 'age' => 25, 'setter' => 'foo');
+
+		$model = new Model($array);
+
+		$this->assertEquals('Taylor', $model->name);
+		$this->assertEquals(25, $model->age);
+		$this->assertEquals('setter: foo', $model->setter);
+	}
+
+	/**
+	 * Test the Model::fill method.
+	 *
+	 * @group laravel
+	 */
+	public function testAttributesAreSetByFillMethod()
+	{
+		$array = array('name' => 'Taylor', 'age' => 25, 'setter' => 'foo');
+
+		$model = new Model();
+		$model->fill($array);
+
+		$this->assertEquals('Taylor', $model->name);
+		$this->assertEquals(25, $model->age);
+		$this->assertEquals('setter: foo', $model->setter);
+	}
+
+	/**
+	 * Test the Model::fill_raw method.
+	 *
+	 * @group laravel
+	 */
+	public function testAttributesAreSetByFillRawMethod()
+	{
+		$array = array('name' => 'Taylor', 'age' => 25, 'setter' => 'foo');
+
+		$model = new Model();
+		$model->fill_raw($array);
+
+		$this->assertEquals($array, $model->attributes);
+	}
+
+	/**
+	 * Test the Model::fill method with accessible.
+	 *
+	 * @group laravel
+	 */
+	public function testAttributesAreSetByFillMethodWithAccessible()
+	{
+		Model::$accessible = array('name', 'age');
+
+		$array = array('name' => 'Taylor', 'age' => 25, 'foo' => 'bar');
+
+		$model = new Model();
+		$model->fill($array);
+
+		$this->assertEquals('Taylor', $model->name);
+		$this->assertEquals(25, $model->age);
+		$this->assertNull($model->foo);
+
+		Model::$accessible = null;
+	}
+
+	/**
+	 * Test the Model::fill method with empty accessible array.
+	 *
+	 * @group laravel
+	 */
+	public function testAttributesAreSetByFillMethodWithEmptyAccessible()
+	{
+		Model::$accessible = array();
+
+		$array = array('name' => 'Taylor', 'age' => 25, 'foo' => 'bar');
+
+		$model = new Model();
+		$model->fill($array);
+
+		$this->assertEquals(array(), $model->attributes);
+		$this->assertNull($model->name);
+		$this->assertNull($model->age);
+		$this->assertNull($model->foo);
+
+		Model::$accessible = null;
+	}
+
+	/**
+	 * Test the Model::fill_raw method with accessible.
+	 *
+	 * @group laravel
+	 */
+	public function testAttributesAreSetByFillRawMethodWithAccessible()
+	{
+		Model::$accessible = array('name', 'age');
+
+		$array = array('name' => 'taylor', 'age' => 25, 'setter' => 'foo');
+
+		$model = new Model();
+		$model->fill_raw($array);
+
+		$this->assertEquals($array, $model->attributes);
+
+		Model::$accessible = null;
+	}
+
+	/**
+	 * Test the Model::__set method.
+	 *
+	 * @group laravel
+	 */
+	public function testAttributeMagicSetterMethodChangesAttribute()
+	{
+		Model::$accessible = array('setter');
+
+		$array = array('setter' => 'foo', 'getter' => 'bar');
+
+		$model = new Model($array);
+		$model->setter = 'bar';
+		$model->getter = 'foo';
+
+		$this->assertEquals('setter: bar', $model->get_attribute('setter'));
+		$this->assertEquals('foo', $model->get_attribute('getter'));
+
+		Model::$accessible = null;
+	}
+
+	/**
+	 * Test the Model::__get method.
+	 *
+	 * @group laravel
+	 */
+	public function testAttributeMagicGetterMethodReturnsAttribute()
+	{
+		$array = array('setter' => 'foo', 'getter' => 'bar');
+
+		$model = new Model($array);
+
+		$this->assertEquals('setter: foo', $model->setter);
+		$this->assertEquals('getter: bar', $model->getter);
+	}
+
+	/**
+	 * Test the Model::set_* method.
+	 *
+	 * @group laravel
+	 */
+	public function testAttributeSetterMethodChangesAttribute()
+	{
+		Model::$accessible = array('setter');
+
+		$array = array('setter' => 'foo', 'getter' => 'bar');
+
+		$model = new Model($array);
+		$model->set_setter('bar');
+		$model->set_getter('foo');
+
+		$this->assertEquals('setter: bar', $model->get_attribute('setter'));
+		$this->assertEquals('foo', $model->get_attribute('getter'));
+
+		Model::$accessible = null;
+	}
+
+	/**
+	 * Test the Model::get_* method.
+	 *
+	 * @group laravel
+	 */
+	public function testAttributeGetterMethodReturnsAttribute()
+	{
+		$array = array('setter' => 'foo', 'getter' => 'bar');
+
+		$model = new Model($array);
+
+		$this->assertEquals('setter: foo', $model->get_setter());
+		$this->assertEquals('getter: bar', $model->get_getter());
+	}
+
+	/**
+	 * Test determination of dirty/changed attributes.
+	 *
+	 * @group laravel
+	 */
+	public function testDeterminationOfChangedAttributes()
+	{
+		$array = array('name' => 'Taylor', 'age' => 25, 'foo' => null);
+
+		$model = new Model($array, true);
+		$model->name = 'Otwell';
+		$model->new = null;
+
+		$this->assertTrue($model->changed('name'));
+		$this->assertFalse($model->changed('age'));
+		$this->assertFalse($model->changed('foo'));
+		$this->assertFalse($model->changed('new'));
+		$this->assertTrue($model->dirty());
+		$this->assertEquals(array('name' => 'Otwell', 'new' => null), $model->get_dirty());
+
+		$model->sync();
+
+		$this->assertFalse($model->changed('name'));
+		$this->assertFalse($model->changed('age'));
+		$this->assertFalse($model->changed('foo'));
+		$this->assertFalse($model->changed('new'));
+		$this->assertFalse($model->dirty());
+		$this->assertEquals(array(), $model->get_dirty());
+	}
+
+	/**
+	 * Test the Model::purge method.
+	 *
+	 * @group laravel
+	 */
+	public function testAttributePurge()
+	{
+		$array = array('name' => 'Taylor', 'age' => 25);
+
+		$model = new Model($array);
+		$model->name = 'Otwell';
+		$model->age = 26;
+
+		$model->purge('name');
+
+		$this->assertFalse($model->changed('name'));
+		$this->assertNull($model->name);
+		$this->assertTrue($model->changed('age'));
+		$this->assertEquals(26, $model->age);
+		$this->assertEquals(array('age' => 26), $model->get_dirty());
+	}
+
+	/**
+	 * Test the Model::table method.
+	 *
+	 * @group laravel
+	 */
+	public function testTableMethodReturnsCorrectName()
+	{
+		$model = new Model();
+		$this->assertEquals('models', $model->table());
+
+		Model::$table = 'table';
+		$this->assertEquals('table', $model->table());
+
+		Model::$table = null;
+		$this->assertEquals('models', $model->table());
+	}
+
+	/**
+	 * Test the Model::to_array method.
+	 *
+	 * @group laravel
+	 */
+	public function testConvertingToArray()
+	{
+		Model::$hidden = array('password', 'hidden');
+
+		$array = array('name' => 'Taylor', 'age' => 25, 'password' => 'laravel', 'null' => null);
+
+		$model = new Model($array);
+
+		$first = new Model(array('first' => 'foo', 'password' => 'hidden'));
+		$second = new Model(array('second' => 'bar', 'password' => 'hidden'));
+		$third = new Model(array('third' => 'baz', 'password' => 'hidden'));
+
+		$model->relationships['one'] = new Model(array('foo' => 'bar', 'password' => 'hidden'));
+		$model->relationships['many'] = array($first, $second, $third);
+		$model->relationships['hidden'] = new Model(array('should' => 'visible'));
+		$model->relationships['null'] = null;
+
+		$this->assertEquals(array(
+			'name' => 'Taylor', 'age' => 25, 'null' => null,
+			'one' => array('foo' => 'bar'),
+			'many' => array(
+				array('first' => 'foo'),
+				array('second' => 'bar'),
+				array('third' => 'baz'),
+			),
+			'hidden' => array('should' => 'visible'),
+			'null' => null,
+		), $model->to_array());
+
+	}
+
+}

+ 20 - 1
laravel/view.php

@@ -44,6 +44,13 @@ class View implements ArrayAccess {
 	 */
 	 */
 	public static $cache = array();
 	public static $cache = array();
 
 
+	/**
+	 * THe last view to be rendered.
+	 *
+	 * @var string
+	 */
+	public static $last;
+
 	/**
 	/**
 	 * The Laravel view loader event name.
 	 * The Laravel view loader event name.
 	 *
 	 *
@@ -367,7 +374,17 @@ class View implements ArrayAccess {
 			ob_get_clean(); throw $e;
 			ob_get_clean(); throw $e;
 		}
 		}
 
 
-		return ob_get_clean();
+		$content = ob_get_clean();
+
+		// The view filter event gives us a last chance to modify the
+		// evaluated contents of the view and return them. This lets
+		// us do something like run the contents through Jade, etc.
+		if (Event::listeners('view.filter'))
+		{
+			return Event::first('view.filter', array($content, $this->path));
+		}
+
+		return $content;
 	}
 	}
 
 
 	/**
 	/**
@@ -377,6 +394,8 @@ class View implements ArrayAccess {
 	 */
 	 */
 	protected function load()
 	protected function load()
 	{
 	{
+		static::$last = array('name' => $this->view, 'path' => $this->path);
+
 		if (isset(static::$cache[$this->path]))
 		if (isset(static::$cache[$this->path]))
 		{
 		{
 			return static::$cache[$this->path];
 			return static::$cache[$this->path];

+ 1 - 1
public/index.php

@@ -3,7 +3,7 @@
  * Laravel - A PHP Framework For Web Artisans
  * Laravel - A PHP Framework For Web Artisans
  *
  *
  * @package  Laravel
  * @package  Laravel
- * @version  3.2.8
+ * @version  3.2.9
  * @author   Taylor Otwell <taylorotwell@gmail.com>
  * @author   Taylor Otwell <taylorotwell@gmail.com>
  * @link     http://laravel.com
  * @link     http://laravel.com
  */
  */