diff --git a/apis.md b/apis.md
old mode 100644
new mode 100755
diff --git a/artisan.md b/artisan.md
old mode 100644
new mode 100755
diff --git a/authentication.md b/authentication.md
old mode 100644
new mode 100755
index 99edacc..d62fb1c
--- a/authentication.md
+++ b/authentication.md
@@ -79,7 +79,7 @@ If the redirect path needs custom generation logic you may define a `redirectTo`
protected function redirectTo()
{
- //
+ return '/path';
}
> {tip} The `redirectTo` method will take precedence over the `redirectTo` attribute.
@@ -226,7 +226,7 @@ The `intended` method on the redirector will redirect the user to the URL they w
#### Specifying Additional Conditions
-If you wish, you also may add extra conditions to the authentication query in addition to the user's e-mail and password. For example, we may verify that user is marked as "active":
+If you wish, you may also add extra conditions to the authentication query in addition to the user's e-mail and password. For example, we may verify that user is marked as "active":
if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
// The user is active, not suspended, and exists.
@@ -383,7 +383,7 @@ You may define your own authentication guards using the `extend` method on the `
}
}
-As you can see in the example above, the callback passed to the `extend` method should return an implementation of `Illuminate\Contracts\Auth\Guard`. This interface contains a few methods you will need to implement to define a custom guard. Once your custom guard has been defined, you may use the guard in the `guards` configuration of your `auth.php` configuration file:
+As you can see in the example above, the callback passed to the `extend` method should return an implementation of `Illuminate\Contracts\Auth\Guard`. This interface contains a few methods you will need to implement to define a custom guard. Once your custom guard has been defined, you may use this guard in the `guards` configuration of your `auth.php` configuration file:
'guards' => [
'api' => [
@@ -403,7 +403,7 @@ If you are not using a traditional relational database to store your users, you
use Illuminate\Support\Facades\Auth;
use App\Extensions\RiakUserProvider;
- use Illuminate\Support\ServiceProvider;
+ use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
@@ -466,7 +466,7 @@ The `retrieveById` function typically receives a key representing the user, such
The `retrieveByToken` function retrieves a user by their unique `$identifier` and "remember me" `$token`, stored in a field `remember_token`. As with the previous method, the `Authenticatable` implementation should be returned.
-The `updateRememberToken` method updates the `$user` field `remember_token` with the new `$token`. The new token can be either a fresh token, assigned on a successful "remember me" login attempt, or `null` when the user is logging out.
+The `updateRememberToken` method updates the `$user` field `remember_token` with the new `$token`. The new token can be either a fresh token, assigned on a successful "remember me" login attempt, or when the user is logging out.
The `retrieveByCredentials` method receives the array of credentials passed to the `Auth::attempt` method when attempting to sign into an application. The method should then "query" the underlying persistent storage for the user matching those credentials. Typically, this method will run a query with a "where" condition on `$credentials['username']`. The method should then return an implementation of `Authenticatable`. **This method should not attempt to do any password validation or authentication.**
diff --git a/authorization.md b/authorization.md
old mode 100644
new mode 100755
index 8974037..568531e
--- a/authorization.md
+++ b/authorization.md
@@ -48,6 +48,40 @@ Gates are Closures that determine if a user is authorized to perform a given act
});
}
+Gates may also be defined using a `Class@method` style callback string, like controllers:
+
+ /**
+ * Register any authentication / authorization services.
+ *
+ * @return void
+ */
+ public function boot()
+ {
+ $this->registerPolicies();
+
+ Gate::define('update-post', 'PostPolicy@update');
+ }
+
+#### Resource Gates
+
+You may also define multiple Gate abilities at once using the `resource` method:
+
+ Gate::resource('posts', 'PostPolicy');
+
+This is identical to manually defining the following Gate definitions:
+
+ Gate::define('posts.view', 'PostPolicy@view');
+ Gate::define('posts.create', 'PostPolicy@create');
+ Gate::define('posts.update', 'PostPolicy@update');
+ Gate::define('posts.delete', 'PostPolicy@delete');
+
+By default, the `view`, `create`, `update`, and `delete` abilities will be defined. You may override or add to the default abilities by passing an array as a third argument to the `resource` method. The keys of the array define the names of the abilities while the values define the method names. For example, the following code will create two new Gate definitions - `posts.image` and `posts.photo`:
+
+ Gate::resource('posts', 'PostPolicy', [
+ 'image' => 'updateImage',
+ 'photo' => 'updatePhoto',
+ ]);
+
### Authorizing Actions
@@ -318,10 +352,10 @@ These directives are convenient shortcuts for writing `@if` and `@unless` statem
Like most of the other authorization methods, you may pass a class name to the `@can` and `@cannot` directives if the action does not require a model instance:
- @can('create', Post::class)
+ @can('create', App\Post::class)
@endcan
- @cannot('create', Post::class)
+ @cannot('create', App\Post::class)
@endcannot
diff --git a/billing.md b/billing.md
old mode 100644
new mode 100755
index 83f7e5d..4e70577
--- a/billing.md
+++ b/billing.md
@@ -32,7 +32,7 @@
Laravel Cashier provides an expressive, fluent interface to [Stripe's](https://stripe.com) and [Braintree's](https://www.braintreepayments.com) subscription billing services. It handles almost all of the boilerplate subscription billing code you are dreading writing. In addition to basic subscription management, Cashier can handle coupons, swapping subscription, subscription "quantities", cancellation grace periods, and even generate invoice PDFs.
-> {note} If you're only performing "one-off" charges and do not offer subscriptions. You should not use Cashier. You should use the Stripe and Braintree SDKs directly.
+> {note} If you're only performing "one-off" charges and do not offer subscriptions, you should not use Cashier. Instead, use the Stripe and Braintree SDKs directly.
## Configuration
@@ -42,9 +42,9 @@ Laravel Cashier provides an expressive, fluent interface to [Stripe's](https://s
#### Composer
-First, add the Cashier package for Stripe to your `composer.json` file and run the `composer update` command:
+First, add the Cashier package for Stripe to your dependencies:
- "laravel/cashier": "~7.0"
+ composer require "laravel/cashier":"~7.0"
#### Service Provider
@@ -92,6 +92,7 @@ Finally, you should configure your Stripe key in your `services.php` configurati
'stripe' => [
'model' => App\User::class,
+ 'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET'),
],
@@ -110,13 +111,15 @@ For many operations, the Stripe and Braintree implementations of Cashier functio
#### Composer
-First, add the Cashier package for Braintree to your `composer.json` file and run the `composer update` command:
+First, add the Cashier package for Braintree to your dependencies:
- "laravel/cashier-braintree": "~2.0"
+ composer require "laravel/cashier-braintree":"~2.0"
#### Service Provider
-Next, register the `Laravel\Cashier\CashierServiceProvider` [service provider](/docs/{{version}}/providers) in your `config/app.php` configuration file.
+Next, register the `Laravel\Cashier\CashierServiceProvider` [service provider](/docs/{{version}}/providers) in your `config/app.php` configuration file:
+
+ Laravel\Cashier\CashierServiceProvider::class
#### Plan Credit Coupon
@@ -199,11 +202,11 @@ To create a subscription, first retrieve an instance of your billable model, whi
$user = User::find(1);
- $user->newSubscription('main', 'monthly')->create($stripeToken);
+ $user->newSubscription('main', 'premium')->create($stripeToken);
The first argument passed to the `newSubscription` method should be the name of the subscription. If your application only offers a single subscription, you might call this `main` or `primary`. The second argument is the specific Stripe / Braintree plan the user is subscribing to. This value should correspond to the plan's identifier in Stripe or Braintree.
-The `create` method will begin the subscription as well as update your database with the customer ID and other relevant billing information.
+The `create` method, which accepts a Stripe credit card / source token, will begin the subscription as well as update your database with the customer ID and other relevant billing information.
#### Additional User Details
@@ -310,7 +313,7 @@ Alternatively, you may set a specific quantity using the `updateQuantity` method
$user->subscription('main')->updateQuantity(10);
-For more information on subscription quantities, consult the [Stripe documentation](https://stripe.com/docs/guides/subscriptions#setting-quantities).
+For more information on subscription quantities, consult the [Stripe documentation](https://stripe.com/docs/subscriptions/quantities).
### Subscription Taxes
diff --git a/blade.md b/blade.md
old mode 100644
new mode 100755
index ebd3e10..cc36f1b
--- a/blade.md
+++ b/blade.md
@@ -144,23 +144,11 @@ Of course, you are not limited to displaying the contents of the variables passe
The current UNIX timestamp is {{ time() }}.
-> {note} Blade `{{ }}` statements are automatically sent through PHP's `htmlentities` function to prevent XSS attacks.
-
-#### Echoing Data If It Exists
-
-Sometimes you may wish to echo a variable, but you aren't sure if the variable has been set. We can express this in verbose PHP code like so:
-
- {{ isset($name) ? $name : 'Default' }}
-
-However, instead of writing a ternary statement, Blade provides you with the following convenient shortcut, which will be compiled to the ternary statement above:
-
- {{ $name or 'Default' }}
-
-In this example, if the `$name` variable exists, its value will be displayed. However, if it does not exist, the word `Default` will be displayed.
+> {note} Blade `{{ }}` statements are automatically sent through PHP's `htmlspecialchars` function to prevent XSS attacks.
#### Displaying Unescaped Data
-By default, Blade `{{ }}` statements are automatically sent through PHP's `htmlentities` function to prevent XSS attacks. If you do not want your data to be escaped, you may use the following syntax:
+By default, Blade `{{ }}` statements are automatically sent through PHP's `htmlspecialchars` function to prevent XSS attacks. If you do not want your data to be escaped, you may use the following syntax:
Hello, {!! $name !!}.
@@ -211,6 +199,16 @@ For convenience, Blade also provides an `@unless` directive:
You are not signed in.
@endunless
+In addition to the conditional directives already discussed, the `@isset` and `@empty` directives may be used as convenient shortcuts for their respective PHP functions:
+
+ @isset($records)
+ // $records is defined and is not null...
+ @endisset
+
+ @empty($records)
+ // $records is "empty"...
+ @endempty
+
### Loops
@@ -339,6 +337,10 @@ Of course, if you attempt to `@include` a view which does not exist, Laravel wil
@includeIf('view.name', ['some' => 'data'])
+If you would like to `@include` a view depending on a given boolean condition, you may use the `@includeWhen` directive:
+
+ @includeWhen($boolean, 'view.name', ['some' => 'data'])
+
> {note} You should avoid using the `__DIR__` and `__FILE__` constants in your Blade views, since they will refer to the location of the cached, compiled view.
@@ -354,6 +356,8 @@ You may also pass a fourth argument to the `@each` directive. This argument dete
@each('view.name', $jobs, 'job', 'view.empty')
+> {note} Views rendered via `@each` do not inherit the variables from the parent view. If the child view requires these variables, you should use `@foreach` and `@include` instead.
+
## Stacks
diff --git a/broadcasting.md b/broadcasting.md
old mode 100644
new mode 100755
index 596fff8..90b4e54
--- a/broadcasting.md
+++ b/broadcasting.md
@@ -1,4 +1,4 @@
-# Event Broadcasting
+# Broadcasting
- [Introduction](#introduction)
- [Configuration](#configuration)
@@ -9,6 +9,7 @@
- [Broadcast Name](#broadcast-name)
- [Broadcast Data](#broadcast-data)
- [Broadcast Queue](#broadcast-queue)
+ - [Broadcast Conditions](#broadcast-conditions)
- [Authorizing Channels](#authorizing-channels)
- [Defining Authorization Routes](#defining-authorization-routes)
- [Defining Authorization Callbacks](#defining-authorization-callbacks)
@@ -57,7 +58,7 @@ Before broadcasting any events, you will first need to register the `App\Provide
If you are broadcasting your events over [Pusher](https://pusher.com), you should install the Pusher PHP SDK using the Composer package manager:
- composer require pusher/pusher-php-server
+ composer require pusher/pusher-php-server "~2.6"
Next, you should configure your Pusher credentials in the `config/broadcasting.php` configuration file. An example Pusher configuration is already included in this file, allowing you to quickly specify your Pusher key, secret, and application ID. The `config/broadcasting.php` file's `pusher` configuration also allows you to specify additional `options` that are supported by Pusher, such as the cluster:
@@ -70,6 +71,8 @@ When using Pusher and [Laravel Echo](#installing-laravel-echo), you should speci
import Echo from "laravel-echo"
+ window.Pusher = require('pusher-js');
+
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'your-pusher-key'
@@ -242,6 +245,13 @@ By default, Laravel will broadcast the event using the event's class name. Howev
return 'server.created';
}
+If you customize the broadcast name using the `broadcastAs` method, you should make sure to register your listener with a leading `.` character. This will instruct Echo to not prepend the application's namespace to the event:
+
+ .listen('.server.created', function (e) {
+ ....
+ });
+
+
### Broadcast Data
@@ -279,6 +289,31 @@ By default, each broadcast event is placed on the default queue for the default
*/
public $broadcastQueue = 'your-queue-name';
+If you want to broadcast your event using the `sync` queue instead of the default queue driver, you can implement the `ShouldBroadcastNow` interface instead of `ShouldBroadcast`:
+
+
+### Broadcast Conditions
+
+Sometimes you want to broadcast your event only if a given condition is true. You may define these conditions by adding a `broadcastWhen` method to your event class:
+
+ /**
+ * Determine if this event should broadcast.
+ *
+ * @return bool
+ */
+ public function broadcastWhen()
+ {
+ return $this->value > 100;
+ }
+
## Authorizing Channels
@@ -437,7 +472,7 @@ All presence channels are also private channels; therefore, users must be [autho
The data returned by the authorization callback will be made available to the presence channel event listeners in your JavaScript application. If the user is not authorized to join the presence channel, you should return `false` or `null`:
- Broadcast::channel('chat.*', function ($user, $roomId) {
+ Broadcast::channel('chat.{roomId}', function ($user, $roomId) {
if ($user->canJoinRoom($roomId)) {
return ['id' => $user->id, 'name' => $user->name];
}
diff --git a/cache.md b/cache.md
old mode 100644
new mode 100755
diff --git a/collections.md b/collections.md
old mode 100644
new mode 100755
index e71060b..0dc4951
--- a/collections.md
+++ b/collections.md
@@ -48,13 +48,16 @@ For the remainder of this documentation, we'll discuss each method available on
[all](#method-all)
+[average](#method-average)
[avg](#method-avg)
[chunk](#method-chunk)
[collapse](#method-collapse)
[combine](#method-combine)
[contains](#method-contains)
+[containsStrict](#method-containsstrict)
[count](#method-count)
[diff](#method-diff)
+[diffAssoc](#method-diffassoc)
[diffKeys](#method-diffkeys)
[each](#method-each)
[every](#method-every)
@@ -71,15 +74,19 @@ For the remainder of this documentation, we'll discuss each method available on
[has](#method-has)
[implode](#method-implode)
[intersect](#method-intersect)
+[intersectKey](#method-intersectkey)
[isEmpty](#method-isempty)
+[isNotEmpty](#method-isnotempty)
[keyBy](#method-keyby)
[keys](#method-keys)
[last](#method-last)
[map](#method-map)
[mapWithKeys](#method-mapwithkeys)
[max](#method-max)
+[median](#method-median)
[merge](#method-merge)
[min](#method-min)
+[mode](#method-mode)
[nth](#method-nth)
[only](#method-only)
[partition](#method-partition)
@@ -105,16 +112,22 @@ For the remainder of this documentation, we'll discuss each method available on
[split](#method-split)
[sum](#method-sum)
[take](#method-take)
+[tap](#method-tap)
+[times](#method-times)
[toArray](#method-toarray)
[toJson](#method-tojson)
[transform](#method-transform)
[union](#method-union)
[unique](#method-unique)
+[uniqueStrict](#method-uniquestrict)
[values](#method-values)
+[when](#method-when)
[where](#method-where)
[whereStrict](#method-wherestrict)
[whereIn](#method-wherein)
[whereInStrict](#method-whereinstrict)
+[whereNotIn](#method-wherenotin)
+[whereNotInStrict](#method-wherenotinstrict)
[zip](#method-zip)
@@ -141,25 +154,23 @@ The `all` method returns the underlying array represented by the collection:
// [1, 2, 3]
-
-#### `avg()` {#collection-method}
+
+#### `average()` {#collection-method}
-The `avg` method returns the average of all items in the collection:
+Alias for the [`avg`](#method-avg) method.
- collect([1, 2, 3, 4, 5])->avg();
+
+#### `avg()` {#collection-method}
- // 3
+The `avg` method returns the [average value](https://en.wikipedia.org/wiki/Average) of a given key:
-If the collection contains nested arrays or objects, you should pass a key to use for determining which values to calculate the average:
+ $average = collect([['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->avg('foo');
- $collection = collect([
- ['name' => 'JavaScript: The Good Parts', 'pages' => 176],
- ['name' => 'JavaScript: The Definitive Guide', 'pages' => 1096],
- ]);
+ // 20
- $collection->avg('pages');
+ $average = collect([1, 1, 2, 4])->avg();
- // 636
+ // 2
#### `chunk()` {#collection-method}
@@ -246,6 +257,13 @@ Finally, you may also pass a callback to the `contains` method to perform your o
// false
+The `contains` method uses "loose" comparisons when checking item values, meaning a string with an integer value will be considered equal to an integer of the same value. Use the [`containsStrict`](#method-containsstrict) method to filter using "strict" comparisons.
+
+
+#### `containsStrict()` {#collection-method}
+
+This method has the same signature as the [`contains`](#method-contains) method; however, all values are compared using "strict" comparisons.
+
#### `count()` {#collection-method}
@@ -270,6 +288,28 @@ The `diff` method compares the collection against another collection or a plain
// [1, 3, 5]
+
+#### `diffAssoc()` {#collection-method}
+
+The `diffAssoc` method compares the collection against another collection or a plain PHP `array` based on its keys and values. This method will return the key / value pairs in the original collection that are not present in the given collection:
+
+ $collection = collect([
+ 'color' => 'orange',
+ 'type' => 'fruit',
+ 'remain' => 6
+ ]);
+
+ $diff = $collection->diffAssoc([
+ 'color' => 'yellow',
+ 'type' => 'fruit',
+ 'remain' => 3,
+ 'used' => 6
+ ]);
+
+ $diff->all();
+
+ // ['color' => 'orange', 'remain' => 6]
+
#### `diffKeys()` {#collection-method}
@@ -594,6 +634,23 @@ The `intersect` method removes any values from the original collection that are
// [0 => 'Desk', 2 => 'Chair']
+
+#### `intersectKey()` {#collection-method}
+
+The `intersectKey` method removes any keys from the original collection that are not present in the given `array` or collection:
+
+ $collection = collect([
+ 'serial' => 'UX301', 'type' => 'screen', 'year' => 2009
+ ]);
+
+ $intersect = $collection->intersectKey([
+ 'reference' => 'UX404', 'type' => 'tab', 'year' => 2011
+ ]);
+
+ $intersect->all();
+
+ // ['type' => 'screen', 'year' => 2009]
+
#### `isEmpty()` {#collection-method}
@@ -603,6 +660,15 @@ The `isEmpty` method returns `true` if the collection is empty; otherwise, `fals
// true
+
+#### `isNotEmpty()` {#collection-method}
+
+The `isNotEmpty` method returns `true` if the collection is not empty; otherwise, `false` is returned:
+
+ collect([])->isNotEmpty();
+
+ // false
+
#### `keyBy()` {#collection-method}
@@ -639,7 +705,6 @@ You may also pass a callback to the method. The callback should return the value
]
*/
-
#### `keys()` {#collection-method}
@@ -734,10 +799,23 @@ The `max` method returns the maximum value of a given key:
// 5
+
+#### `median()` {#collection-method}
+
+The `median` method returns the [median value](https://en.wikipedia.org/wiki/Median) of a given key:
+
+ $median = collect([['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->median('foo');
+
+ // 15
+
+ $median = collect([1, 1, 2, 4])->median();
+
+ // 1.5
+
#### `merge()` {#collection-method}
-The `merge` method merges the given array with the original collection. If a string key in the given array matches a string key in the original collection, the given array's value will overwrite the value in the original collection:
+The `merge` method merges the given array or collection with the original collection. If a string key in the given items matches a string key in the original collection, the given items's value will overwrite the value in the original collection:
$collection = collect(['product_id' => 1, 'price' => 100]);
@@ -747,7 +825,7 @@ The `merge` method merges the given array with the original collection. If a str
// ['product_id' => 1, 'price' => 200, 'discount' => false]
-If the given array's keys are numeric, the values will be appended to the end of the collection:
+If the given items's keys are numeric, the values will be appended to the end of the collection:
$collection = collect(['Desk', 'Chair']);
@@ -770,6 +848,19 @@ The `min` method returns the minimum value of a given key:
// 1
+
+#### `mode()` {#collection-method}
+
+The `mode` method returns the [mode value](https://en.wikipedia.org/wiki/Mode_(statistics)) of a given key:
+
+ $mode = collect([['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->mode('foo');
+
+ // [10]
+
+ $mode = collect([1, 1, 2, 4])->mode();
+
+ // [1]
+
#### `nth()` {#collection-method}
@@ -880,13 +971,13 @@ The `prepend` method adds an item to the beginning of the collection:
You may also pass a second argument to set the key of the prepended item:
- $collection = collect(['one' => 1, 'two', => 2]);
+ $collection = collect(['one' => 1, 'two' => 2]);
$collection->prepend(0, 'zero');
$collection->all();
- // ['zero' => 0, 'one' => 1, 'two', => 2]
+ // ['zero' => 0, 'one' => 1, 'two' => 2]
#### `pull()` {#collection-method}
@@ -1010,7 +1101,7 @@ The `search` method searches the collection for the given value and returns its
// 1
-The search is done using a "loose" comparison, meaning a string with an integer value will be considered equal to an integer of the same value. To use strict comparison, pass `true` as the second argument to the method:
+The search is done using a "loose" comparison, meaning a string with an integer value will be considered equal to an integer of the same value. To use "strict" comparison, pass `true` as the second argument to the method:
$collection->search('4', true);
@@ -1050,7 +1141,7 @@ The `shuffle` method randomly shuffles the items in the collection:
$shuffled->all();
- // [3, 2, 5, 1, 4] // (generated randomly)
+ // [3, 2, 5, 1, 4] - (generated randomly)
#### `slice()` {#collection-method}
@@ -1073,7 +1164,7 @@ If you would like to limit the size of the returned slice, pass the desired size
// [5, 6]
-The returned slice will preserve keys by default. If you do not wish to preserve the original keys, you can use the `values` method to reindex them.
+The returned slice will preserve keys by default. If you do not wish to preserve the original keys, you can use the [`values`](#method-values) method to reindex them.
#### `sort()` {#collection-method}
@@ -1257,6 +1348,49 @@ You may also pass a negative integer to take the specified amount of items from
// [4, 5]
+
+#### `tap()` {#collection-method}
+
+The `tap` method passes the collection to the given callback, allowing you to "tap" into the collection at a specific point and do something with the items while not affecting the collection itself:
+
+ collect([2, 4, 3, 1, 5])
+ ->sort()
+ ->tap(function ($collection) {
+ Log::debug('Values after sorting', $collection->values()->toArray());
+ })
+ ->shift();
+
+ // 1
+
+
+#### `times()` {#collection-method}
+
+The static `times` method creates a new collection by invoking the callback a given amount of times:
+
+ $collection = Collection::times(10, function ($number) {
+ return $number * 9;
+ });
+
+ $collection->all();
+
+ // [9, 18, 27, 36, 45, 54, 63, 72, 81, 90]
+
+This method can be useful when combined with factories to create [Eloquent](/docs/{{version}}/eloquent) models:
+
+ $categories = Collection::times(3, function ($number) {
+ return factory(Category::class)->create(['name' => 'Category #'.$number]);
+ });
+
+ $categories->all();
+
+ /*
+ [
+ ['id' => 1, 'name' => 'Category #1'],
+ ['id' => 2, 'name' => 'Category #2'],
+ ['id' => 3, 'name' => 'Category #3'],
+ ]
+ */
+
#### `toArray()` {#collection-method}
@@ -1277,7 +1411,7 @@ The `toArray` method converts the collection into a plain PHP `array`. If the co
#### `toJson()` {#collection-method}
-The `toJson` method converts the collection into JSON:
+The `toJson` method converts the collection into a JSON serialized string:
$collection = collect(['name' => 'Desk', 'price' => 200]);
@@ -1366,6 +1500,13 @@ You may also pass your own callback to determine item uniqueness:
]
*/
+The `unique` method uses "loose" comparisons when checking item values, meaning a string with an integer value will be considered equal to an integer of the same value. Use the [`uniqueStrict`](#method-uniquestrict) method to filter using "strict" comparisons.
+
+
+#### `uniqueStrict()` {#collection-method}
+
+This method has the same signature as the [`unique`](#method-unique) method; however, all values are compared using "strict" comparisons.
+
#### `values()` {#collection-method}
@@ -1386,6 +1527,22 @@ The `values` method returns a new collection with the keys reset to consecutive
1 => ['product' => 'Desk', 'price' => 200],
]
*/
+
+
+#### `when()` {#collection-method}
+
+The `when` method will execute the given callback when the first argument given to the method evaluates to `true`:
+
+ $collection = collect([1, 2, 3]);
+
+ $collection->when(true, function ($collection) {
+ return $collection->push(4);
+ });
+
+ $collection->all();
+
+ // [1, 2, 3, 4]
+
#### `where()` {#collection-method}
@@ -1403,13 +1560,13 @@ The `where` method filters the collection by a given key / value pair:
$filtered->all();
/*
- [
- ['product' => 'Chair', 'price' => 100],
- ['product' => 'Door', 'price' => 100],
- ]
+ [
+ ['product' => 'Chair', 'price' => 100],
+ ['product' => 'Door', 'price' => 100],
+ ]
*/
-The `where` method uses loose comparisons when checking item values. Use the [`whereStrict`](#method-wherestrict) method to filter using "strict" comparisons.
+The `where` method uses "loose" comparisons when checking item values, meaning a string with an integer value will be considered equal to an integer of the same value. Use the [`whereStrict`](#method-wherestrict) method to filter using "strict" comparisons.
#### `whereStrict()` {#collection-method}
@@ -1419,7 +1576,7 @@ This method has the same signature as the [`where`](#method-where) method; howev
#### `whereIn()` {#collection-method}
-The `whereIn` method filters the collection by a given key / value contained within the given array.
+The `whereIn` method filters the collection by a given key / value contained within the given array:
$collection = collect([
['product' => 'Desk', 'price' => 200],
@@ -1433,18 +1590,48 @@ The `whereIn` method filters the collection by a given key / value contained wit
$filtered->all();
/*
- [
- ['product' => 'Bookcase', 'price' => 150],
- ['product' => 'Desk', 'price' => 200],
- ]
+ [
+ ['product' => 'Bookcase', 'price' => 150],
+ ['product' => 'Desk', 'price' => 200],
+ ]
*/
-The `whereIn` method uses "loose" comparisons when checking item values. Use the [`whereInStrict`](#method-whereinstrict) method to filter using strict comparisons.
+The `whereIn` method uses "loose" comparisons when checking item values, meaning a string with an integer value will be considered equal to an integer of the same value. Use the [`whereInStrict`](#method-whereinstrict) method to filter using "strict" comparisons.
#### `whereInStrict()` {#collection-method}
-This method has the same signature as the [`whereIn`](#method-wherein) method; however, all values are compared using strict comparisons.
+This method has the same signature as the [`whereIn`](#method-wherein) method; however, all values are compared using "strict" comparisons.
+
+
+#### `whereNotIn()` {#collection-method}
+
+The `whereNotIn` method filters the collection by a given key / value not contained within the given array:
+
+ $collection = collect([
+ ['product' => 'Desk', 'price' => 200],
+ ['product' => 'Chair', 'price' => 100],
+ ['product' => 'Bookcase', 'price' => 150],
+ ['product' => 'Door', 'price' => 100],
+ ]);
+
+ $filtered = $collection->whereNotIn('price', [150, 200]);
+
+ $filtered->all();
+
+ /*
+ [
+ ['product' => 'Chair', 'price' => 100],
+ ['product' => 'Door', 'price' => 100],
+ ]
+ */
+
+The `whereNotIn` method uses "loose" comparisons when checking item values, meaning a string with an integer value will be considered equal to an integer of the same value. Use the [`whereNotInStrict`](#method-wherenotinstrict) method to filter using "strict" comparisons.
+
+
+#### `whereNotInStrict()` {#collection-method}
+
+This method has the same signature as the [`whereNotIn`](#method-wherenotin) method; however, all values are compared using "strict" comparisons.
#### `zip()` {#collection-method}
@@ -1462,7 +1649,7 @@ The `zip` method merges together the values of the given array with the values o
## Higher Order Messages
-Collections also provide support for "higher order messages", which are short-cuts for performing common actions on collections. The collection methods that provide higher order messages are: `contains`, `each`, `every`, `filter`, `first`, `map`, `partition`, `reject`, `sortBy`, `sortByDesc`, and `sum`.
+Collections also provide support for "higher order messages", which are short-cuts for performing common actions on collections. The collection methods that provide higher order messages are: `average`, `avg`, `contains`, `each`, `every`, `filter`, `first`, `flatMap`, `map`, `partition`, `reject`, `sortBy`, `sortByDesc`, and `sum`.
Each higher order message can be accessed as a dynamic property on a collection instance. For instance, let's use the `each` higher order message to call a method on each object within a collection:
diff --git a/configuration.md b/configuration.md
old mode 100644
new mode 100755
index a72764b..568153a
--- a/configuration.md
+++ b/configuration.md
@@ -2,6 +2,7 @@
- [Introduction](#introduction)
- [Environment Configuration](#environment-configuration)
+ - [Retrieving Environment Configuration](#retrieving-environment-configuration)
- [Determining The Current Environment](#determining-the-current-environment)
- [Accessing Configuration Values](#accessing-configuration-values)
- [Configuration Caching](#configuration-caching)
@@ -15,13 +16,18 @@ All of the configuration files for the Laravel framework are stored in the `conf
## Environment Configuration
-It is often helpful to have different configuration values based on the environment the application is running in. For example, you may wish to use a different cache driver locally than you do on your production server.
+It is often helpful to have different configuration values based on the environment where the application is running. For example, you may wish to use a different cache driver locally than you do on your production server.
To make this a cinch, Laravel utilizes the [DotEnv](https://github.com/vlucas/phpdotenv) PHP library by Vance Lucas. In a fresh Laravel installation, the root directory of your application will contain a `.env.example` file. If you install Laravel via Composer, this file will automatically be renamed to `.env`. Otherwise, you should rename the file manually.
-> {tip} You may also create a `.env.testing` file. This file will override values from the `.env` file when running PHPUnit tests or executing Artisan commands with the `--env=testing` option.
+Your `.env` file should not be committed to your application's source control, since each developer / server using your application could require a different environment configuration. Furthermore, this would be a security risk in the event an intruder gain access to your source control repository, since any sensitive credentials would get exposed.
-#### Retrieving Environment Configuration
+If you are developing with a team, you may wish to continue including a `.env.example` file with your application. By putting place-holder values in the example configuration file, other developers on your team can clearly see which environment variables are needed to run your application. You may also create a `.env.testing` file. This file will override values from the `.env` file when running PHPUnit tests or executing Artisan commands with the `--env=testing` option.
+
+> {tip} Any variable in your `.env` file can be overridden by external environment variables such as server-level or system-level environment variables.
+
+
+### Retrieving Environment Configuration
All of the variables listed in this file will be loaded into the `$_ENV` PHP super-global when your application receives a request. However, you may use the `env` helper to retrieve values from these variables in your configuration files. In fact, if you review the Laravel configuration files, you will notice several of the options already using this helper:
@@ -29,10 +35,6 @@ All of the variables listed in this file will be loaded into the `$_ENV` PHP sup
The second value passed to the `env` function is the "default value". This value will be used if no environment variable exists for the given key.
-Your `.env` file should not be committed to your application's source control, since each developer / server using your application could require a different environment configuration.
-
-If you are developing with a team, you may wish to continue including a `.env.example` file with your application. By putting place-holder values in the example configuration file, other developers on your team can clearly see which environment variables are needed to run your application.
-
### Determining The Current Environment
@@ -46,10 +48,12 @@ You may also pass arguments to the `environment` method to check if the environm
// The environment is local
}
- if (App::environment('local', 'staging')) {
+ if (App::environment(['local', 'staging'])) {
// The environment is either local OR staging...
}
+> {tip} The current application environment detection can be overriden by a server-level `APP_ENV` environment variable. This can be useful when you need to share the same application for different environment configurations, so you can set up a given host to match a given environment in your server's configurations.
+
## Accessing Configuration Values
@@ -87,9 +91,7 @@ To disable maintenance mode, use the `up` command:
php artisan up
-#### Maintenance Mode Response Template
-
-The default template for maintenance mode responses is located in `resources/views/errors/503.blade.php`. You are free to modify this view as needed for your application.
+> {tip} You may customize the default maintenance mode template by defining your own template at `resources/views/errors/503.blade.php`.
#### Maintenance Mode & Queues
diff --git a/container.md b/container.md
old mode 100644
new mode 100755
index 5431105..365911c
--- a/container.md
+++ b/container.md
@@ -10,6 +10,7 @@
- [The Make Method](#the-make-method)
- [Automatic Injection](#automatic-injection)
- [Container Events](#container-events)
+- [PSR-11](#psr-11)
## Introduction
@@ -98,7 +99,7 @@ You may also bind an existing object instance into the container using the `inst
$api = new HelpSpot\API(new HttpClient);
- $this->app->instance('HelpSpot\Api', $api);
+ $this->app->instance('HelpSpot\API', $api);
#### Binding Primitives
@@ -190,6 +191,10 @@ If you are in a location of your code that does not have access to the `$app` va
$api = resolve('HelpSpot\API');
+If some of your class' dependencies are not resolvable via the container, you may inject them by passing them as an associative array into the `makeWith` method:
+
+ $api = $this->app->makeWith('HelpSpot\API', ['id' => 1]);
+
#### Automatic Injection
@@ -247,3 +252,18 @@ The service container fires an event each time it resolves an object. You may li
});
As you can see, the object being resolved will be passed to the callback, allowing you to set any additional properties on the object before it is given to its consumer.
+
+
+## PSR-11
+
+Laravel's service container implements the [PSR-11](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-11-container.md) interface. Therefore, you may type-hint the PSR-11 container interface to obtain an instance of the Laravel container:
+
+ use Psr\Container\ContainerInterface;
+
+ Route::get('/', function (ContainerInterface $container) {
+ $service = $container->get('Service');
+
+ //
+ });
+
+> {note} Calling the `get` method will throw an exception if the identifier has not been explicitly bound into the container.
diff --git a/contracts.md b/contracts.md
old mode 100644
new mode 100755
index 4d8a820..df6819d
--- a/contracts.md
+++ b/contracts.md
@@ -192,7 +192,7 @@ Contract | References Facade
[Illuminate\Contracts\Mail\Mailer](https://github.com/illuminate/contracts/blob/{{version}}/Mail/Mailer.php) | Mail
[Illuminate\Contracts\Queue\Factory](https://github.com/illuminate/contracts/blob/{{version}}/Queue/Factory.php) | Queue::driver()
[Illuminate\Contracts\Queue\Queue](https://github.com/illuminate/contracts/blob/{{version}}/Queue/Queue.php) | Queue
-[Illuminate\Contracts\Redis\Database](https://github.com/illuminate/contracts/blob/{{version}}/Redis/Database.php) | Redis
+[Illuminate\Contracts\Redis\Factory](https://github.com/illuminate/contracts/blob/{{version}}/Redis/Factory.php) | Redis
[Illuminate\Contracts\Routing\Registrar](https://github.com/illuminate/contracts/blob/{{version}}/Routing/Registrar.php) | Route
[Illuminate\Contracts\Routing\ResponseFactory](https://github.com/illuminate/contracts/blob/{{version}}/Routing/ResponseFactory.php) | Response
[Illuminate\Contracts\Routing\UrlGenerator](https://github.com/illuminate/contracts/blob/{{version}}/Routing/UrlGenerator.php) | URL
diff --git a/contributing.md b/contributing.md
old mode 100644
new mode 100755
index 266c057..e68c3d3
--- a/contributing.md
+++ b/contributing.md
@@ -1,17 +1,3 @@
-# ပူးပေါင်းပါဝင်မှု လမ်းညွန်
+# Contribution Guidelines
-###ဘာသာပြန်ခြင်း
-
- - ကျွန်တော်တို့ကို ပူးပေါင်းပါဝင် ကူညီပြီးဘာသာပြန်ချင်တယ်ဆိုရင်
- [docs](https://github.com/setkyar/laravel-docs/) ကိုဦးစွာ Fork လုပ်ပါ၊
-
- - ဘယ်အပိုင်းကို ဘာသာပြန်မည်ဆိုတာကို [Facebook](https://www.facebook.com/groups/250409601822202/) မှာပြောပေးပါ။ (Fork
- လုပ်ပြီးဘာသာပြန်နေတုန်းအခြားတစ်ယောက်ယောက်ကပါဘာသာပြန်နေတာမျိုးဖြစ်မှာစိုးလို့ပါ)
-
- - သင်ဘာသာပြန်မည့် File ကိုဘာသာပြန်ပါ။ ဘာသာပြန်ပြီးရင် မူရင်း repo ဆီက
- [pull request](https://github.com/setkyar/laravel-docs/pulls) တောင်းပါ။ (pull request တောင်းတာကို မြန်မြန် accept
- လုပ်စေချင်တယ်ဆိုရင်[Facebook]( https://www.facebook.com/groups/250409601822202/) မှာပါတင်ပေးပါ)
-
-###ဘာသာပြန်အဆင်ပြေမှူနှင့် စာလုံးပေါင်းအမှား
-
-ဘာသာပြန်ထားတာတွေ ကိုဦးစွာဖတ်ပါ။ ဘာသာပြန်အဆင်ပြေမှူ နဲ့ စာလုံးပေါင်း အမှားတွေကို စစ်ပါ။ ဘာသာပြန်အဆင်ပြေမှူမရှိတာတို့ စာလုံးပေါင်းအမှားတွေတွေ့ရင် GitHub မှာ [issue](https://github.com/setkyar/laravel-docs/issues) တင်ပေးပါ။(အမှားတွေကို အမြန်ဆုံး စစ်ပေးဖို့ [Facebook](https://www.facebook.com/groups/250409601822202/) မှာပါတင်ပေးပါ)
+If you are submitting documentation for the **current stable release**, submit it to the corresponding branch. For example, documentation for Laravel 5.1 would be submitted to the `5.1` branch. Documentation intended for the next release of Laravel should be submitted to the `master` branch.
\ No newline at end of file
diff --git a/contributions.md b/contributions.md
old mode 100644
new mode 100755
index 9c94c09..f0f9d80
--- a/contributions.md
+++ b/contributions.md
@@ -19,19 +19,21 @@ Remember, bug reports are created in the hope that others with the same problem
The Laravel source code is managed on Github, and there are repositories for each of the Laravel projects:
-- [Laravel Framework](https://github.com/laravel/framework)
+
- [Laravel Application](https://github.com/laravel/laravel)
+- [Laravel Art](https://github.com/laravel/art)
- [Laravel Documentation](https://github.com/laravel/docs)
- [Laravel Cashier](https://github.com/laravel/cashier)
- [Laravel Cashier for Braintree](https://github.com/laravel/cashier-braintree)
- [Laravel Envoy](https://github.com/laravel/envoy)
+- [Laravel Framework](https://github.com/laravel/framework)
- [Laravel Homestead](https://github.com/laravel/homestead)
- [Laravel Homestead Build Scripts](https://github.com/laravel/settler)
- [Laravel Passport](https://github.com/laravel/passport)
- [Laravel Scout](https://github.com/laravel/scout)
- [Laravel Socialite](https://github.com/laravel/socialite)
- [Laravel Website](https://github.com/laravel/laravel.com)
-- [Laravel Art](https://github.com/laravel/art)
+
## Core Development Discussion
diff --git a/controllers.md b/controllers.md
old mode 100644
new mode 100755
index 307df0d..0348d48
--- a/controllers.md
+++ b/controllers.md
@@ -10,6 +10,7 @@
- [Partial Resource Routes](#restful-partial-resource-routes)
- [Naming Resource Routes](#restful-naming-resource-routes)
- [Naming Resource Route Parameters](#restful-naming-resource-route-parameters)
+ - [Localizing Resource URIs](#restful-localizing-resource-uris)
- [Supplementing Resource Controllers](#restful-supplementing-resource-controllers)
- [Dependency Injection & Controllers](#dependency-injection-and-controllers)
- [Route Caching](#route-caching)
@@ -205,6 +206,32 @@ By default, `Route::resource` will create the route parameters for your resource
/user/{admin_user}
+
+### Localizing Resource URIs
+
+By default, `Route::resource` will create resource URIs using English verbs. If you need to localize the `create` and `edit` action verbs, you may use the `Route::resourceVerbs` method. This may be done in the `boot` method of your `AppServiceProvider`:
+
+ use Illuminate\Support\Facades\Route;
+
+ /**
+ * Bootstrap any application services.
+ *
+ * @return void
+ */
+ public function boot()
+ {
+ Route::resourceVerbs([
+ 'create' => 'crear',
+ 'edit' => 'editar',
+ ]);
+ }
+
+Once the verbs have been customized, a resource route registration such as `Route::resource('fotos', 'PhotoController')` will produce the following URIs:
+
+ /fotos/crear
+
+ /fotos/{foto}/editar
+
### Supplementing Resource Controllers
diff --git a/csrf.md b/csrf.md
old mode 100644
new mode 100755
index 7533ffc..4694d34
--- a/csrf.md
+++ b/csrf.md
@@ -21,6 +21,10 @@ Anytime you define a HTML form in your application, you should include a hidden
The `VerifyCsrfToken` [middleware](/docs/{{version}}/middleware), which is included in the `web` middleware group, will automatically verify that the token in the request input matches the token stored in the session.
+#### CSRF Tokens & JavaScript
+
+When building JavaScript driven applications, it is convenient to have your JavaScript HTTP library automatically attach the CSRF token to every outgoing request. By default, the `resources/assets/js/bootstrap.js` file registers the value of the `csrf-token` meta tag with the Axios HTTP library. If you are not using this library, you will need to manually configure this behavior for your application.
+
## Excluding URIs From CSRF Protection
@@ -61,9 +65,11 @@ Then, once you have created the `meta` tag, you can instruct a library like jQue
}
});
+> {tip} By default, the `resources/assets/js/bootstrap.js` file registers the value of the `csrf-token` meta tag with the Axios HTTP library. If you are not using this library, you will need to manually configure this behavior for your application.
+
## X-XSRF-TOKEN
Laravel stores the current CSRF token in a `XSRF-TOKEN` cookie that is included with each response generated by the framework. You can use the cookie value to set the `X-XSRF-TOKEN` request header.
-This cookie is primarily sent as a convenience since some JavaScript frameworks, like Angular, automatically place its value in the `X-XSRF-TOKEN` header.
+This cookie is primarily sent as a convenience since some JavaScript frameworks and libraries, like Angular and Axios, automatically place its value in the `X-XSRF-TOKEN` header.
diff --git a/database-testing.md b/database-testing.md
old mode 100644
new mode 100755
index 36f10e8..1684d5a
--- a/database-testing.md
+++ b/database-testing.md
@@ -10,6 +10,7 @@
- [Creating Models](#creating-models)
- [Persisting Models](#persisting-models)
- [Relationships](#relationships)
+- [Available Assertions](#available-assertions)
## Introduction
@@ -25,6 +26,8 @@ Laravel provides a variety of helpful tools to make it easier to test your datab
]);
}
+You can also used the `assertDatabaseMissing` helper to assert that data does not exist in the database.
+
Of course, the `assertDatabaseHas` method and other helpers like it are for convenience. You are free to use any of PHPUnit's built-in assertion methods to supplement your tests.
@@ -119,11 +122,17 @@ Of course, you are free to add your own additional factories to the `ModelFactor
### Factory States
-States allow you to define discrete modifications that can be applied to your model factories in any combination. For example, your `User` model might have a `delinquent` state that modifies one of its default attribute values. You may define your state transformations using the `state` method:
+States allow you to define discrete modifications that can be applied to your model factories in any combination. For example, your `User` model might have a `delinquent` state that modifies one of its default attribute values. You may define your state transformations using the `state` method. For simple states, you may pass an array of attribute modifications:
+
+ $factory->state(App\User::class, 'delinquent', [
+ 'account_status' => 'delinquent',
+ ]);
+
+If your state requires calculation or a `$faker` instance, you may use a Closure to calculate the state's attribute modifications:
- $factory->state(App\User::class, 'delinquent', function ($faker) {
+ $factory->state(App\User::class, 'address', function ($faker) {
return [
- 'account_status' => 'delinquent',
+ 'address' => $faker->address,
];
});
@@ -224,3 +233,14 @@ These Closures also receive the evaluated attribute array of the factory that de
}
];
});
+
+
+## Available Assertions
+
+Laravel provides several database assertions for your [PHPUnit](https://phpunit.de/) tests:
+
+Method | Description
+------------- | -------------
+`$this->assertDatabaseHas($table, array $data);` | Assert that a table in the database contains the given data.
+`$this->assertDatabaseMissing($table, array $data);` | Assert that a table in the database does not contain the given data.
+`$this->assertSoftDeleted($table, array $data);` | Assert that the given record has been soft deleted.
diff --git a/database.md b/database.md
old mode 100644
new mode 100755
index 3090a0f..701304a
--- a/database.md
+++ b/database.md
@@ -66,8 +66,8 @@ To see how read / write connections should be configured, let's look at this exa
'database' => 'database',
'username' => 'root',
'password' => '',
- 'charset' => 'utf8',
- 'collation' => 'utf8_unicode_ci',
+ 'charset' => 'utf8mb4',
+ 'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
],
diff --git a/documentation.md b/documentation.md
old mode 100644
new mode 100755
index ab11db8..1c6d510
--- a/documentation.md
+++ b/documentation.md
@@ -1,22 +1,21 @@
-- Prologue
+- ## Prologue
- [Release Notes](/docs/{{version}}/releases)
- [Upgrade Guide](/docs/{{version}}/upgrade)
- [Contribution Guide](/docs/{{version}}/contributions)
- [API Documentation](/api/{{version}})
-- Getting Started
+- ## Getting Started
- [Installation](/docs/{{version}}/installation)
- [Configuration](/docs/{{version}}/configuration)
- [Directory Structure](/docs/{{version}}/structure)
- - [Request Lifecycle](/docs/{{version}}/lifecycle)
-- Dev Environments
- [Homestead](/docs/{{version}}/homestead)
- [Valet](/docs/{{version}}/valet)
-- Core Concepts
+- ## Architecture Concepts
+ - [Request Lifecycle](/docs/{{version}}/lifecycle)
- [Service Container](/docs/{{version}}/container)
- [Service Providers](/docs/{{version}}/providers)
- [Facades](/docs/{{version}}/facades)
- [Contracts](/docs/{{version}}/contracts)
-- The HTTP Layer
+- ## The Basics
- [Routing](/docs/{{version}}/routing)
- [Middleware](/docs/{{version}}/middleware)
- [CSRF Protection](/docs/{{version}}/csrf)
@@ -26,52 +25,52 @@
- [Views](/docs/{{version}}/views)
- [Session](/docs/{{version}}/session)
- [Validation](/docs/{{version}}/validation)
-- Frontend
+ - [Errors & Logging](/docs/{{version}}/errors)
+- ## Frontend
- [Blade Templates](/docs/{{version}}/blade)
- [Localization](/docs/{{version}}/localization)
- [Frontend Scaffolding](/docs/{{version}}/frontend)
- [Compiling Assets](/docs/{{version}}/mix)
-- Security
+- ## Security
- [Authentication](/docs/{{version}}/authentication)
- [API Authentication](/docs/{{version}}/passport)
- [Authorization](/docs/{{version}}/authorization)
- [Encryption](/docs/{{version}}/encryption)
- [Hashing](/docs/{{version}}/hashing)
- [Password Reset](/docs/{{version}}/passwords)
-- General Topics
+- ## Digging Deeper
- [Artisan Console](/docs/{{version}}/artisan)
- [Broadcasting](/docs/{{version}}/broadcasting)
- [Cache](/docs/{{version}}/cache)
- [Collections](/docs/{{version}}/collections)
- - [Errors & Logging](/docs/{{version}}/errors)
- [Events](/docs/{{version}}/events)
- [File Storage](/docs/{{version}}/filesystem)
- [Helpers](/docs/{{version}}/helpers)
- [Mail](/docs/{{version}}/mail)
- [Notifications](/docs/{{version}}/notifications)
- - [Packages](/docs/{{version}}/packages)
+ - [Package Development](/docs/{{version}}/packages)
- [Queues](/docs/{{version}}/queues)
- - [Scheduled Tasks](/docs/{{version}}/scheduling)
-- Database
+ - [Task Scheduling](/docs/{{version}}/scheduling)
+- ## Database
- [Getting Started](/docs/{{version}}/database)
- [Query Builder](/docs/{{version}}/queries)
- [Pagination](/docs/{{version}}/pagination)
- [Migrations](/docs/{{version}}/migrations)
- [Seeding](/docs/{{version}}/seeding)
- [Redis](/docs/{{version}}/redis)
-- Eloquent ORM
+- ## Eloquent ORM
- [Getting Started](/docs/{{version}}/eloquent)
- [Relationships](/docs/{{version}}/eloquent-relationships)
- [Collections](/docs/{{version}}/eloquent-collections)
- [Mutators](/docs/{{version}}/eloquent-mutators)
- [Serialization](/docs/{{version}}/eloquent-serialization)
-- Testing
+- ## Testing
- [Getting Started](/docs/{{version}}/testing)
- [HTTP Tests](/docs/{{version}}/http-tests)
- [Browser Tests](/docs/{{version}}/dusk)
- [Database](/docs/{{version}}/database-testing)
- [Mocking](/docs/{{version}}/mocking)
-- Official Packages
+- ## Official Packages
- [Cashier](/docs/{{version}}/billing)
- [Envoy](/docs/{{version}}/envoy)
- [Passport](/docs/{{version}}/passport)
diff --git a/dusk.md b/dusk.md
old mode 100644
new mode 100755
index 1010224..780df0d
--- a/dusk.md
+++ b/dusk.md
@@ -3,6 +3,7 @@
- [Introduction](#introduction)
- [Installation](#installation)
- [Using Other Browsers](#using-other-browsers)
+ - [ChromeDriver Options](#chromedriver-options)
- [Getting Started](#getting-started)
- [Generating Tests](#generating-tests)
- [Running Tests](#running-tests)
@@ -25,6 +26,9 @@
- [Navigating To Pages](#navigating-to-pages)
- [Shorthand Selectors](#shorthand-selectors)
- [Page Methods](#page-methods)
+- [Continuous Integration](#continuous-integration)
+ - [Travis CI](#running-tests-on-travis-ci)
+ - [CircleCI](#running-tests-on-circle-ci)
## Introduction
@@ -36,9 +40,9 @@ Laravel Dusk provides an expressive, easy-to-use browser automation and testing
To get started, you should add the `laravel/dusk` Composer dependency to your project:
- composer require laravel/dusk
+ composer require --dev laravel/dusk
-Once Dusk is installed, you should register the `Laravel\Dusk\DuskServiceProvider` service provider. You should register the provider within the `register` method of your `AppServiceProvider` in order to limit the environments in which Dusk is available, since it exposes the ability to login as other users:
+Once Dusk is installed, you should register the `Laravel\Dusk\DuskServiceProvider` service provider. You should register the provider within the `register` method of your `AppServiceProvider` in order to limit the environments in which Dusk is available, since it exposes the ability to log in as other users:
use Laravel\Dusk\DuskServiceProvider;
@@ -92,7 +96,30 @@ Next, you may simply modify the `driver` method to connect to the URL and port o
protected function driver()
{
return RemoteWebDriver::create(
- 'http://localhost:4444', DesiredCapabilities::phantomjs()
+ 'http://localhost:4444/wd/hub', DesiredCapabilities::phantomjs()
+ );
+ }
+
+
+### ChromeDriver Options
+
+To customize the ChromeDriver session, you may modify the `driver` method of the `DuskTestCase` class:
+
+ use Facebook\WebDriver\Chrome\ChromeOptions;
+
+ /**
+ * Create the RemoteWebDriver instance.
+ *
+ * @return \Facebook\WebDriver\Remote\RemoteWebDriver
+ */
+ protected function driver()
+ {
+ $options = (new ChromeOptions)->addArguments(['--headless']);
+
+ return RemoteWebDriver::create(
+ 'http://localhost:9515', DesiredCapabilities::chrome()->setCapability(
+ ChromeOptions::CAPABILITY, $options
+ )
);
}
@@ -225,6 +252,8 @@ Often, you will be testing pages that require authentication. You can use Dusk's
->visit('/home');
});
+> {note} After using the `loginAs` method, the user session will be maintained for all tests within the file.
+
## Interacting With Elements
@@ -283,6 +312,10 @@ To select a value in a dropdown selection box, you may use the `select` method.
$browser->select('size', 'Large');
+You may select a random option by omitting the second parameter:
+
+ $browser->select('size');
+
#### Checkboxes
To "check" a checkbox field, you may use the `check` method. Like many other input related methods, a full CSS selector is not required. If an exact selector match can't be found, Dusk will search for a checkbox with a matching `name` attribute:
@@ -338,6 +371,13 @@ The `drag` method may be used to drag an element matching the given selector to
$browser->drag('.from-selector', '.to-selector');
+Or, you may drag an element in a single direction:
+
+ $browser->dragLeft('.selector', 10);
+ $browser->dragRight('.selector', 10);
+ $browser->dragUp('.selector', 10);
+ $browser->dragDown('.selector', 10);
+
### Scoping Selectors
@@ -404,6 +444,20 @@ The `waitForLink` method may be used to wait until the given link text is displa
// Wait a maximum of one second for the link...
$browser->waitForLink('Create', 1);
+#### Waiting On The Page Location
+
+When making a path assertion such as `$browser->assertPathIs('/home')`, the assertion can fail if `window.location.pathname` is being updated asynchronously. You may use the `waitForLocation` method to wait for the location to be a given value:
+
+ $browser->waitForLocation('/secret');
+
+#### Waiting for Page Reloads
+
+If you need to make assertions after a page has been reloaded, use the `waitForReload` method:
+
+ $browser->click('.some-action')
+ ->waitForReload()
+ ->assertSee('something');
+
#### Waiting On JavaScript Expressions
Sometimes you may wish to pause the execution of a test until a given JavaScript expression evaluates to `true`. You may easily accomplish this using the `waitUntil` method. When passing an expression to this method, you do not need to include the `return` keyword or an ending semi-colon:
@@ -416,6 +470,14 @@ Sometimes you may wish to pause the execution of a test until a given JavaScript
// Wait a maximum of one second for the expression to be true...
$browser->waitUntil('App.data.servers.length > 0', 1);
+#### Waiting With A Callback
+
+Many of the "wait" methods in Dusk rely on the underlying `waitUsing` method. You may use this method directly to wait for a given callback to return `true`. The `waitUsing` method accepts the maximum number of seconds to wait, the interval at which the Closure should be evaluated, the Closure, and an optional failure message:
+
+ $browser->waitUsing(10, 1, function () use ($something) {
+ return $something->isReady();
+ }, "Something wasn't ready in time.");
+
## Available Assertions
@@ -426,6 +488,10 @@ Assertion | Description
`$browser->assertTitle($title)` | Assert the page title matches the given text.
`$browser->assertTitleContains($title)` | Assert the page title contains the given text.
`$browser->assertPathIs('/home')` | Assert the current path matches the given path.
+`$browser->assertPathIsNot('/home')` | Assert the current path does not match the given path.
+`$browser->assertRouteIs($name, $parameters)` | Assert the current URL matches the given named route's URL.
+`$browser->assertQueryStringHas($name, $value)` | Assert the given query string parameter is present and has a given value.
+`$browser->assertQueryStringMissing($name)` | Assert the given query string parameter is missing.
`$browser->assertHasCookie($name)` | Assert the given cookie is present.
`$browser->assertCookieValue($name, $value)` | Assert a cookie has a given value.
`$browser->assertPlainCookieValue($name, $value)` | Assert an unencrypted cookie has a given value.
@@ -439,6 +505,8 @@ Assertion | Description
`$browser->assertInputValueIsNot($field, $value)` | Assert the given input field does not have the given value.
`$browser->assertChecked($field)` | Assert the given checkbox is checked.
`$browser->assertNotChecked($field)` | Assert the given checkbox is not checked.
+`$browser->assertRadioSelected($field, $value)` | Assert the given radio field is selected.
+`$browser->assertRadioNotSelected($field, $value)` | Assert the given radio field is not selected.
`$browser->assertSelected($field, $value)` | Assert the given dropdown has the given value selected.
`$browser->assertNotSelected($field, $value)` | Assert the given dropdown does not have the given value selected.
`$browser->assertValue($selector, $value)` | Assert the element matching the given selector has the given value.
@@ -460,7 +528,7 @@ To generate a page object, use the `dusk:page` Artisan command. All page objects
### Configuring Pages
-By default, pages have three methods: `url`, `assert`, and `selectors`. We will discuss the `url` and `assert` methods now. The `selectors` method will be [discussed in more detail below](#shorthand-selectors).
+By default, pages have three methods: `url`, `assert`, and `elements`. We will discuss the `url` and `assert` methods now. The `elements` method will be [discussed in more detail below](#shorthand-selectors).
#### The `url` Method
@@ -511,7 +579,7 @@ Sometimes you may already be on a given page and need to "load" the page's selec
### Shorthand Selectors
-The `selectors` method of pages allows you to define quick, easy-to-remember shortcuts for any CSS selector on your page. For example, let's define a shortcut for the "email" input field of the application's login page:
+The `elements` method of pages allows you to define quick, easy-to-remember shortcuts for any CSS selector on your page. For example, let's define a shortcut for the "email" input field of the application's login page:
/**
* Get the element shortcuts for the page.
@@ -582,3 +650,62 @@ Once the method has been defined, you may use it within any test that utilizes t
$browser->visit(new Dashboard)
->createPlaylist('My Playlist')
->assertSee('My Playlist');
+
+
+## Continuous Integration
+
+
+### Travis CI
+
+To run your Dusk tests on Travis CI, we will need to use the "sudo-enabled" Ubuntu 14.04 (Trusty) environment. Since Travis CI is not a graphical environment, we will need to take some extra steps in order to launch a Chrome browser. In addition, we will use `php artisan serve` to launch PHP's built-in web server:
+
+ sudo: required
+ dist: trusty
+
+ before_script:
+ - export DISPLAY=:99.0
+ - sh -e /etc/init.d/xvfb start
+ - ./vendor/laravel/dusk/bin/chromedriver-linux &
+ - cp .env.testing .env
+ - php artisan serve > /dev/null 2>&1 &
+
+ script:
+ - php artisan dusk
+
+
+### CircleCI
+
+#### CircleCI 1.0
+
+If you are using CircleCI 1.0 to run your Dusk tests, you may use this configuration file as a starting point. Like TravisCI, we will use the `php artisan serve` command to launch PHP's built-in web server:
+
+ test:
+ pre:
+ - "./vendor/laravel/dusk/bin/chromedriver-linux":
+ background: true
+ - cp .env.testing .env
+ - "php artisan serve":
+ background: true
+
+ override:
+ - php artisan dusk
+
+ #### CircleCI 2.0
+
+ If you are using CircleCI 2.0 to run your Dusk tests, you may add these steps to your build:
+
+ version: 2
+ jobs:
+ build:
+ steps:
+ - run:
+ name: Start Chrome Driver
+ command: ./vendor/laravel/dusk/bin/chromedriver-linux
+ background: true
+ - run:
+ name: Run Laravel Server
+ command: php artisan serve
+ background: true
+ - run:
+ name: Run Laravel Dusk Tests
+ command: php artisan dusk
diff --git a/eloquent-collections.md b/eloquent-collections.md
old mode 100644
new mode 100755
index 663e90d..fd9f0aa
--- a/eloquent-collections.md
+++ b/eloquent-collections.md
@@ -51,11 +51,13 @@ All Eloquent collections extend the base [Laravel collection](/docs/{{version}}/
[all](/docs/{{version}}/collections#method-all)
+[average](/docs/{{version}}/collections#method-average)
[avg](/docs/{{version}}/collections#method-avg)
[chunk](/docs/{{version}}/collections#method-chunk)
[collapse](/docs/{{version}}/collections#method-collapse)
[combine](/docs/{{version}}/collections#method-combine)
[contains](/docs/{{version}}/collections#method-contains)
+[containsStrict](/docs/{{version}}/collections#method-containsstrict)
[count](/docs/{{version}}/collections#method-count)
[diff](/docs/{{version}}/collections#method-diff)
[diffKeys](/docs/{{version}}/collections#method-diffkeys)
@@ -75,14 +77,21 @@ All Eloquent collections extend the base [Laravel collection](/docs/{{version}}/
[implode](/docs/{{version}}/collections#method-implode)
[intersect](/docs/{{version}}/collections#method-intersect)
[isEmpty](/docs/{{version}}/collections#method-isempty)
+[isNotEmpty](/docs/{{version}}/collections#method-isnotempty)
[keyBy](/docs/{{version}}/collections#method-keyby)
[keys](/docs/{{version}}/collections#method-keys)
[last](/docs/{{version}}/collections#method-last)
[map](/docs/{{version}}/collections#method-map)
+[mapWithKeys](/docs/{{version}}/collections#method-mapwithkeys)
[max](/docs/{{version}}/collections#method-max)
+[median](/docs/{{version}}/collections#method-median)
[merge](/docs/{{version}}/collections#method-merge)
[min](/docs/{{version}}/collections#method-min)
+[mode](/docs/{{version}}/collections#method-mode)
+[nth](/docs/{{version}}/collections#method-nth)
[only](/docs/{{version}}/collections#method-only)
+[partition](/docs/{{version}}/collections#method-partition)
+[pipe](/docs/{{version}}/collections#method-pipe)
[pluck](/docs/{{version}}/collections#method-pluck)
[pop](/docs/{{version}}/collections#method-pop)
[prepend](/docs/{{version}}/collections#method-prepend)
@@ -101,18 +110,24 @@ All Eloquent collections extend the base [Laravel collection](/docs/{{version}}/
[sortBy](/docs/{{version}}/collections#method-sortby)
[sortByDesc](/docs/{{version}}/collections#method-sortbydesc)
[splice](/docs/{{version}}/collections#method-splice)
+[split](/docs/{{version}}/collections#method-split)
[sum](/docs/{{version}}/collections#method-sum)
[take](/docs/{{version}}/collections#method-take)
+[tap](/docs/{{version}}/collections#method-tap)
[toArray](/docs/{{version}}/collections#method-toarray)
[toJson](/docs/{{version}}/collections#method-tojson)
[transform](/docs/{{version}}/collections#method-transform)
[union](/docs/{{version}}/collections#method-union)
[unique](/docs/{{version}}/collections#method-unique)
+[uniqueStrict](/docs/{{version}}/collections#method-uniquestrict)
[values](/docs/{{version}}/collections#method-values)
+[when](/docs/{{version}}/collections#method-when)
[where](/docs/{{version}}/collections#method-where)
[whereStrict](/docs/{{version}}/collections#method-wherestrict)
[whereIn](/docs/{{version}}/collections#method-wherein)
-[whereInLoose](/docs/{{version}}/collections#method-whereinloose)
+[whereInStrict](/docs/{{version}}/collections#method-whereinstrict)
+[whereNotIn](/docs/{{version}}/collections#method-wherenotin)
+[whereNotInStrict](/docs/{{version}}/collections#method-wherenotinstrict)
[zip](/docs/{{version}}/collections#method-zip)
diff --git a/eloquent-mutators.md b/eloquent-mutators.md
old mode 100644
new mode 100755
index 5cceb29..222f2c3
--- a/eloquent-mutators.md
+++ b/eloquent-mutators.md
@@ -157,7 +157,7 @@ For example, let's cast the `is_admin` attribute, which is stored in our databas
class User extends Model
{
/**
- * The attributes that should be casted to native types.
+ * The attributes that should be cast to native types.
*
* @var array
*/
@@ -188,7 +188,7 @@ The `array` cast type is particularly useful when working with columns that are
class User extends Model
{
/**
- * The attributes that should be casted to native types.
+ * The attributes that should be cast to native types.
*
* @var array
*/
diff --git a/eloquent-relationships.md b/eloquent-relationships.md
old mode 100644
new mode 100755
index f60a7ba..6c63d69
--- a/eloquent-relationships.md
+++ b/eloquent-relationships.md
@@ -120,6 +120,41 @@ If your parent model does not use `id` as its primary key, or you wish to join t
return $this->belongsTo('App\User', 'foreign_key', 'other_key');
}
+
+#### Default Models
+
+The `belongsTo` relationship allows you to define a default model that will be returned if the given relationship is `null`. This pattern is often referred to as the [Null Object pattern](https://en.wikipedia.org/wiki/Null_Object_pattern) and can help remove conditional checks in your code. In the following example, the `user` relation will return an empty `App\User` model if no `user` is attached to the post:
+
+ /**
+ * Get the author of the post.
+ */
+ public function user()
+ {
+ return $this->belongsTo('App\User')->withDefault();
+ }
+
+To populate the default model with attributes, you may pass an array or Closure to the `withDefault` method:
+
+ /**
+ * Get the author of the post.
+ */
+ public function user()
+ {
+ return $this->belongsTo('App\User')->withDefault([
+ 'name' => 'Guest Author',
+ ]);
+ }
+
+ /**
+ * Get the author of the post.
+ */
+ public function user()
+ {
+ return $this->belongsTo('App\User')->withDefault(function ($user) {
+ $user->name = 'Guest Author';
+ });
+ }
+
### One To Many
@@ -307,7 +342,7 @@ You can also filter the results returned by `belongsToMany` using the `wherePivo
#### Defining Custom Intermediate Table Models
-If you would like to define a custom model to represent the intermediate table of your relationship, you may call the `using` method when defining the relationship. All custom models used to represent intermediate tables of relationships must extend the `Illuminate\Database\Eloquent\Relations\Pivot` class:
+If you would like to define a custom model to represent the intermediate table of your relationship, you may call the `using` method when defining the relationship. All custom models used to represent intermediate tables of relationships must extend the `Illuminate\Database\Eloquent\Relations\Pivot` class. For example, we may define a `Role` which uses a custom `UserRole` pivot model:
### Has Many Through
@@ -368,15 +416,19 @@ Now that we have examined the table structure for the relationship, let's define
The first argument passed to the `hasManyThrough` method is the name of the final model we wish to access, while the second argument is the name of the intermediate model.
-Typical Eloquent foreign key conventions will be used when performing the relationship's queries. If you would like to customize the keys of the relationship, you may pass them as the third and fourth arguments to the `hasManyThrough` method. The third argument is the name of the foreign key on the intermediate model, the fourth argument is the name of the foreign key on the final model, and the fifth argument is the local key:
+Typical Eloquent foreign key conventions will be used when performing the relationship's queries. If you would like to customize the keys of the relationship, you may pass them as the third and fourth arguments to the `hasManyThrough` method. The third argument is the name of the foreign key on the intermediate model. The fourth argument is the name of the foreign key on the final model. The fifth argument is the local key, while the sixth argument is the local key of the intermediate model:
class Country extends Model
{
public function posts()
{
return $this->hasManyThrough(
- 'App\Post', 'App\User',
- 'country_id', 'user_id', 'id'
+ 'App\Post',
+ 'App\User',
+ 'country_id', // Foreign key on users table...
+ 'user_id', // Foreign key on posts table...
+ 'id', // Local key on countries table...
+ 'id' // Local key on users table...
);
}
}
@@ -675,6 +727,19 @@ You may add the "counts" for multiple relations as well as add constraints to th
echo $posts[0]->votes_count;
echo $posts[0]->comments_count;
+You may also alias the relationship count result, allowing multiple counts on the same relationship:
+
+ $posts = Post::withCount([
+ 'comments',
+ 'comments AS pending_comments' => function ($query) {
+ $query->where('approved', false);
+ }
+ ])->get();
+
+ echo $posts[0]->comments_count;
+
+ echo $posts[0]->pending_comments_count;
+
## Eager Loading
@@ -725,7 +790,7 @@ For this operation, only two queries will be executed:
Sometimes you may need to eager load several different relationships in a single operation. To do so, just pass additional arguments to the `with` method:
- $books = App\Book::with('author', 'publisher')->get();
+ $books = App\Book::with(['author', 'publisher'])->get();
#### Nested Eager Loading
@@ -801,7 +866,20 @@ In addition to the `save` and `saveMany` methods, you may also use the `create`
'message' => 'A new comment.',
]);
-Before using the `create` method, be sure to review the documentation on attribute [mass assignment](/docs/{{version}}/eloquent#mass-assignment).
+> {tip} Before using the `create` method, be sure to review the documentation on attribute [mass assignment](/docs/{{version}}/eloquent#mass-assignment).
+
+You may use the `createMany` method to create multiple related models:
+
+ $post = App\Post::find(1);
+
+ $post->comments()->createMany([
+ [
+ 'message' => 'A new comment.',
+ ],
+ [
+ 'message' => 'Another new comment.',
+ ],
+ ]);
### Belongs To Relationships
@@ -849,7 +927,10 @@ For convenience, `attach` and `detach` also accept arrays of IDs as input:
$user->roles()->detach([1, 2, 3]);
- $user->roles()->attach([1 => ['expires' => $expires], 2, 3]);
+ $user->roles()->attach([
+ 1 => ['expires' => $expires],
+ 2 => ['expires' => $expires]
+ ]);
#### Syncing Associations
diff --git a/eloquent-serialization.md b/eloquent-serialization.md
old mode 100644
new mode 100755
index 5d6a7a4..b0fb6a0
--- a/eloquent-serialization.md
+++ b/eloquent-serialization.md
@@ -72,7 +72,7 @@ Sometimes you may wish to limit the attributes, such as passwords, that are incl
protected $hidden = ['password'];
}
-> {note} When hiding relationships, use the relationship's method name, not its dynamic property name.
+> {note} When hiding relationships, use the relationship's method name.
Alternatively, you may use the `visible` property to define a white-list of attributes that should be included in your model's array and JSON representation. All other attributes will be hidden when the model is converted to an array or JSON:
diff --git a/eloquent.md b/eloquent.md
old mode 100644
new mode 100755
index ad122be..b47c0b4
--- a/eloquent.md
+++ b/eloquent.md
@@ -220,7 +220,7 @@ The `cursor` method allows you to iterate through your database records using a
## Retrieving Single Models / Aggregates
-Of course, in addition to retrieving all of the records for a given table, you may also retrieve single records using `find` and `first`. Instead of returning a collection of models, these methods return a single model instance:
+Of course, in addition to retrieving all of the records for a given table, you may also retrieve single records using `find` or `first`. Instead of returning a collection of models, these methods return a single model instance:
// Retrieve a model by its primary key...
$flight = App\Flight::find(1);
@@ -387,12 +387,22 @@ There are two other methods you may use to create models by mass assigning attri
The `firstOrNew` method, like `firstOrCreate` will attempt to locate a record in the database matching the given attributes. However, if a model is not found, a new model instance will be returned. Note that the model returned by `firstOrNew` has not yet been persisted to the database. You will need to call `save` manually to persist it:
- // Retrieve the flight by the attributes, or create it if it doesn't exist...
+ // Retrieve flight by name, or create it if it doesn't exist...
$flight = App\Flight::firstOrCreate(['name' => 'Flight 10']);
- // Retrieve the flight by the attributes, or instantiate a new instance...
+ // Retrieve flight by name, or create it with the name and delayed attributes...
+ $flight = App\Flight::firstOrCreate(
+ ['name' => 'Flight 10'], ['delayed' => 1]
+ );
+
+ // Retrieve by name, or instantiate...
$flight = App\Flight::firstOrNew(['name' => 'Flight 10']);
+ // Retrieve by name, or instantiate with the name and delayed attributes...
+ $flight = App\Flight::firstOrNew(
+ ['name' => 'Flight 10'], ['delayed' => 1]
+ );
+
#### `updateOrCreate`
You may also come across situations where you want to update an existing model or create a new model if none exists. Laravel provides an `updateOrCreate` method to do this in one step. Like the `firstOrCreate` method, `updateOrCreate` persists the model, so there's no need to call `save()`:
@@ -553,7 +563,7 @@ Writing a global scope is simple. Define a class that implements the `Illuminate
}
}
-> {tip} There is not a predefined folder for scopes in a default Laravel application, so feel free to make your own `Scopes` folder within your Laravel application's `app` directory.
+> {tip} If your global scope is adding columns to the select clause of the query, you should use the `addSelect` method instead of `select`. This will prevent the unintentional replacement of the query's existing select clause.
#### Applying Global Scopes
@@ -709,7 +719,7 @@ Eloquent models fire several events, allowing you to hook into the following poi
Whenever a new model is saved for the first time, the `creating` and `created` events will fire. If a model already existed in the database and the `save` method is called, the `updating` / `updated` events will fire. However, in both cases, the `saving` / `saved` events will fire.
-To get started, define an `$events` property on your Eloquent model that maps various points of the Eloquent model's lifecycle to your own [event classes](/docs/{{version}}/events):
+To get started, define a `$dispatchesEvents` property on your Eloquent model that maps various points of the Eloquent model's lifecycle to your own [event classes](/docs/{{version}}/events):
UserSaved::class,
'deleted' => UserDeleted::class,
];
diff --git a/encryption.md b/encryption.md
old mode 100644
new mode 100755
diff --git a/envoy.md b/envoy.md
old mode 100644
new mode 100755
index 2155e6a..015cc15
--- a/envoy.md
+++ b/envoy.md
@@ -22,7 +22,7 @@
First, install Envoy using the Composer `global require` command:
- composer global require "laravel/envoy=~1.0"
+ composer global require laravel/envoy
Since global Composer libraries can sometimes cause package version conflicts, you may wish to consider using `cgr`, which is a drop-in replacement for the `composer global require` command. The `cgr` library's installation instructions can be [found on GitHub](https://github.com/consolidation-org/cgr).
diff --git a/errors.md b/errors.md
old mode 100644
new mode 100755
index f4bdb32..53762d9
--- a/errors.md
+++ b/errors.md
@@ -144,7 +144,9 @@ The `abort` helper will immediately raise an exception which will be rendered by
### Custom HTTP Error Pages
-Laravel makes it easy to display custom error pages for various HTTP status codes. For example, if you wish to customize the error page for 404 HTTP status codes, create a `resources/views/errors/404.blade.php`. This file will be served on all 404 errors generated by your application. The views within this directory should be named to match the HTTP status code they correspond to. The `HttpException` instance raised by the `abort` function will be passed to the view as an `$exception` variable.
+Laravel makes it easy to display custom error pages for various HTTP status codes. For example, if you wish to customize the error page for 404 HTTP status codes, create a `resources/views/errors/404.blade.php`. This file will be served on all 404 errors generated by your application. The views within this directory should be named to match the HTTP status code they correspond to. The `HttpException` instance raised by the `abort` function will be passed to the view as an `$exception` variable:
+
+ {{ $exception->getMessage() }}
## Logging
diff --git a/events.md b/events.md
old mode 100644
new mode 100755
index acb5322..67aab45
--- a/events.md
+++ b/events.md
@@ -277,7 +277,7 @@ To dispatch an event, you may pass an instance of the event to the `event` helpe
}
}
-> {tip} When testing, it can be helpful to assert that certain events were dispatched without actually triggering their listeners. Laravel's [built-in testing helpers](/docs/{{version}}/mocking#mocking-events) makes it a cinch.
+> {tip} When testing, it can be helpful to assert that certain events were dispatched without actually triggering their listeners. Laravel's [built-in testing helpers](/docs/{{version}}/mocking#event-fake) makes it a cinch.
## Event Subscribers
diff --git a/facades.md b/facades.md
old mode 100644
new mode 100755
index d1ee28a..9a4061e
--- a/facades.md
+++ b/facades.md
@@ -108,8 +108,8 @@ The `Facade` base class makes use of the `__callStatic()` magic-method to defer
namespace App\Http\Controllers;
- use Cache;
use App\Http\Controllers\Controller;
+ use Illuminate\Support\Facades\Cache;
class UserController extends Controller
{
diff --git a/filesystem.md b/filesystem.md
old mode 100644
new mode 100755
index 3de773b..c1cef46
--- a/filesystem.md
+++ b/filesystem.md
@@ -1,4 +1,4 @@
-# Filesystem / Cloud Storage
+# File Storage
- [Introduction](#introduction)
- [Configuration](#configuration)
@@ -166,7 +166,7 @@ The `put` method may be used to store raw file contents on a disk. You may also
#### Automatic Streaming
-If you would like Laravel to automatically manage streaming a given file to your storage location, you may use the `putFile` or `putFileAs` method. This method accepts either a `Illuminate\Http\File` or `Illuminate\Http\UploadedFile` instance and will automatically stream the file to your desire location:
+If you would like Laravel to automatically manage streaming a given file to your storage location, you may use the `putFile` or `putFileAs` method. This method accepts either a `Illuminate\Http\File` or `Illuminate\Http\UploadedFile` instance and will automatically stream the file to your desired location:
use Illuminate\Http\File;
@@ -321,7 +321,11 @@ Finally, the `deleteDirectory` may be used to remove a directory and all of its
Laravel's Flysystem integration provides drivers for several "drivers" out of the box; however, Flysystem is not limited to these and has adapters for many other storage systems. You can create a custom driver if you want to use one of these additional adapters in your Laravel application.
-In order to set up the custom filesystem you will need to create a [service provider](/docs/{{version}}/providers) such as `DropboxServiceProvider`. In the provider's `boot` method, you may use the `Storage` facade's `extend` method to define the custom driver:
+In order to set up the custom filesystem you will need a Flysystem adapter. Let's add a community maintained Dropbox adapter to our project:
+
+ composer require spatie/flysystem-dropbox
+
+Next, you should create a [service provider](/docs/{{version}}/providers) such as `DropboxServiceProvider`. In the provider's `boot` method, you may use the `Storage` facade's `extend` method to define the custom driver:
## Writing CSS
-The Laravel `package.json` file includes the `bootstrap-sass` package to help you get started prototyping your application's frontend using Bootstrap. However, feel free to add or remove packages from the `package.json` file as needed for your own application. You are not required to use the Bootstrap framework to build your Laravel application - it is simply provided as a good starting point for those who choose to use it.
+Laravel's `package.json` file includes the `bootstrap-sass` package to help you get started prototyping your application's frontend using Bootstrap. However, feel free to add or remove packages from the `package.json` file as needed for your own application. You are not required to use the Bootstrap framework to build your Laravel application - it is simply provided as a good starting point for those who choose to use it.
-Before compiling your CSS, install your project's frontend dependencies using NPM:
+Before compiling your CSS, install your project's frontend dependencies using the [Node package manager (NPM)](https://www.npmjs.org):
npm install
@@ -42,7 +40,7 @@ All of the JavaScript dependencies required by your application can be found in
npm install
-By default, the Laravel `package.json` file includes a few packages such as `vue` and `axios` to help you get started building your JavaScript application. Feel free to add or remove from the `package.json` file as needed for your own application.
+> {tip} By default, the Laravel `package.json` file includes a few packages such as `vue` and `axios` to help you get started building your JavaScript application. Feel free to add or remove from the `package.json` file as needed for your own application.
Once the packages are installed, you can use the `npm run dev` command to [compile your assets](/docs/{{version}}/mix). Webpack is a module bundler for modern JavaScript applications. When you run the `npm run dev` command, Webpack will execute the instructions in your `webpack.mix.js` file:
diff --git a/hashing.md b/hashing.md
old mode 100644
new mode 100755
diff --git a/helpers.md b/helpers.md
old mode 100644
new mode 100755
index 2cb4b52..a85985a
--- a/helpers.md
+++ b/helpers.md
@@ -1,4 +1,4 @@
-# Helper Functions
+# Helpers
- [Introduction](#introduction)
- [Available Methods](#available-methods)
@@ -45,6 +45,7 @@ Laravel includes a variety of global "helper" PHP functions. Many of these funct
[array_sort](#method-array-sort)
[array_sort_recursive](#method-array-sort-recursive)
[array_where](#method-array-where)
+[array_wrap](#method-array-wrap)
[head](#method-head)
[last](#method-last)
@@ -72,9 +73,12 @@ Laravel includes a variety of global "helper" PHP functions. Many of these funct
[class_basename](#method-class-basename)
[e](#method-e)
[ends_with](#method-ends-with)
+[kebab_case](#method-kebab-case)
[snake_case](#method-snake-case)
[str_limit](#method-str-limit)
[starts_with](#method-starts-with)
+[str_after](#method-str-after)
+[str_before](#method-str-before)
[str_contains](#method-str-contains)
[str_finish](#method-str-finish)
[str_is](#method-str-is)
@@ -418,10 +422,21 @@ The `array_where` function filters the array using the given Closure:
// [1 => 200, 3 => 400]
+
+#### `array_wrap()` {#collection-method}
+
+The `array_wrap` function will wrap the given value in an array. If the given value is already an array it will not be changed:
+
+ $string = 'Laravel';
+
+ $array = array_wrap($string);
+
+ // [0 => 'Laravel']
+
#### `head()` {#collection-method}
-The `head` function simply returns the first element in the given array:
+The `head` function returns the first element in the given array:
$array = [100, 200, 300];
@@ -492,7 +507,7 @@ The `public_path` function returns the fully qualified path to the `public` dire
#### `resource_path()` {#collection-method}
-The `resource_path` function returns the fully qualified path to the `resources` directory. You may also use the `resource_path` function to generate a fully qualified path to a given file relative to the storage directory:
+The `resource_path` function returns the fully qualified path to the `resources` directory. You may also use the `resource_path` function to generate a fully qualified path to a given file relative to the resources directory:
$path = resource_path();
@@ -531,7 +546,7 @@ The `class_basename` returns the class name of the given class with the class' n
#### `e()` {#collection-method}
-The `e` function runs `htmlspecialchars` over the given string:
+The `e` function runs PHP's `htmlspecialchars` function with the `double_encode` option set to `false`:
echo e('foo');
@@ -546,6 +561,16 @@ The `ends_with` function determines if the given string ends with the given valu
// true
+
+#### `kebab_case()` {#collection-method}
+
+The `kebab_case` function converts the given string to `kebab-case`:
+
+ $value = kebab_case('fooBar');
+
+ // foo-bar
+
+
#### `snake_case()` {#collection-method}
@@ -573,6 +598,24 @@ The `starts_with` function determines if the given string begins with the given
// true
+
+#### `str_after()` {#collection-method}
+
+The `str_after` function returns everything after the given value in a string:
+
+ $value = str_after('This is: a test', 'This is:');
+
+ // ' a test'
+
+
+#### `str_before()` {#collection-method}
+
+The `str_before` function returns everything before the given value in a string:
+
+ $value = str_before('Test :it before', ':it before');
+
+ // 'Test '
+
#### `str_contains()` {#collection-method}
@@ -729,6 +772,10 @@ If the route accepts parameters, you may pass them as the second argument to the
$url = route('routeName', ['id' => 1]);
+By default, the `route` function generates an absolute URL. If you wish to generate a relative URL, you may pass `false` as the third parameter:
+
+ $url = route('routeName', ['id' => 1], false);
+
#### `secure_url()` {#collection-method}
diff --git a/homestead.md b/homestead.md
old mode 100644
new mode 100755
index 35874b1..b333ffe
--- a/homestead.md
+++ b/homestead.md
@@ -14,9 +14,13 @@
- [Adding Additional Sites](#adding-additional-sites)
- [Configuring Cron Schedules](#configuring-cron-schedules)
- [Ports](#ports)
+ - [Sharing Your Environment](#sharing-your-environment)
+ - [Multiple PHP Versions](#multiple-php-versions)
- [Network Interfaces](#network-interfaces)
- [Updating Homestead](#updating-homestead)
- [Old Versions](#old-versions)
+- [Provider Specific Settings](#provider-specific-settings)
+ - [VirtualBox](#provider-specific-virtualbox)
## Introduction
@@ -41,10 +45,12 @@ Homestead runs on any Windows, Mac, or Linux system, and includes the Nginx web
- Sqlite3
- Postgres
- Composer
-- Node (With Yarn, PM2, Bower, Grunt, and Gulp)
+- Node (With Yarn, Bower, Grunt, and Gulp)
- Redis
- Memcached
- Beanstalkd
+- Mailhog
+- ngrok
## Installation & Setup
@@ -74,7 +80,14 @@ You may install Homestead by simply cloning the repository. Consider cloning the
git clone https://github.com/laravel/homestead.git Homestead
-Once you have cloned the Homestead repository, run the `bash init.sh` command from the Homestead directory to create the `Homestead.yaml` configuration file. The `Homestead.yaml` file will be placed in the `~/.homestead` hidden directory:
+You should check out a tagged version of Homestead since the `master` branch may not always be stable. You can find the latest stable version on the [Github Release Page](https://github.com/laravel/homestead/releases):
+
+ cd Homestead
+
+ // Clone the desired release...
+ git checkout v5.4.0
+
+Once you have cloned the Homestead repository, run the `bash init.sh` command from the Homestead directory to create the `Homestead.yaml` configuration file. The `Homestead.yaml` file will be placed in the Homestead directory:
// Mac / Linux...
bash init.sh
@@ -87,7 +100,7 @@ Once you have cloned the Homestead repository, run the `bash init.sh` command fr
#### Setting Your Provider
-The `provider` key in your `~/.homestead/Homestead.yaml` file indicates which Vagrant provider should be used: `virtualbox`, `vmware_fusion`, `vmware_workstation`, or `parallels`. You may set this to the provider you prefer:
+The `provider` key in your `Homestead.yaml` file indicates which Vagrant provider should be used: `virtualbox`, `vmware_fusion`, `vmware_workstation`, or `parallels`. You may set this to the provider you prefer:
provider: virtualbox
@@ -99,13 +112,15 @@ The `folders` property of the `Homestead.yaml` file lists all of the folders you
- map: ~/Code
to: /home/vagrant/Code
-To enable [NFS](https://www.vagrantup.com/docs/synced-folders/nfs.html), just add a simple flag to your synced folder configuration:
+To enable [NFS](https://www.vagrantup.com/docs/synced-folders/nfs.html), you only need to add a simple flag to your synced folder configuration:
folders:
- map: ~/Code
to: /home/vagrant/Code
type: "nfs"
+> {note} When using NFS, you should consider installing the [vagrant-bindfs](https://github.com/gael-ian/vagrant-bindfs) plug-in. This plug-in will maintain the correct user / group permissions for files and directories within the Homestead box.
+
You may also pass any options supported by Vagrant's [Synced Folders](https://www.vagrantup.com/docs/synced-folders/basic_usage.html) by listing them under the `options` key:
folders:
@@ -133,7 +148,7 @@ You must add the "domains" for your Nginx sites to the `hosts` file on your mach
192.168.10.10 homestead.app
-Make sure the IP address listed is the one set in your `~/.homestead/Homestead.yaml` file. Once you have added the domain to your `hosts` file and launched the Vagrant box you will be able to access the site via your web browser:
+Make sure the IP address listed is the one set in your `Homestead.yaml` file. Once you have added the domain to your `hosts` file and launched the Vagrant box you will be able to access the site via your web browser:
http://homestead.app
@@ -183,9 +198,9 @@ If you prefer to use MariaDB instead of MySQL, you may add the `mariadb` option
### Accessing Homestead Globally
-Sometimes you may want to `vagrant up` your Homestead machine from anywhere on your filesystem. You can do this on Mac / Linux systems by adding a Bash function to your Bash profile. On Windows, you may accomplish this by adding a "batch" file to your `PATH`. This scripts will allow you to run any Vagrant command from anywhere on your system and will automatically point that command to your Homestead installation:
+Sometimes you may want to `vagrant up` your Homestead machine from anywhere on your filesystem. You can do this on Mac / Linux systems by adding a Bash function to your Bash profile. On Windows, you may accomplish this by adding a "batch" file to your `PATH`. These scripts will allow you to run any Vagrant command from anywhere on your system and will automatically point that command to your Homestead installation:
-#### Linux
+#### Mac / Linux
function homestead() {
( cd ~/Homestead && vagrant $* )
@@ -229,7 +244,7 @@ To connect to your MySQL or Postgres database from your host machine's database
### Adding Additional Sites
-Once your Homestead environment is provisioned and running, you may want to add additional Nginx sites for your Laravel applications. You can run as many Laravel installations as you wish on a single Homestead environment. To add an additional site, simply add the site to your `~/.homestead/Homestead.yaml` file:
+Once your Homestead environment is provisioned and running, you may want to add additional Nginx sites for your Laravel applications. You can run as many Laravel installations as you wish on a single Homestead environment. To add an additional site, simply add the site to your `Homestead.yaml` file:
sites:
- map: homestead.app
@@ -244,6 +259,30 @@ If Vagrant is not automatically managing your "hosts" file, you may need to add
Once the site has been added, run the `vagrant reload --provision` command from your Homestead directory.
+
+#### Site Types
+
+Homestead supports several types of sites which allow you to easily run projects that are not based on Laravel. For example, we may easily add a Symfony application to Homestead using the `symfony2` site type:
+
+ sites:
+ - map: symfony2.app
+ to: /home/vagrant/Code/Symfony/public
+ type: symfony2
+
+The available site types are: `apache`, `laravel` (the default), `proxy`, `silverstripe`, `statamic`, `symfony2`, and `symfony4`.
+
+
+#### Site Parameters
+
+You may add additional Nginx `fastcgi_param` values to your site via the `params` site directive. For example, we'll add a `FOO` parameter with a value of `BAR`:
+
+ sites:
+ - map: homestead.app
+ to: /home/vagrant/Code/Laravel/public
+ params:
+ - key: FOO
+ value: BAR
+
### Configuring Cron Schedules
@@ -268,18 +307,44 @@ By default, the following ports are forwarded to your Homestead environment:
- **HTTPS:** 44300 → Forwards To 443
- **MySQL:** 33060 → Forwards To 3306
- **Postgres:** 54320 → Forwards To 5432
+- **Mailhog:** 8025 → Forwards To 8025
#### Forwarding Additional Ports
If you wish, you may forward additional ports to the Vagrant box, as well as specify their protocol:
ports:
- - send: 93000
- to: 9300
+ - send: 50000
+ to: 5000
- send: 7777
to: 777
protocol: udp
+
+### Sharing Your Environment
+
+Sometimes you may wish to share what you're currently working on with coworkers or a client. Vagrant has a built-in way to support this via `vagrant share`; however, this will not work if you have multiple sites configured in your `Homestead.yaml` file.
+
+To solve this problem, Homestead includes its own `share` command. To get started, SSH into your Homestead machine via `vagrant ssh` and run `share homestead.app`. This will share the `homestead.app` site from your `Homestead.yaml` configuration file. Of course, you may substitute any of your other configured sites for `homestead.app`:
+
+ share homestead.app
+
+After running the command, you will see an Ngrok screen appear which contains the activity log and the publicly accessible URLs for the shared site. If you would like to specify a custom region, subdomain, or other Ngrok runtime option, you may add them to your `share` command:
+
+ share homestead.app -region=eu -subdomain=laravel
+
+> {note} Remember, Vagrant is inherently insecure and you are exposing your virtual machine to the Internet when running the `share` command.
+
+
+### Multiple PHP Versions
+
+Homestead 6 introduced support for multiple versions of PHP on the same virtual machine. You may specify which version of PHP to use for a given site within your `Homestead.yaml` file. The available PHP versions are: "5.6", "7.0", and "7.1":
+
+ sites:
+ - map: homestead.app
+ to: /home/vagrant/Code/Laravel/public
+ php: "5.6"
+
## Network Interfaces
@@ -337,3 +402,14 @@ When you use an older version of the Homestead box you need to match that with a
|---|---|---|
| PHP 7.0 | 3.1.0 | 0.6.0 |
| PHP 7.1 | 4.0.0 | 1.0.0 |
+
+
+## Provider Specific Settings
+
+
+### VirtualBox
+
+By default, Homestead configures the `natdnshostresolver` setting to `on`. This allows Homestead to use your host operating system's DNS settings. If you would like to override this behavior, add the following lines to your `Homestead.yaml` file:
+
+ provider: virtualbox
+ natdnshostresolver: off
diff --git a/http-tests.md b/http-tests.md
old mode 100644
new mode 100755
index 33ff0af..3494eb9
--- a/http-tests.md
+++ b/http-tests.md
@@ -3,6 +3,7 @@
- [Introduction](#introduction)
- [Session / Authentication](#session-and-authentication)
- [Testing JSON APIs](#testing-json-apis)
+- [Testing File Uploads](#testing-file-uploads)
- [Available Assertions](#available-assertions)
@@ -37,7 +38,7 @@ Laravel provides a very fluent API for making HTTP requests to your application
The `get` method makes a `GET` request into the application, while the `assertStatus` method asserts that the returned response should have the given HTTP status code. In addition to this simple assertion, Laravel also contains a variety of assertions for inspecting the response headers, content, JSON structure, and more.
-### Session / Authentication
+## Session / Authentication
Laravel provides several helpers for working with the session during HTTP testing. First, you may set the session data to a given array using the `withSession` method. This is useful for loading the session with data before issuing a request to your application:
@@ -56,15 +57,17 @@ Of course, one common use of the session is for maintaining state for the authen
create();
+ $user = factory(User::class)->create();
$response = $this->actingAs($user)
->withSession(['foo' => 'bar'])
- ->get('/')
+ ->get('/');
}
}
@@ -73,7 +76,7 @@ You may also specify which guard should be used to authenticate the given user b
$this->actingAs($user, 'api')
-### Testing JSON APIs
+## Testing JSON APIs
Laravel also provides several helpers for testing JSON APIs and their responses. For example, the `json`, `get`, `post`, `put`, `patch`, and `delete` methods may be used to issue requests with various HTTP verbs. You may also easily pass data and headers to these methods. To get started, let's write a test to make a `POST` request to `/user` and assert that the expected data was returned:
@@ -98,7 +101,7 @@ Laravel also provides several helpers for testing JSON APIs and their responses.
}
}
-> {tip} The `assertJson` method converts the response to an array and utilizes `PHPUnit::assertArraySubset` to verify that the given fragment exists within the JSON response returned by the application. So, if there are other properties in the JSON response, this test will still pass as long as the given fragment is present.
+> {tip} The `assertJson` method converts the response to an array and utilizes `PHPUnit::assertArraySubset` to verify that the given array exists within the JSON response returned by the application. So, if there are other properties in the JSON response, this test will still pass as long as the given fragment is present.
### Verifying Exact Match
@@ -126,8 +129,52 @@ If you would like to verify that the given array is an **exact** match for the J
}
}
+
+## Testing File Uploads
+
+The `Illuminate\Http\UploadedFile` class provides a `fake` method which may be used to generate dummy files or images for testing. This, combined with the `Storage` facade's `fake` method greatly simplifies the testing of file uploads. For example, you may combine these two features to easily test an avatar upload form:
+
+ json('POST', '/avatar', [
+ 'avatar' => UploadedFile::fake()->image('avatar.jpg')
+ ]);
+
+ // Assert the file was stored...
+ Storage::disk('avatars')->assertExists('avatar.jpg');
+
+ // Assert a file does not exist...
+ Storage::disk('avatars')->assertMissing('missing.jpg');
+ }
+ }
+
+#### Fake File Customization
+
+When creating files using the `fake` method, you may specify the width, height, and size of the image in order to better test your validation rules:
+
+ UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);
+
+In addition to creating images, you may create files of any other type using the `create` method:
+
+ UploadedFile::fake()->create('document.pdf', $sizeInKilobytes);
+
-### Available Assertions
+## Available Assertions
Laravel provides a variety of custom assertion methods for your [PHPUnit](https://phpunit.de/) tests. These assertions may be accessed on the response that is returned from the `json`, `get`, `post`, `put`, and `delete` test methods:
@@ -139,7 +186,12 @@ Method | Description
`$response->assertCookie($cookieName, $value = null);` | Assert that the response contains the given cookie.
`$response->assertPlainCookie($cookieName, $value = null);` | Assert that the response contains the given cookie (unencrypted).
`$response->assertSessionHas($key, $value = null);` | Assert that the session contains the given piece of data.
+`$response->assertSessionHasErrors(array $keys);` | Assert that the session contains an error for the given field.
`$response->assertSessionMissing($key);` | Assert that the session does not contain the given key.
`$response->assertJson(array $data);` | Assert that the response contains the given JSON data.
+`$response->assertJsonFragment(array $data);` | Assert that the response contains the given JSON fragment.
+`$response->assertJsonMissing(array $data);` | Assert that the response does not contain the given JSON fragment.
`$response->assertExactJson(array $data);` | Assert that the response contains an exact match of the given JSON data.
+`$response->assertJsonStructure(array $structure);` | Assert that the response has a given JSON structure.
+`$response->assertViewIs($value);` | Assert that the given view was returned by the route.
`$response->assertViewHas($key, $value = null);` | Assert that the response view was given a piece of data.
diff --git a/installation.md b/installation.md
old mode 100644
new mode 100755
index db68b6d..ffa7108
--- a/installation.md
+++ b/installation.md
@@ -10,7 +10,7 @@
## Installation
-> {video} Are you a visual learner? Laracasts provides a [free, thorough introduction to Laravel](https://laracasts.com/series/laravel-from-scratch-2017) for newcomers to the framework. It's a great place to start your journey.
+> {video} Are you a visual learner? Laracasts provides a [free, thorough introduction to Laravel](http://laravelfromscratch.com) for newcomers to the framework. It's a great place to start your journey.
### Server Requirements
diff --git a/license.md b/license.md
old mode 100644
new mode 100755
diff --git a/lifecycle.md b/lifecycle.md
old mode 100644
new mode 100755
diff --git a/localization.md b/localization.md
old mode 100644
new mode 100755
index 075487c..647dd37
--- a/localization.md
+++ b/localization.md
@@ -86,7 +86,7 @@ For applications with heavy translation requirements, defining every string with
Translation files that use translation strings as keys are stored as JSON files in the `resources/lang` directory. For example, if your application has a Spanish translation, you should create a `resources/lang/es.json` file:
{
- "I love programming.": "Me encanta la programación."
+ "I love programming.": "Me encanta programar."
}
diff --git a/mail.md b/mail.md
old mode 100644
new mode 100755
index d0968d7..5dcd262
--- a/mail.md
+++ b/mail.md
@@ -9,6 +9,7 @@
- [View Data](#view-data)
- [Attachments](#attachments)
- [Inline Attachments](#inline-attachments)
+ - [Customizing The SwiftMailer Message](#customizing-the-swiftmailer-message)
- [Markdown Mailables](#markdown-mailables)
- [Generating Markdown Mailables](#generating-markdown-mailables)
- [Writing Markdown Messages](#writing-markdown-messages)
@@ -298,6 +299,8 @@ Embedding inline images into your emails is typically cumbersome; however, Larav