Merge branch 'staging'
This commit is contained in:
commit
ae5331b312
2
artisan
2
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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -127,6 +127,8 @@ public function logout()
|
||||||
$this->cookie($this->recaller(), null, -2000);
|
$this->cookie($this->recaller(), null, -2000);
|
||||||
|
|
||||||
Session::forget($this->token());
|
Session::forget($this->token());
|
||||||
|
|
||||||
|
$this->token = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -528,7 +528,7 @@ public function get_dirty()
|
||||||
|
|
||||||
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 @@ public function get_dirty()
|
||||||
*/
|
*/
|
||||||
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 @@ public function __isset($key)
|
||||||
{
|
{
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@ # Laravel Change Log
|
||||||
|
|
||||||
## 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 @@ ## Contents
|
||||||
- [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
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,18 @@ public static function exception($exception, $trace = true)
|
||||||
|
|
||||||
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 @@ public static function exception($exception, $trace = true)
|
||||||
{
|
{
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -137,7 +137,7 @@
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
|
|
@ -49,15 +49,9 @@ public static function write($type, $message)
|
||||||
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
|
$message = static::format($type, $message);
|
||||||
// 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);
|
|
||||||
|
|
||||||
File::append(path('storage').'logs/'.date('Y-m-d').'.log', $message);
|
File::append(path('storage').'logs/'.date('Y-m-d').'.log', $message);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -9,17 +9,22 @@ class Str {
|
||||||
*/
|
*/
|
||||||
public static $pluralizer;
|
public static $pluralizer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the default string encoding for the application.
|
* Cache application encoding locally to save expensive calls to Config::get().
|
||||||
*
|
*
|
||||||
* This method is simply a short-cut to Config::get('application.encoding').
|
* @var string
|
||||||
*
|
*/
|
||||||
* @return string
|
public static $encoding = null;
|
||||||
*/
|
|
||||||
public static function encoding()
|
/**
|
||||||
{
|
* Get the appliction.encoding without needing to request it from Config::get() each time.
|
||||||
return Config::get('application.encoding');
|
*
|
||||||
}
|
* @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.
|
||||||
|
|
|
@ -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');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -294,9 +294,6 @@ public function testLogoutMethodLogsOutUser()
|
||||||
|
|
||||||
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']));
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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 @@ public function get()
|
||||||
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 @@ public function get()
|
||||||
*/
|
*/
|
||||||
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];
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue