diff --git a/authentication.md b/authentication.md index 26b6cb71d0..64e810db3b 100644 --- a/authentication.md +++ b/authentication.md @@ -404,7 +404,7 @@ You will need to provide an HTML view for the password reset request form. This {!! csrf_field() !!}
- Email + Email
diff --git a/billing.md b/billing.md index 4977b1be2d..7102a5e5da 100644 --- a/billing.md +++ b/billing.md @@ -2,19 +2,19 @@ - [Introduction](#introduction) - [Subscriptions](#subscriptions) - - [Creating Subscriptions](#creating-subscriptions) - - [Checking Subscription Status](#checking-subscription-status) - - [Changing Plans](#changing-plans) - - [Subscription Quantity](#subscription-quantity) - - [Subscription Taxes](#subscription-taxes) - - [Cancelling Subscriptions](#cancelling-subscriptions) - - [Resuming Subscriptions](#resuming-subscriptions) + - [Creating Subscriptions](#creating-subscriptions) + - [Checking Subscription Status](#checking-subscription-status) + - [Changing Plans](#changing-plans) + - [Subscription Quantity](#subscription-quantity) + - [Subscription Taxes](#subscription-taxes) + - [Cancelling Subscriptions](#cancelling-subscriptions) + - [Resuming Subscriptions](#resuming-subscriptions) - [Handling Stripe Webhooks](#handling-stripe-webhooks) - - [Failed Subscriptions](#handling-failed-subscriptions) - - [Other Webhooks](#handling-other-webhooks) + - [Failed Subscriptions](#handling-failed-subscriptions) + - [Other Webhooks](#handling-other-webhooks) - [Single Charges](#single-charges) - [Invoices](#invoices) - - [Generating Invoice PDFs](#generating-invoice-pdfs) + - [Generating Invoice PDFs](#generating-invoice-pdfs) ## Introduction @@ -28,9 +28,9 @@ Laravel Cashier provides an expressive, fluent interface to [Stripe's](https://s First, add the Cashier package to your `composer.json` file and run the `composer update` command: - "laravel/cashier": "~5.0" (For Stripe SDK ~2.0, and Stripe APIs on 2015-02-18 version and later) - "laravel/cashier": "~4.0" (For Stripe APIs on 2015-02-18 version and later) - "laravel/cashier": "~3.0" (For Stripe APIs up to and including 2015-02-16 version) + "laravel/cashier": "~5.0" (For Stripe SDK ~2.0, and Stripe APIs on 2015-02-18 version and later) + "laravel/cashier": "~4.0" (For Stripe APIs on 2015-02-18 version and later) + "laravel/cashier": "~3.0" (For Stripe APIs up to and including 2015-02-16 version) #### Service Provider @@ -46,15 +46,15 @@ Once the migration has been created, simply run the `migrate` command. Next, add the `Billable` trait and appropriate date mutators to your model definition: - use Laravel\Cashier\Billable; - use Laravel\Cashier\Contracts\Billable as BillableContract; + use Laravel\Cashier\Billable; + use Laravel\Cashier\Contracts\Billable as BillableContract; - class User extends Model implements BillableContract - { - use Billable; + class User extends Model implements BillableContract + { + use Billable; - protected $dates = ['trial_ends_at', 'subscription_ends_at']; - } + protected $dates = ['trial_ends_at', 'subscription_ends_at']; + } Adding the columns to your model's `$dates` property will instruct Eloquent to return the columns as Carbon / DateTime instances instead of raw strings. @@ -62,10 +62,10 @@ Adding the columns to your model's `$dates` property will instruct Eloquent to r Finally, set your Stripe key in your `services.php` configuration file: - 'stripe' => [ - 'model' => 'User', - 'secret' => env('STRIPE_API_SECRET'), - ], + 'stripe' => [ + 'model' => 'User', + 'secret' => env('STRIPE_API_SECRET'), + ], ## Subscriptions @@ -75,25 +75,25 @@ Finally, set your Stripe key in your `services.php` configuration file: To create a subscription, first retrieve an instance of your billable model, which typically will be an instance of `App\User`. Once you have retrieved the model instance, you may use the `subscription` method to manage the model's subscription: - $user = User::find(1); + $user = User::find(1); - $user->subscription('monthly')->create($creditCardToken); + $user->subscription('monthly')->create($creditCardToken); The `create` method will automatically create the Stripe subscription, as well as update your database with Stripe customer ID and other relevant billing information. If your plan has a trial configured in Stripe, the trial end date will also automatically be set on the user record. In you want to implement trial periods, but are managing the trials entirely within your application instead of defining them within Stripe, you must manually set the trial end date: - $user->trial_ends_at = Carbon::now()->addDays(14); + $user->trial_ends_at = Carbon::now()->addDays(14); - $user->save(); + $user->save(); #### Additional User Details If you would like to specify additional customer details, you may do so by passing them as second argument to the `create` method: - $user->subscription('monthly')->create($creditCardToken, [ - 'email' => $email, 'description' => 'Our First Customer' - ]); + $user->subscription('monthly')->create($creditCardToken, [ + 'email' => $email, 'description' => 'Our First Customer' + ]); To learn more about the additional fields supported by Stripe, check out Stripe's [documentation on customer creation](https://stripe.com/docs/api#create_customer). @@ -101,94 +101,94 @@ To learn more about the additional fields supported by Stripe, check out Stripe' If you would like to apply a coupon when creating the subscription, you may use the `withCoupon` method: - $user->subscription('monthly') - ->withCoupon('code') - ->create($creditCardToken); + $user->subscription('monthly') + ->withCoupon('code') + ->create($creditCardToken); ### Checking Subscription Status Once a user is subscribed to your application, you may easily check their subscription status using a variety of convenient methods. First, the `subscribed` method returns `true` if the user has an active subscription, even if the subscription is currently within its trial period:s - if ($user->subscribed()) { - // - } + if ($user->subscribed()) { + // + } The `subscribed` method also makes a great candidate for a [route middleware](/docs/{{version}}/middleware), allowing you to filter access to routes and controllers based on the user's subscription status: - public function handle($request, Closure $next) - { - if ($request->user() && ! $request->user()->subscribed()) { - // This user is not a paying customer... - return redirect('billing'); - } + public function handle($request, Closure $next) + { + if ($request->user() && ! $request->user()->subscribed()) { + // This user is not a paying customer... + return redirect('billing'); + } - return $next($request); - } + return $next($request); + } If you would like to determine if a user is still within their trial period, you may use the `onTrial` method. This method can be useful for displaying a warning to the user that they are still on their trial period: - if ($user->onTrial()) { - // - } + if ($user->onTrial()) { + // + } The `onPlan` method may be used to determine if the user is subscribed to a given plan based on its Stripe ID: - if ($user->onPlan('monthly')) { - // - } + if ($user->onPlan('monthly')) { + // + } #### Cancelled Subscription Status To determine if the user was once an active subscriber, but has cancelled their subscription, you may use the `cancelled` method: - if ($user->cancelled()) { - // - } + if ($user->cancelled()) { + // + } You may also determine if a user has cancelled their subscription, but are still on their "grace period" until the subscription fully expires. For example, if a user cancels a subscription on March 5th that was originally scheduled to expire on March 10th, the user is on their "grace period" until March 10th. Note that the `subscribed` method still returns `true` during this time. - if ($user->onGracePeriod()) { - // - } + if ($user->onGracePeriod()) { + // + } The `everSubscribed` method may be used to determine if the user has ever subscribed to a plan in your application: - if ($user->everSubscribed()) { - // - } + if ($user->everSubscribed()) { + // + } ### Changing Plans After a user is subscribed to your application, they may occasionally want to change to a new subscription plan. To swap a user to a new subscription, use the `swap` method. For example, we may easily switch a user to the `premium` subscription: - $user = App\User::find(1); + $user = App\User::find(1); - $user->subscription('premium')->swap(); + $user->subscription('premium')->swap(); If the user is on trial, the trial period will be maintained. Also, if a "quantity" exists for the subscription, that quantity will also be maintained. When swapping plans, you may also use the `prorate` method to indicate that the charges should be pro-rated. In addition, you may use the `swapAndInvoice` method to immediately invoice the user for the plan change: - $user->subscription('premium') - ->prorate() - ->swapAndInvoice(); + $user->subscription('premium') + ->prorate() + ->swapAndInvoice(); ### Subscription Quantity Sometimes subscriptions are affected by "quantity". For example, your application might charge $10 per month **per user** on an account. To easily increment or decrement your subscription quantity, use the `increment` and `decrement` methods: - $user = User::find(1); + $user = User::find(1); - $user->subscription()->increment(); + $user->subscription()->increment(); - // Add five to the subscription's current quantity... - $user->subscription()->increment(5); + // Add five to the subscription's current quantity... + $user->subscription()->increment(5); - $user->subscription()->decrement(); + $user->subscription()->decrement(); - // Subtract five to the subscription's current quantity... - $user->subscription()->decrement(5); + // Subtract five to the subscription's current quantity... + $user->subscription()->decrement(5); For more information on subscription quantities, consult the [Stripe documentation](https://stripe.com/docs/guides/subscriptions#setting-quantities). @@ -197,9 +197,9 @@ For more information on subscription quantities, consult the [Stripe documentati With Cashier, it's easy to provide the `tax_percent` value sent to Stripe. To specify the tax percentage a user pays on a subscription, implement the `getTaxPercent` method on your billable model, and return a numeric value between 0 and 100, with no more than 2 decimal places. - public function getTaxPercent() { - return 20; - } + public function getTaxPercent() { + return 20; + } This enables you to apply a tax rate on a model-by-model basis, which may be helpful for a user base that spans multiple countries. @@ -208,22 +208,22 @@ This enables you to apply a tax rate on a model-by-model basis, which may be hel To cancel a subscription, simply call the `cancel` method on the user's subscription: - $user->subscription()->cancel(); + $user->subscription()->cancel(); When a subscription is cancelled, Cashier will automatically set the `subscription_ends_at` column in your database. This column is used to know when the `subscribed` method should begin returning `false`. For example, if a customer cancels a subscription on March 1st, but the subscription was not scheduled to end until March 5th, the `subscribed` method will continue to return `true` until March 5th. You may determine if a user has cancelled their subscription but are still on their "grace period" using the `onGracePeriod` method: - if ($user->onGracePeriod()) { - // - } + if ($user->onGracePeriod()) { + // + } ### Resuming Subscriptions If a user has cancelled their subscription and you wish to resume it, use the `resume` method: - $user->subscription('monthly')->resume($creditCardToken); + $user->subscription('monthly')->resume($creditCardToken); If the user cancels a subscription and then resumes that subscription before the subscription has fully expired, they will not be billed immediately. Instead, their subscription will simply be re-activated, and they will be billed on the original billing cycle. @@ -235,60 +235,60 @@ If the user cancels a subscription and then resumes that subscription before the What if a customer's credit card expires? No worries - Cashier includes a Webhook controller that can easily cancel the customer's subscription for you. Just point a route to the controller: - Route::post('stripe/webhook', 'Laravel\Cashier\WebhookController@handleWebhook'); + Route::post('stripe/webhook', 'Laravel\Cashier\WebhookController@handleWebhook'); That's it! Failed payments will be captured and handled by the controller. The controller will cancel the customer's subscription when Stripe determines the subscription has failed (normally after three failed payment attempts). Don't forget: you will need to configure the webhook URI in your Stripe control panel settings. Since Stripe webhooks need to bypass Laravel's [CSRF verification](/docs/{{version}}/routing#csrf-protection), be sure to list the URI an exception in your `VerifyCsrfToken` middleware: - protected $except = [ - 'stripe/*', - ]; + protected $except = [ + 'stripe/*', + ]; ### Other Webhooks If you have additional Stripe webhook events you would like to handle, simply extend the Webhook controller. Your method names should correspond to Cashier's expected convention, specifically, methods should be prefixed with `handle` and the "camel case" name of the Stripe webhook you wish to handle. For example, if you wish to handle the `invoice.payment_succeeded` webhook, you should add a `handleInvoicePaymentSucceeded` method to the controller. - ## Single Charges If you would like to make a "one off" charge against a subscribed customer's credit card, you may use the `charge` method on a billable model instance. The `charge` method accepts the amount you would like to charge in the **lowest denominator of the currency used by your application**. So, for example, the example above will charge 100 cents, or $1.00, against the user's credit card: - $user->charge(100); + $user->charge(100); The `charge` method accepts an array as its second argument, allowing you to pass any options you wish to the underlying Stripe charge creation: - $user->charge(100, [ - 'source' => $token, - 'receipt_email' => $user->email, - ]); + $user->charge(100, [ + 'source' => $token, + 'receipt_email' => $user->email, + ]); The `charge` method will return `false` if the charge fails. This typically indicates the charge was denied: - if ( ! $user->charge(100)) { - // The charge was denied... - } + if ( ! $user->charge(100)) { + // The charge was denied... + } If the charge is successful, the full Stripe response will be returned from the method. @@ -297,28 +297,28 @@ If the charge is successful, the full Stripe response will be returned from the You may easily retrieve an array of a billable model's invoices using the `invoices` method: - $invoices = $user->invoices(); + $invoices = $user->invoices(); When listing the invoices for the customer, you may use the invoice's helper methods to display the relevant invoice information. For example, you may wish to list every invoice in a table, allowing the user to easily download any of them: - - @foreach ($invoices as $invoice) - - - - - - @endforeach -
{{ $invoice->dateString() }}{{ $invoice->dollars() }}Download
+ + @foreach ($invoices as $invoice) + + + + + + @endforeach +
{{ $invoice->dateString() }}{{ $invoice->dollars() }}Download
#### Generating Invoice PDFs From within a route or controller, use the `downloadInvoice` method to generate a PDF download of the invoice. This method will automatically generate the proper HTTP response to send the download to the browser: - Route::get('user/invoice/{invoice}', function ($invoiceId) { - return Auth::user()->downloadInvoice($invoiceId, [ - 'vendor' => 'Your Company', - 'product' => 'Your Product', - ]); - }); + Route::get('user/invoice/{invoice}', function ($invoiceId) { + return Auth::user()->downloadInvoice($invoiceId, [ + 'vendor' => 'Your Company', + 'product' => 'Your Product', + ]); + }); diff --git a/blade.md b/blade.md index 87e9961fd3..9d19b30c3c 100644 --- a/blade.md +++ b/blade.md @@ -2,8 +2,8 @@ - [Introduction](#introduction) - [Template Inheritance](#template-inheritance) - - [Defining A Layout](#defining-a-layout) - - [Extending A Layout](#extending-a-layout) + - [Defining A Layout](#defining-a-layout) + - [Extending A Layout](#extending-a-layout) - [Displaying Data](#displaying-data) - [Control Structures](#control-structures) - [Service Injection](#service-injection) @@ -22,22 +22,22 @@ Blade is the simple, yet powerful templating engine provided with Laravel. Unlik Two of the primary benefits of using Blade are _template inheritance_ and _sections_. To get started, let's take a look at a simple example. First, we will examine a "master" page layout. Since most web applications maintain the same general layout across various pages, it's convenient to define this layout as a single Blade view: - + - - - App Name - @yield('title') - - - @section('sidebar') - This is the master sidebar. - @show + + + App Name - @yield('title') + + + @section('sidebar') + This is the master sidebar. + @show -
- @yield('content') -
- - +
+ @yield('content') +
+ + As you can see, this file contains typical HTML mark-up. However, take note of the `@section` and `@yield` directives. The `@section` directive, as the name implies, defines a section of content, while the `@yield` directive is used to display the contents of a given section. @@ -48,46 +48,46 @@ Now that we have defined a layout for our application, let's define a child page When defining a child page, you may use the Blade `@extends` directive to specify which layout the child page should "inherit". Views which `@extends` a Blade layout may inject content into the layout's sections using `@section` directives. Remember, as seen in the example above, the contents of these sections will be displayed in the layout using `@yield`: - + - @extends('layouts.master') + @extends('layouts.master') - @section('title', 'Page Title') + @section('title', 'Page Title') - @section('sidebar') - @@parent + @section('sidebar') + @@parent -

This is appended to the master sidebar.

- @endsection +

This is appended to the master sidebar.

+ @endsection - @section('content') -

This is my body content.

- @endsection + @section('content') +

This is my body content.

+ @endsection In this example, the `sidebar` section is utilizing the `@@parent` directive to append (rather than overwriting) content to the layout's sidebar. The `@@parent` directive will be replaced by the content of the layout when the view is rendered. Of course, just like plain PHP views, Blade views may be returned from routes using the global `view` helper function: - Route::get('blade', function () { - return view('child'); - }); + Route::get('blade', function () { + return view('child'); + }); ## Displaying Data You may display data passed to your Blade views by wrapping the variable in "curly" braces. For example, given the following route: - Route::get('greeting', function () { - return view('welcome', ['name' => 'Samantha']); - }); + Route::get('greeting', function () { + return view('welcome', ['name' => 'Samantha']); + }); You may display the contents of the `name` variable like so: - Hello, {{ $name }}. + Hello, {{ $name }}. Of course, you are not limited to displaying the contents of the variables passed to the view. You may also echo the results of any PHP function. In fact, you can put any PHP code you wish inside of a Blade echo statement: - The current UNIX timestamp is {{ time() }}. + The current UNIX timestamp is {{ time() }}. > **Note:** Blade `{{ }}` statements are automatically sent through PHP's `htmlentities` function to prevent XSS attacks. @@ -95,9 +95,9 @@ Of course, you are not limited to displaying the contents of the variables passe Since many JavaScript frameworks also use "curly" braces to indicate a given expression should be displayed in the browser, you may use the `@` symbol to inform the Blade rendering engine an expression should remain untouched. For example: -

Laravel

+

Laravel

- Hello, @{{ name }}. + Hello, @{{ name }}. In this example, the `@` symbol will be removed by Blade; however, `{{ name }}` expression will remain untouched by the Blade engine, allowing it to instead be rendered by your JavaScript framework. @@ -105,11 +105,11 @@ In this example, the `@` symbol will be removed by Blade; however, `{{ name }}` 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' }} + {{ isset($name) ? $name : 'Default' }} However, instead of writing a ternary statement, Blade provides you with the following convenient short-cut: - {{ $name or 'Default' }} + {{ $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. @@ -117,7 +117,7 @@ In this example, if the `$name` variable exists, its value will be displayed. Ho 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: - Hello, {!! $name !!}. + Hello, {!! $name !!}. > **Note:** Be very careful when echoing content that is supplied by users of your application. Always use the double curly brace syntax to escape any HTML entities in the content. @@ -130,74 +130,74 @@ In addition to template inheritance and displaying data, Blade also provides con You may construct `if` statements using the `@if`, `@elseif`, `@else`, and `@endif` directives. These directives function identically to their PHP counterparts: - @if (count($records) === 1) - I have one record! - @elseif (count($records) > 1) - I have multiple records! - @else - I don't have any records! - @endif + @if (count($records) === 1) + I have one record! + @elseif (count($records) > 1) + I have multiple records! + @else + I don't have any records! + @endif For convenience, Blade also provides an `@unless` directive: - @unless (Auth::check()) - You are not signed in. - @endunless + @unless (Auth::check()) + You are not signed in. + @endunless #### Loops In addition to conditional statements, Blade provides simple directives for working with PHP's supported loop structures. Again, each of these directives functions identically to their PHP counterparts: - @for ($i = 0; $i < 10; $i++) - The current value is {{ $i }} - @endfor + @for ($i = 0; $i < 10; $i++) + The current value is {{ $i }} + @endfor - @foreach ($users as $user) -

This is user {{ $user->id }}

- @endforeach + @foreach ($users as $user) +

This is user {{ $user->id }}

+ @endforeach - @forelse ($users as $user) -
  • {{ $user->name }}
  • - @empty -

    No users

    - @endforelse + @forelse ($users as $user) +
  • {{ $user->name }}
  • + @empty +

    No users

    + @endforelse - @while (true) -

    I'm looping forever.

    - @endwhile + @while (true) +

    I'm looping forever.

    + @endwhile #### Including Sub-Views Blade's `@include` directive, allows you to easily include a Blade view from within an existing view. All variables that are available to the parent view will be made available to the included view: -
    - @include('shared.errors') +
    + @include('shared.errors') -
    - -
    -
    +
    + +
    +
    Even though the included view will inherit all data available in the parent view, you may also pass an array of extra data to the included view: - @include('view.name', ['some' => 'data']) + @include('view.name', ['some' => 'data']) #### Comments Blade also allows you to define comments in your views. However, unlike HTML comments, Blade comments are not included in the HTML returned by your application: - {{-- This comment will not be present in the rendered HTML --}} + {{-- This comment will not be present in the rendered HTML --}} ## Service Injection The `@inject` directive may be used to retrieve a service from the Laravel [service container](/docs/{{version}}/container). The first argument passed to `@inject` is the name of the variable the service will be placed into, while the second argument is the class / interface name of the service you wish to resolve: - @inject('metrics', 'App\Services\MetricsService') + @inject('metrics', 'App\Services\MetricsService') -
    - Monthly Revenue: {{ $metrics->monthlyRevenue() }}. -
    +
    + Monthly Revenue: {{ $metrics->monthlyRevenue() }}. +
    ## Extending Blade @@ -206,40 +206,40 @@ Blade even allows you to define your own custom directives. You can use the `dir The following example creates a `@datetime($var)` directive which formats a given `$var`: - format('m/d/Y H:i'); ?>"; - }); - } - - /** - * Register bindings in the container. - * - * @return void - */ - public function register() - { - // - } - } + format('m/d/Y H:i'); ?>"; + }); + } + + /** + * Register bindings in the container. + * + * @return void + */ + public function register() + { + // + } + } As you can see, Laravel's `with` helper function was used in this directive. The `with` helper simply returns the object / value it is given, allowing for convenient method chaining. The final PHP generated by this directive will be: - format('m/d/Y H:i'); ?> + format('m/d/Y H:i'); ?> diff --git a/cache.md b/cache.md index 43e29477c9..927a17af6b 100644 --- a/cache.md +++ b/cache.md @@ -2,10 +2,10 @@ - [Configuration](#configuration) - [Cache Usage](#cache-usage) - - [Obtaining A Cache Instance](#obtaining-a-cache-instance) - - [Retrieving Items From The Cache](#retrieving-items-from-the-cache) - - [Storing Items In The Cache](#storing-items-in-the-cache) - - [Removing Items From The Cache](#removing-items-from-the-cache) + - [Obtaining A Cache Instance](#obtaining-a-cache-instance) + - [Retrieving Items From The Cache](#retrieving-items-from-the-cache) + - [Storing Items In The Cache](#storing-items-in-the-cache) + - [Removing Items From The Cache](#removing-items-from-the-cache) - [Adding Custom Cache Drivers](#adding-custom-cache-drivers) @@ -21,11 +21,11 @@ The cache configuration file also contains various other options, which are docu When using the `database` cache driver, you will need to setup a table to contain the cache items. You'll find an example `Schema` declaration for the table below: - Schema::create('cache', function($table) { - $table->string('key')->unique(); - $table->text('value'); - $table->integer('expiration'); - }); + Schema::create('cache', function($table) { + $table->string('key')->unique(); + $table->text('value'); + $table->integer('expiration'); + }); #### Memcached @@ -33,23 +33,23 @@ Using the Memcached cache requires the [Memcached PECL package](http://pecl.php. The default [configuration](#configuration) uses TCP/IP based on [Memcached::addServer](http://php.net/manual/en/memcached.addserver.php): - 'memcached' => [ - [ - 'host' => '127.0.0.1', - 'port' => 11211, - 'weight' => 100 - ], - ], + 'memcached' => [ + [ + 'host' => '127.0.0.1', + 'port' => 11211, + 'weight' => 100 + ], + ], You may also set the `host` option to a UNIX socket path. If you do this, the `port` option should be set to `0`: - 'memcached' => [ - [ - 'host' => '/var/run/memcached/memcached.sock', - 'port' => 0, - 'weight' => 100 - ], - ], + 'memcached' => [ + [ + 'host' => '/var/run/memcached/memcached.sock', + 'port' => 0, + 'weight' => 100 + ], + ], #### Redis @@ -69,121 +69,121 @@ However, you may also use the `Cache` facade, which is what we will use througho For example, let's import the `Cache` facade into a controller: - get('foo'); + $value = Cache::store('file')->get('foo'); - Cache::store('redis')->put('bar', 'baz', 10); + Cache::store('redis')->put('bar', 'baz', 10); ### Retrieving Items From The Cache The `get` method on the `Cache` facade is used to retrieve items from the cache. If the item does not exist in the cache, `null` will be returned. If you wish, you may pass a second argument to the `get` method specifying the custom default value you wish to be returned if the item doesn't exist: - $value = Cache::get('key'); + $value = Cache::get('key'); - $value = Cache::get('key', 'default'); + $value = Cache::get('key', 'default'); You may even pass a `Closure` as the default value. The result of the `Closure` will be returned if the specified item does not exist in the cache. Passing a Closure allows you to defer the retrieval of default values from a database or other external service: - $value = Cache::get('key', function() { - return DB::table(...)->get(); - }); + $value = Cache::get('key', function() { + return DB::table(...)->get(); + }); #### Checking For Item Existence The `has` method may be used to determine if an item exists in the cache: - if (Cache::has('key')) { - // - } + if (Cache::has('key')) { + // + } #### Incrementing / Decrementing Values The `increment` and `decrement` methods may be used to adjust the value of integer items in the cache. Both of these methods optionally accept a second argument indicating the amount by which to increment or decrement the item's value: - Cache::increment('key'); + Cache::increment('key'); - Cache::increment('key', $amount); + Cache::increment('key', $amount); - Cache::decrement('key'); + Cache::decrement('key'); - Cache::decrement('key', $amount); + Cache::decrement('key', $amount); #### Retrieve Or Update Sometimes you may wish to retrieve an item from the cache, but also store a default value if the requested item doesn't exist. For example, you may wish to retrieve all users from the cache or, if they don't exist, retrieve them from the database and add them to the cache. You may do this using the `Cache::remember` method: - $value = Cache::remember('users', $minutes, function() { - return DB::table('users')->get(); - }); + $value = Cache::remember('users', $minutes, function() { + return DB::table('users')->get(); + }); If the item does not exist in the cache, the `Closure` passed to the `remember` method will be executed and its result will be placed in the cache. You may also combine the `remember` and `forever` methods: - $value = Cache::rememberForever('users', function() { - return DB::table('users')->get(); - }); + $value = Cache::rememberForever('users', function() { + return DB::table('users')->get(); + }); #### Retrieve And Delete If you need to retrieve an item from the cache and then delete it, you may use the `pull` method. Like the `get` method, `null` will be returned if the item does not exist in the cache: - $value = Cache::pull('key'); + $value = Cache::pull('key'); ### Storing Items In The Cache You may use the `put` method on the `Cache` facade to store items in the cache. When you place an item in the cache, you will need to specify the number of minutes for which the value should be cached: - Cache::put('key', 'value', $minutes); + Cache::put('key', 'value', $minutes); Instead of passing the number of minutes until the item expires, you may also pass a PHP `DateTime` instance representing the expiration time of the cached item: - $expiresAt = Carbon::now()->addMinutes(10); + $expiresAt = Carbon::now()->addMinutes(10); - Cache::put('key', 'value', $expiresAt); + Cache::put('key', 'value', $expiresAt); The `add` method will only add the item to the cache if it does not already exist in the cache store. The method will return `true` if the item is actually added to the cache. Otherwise, the method will return `false`: - Cache::add('key', 'value', $minutes); + Cache::add('key', 'value', $minutes); The `forever` method may be used to store an item in the cache permanently. These values must be manually removed from the cache using the `forget` method: - Cache::forever('key', 'value'); + Cache::forever('key', 'value'); ### Removing Items From The Cache You may remove items from the cache using the `forget` method on the `Cache` facade: - Cache::forget('key'); + Cache::forget('key'); ## Adding Custom Cache Drivers @@ -192,38 +192,38 @@ To extend the Laravel cache with a custom driver, we will use the `extend` metho For example, to register a new cache driver named "mongo": - map(function ($name) { - return strtoupper($name); - }) - ->reject(function ($name) { - return empty($name); - }); + $collection = collect(['taylor', 'abigail', null])->map(function ($name) { + return strtoupper($name); + }) + ->reject(function ($name) { + return empty($name); + }); As you can see, the `Collection` class allows you to chain its methods to perform fluent mapping and reducing of the underlying array. In general, every `Collection` method returns an entirely new `Collection` instance. @@ -24,7 +24,7 @@ As you can see, the `Collection` class allows you to chain its methods to perfor As mentioned above, the `collect` helper returns a new `Illuminate\Support\Collection` instance for the given array. So, creating a collection is as simple as: - $collection = collect([1, 2, 3]); + $collection = collect([1, 2, 3]); By default, collections of [Eloquent](/docs/{{version}}/eloquent) models are always returned as `Collection` instances; however, feel free to use the `Collection` class wherever it is convenient for your application. @@ -36,14 +36,14 @@ For the remainder of this documentation, we'll discuss each method available on You may select any method from this table to see an example of its usage:
    @@ -105,13 +105,13 @@ You may select any method from this table to see an example of its usage: ## Method Listing @@ -119,137 +119,137 @@ You may select any method from this table to see an example of its usage: The `all` method simply returns the underlying array represented by the collection: - collect([1, 2, 3])->all(); + collect([1, 2, 3])->all(); - // [1, 2, 3] + // [1, 2, 3] #### `chunk()` {#collection-method} The `chunk` method breaks the collection into multiple, smaller collections of a given size: - $collection = collect([1, 2, 3, 4, 5, 6, 7]); + $collection = collect([1, 2, 3, 4, 5, 6, 7]); - $chunks = $collection->chunk(4); + $chunks = $collection->chunk(4); - $chunks->toArray(); + $chunks->toArray(); - // [[1, 2, 3, 4], [5, 6, 7]] + // [[1, 2, 3, 4], [5, 6, 7]] This method is especially useful in [views](/docs/{{version}}/views) when working with a grid system such as [Bootstrap](http://getbootstrap.com/css/#grid). Imagine you have a collection of [Eloquent](/docs/{{version}}/eloquent) models you want to display in a grid: - @foreach ($products->chunk(3) as $chunk) -
    - @foreach ($chunk as $product) -
    {{ $product->name }}
    - @endforeach -
    - @endforeach + @foreach ($products->chunk(3) as $chunk) +
    + @foreach ($chunk as $product) +
    {{ $product->name }}
    + @endforeach +
    + @endforeach #### `collapse()` {#collection-method} The `collapse` method collapses a collection of arrays into a flat collection: - $collection = collect([[1, 2, 3], [4, 5, 6], [7, 8, 9]]); + $collection = collect([[1, 2, 3], [4, 5, 6], [7, 8, 9]]); - $collapsed = $collection->collapse(); + $collapsed = $collection->collapse(); - $collapsed->all(); + $collapsed->all(); - // [1, 2, 3, 4, 5, 6, 7, 8, 9] + // [1, 2, 3, 4, 5, 6, 7, 8, 9] #### `contains()` {#collection-method} The `contains` method determines whether the collection contains a given item: - $collection = collect(['name' => 'Desk', 'price' => 100]); + $collection = collect(['name' => 'Desk', 'price' => 100]); - $collection->contains('Desk'); + $collection->contains('Desk'); - // true + // true - $collection->contains('New York'); + $collection->contains('New York'); - // false + // false You may also pass a key / value pair to the `contains` method, which will determine if the given pair exists in the collection: - $collection = collect([ - ['product' => 'Desk', 'price' => 200], - ['product' => 'Chair', 'price' => 100], - ]); + $collection = collect([ + ['product' => 'Desk', 'price' => 200], + ['product' => 'Chair', 'price' => 100], + ]); - $collection->contains('product', 'Bookcase'); + $collection->contains('product', 'Bookcase'); - // false + // false Finally, you may also pass a callback to the `contains` method to perform your own truth test: - $collection = collect([1, 2, 3, 4, 5]); + $collection = collect([1, 2, 3, 4, 5]); - $collection->contains(function ($key, $value) { - return $value > 5; - }); + $collection->contains(function ($key, $value) { + return $value > 5; + }); - // false + // false #### `count()` {#collection-method} The `count` method returns the total number of items in the collection: - $collection = collect([1, 2, 3, 4]); + $collection = collect([1, 2, 3, 4]); - $collection->count(); + $collection->count(); - // 4 + // 4 #### `diff()` {#collection-method} The `diff` method compares the collection against another collection or a plain PHP `array`: - $collection = collect([1, 2, 3, 4, 5]); + $collection = collect([1, 2, 3, 4, 5]); - $diff = $collection->diff([2, 4, 6, 8]); + $diff = $collection->diff([2, 4, 6, 8]); - $diff->all(); + $diff->all(); - // [1, 3, 5] + // [1, 3, 5] #### `each()` {#collection-method} The `each` method iterates over the items in the collection and passes each item to a given callback: - $collection = $collection->each(function ($item, $key) { - // - }); + $collection = $collection->each(function ($item, $key) { + // + }); Return `false` from your callback to break out of the loop: - $collection = $collection->each(function ($item, $key) { - if (/* some condition */) { - return false; - } - }); + $collection = $collection->each(function ($item, $key) { + if (/* some condition */) { + return false; + } + }); #### `filter()` {#collection-method} The `filter` method filters the collection by a given callback, keeping only those items that pass a given truth test: - $collection = collect([1, 2, 3, 4]); + $collection = collect([1, 2, 3, 4]); - $filtered = $collection->filter(function ($item) { - return $item > 2; - }); + $filtered = $collection->filter(function ($item) { + return $item > 2; + }); - $filtered->all(); + $filtered->all(); - // [3, 4] + // [3, 4] For the inverse of `filter`, see the [reject](#method-reject) method. @@ -258,56 +258,56 @@ For the inverse of `filter`, see the [reject](#method-reject) method. The `first` method returns the first element in the collection that passes a given truth test: - collect([1, 2, 3, 4])->first(function ($key, $value) { - return $value > 2; - }); + collect([1, 2, 3, 4])->first(function ($key, $value) { + return $value > 2; + }); - // 3 + // 3 You may also call the `first` method with no arguments to get the first element in the collection. If the collection is empty, `null` is returned: - collect([1, 2, 3, 4])->first(); + collect([1, 2, 3, 4])->first(); - // 1 + // 1 #### `flatten()` {#collection-method} The `flatten` method flattens a multi-dimensional collection into a single dimension: - $collection = collect(['name' => 'taylor', 'languages' => ['php', 'javascript']]); + $collection = collect(['name' => 'taylor', 'languages' => ['php', 'javascript']]); - $flattened = $collection->flatten(); + $flattened = $collection->flatten(); - $flattened->all(); + $flattened->all(); - // ['taylor', 'php', 'javascript']; + // ['taylor', 'php', 'javascript']; #### `flip()` {#collection-method} The `flip` method swaps the collection's keys with their corresponding values: - $collection = collect(['name' => 'taylor', 'framework' => 'laravel']); + $collection = collect(['name' => 'taylor', 'framework' => 'laravel']); - $flipped = $collection->flip(); + $flipped = $collection->flip(); - $flipped->all(); + $flipped->all(); - // ['taylor' => 'name', 'laravel' => 'framework'] + // ['taylor' => 'name', 'laravel' => 'framework'] #### `forget()` {#collection-method} The `forget` method removes an item from the collection by its key: - $collection = collect(['name' => 'taylor', 'framework' => 'laravel']); + $collection = collect(['name' => 'taylor', 'framework' => 'laravel']); - $collection->forget('name'); + $collection->forget('name'); - $collection->all(); + $collection->all(); - // [framework' => 'laravel'] + // [framework' => 'laravel'] > **Note:** Unlike most other collection methods, `forget` does not return a new modified collection; it modifies the collection it is called on. @@ -316,11 +316,11 @@ The `forget` method removes an item from the collection by its key: The `forPage` method returns a new collection containing the items that would be present on a given page number: - $collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9])->forPage(2, 3); + $collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9])->forPage(2, 3); - $collection->all(); + $collection->all(); - // [4, 5, 6] + // [4, 5, 6] The method requires the page number and the number of items to show per page, respectively. @@ -329,85 +329,85 @@ The method requires the page number and the number of items to show per page, re The `get` method returns the item at a given key. If the key does not exist, `null` is returned: - $collection = collect(['name' => 'taylor', 'framework' => 'laravel']); + $collection = collect(['name' => 'taylor', 'framework' => 'laravel']); - $value = $collection->get('name'); + $value = $collection->get('name'); - // taylor + // taylor You may optionally pass a default value as the second argument: - $collection = collect(['name' => 'taylor', 'framework' => 'laravel']); + $collection = collect(['name' => 'taylor', 'framework' => 'laravel']); - $value = $collection->get('foo', 'default-value'); + $value = $collection->get('foo', 'default-value'); - // default-value + // default-value You may even pass a callback as the default value. The result of the callback will be returned if the specified key does not exist: - $collection->get('email', function () { - return 'default-value'; - }); + $collection->get('email', function () { + return 'default-value'; + }); - // default-value + // default-value #### `groupBy()` {#collection-method} The `groupBy` method groups the collection's items by a given key: - $collection = collect([ - ['account_id' => 'account-x10', 'product' => 'Chair'], - ['account_id' => 'account-x10', 'product' => 'Bookcase'], - ['account_id' => 'account-x11', 'product' => 'Desk'], - ]); + $collection = collect([ + ['account_id' => 'account-x10', 'product' => 'Chair'], + ['account_id' => 'account-x10', 'product' => 'Bookcase'], + ['account_id' => 'account-x11', 'product' => 'Desk'], + ]); - $grouped = $collection->groupBy('account_id'); + $grouped = $collection->groupBy('account_id'); - $grouped->toArray(); + $grouped->toArray(); - /* - [ - 'account-x10' => [ - ['account_id' => 'account-x10', 'product' => 'Chair'], - ['account_id' => 'account-x10', 'product' => 'Bookcase'], - ], - 'account-x11' => [ - ['account_id' => 'account-x11', 'product' => 'Desk'], - ], - ] - */ + /* + [ + 'account-x10' => [ + ['account_id' => 'account-x10', 'product' => 'Chair'], + ['account_id' => 'account-x10', 'product' => 'Bookcase'], + ], + 'account-x11' => [ + ['account_id' => 'account-x11', 'product' => 'Desk'], + ], + ] + */ In addition to passing a string `key`, you may also pass a callback. The callback should return the value you wish to key the group by: - $grouped = $collection->groupBy(function ($item, $key) { - return substr($item['account_id'], -3); - }); + $grouped = $collection->groupBy(function ($item, $key) { + return substr($item['account_id'], -3); + }); - $grouped->toArray(); + $grouped->toArray(); - /* - [ - 'x10' => [ - ['account_id' => 'account-x10', 'product' => 'Chair'], - ['account_id' => 'account-x10', 'product' => 'Bookcase'], - ], - 'x11' => [ - ['account_id' => 'account-x11', 'product' => 'Desk'], - ], - ] - */ + /* + [ + 'x10' => [ + ['account_id' => 'account-x10', 'product' => 'Chair'], + ['account_id' => 'account-x10', 'product' => 'Bookcase'], + ], + 'x11' => [ + ['account_id' => 'account-x11', 'product' => 'Desk'], + ], + ] + */ #### `has()` {#collection-method} The `has` method determines if a given key exists in the collection: - $collection = collect(['account_id' => 1, 'product' => 'Desk']); + $collection = collect(['account_id' => 1, 'product' => 'Desk']); - $collection->has('email'); + $collection->has('email'); - // false + // false #### `implode()` {#collection-method} @@ -416,33 +416,33 @@ The `implode` method joins the items in a collection. Its arguments depend on th If the collection contains arrays or objects, you should pass the key of the attributes you wish to join, and the "glue" string you wish to place between the values: - $collection = collect([ - ['account_id' => 1, 'product' => 'Desk'], - ['account_id' => 2, 'product' => 'Chair'], - ]); + $collection = collect([ + ['account_id' => 1, 'product' => 'Desk'], + ['account_id' => 2, 'product' => 'Chair'], + ]); - $collection->implode('product', ', '); + $collection->implode('product', ', '); - // Desk, Chair + // Desk, Chair If the collection contains simple strings or numeric values, simply pass the "glue" as the only argument to the method: - collect([1, 2, 3, 4, 5])->implode('-'); + collect([1, 2, 3, 4, 5])->implode('-'); - // '1-2-3-4-5' + // '1-2-3-4-5' #### `intersect()` {#collection-method} The `intersect` method removes any values that are not present in the given `array` or collection: - $collection = collect(['Desk', 'Sofa', 'Chair']); + $collection = collect(['Desk', 'Sofa', 'Chair']); - $intersect = $collection->intersect(['Desk', 'Chair', 'Bookcase']); + $intersect = $collection->intersect(['Desk', 'Chair', 'Bookcase']); - $intersect->all(); + $intersect->all(); - // [0 => 'Desk', 2 => 'Chair'] + // [0 => 'Desk', 2 => 'Chair'] As you can see, the resulting collection will preserve the original collection's keys. @@ -451,47 +451,47 @@ As you can see, the resulting collection will preserve the original collection's The `isEmpty` method returns `true` if the collection is empty; otherwise, `false` is returned: - collect([])->isEmpty(); + collect([])->isEmpty(); - // true + // true #### `keyBy()` {#collection-method} Keys the collection by the given key: - $collection = collect([ - ['product_id' => 'prod-100', 'name' => 'desk'], - ['product_id' => 'prod-200', 'name' => 'chair'], - ]); + $collection = collect([ + ['product_id' => 'prod-100', 'name' => 'desk'], + ['product_id' => 'prod-200', 'name' => 'chair'], + ]); - $keyed = $collection->keyBy('product_id'); + $keyed = $collection->keyBy('product_id'); - $keyed->all(); + $keyed->all(); - /* - [ - 'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'], - 'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'], - ] - */ + /* + [ + 'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'], + 'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'], + ] + */ If multiple items have the same key, only the last one will appear in the new collection. You may also pass your own callback, which should return the value to key the collection by: - $keyed = $collection->keyBy(function ($item) { - return strtoupper($item['product_id']); - }); + $keyed = $collection->keyBy(function ($item) { + return strtoupper($item['product_id']); + }); - $keyed->all(); + $keyed->all(); - /* - [ - 'PROD-100' => ['product_id' => 'prod-100', 'name' => 'Desk'], - 'PROD-200' => ['product_id' => 'prod-200', 'name' => 'Chair'], - ] - */ + /* + [ + 'PROD-100' => ['product_id' => 'prod-100', 'name' => 'Desk'], + 'PROD-200' => ['product_id' => 'prod-200', 'name' => 'Chair'], + ] + */ @@ -499,48 +499,48 @@ You may also pass your own callback, which should return the value to key the co The `keys` method returns all of the collection's keys: - $collection = collect([ - 'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'], - 'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'], - ]); + $collection = collect([ + 'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'], + 'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'], + ]); - $keys = $collection->keys(); + $keys = $collection->keys(); - $keys->all(); + $keys->all(); - // ['prod-100', 'prod-200'] + // ['prod-100', 'prod-200'] #### `last()` {#collection-method} The `last` method returns the last element in the collection that passes a given truth test: - collect([1, 2, 3, 4])->last(function ($key, $value) { - return $value < 3; - }); + collect([1, 2, 3, 4])->last(function ($key, $value) { + return $value < 3; + }); - // 2 + // 2 You may also call the `last` method with no arguments to get the last element in the collection. If the collection is empty, `null` is returned: - collect([1, 2, 3, 4])->last(); + collect([1, 2, 3, 4])->last(); - // 4 + // 4 #### `map()` {#collection-method} The `map` method iterates through the collection and passes each value to the given callback. The callback is free to modify the item and return it, thus forming a new collection of modified items: - $collection = collect([1, 2, 3, 4, 5]); + $collection = collect([1, 2, 3, 4, 5]); - $multiplied = $collection->map(function ($item, $key) { - return $item * 2; - }); + $multiplied = $collection->map(function ($item, $key) { + return $item * 2; + }); - $multiplied->all(); + $multiplied->all(); - // [2, 4, 6, 8, 10] + // [2, 4, 6, 8, 10] > **Note:** Like most other collection methods, `map` returns a new collection instance; it does not modify the collection it is called on. If you want to transform the original collection, use the [`transform`](#method-transform) method. @@ -549,171 +549,171 @@ The `map` method iterates through the collection and passes each value to the gi The `merge` method merges the given array into the collection. Any string key in the array matching a string key in the collection will overwrite the value in the collection: - $collection = collect(['product_id' => 1, 'name' => 'Desk']); + $collection = collect(['product_id' => 1, 'name' => 'Desk']); - $merged = $collection->merge(['price' => 100, 'discount' => false]); + $merged = $collection->merge(['price' => 100, 'discount' => false]); - $merged->all(); + $merged->all(); - // ['product_id' => 1, 'name' => 'Desk', 'price' => 100, 'discount' => false] + // ['product_id' => 1, 'name' => 'Desk', 'price' => 100, 'discount' => false] If the given array's keys are numeric, the values will be appended to the end of the collection: - $collection = collect(['Desk', 'Chair']); + $collection = collect(['Desk', 'Chair']); - $merged = $collection->merge(['Bookcase', 'Door']); + $merged = $collection->merge(['Bookcase', 'Door']); - $merged->all(); + $merged->all(); - // ['Desk', 'Chair', 'Bookcase', 'Door'] + // ['Desk', 'Chair', 'Bookcase', 'Door'] #### `pluck()` {#collection-method} The `pluck` method retrieves all of the collection values for a given key: - $collection = collect([ - ['product_id' => 'prod-100', 'name' => 'Desk'], - ['product_id' => 'prod-200', 'name' => 'Chair'], - ]); + $collection = collect([ + ['product_id' => 'prod-100', 'name' => 'Desk'], + ['product_id' => 'prod-200', 'name' => 'Chair'], + ]); - $plucked = $collection->pluck('name'); + $plucked = $collection->pluck('name'); - $plucked->all(); + $plucked->all(); - // ['Desk', 'Chair'] + // ['Desk', 'Chair'] You may also specify how you wish the resulting collection to be keyed: - $plucked = $collection->pluck('name', 'product_id'); + $plucked = $collection->pluck('name', 'product_id'); - $plucked->all(); + $plucked->all(); - // ['prod-100' => 'Desk', 'prod-200' => 'Chair'] + // ['prod-100' => 'Desk', 'prod-200' => 'Chair'] #### `pop()` {#collection-method} The `pop` method removes and returns the last item from the collection: - $collection = collect([1, 2, 3, 4, 5]); + $collection = collect([1, 2, 3, 4, 5]); - $collection->pop(); + $collection->pop(); - // 5 + // 5 - $collection->all(); + $collection->all(); - // [1, 2, 3, 4] + // [1, 2, 3, 4] #### `prepend()` {#collection-method} The `prepend` method adds an item to the beginning of the collection: - $collection = collect([1, 2, 3, 4, 5]); + $collection = collect([1, 2, 3, 4, 5]); - $collection->prepend(0); + $collection->prepend(0); - $collection->all(); + $collection->all(); - // [0, 1, 2, 3, 4, 5] + // [0, 1, 2, 3, 4, 5] #### `pull()` {#collection-method} The `pull` method removes and returns an item from the collection by its key: - $collection = collect(['product_id' => 'prod-100', 'name' => 'Desk']); + $collection = collect(['product_id' => 'prod-100', 'name' => 'Desk']); - $collection->pull('name'); + $collection->pull('name'); - // 'Desk' + // 'Desk' - $collection->all(); + $collection->all(); - // ['product_id' => 'prod-100'] + // ['product_id' => 'prod-100'] #### `push()` {#collection-method} The `push` method appends an item to the end of the collection: - $collection = collect([1, 2, 3, 4]); + $collection = collect([1, 2, 3, 4]); - $collection->push(5); + $collection->push(5); - $collection->all(); + $collection->all(); - // [1, 2, 3, 4, 5] + // [1, 2, 3, 4, 5] #### `put()` {#collection-method} The `put` method sets the given key and value in the collection: - $collection = collect(['product_id' => 1, 'name' => 'Desk']); + $collection = collect(['product_id' => 1, 'name' => 'Desk']); - $collection->put('price', 100); + $collection->put('price', 100); - $collection->all(); + $collection->all(); - // ['product_id' => 1, 'name' => 'Desk', 'price' => 100] + // ['product_id' => 1, 'name' => 'Desk', 'price' => 100] #### `random()` {#collection-method} The `random` method returns a random item from the collection: - $collection = collect([1, 2, 3, 4, 5]); + $collection = collect([1, 2, 3, 4, 5]); - $collection->random(); + $collection->random(); - // 4 - (retrieved randomly) + // 4 - (retrieved randomly) You may optionally pass an integer to `random`. If that integer is more than `1`, a collection of items is returned: - $random = $collection->random(3); + $random = $collection->random(3); - $random->all(); + $random->all(); - // [2, 4, 5] - (retrieved randomly) + // [2, 4, 5] - (retrieved randomly) #### `reduce()` {#collection-method} The `reduce` method reduces the collection to a single value, passing the result of each iteration into the subsequent iteration: - $collection = collect([1, 2, 3]); + $collection = collect([1, 2, 3]); - $total = $collection->reduce(function ($carry, $item) { - return $carry + $item; - }); + $total = $collection->reduce(function ($carry, $item) { + return $carry + $item; + }); - // 6 + // 6 The value for `$carry` on the first iteration is `null`; however, you may specify its initial value by passing a second argument to `reduce`: - $collection->reduce(function ($carry, $item) { - return $carry + $item; - }, 4); + $collection->reduce(function ($carry, $item) { + return $carry + $item; + }, 4); - // 10 + // 10 #### `reject()` {#collection-method} The `reject` method filters the collection using the given callback. The callback should return `true` for any items it wishes to remove from the resulting collection: - $collection = collect([1, 2, 3, 4]); + $collection = collect([1, 2, 3, 4]); - $filtered = $collection->reject(function ($item) { - return $item > 2; - }); + $filtered = $collection->reject(function ($item) { + return $item > 2; + }); - $filtered->all(); + $filtered->all(); - // [1, 2] + // [1, 2] For the inverse of the `reject` method, see the [`filter`](#method-filter) method. @@ -722,87 +722,87 @@ For the inverse of the `reject` method, see the [`filter`](#method-filter) metho The `reverse` method reverses the order of the collection's items: - $collection = collect([1, 2, 3, 4, 5]); + $collection = collect([1, 2, 3, 4, 5]); - $reversed = $collection->reverse(); + $reversed = $collection->reverse(); - $reversed->all(); + $reversed->all(); - // [5, 4, 3, 2, 1] + // [5, 4, 3, 2, 1] #### `search()` {#collection-method} The `search` method searches the collection for the given value and returns its key if found. If the item is not found, `false` is returned. - $collection = collect([2, 4, 6, 8]); + $collection = collect([2, 4, 6, 8]); - $collection->search(4); + $collection->search(4); - // 1 + // 1 The search is done using a "loose" comparison. To use strict comparison, pass `true` as the second argument to the method: - $collection->search('4', true); + $collection->search('4', true); - // false + // false Alternatively, you may pass in your own callback to search for the first item that passes your truth test: - $collection->search(function ($item, $key) { - return $item > 5; - }); + $collection->search(function ($item, $key) { + return $item > 5; + }); - // 2 + // 2 #### `shift()` {#collection-method} The `shift` method removes and returns the first item from the collection: - $collection = collect([1, 2, 3, 4, 5]); + $collection = collect([1, 2, 3, 4, 5]); - $collection->shift(); + $collection->shift(); - // 1 + // 1 - $collection->all(); + $collection->all(); - // [2, 3, 4, 5] + // [2, 3, 4, 5] #### `shuffle()` {#collection-method} The `shuffle` method randomly shuffles the items in the collection: - $collection = collect([1, 2, 3, 4, 5]); + $collection = collect([1, 2, 3, 4, 5]); - $shuffled = $collection->shuffle(); + $shuffled = $collection->shuffle(); - $shuffled->all(); + $shuffled->all(); - // [3, 2, 5, 1, 4] // (generated randomly) + // [3, 2, 5, 1, 4] // (generated randomly) #### `slice()` {#collection-method} The `slice` method returns a slice of the collection starting at the given index: - $collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + $collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); - $slice = $collection->slice(4); + $slice = $collection->slice(4); - $slice->all(); + $slice->all(); - // [5, 6, 7, 8, 9, 10] + // [5, 6, 7, 8, 9, 10] If you would like to limit the size of the returned slice, pass the desired size as the second argument to the method: - $slice = $collection->slice(4, 2); + $slice = $collection->slice(4, 2); - $slice->all(); + $slice->all(); - // [5, 6] + // [5, 6] The returned slice will have new, numerically indexed keys. If you wish to preserve the original keys, pass `true` as the third argument to the method. @@ -811,13 +811,13 @@ The returned slice will have new, numerically indexed keys. If you wish to prese The `sort` method sorts the collection: - $collection = collect([5, 3, 1, 2, 4]); + $collection = collect([5, 3, 1, 2, 4]); - $sorted = $collection->sort(); + $sorted = $collection->sort(); - $sorted->values()->all(); + $sorted->values()->all(); - // [1, 2, 3, 4, 5] + // [1, 2, 3, 4, 5] The sorted collection keeps the original array keys. In this example we used the [`values`](#method-values) method to reset the keys to consecutively numbered indexes. @@ -830,47 +830,47 @@ If your sorting needs are more advanced, you may pass a callback to `sort` with The `sortBy` method sorts the collection by the given key: - $collection = collect([ - ['name' => 'Desk', 'price' => 200], - ['name' => 'Chair', 'price' => 100], - ['name' => 'Bookcase', 'price' => 150], - ]); + $collection = collect([ + ['name' => 'Desk', 'price' => 200], + ['name' => 'Chair', 'price' => 100], + ['name' => 'Bookcase', 'price' => 150], + ]); - $sorted = $collection->sortBy('price'); + $sorted = $collection->sortBy('price'); - $sorted->values()->all(); + $sorted->values()->all(); - /* - [ - ['name' => 'Chair', 'price' => 100], - ['name' => 'Bookcase', 'price' => 150], - ['name' => 'Desk', 'price' => 200], - ] - */ + /* + [ + ['name' => 'Chair', 'price' => 100], + ['name' => 'Bookcase', 'price' => 150], + ['name' => 'Desk', 'price' => 200], + ] + */ The sorted collection keeps the original array keys. In this example we used the [`values`](#method-values) method to reset the keys to consecutively numbered indexes. You can also pass your own callback to determine how to sort the collection values: - $collection = collect([ - ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']], - ['name' => 'Chair', 'colors' => ['Black']], - ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']], - ]); + $collection = collect([ + ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']], + ['name' => 'Chair', 'colors' => ['Black']], + ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']], + ]); - $sorted = $collection->sortBy(function ($product, $key) { - return count($product['colors']); - }); + $sorted = $collection->sortBy(function ($product, $key) { + return count($product['colors']); + }); - $sorted->values()->all(); + $sorted->values()->all(); - /* - [ - ['name' => 'Chair', 'colors' => ['Black']], - ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']], - ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']], - ] - */ + /* + [ + ['name' => 'Chair', 'colors' => ['Black']], + ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']], + ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']], + ] + */ #### `sortByDesc()` {#collection-method} @@ -882,117 +882,117 @@ This method has the same signature as the [`sortBy`](#method-sortby) method, but The `splice` method removes and returns a slice of items starting at the specified index: - $collection = collect([1, 2, 3, 4, 5]); + $collection = collect([1, 2, 3, 4, 5]); - $chunk = $collection->splice(2); + $chunk = $collection->splice(2); - $chunk->all(); + $chunk->all(); - // [3, 4, 5] + // [3, 4, 5] - $collection->all(); + $collection->all(); - // [1, 2] + // [1, 2] You may pass a second argument to limit the size of the resulting chunk: - $collection = collect([1, 2, 3, 4, 5]); + $collection = collect([1, 2, 3, 4, 5]); - $chunk = $collection->splice(2, 1); + $chunk = $collection->splice(2, 1); - $chunk->all(); + $chunk->all(); - // [3] + // [3] - $collection->all(); + $collection->all(); - // [1, 2, 4, 5] + // [1, 2, 4, 5] In addition, you can pass a third argument containing the new items to replace the items removed from the collection: - $collection = collect([1, 2, 3, 4, 5]); + $collection = collect([1, 2, 3, 4, 5]); - $chunk = $collection->splice(2, 1, [10, 11]); + $chunk = $collection->splice(2, 1, [10, 11]); - $chunk->all(); + $chunk->all(); - // [3] + // [3] - $collection->all(); + $collection->all(); - // [1, 2, 10, 11, 4, 5] + // [1, 2, 10, 11, 4, 5] #### `sum()` {#collection-method} The `sum` method returns the sum of all items in the collection: - collect([1, 2, 3, 4, 5])->sum(); + collect([1, 2, 3, 4, 5])->sum(); - // 15 + // 15 If the collection contains nested arrays or objects, you should pass a key to use for determining which values to sum: - $collection = collect([ - ['name' => 'JavaScript: The Good Parts', 'pages' => 176], - ['name' => 'JavaScript: The Definitive Guide', 'pages' => 1096], - ]); + $collection = collect([ + ['name' => 'JavaScript: The Good Parts', 'pages' => 176], + ['name' => 'JavaScript: The Definitive Guide', 'pages' => 1096], + ]); - $collection->sum('pages'); + $collection->sum('pages'); - // 1272 + // 1272 In addition, you may pass your own callback to determine which values of the collection to sum: - $collection = collect([ - ['name' => 'Chair', 'colors' => ['Black']], - ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']], - ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']], - ]); + $collection = collect([ + ['name' => 'Chair', 'colors' => ['Black']], + ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']], + ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']], + ]); - $collection->sum(function ($product) { - return count($product['colors']); - }); + $collection->sum(function ($product) { + return count($product['colors']); + }); - // 6 + // 6 #### `take()` {#collection-method} The `take` method returns a new collection with the specified number of items: - $collection = collect([0, 1, 2, 3, 4, 5]); + $collection = collect([0, 1, 2, 3, 4, 5]); - $chunk = $collection->take(3); + $chunk = $collection->take(3); - $chunk->all(); + $chunk->all(); - // [0, 1, 2] + // [0, 1, 2] You may also pass a negative integer to take the specified amount of items from the end of the collection: - $collection = collect([0, 1, 2, 3, 4, 5]); + $collection = collect([0, 1, 2, 3, 4, 5]); - $chunk = $collection->take(-2); + $chunk = $collection->take(-2); - $chunk->all(); + $chunk->all(); - // [4, 5] + // [4, 5] #### `toArray()` {#collection-method} The `toArray` method converts the collection into a plain PHP `array`. If the collection's values are [Eloquent](/docs/{{version}}/eloquent) models, the models will also be converted to arrays: - $collection = collect(['name' => 'Desk', 'price' => 200]); + $collection = collect(['name' => 'Desk', 'price' => 200]); - $collection->toArray(); + $collection->toArray(); - /* - [ - ['name' => 'Desk', 'price' => 200], - ] - */ + /* + [ + ['name' => 'Desk', 'price' => 200], + ] + */ > **Note:** `toArray` also converts all of its nested objects to an array. If you want to get the underlying array as is, use the [`all`](#method-all) method instead. @@ -1001,26 +1001,26 @@ The `toArray` method converts the collection into a plain PHP `array`. If the co The `toJson` method converts the collection into JSON: - $collection = collect(['name' => 'Desk', 'price' => 200]); + $collection = collect(['name' => 'Desk', 'price' => 200]); - $collection->toJson(); + $collection->toJson(); - // '{"name":"Desk","price":200}' + // '{"name":"Desk","price":200}' #### `transform()` {#collection-method} The `transform` method iterates over the collection and calls the given callback with each item in the collection. The items in the collection will be replaced by the values returned by the callback: - $collection = collect([1, 2, 3, 4, 5]); + $collection = collect([1, 2, 3, 4, 5]); - $collection->transform(function ($item, $key) { - return $item * 2; - }); + $collection->transform(function ($item, $key) { + return $item * 2; + }); - $collection->all(); + $collection->all(); - // [2, 4, 6, 8, 10] + // [2, 4, 6, 8, 10] > **Note:** Unlike most other collection methods, `transform` modifies the collection itself. If you wish to create a new collection instead, use the [`map`](#method-map) method. @@ -1029,96 +1029,96 @@ The `transform` method iterates over the collection and calls the given callback The `unique` method returns all of the unique items in the collection: - $collection = collect([1, 1, 2, 2, 3, 4, 2]); + $collection = collect([1, 1, 2, 2, 3, 4, 2]); - $unique = $collection->unique(); + $unique = $collection->unique(); - $unique->values()->all(); + $unique->values()->all(); - // [1, 2, 3, 4] + // [1, 2, 3, 4] The returned collection keeps the original array keys. In this example we used the [`values`](#method-values) method to reset the keys to consecutively numbered indexes. When dealing with nested arrays or objects, you may specify the key used to determine uniqueness: - $collection = collect([ - ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'], - ['name' => 'iPhone 5', 'brand' => 'Apple', 'type' => 'phone'], - ['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'], - ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'], - ['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'], - ]); + $collection = collect([ + ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'], + ['name' => 'iPhone 5', 'brand' => 'Apple', 'type' => 'phone'], + ['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'], + ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'], + ['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'], + ]); - $unique = $collection->unique('brand'); + $unique = $collection->unique('brand'); - $unique->values()->all(); + $unique->values()->all(); - /* - [ - ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'], - ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'], - ] - */ + /* + [ + ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'], + ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'], + ] + */ You may also pass your own callback to determine item uniqueness: - $unique = $collection->unique(function ($item) { - return $item['brand'].$item['type']; - }); + $unique = $collection->unique(function ($item) { + return $item['brand'].$item['type']; + }); - $unique->values()->all(); + $unique->values()->all(); - /* - [ - ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'], - ['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'], - ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'], - ['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'], - ] - */ + /* + [ + ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'], + ['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'], + ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'], + ['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'], + ] + */ #### `values()` {#collection-method} The `values` method returns a new collection with the keys reset to consecutive integers: - $collection = collect([ - 10 => ['product' => 'Desk', 'price' => 200], - 11 => ['product' => 'Desk', 'price' => 200] - ]); + $collection = collect([ + 10 => ['product' => 'Desk', 'price' => 200], + 11 => ['product' => 'Desk', 'price' => 200] + ]); - $values = $collection->values(); + $values = $collection->values(); - $values->all(); + $values->all(); - /* - [ - 0 => ['product' => 'Desk', 'price' => 200], - 1 => ['product' => 'Desk', 'price' => 200], - ] - */ + /* + [ + 0 => ['product' => 'Desk', 'price' => 200], + 1 => ['product' => 'Desk', 'price' => 200], + ] + */ #### `where()` {#collection-method} The `where` method filters the collection by a given key / value pair: - $collection = collect([ - ['product' => 'Desk', 'price' => 200], - ['product' => 'Chair', 'price' => 100], - ['product' => 'Bookcase', 'price' => 150], - ['product' => 'Door', 'price' => 100], - ]); + $collection = collect([ + ['product' => 'Desk', 'price' => 200], + ['product' => 'Chair', 'price' => 100], + ['product' => 'Bookcase', 'price' => 150], + ['product' => 'Door', 'price' => 100], + ]); - $filtered = $collection->where('price', 100); + $filtered = $collection->where('price', 100); - $filtered->all(); + $filtered->all(); - /* - [ - ['product' => 'Chair', 'price' => 100], - ['product' => 'Door', 'price' => 100], - ] - */ + /* + [ + ['product' => 'Chair', 'price' => 100], + ['product' => 'Door', 'price' => 100], + ] + */ The `where` method uses strict comparisons when checking item values. Use the [`whereLoose`](#where-loose) method to filter using "loose" comparisons. @@ -1132,10 +1132,10 @@ This method has the same signature as the [`where`](#method-where) method; howev The `zip` method merges together the values of the given array with the values of the collection at the corresponding index: - $collection = collect(['Chair', 'Desk']); + $collection = collect(['Chair', 'Desk']); - $zipped = $collection->zip([100, 200]); + $zipped = $collection->zip([100, 200]); - $zipped->all(); + $zipped->all(); - // [['Chair', 100], ['Desk', 200]] + // [['Chair', 100], ['Desk', 200]] diff --git a/container.md b/container.md index f55ad38d60..3cc1d32eda 100644 --- a/container.md +++ b/container.md @@ -2,9 +2,9 @@ - [Introduction](#introduction) - [Binding](#binding) - - [Binding Interfaces To Implementations](#binding-interfaces-to-implementations) - - [Contextual Binding](#contextual-binding) - - [Tagging](#tagging) + - [Binding Interfaces To Implementations](#binding-interfaces-to-implementations) + - [Contextual Binding](#contextual-binding) + - [Tagging](#tagging) - [Resolving](#resolving) - [Container Events](#container-events) @@ -15,42 +15,42 @@ The Laravel service container is a powerful tool for managing class dependencies Let's look at a simple example: - mailer = $mailer; - } - - /** - * Purchase a podcast. - * - * @return void - */ - public function handle() - { - // - } - } + mailer = $mailer; + } + + /** + * Purchase a podcast. + * + * @return void + */ + public function handle() + { + // + } + } In this example, the `PurchasePodcast` job needs to send e-mails when a podcast is purchased. So, we will **inject** a service that is able to send e-mails. Since the service is injected, we are able to easily swap it out with another implementation. We are also able to easily "mock", or create a dummy implementation of the mailer when testing our application. @@ -63,9 +63,9 @@ Almost all of your service container bindings will be registered within [service Within a service provider, you always have access to the container via the `$this->app` instance variable. We can register a binding using the `bind` method, passing the class or interface name that we wish to register along with a `Closure` that returns an instance of the class: - $this->app->bind('HelpSpot\API', function ($app) { - return new HelpSpot\API($app['HttpClient']); - }); + $this->app->bind('HelpSpot\API', function ($app) { + return new HelpSpot\API($app['HttpClient']); + }); Notice that we receive the container itself as an argument to the resolver. We can then use the container to resolve sub-dependencies of the object we are building. @@ -73,141 +73,141 @@ Notice that we receive the container itself as an argument to the resolver. We c The `singleton` method binds a class or interface into the container that should only be resolved one time, and then that same instance will be returned on subsequent calls into the container: - $this->app->singleton('FooBar', function ($app) { - return new FooBar($app['SomethingElse']); - }); + $this->app->singleton('FooBar', function ($app) { + return new FooBar($app['SomethingElse']); + }); #### Binding Instances You may also bind an existing object instance into the container using the `instance` method. The given instance will always be returned on subsequent calls into the container: - $fooBar = new FooBar(new SomethingElse); + $fooBar = new FooBar(new SomethingElse); - $this->app->instance('FooBar', $fooBar); + $this->app->instance('FooBar', $fooBar); ### Binding Interfaces To Implementations A very powerful feature of the service container is its ability to bind an interface to a given implementation. For example, let's assume we have an `EventPusher` interface and a `RedisEventPusher` implementation. Once we have coded our `RedisEventPusher` implementation of this interface, we can register it with the service container like so: - $this->app->bind('App\Contracts\EventPusher', 'App\Services\RedisEventPusher'); + $this->app->bind('App\Contracts\EventPusher', 'App\Services\RedisEventPusher'); This tells the container that it should inject the `RedisEventPusher` when a class needs an implementation of `EventPusher`. Now we can type-hint the `EventPusher` interface in a constructor, or any other location where dependencies are injected by the service container: - use App\Contracts\EventPusher; + use App\Contracts\EventPusher; - /** - * Create a new class instance. - * - * @param EventPusher $pusher - * @return void - */ - public function __construct(EventPusher $pusher) - { - $this->pusher = $pusher; - } + /** + * Create a new class instance. + * + * @param EventPusher $pusher + * @return void + */ + public function __construct(EventPusher $pusher) + { + $this->pusher = $pusher; + } ### Contextual Binding Sometimes you may have two classes that utilize the same interface, but you wish to inject different implementations into each class. For example, when our system receives a new Order, we may want to send an event via [PubNub](http://www.pubnub.com/) rather than Pusher. Laravel provides a simple, fluent interface for defining this behavior: - $this->app->when('App\Handlers\Commands\CreateOrderHandler') - ->needs('App\Contracts\EventPusher') - ->give('App\Services\PubNubEventPusher'); + $this->app->when('App\Handlers\Commands\CreateOrderHandler') + ->needs('App\Contracts\EventPusher') + ->give('App\Services\PubNubEventPusher'); You may even pass a Closure to the `give` method: - $this->app->when('App\Handlers\Commands\CreateOrderHandler') - ->needs('App\Contracts\EventPusher') - ->give(function () { - // Resolve dependency... - }); + $this->app->when('App\Handlers\Commands\CreateOrderHandler') + ->needs('App\Contracts\EventPusher') + ->give(function () { + // Resolve dependency... + }); ### Tagging Occasionally, you may need to resolve all of a certain "category" of binding. For example, perhaps you are building a report aggregator that receives an array of many different `Report` interface implementations. After registering the `Report` implementations, you can assign them a tag using the `tag` method: - $this->app->bind('SpeedReport', function () { - // - }); + $this->app->bind('SpeedReport', function () { + // + }); - $this->app->bind('MemoryReport', function () { - // - }); + $this->app->bind('MemoryReport', function () { + // + }); - $this->app->tag(['SpeedReport', 'MemoryReport'], 'reports'); + $this->app->tag(['SpeedReport', 'MemoryReport'], 'reports'); Once the services have been tagged, you may easily resolve them all via the `tagged` method: - $this->app->bind('ReportAggregator', function ($app) { - return new ReportAggregator($app->tagged('reports')); - }); + $this->app->bind('ReportAggregator', function ($app) { + return new ReportAggregator($app->tagged('reports')); + }); ## Resolving There are several ways to resolve something out of the container. First, you may use the `make` method, which accepts the name of the class or interface you wish to resolve: - $fooBar = $this->app->make('FooBar'); + $fooBar = $this->app->make('FooBar'); Secondly, you may access the container like an array, since it implements PHP's `ArrayAccess` interface: - $fooBar = $this->app['FooBar']; + $fooBar = $this->app['FooBar']; Lastly, but most importantly, you may simply "type-hint" the dependency in the constructor of a class that is resolved by the container, including [controllers](/docs/{{version}}/controllers), [event listeners](/docs/{{version}}/events), [queue jobs](/docs/{{version}}/queues), [middleware](/docs/{{version}}/middleware), and more. In practice, this is how most of your objects are resolved by the container. The container will automatically inject dependencies for the classes it resolves. For example, you may type-hint a repository defined by your application in a controller's constructor. The repository will automatically be resolved and injected into the class: - users = $users; - } - - /** - * Show the user with the given ID. - * - * @param int $id - * @return Response - */ - public function show($id) - { - // - } - } + users = $users; + } + + /** + * Show the user with the given ID. + * + * @param int $id + * @return Response + */ + public function show($id) + { + // + } + } ## Container Events The service container fires an event each time it resolves an object. You may listen to this event using the `resolving` method: - $this->app->resolving(function ($object, $app) { - // Called when container resolves object of any type... - }); + $this->app->resolving(function ($object, $app) { + // Called when container resolves object of any type... + }); - $this->app->resolving(function (FooBar $fooBar, $app) { - // Called when container resolves objects of type "FooBar"... - }); + $this->app->resolving(function (FooBar $fooBar, $app) { + // Called when container resolves objects of type "FooBar"... + }); 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. diff --git a/contracts.md b/contracts.md index e0c68ac8aa..0abba8d40c 100644 --- a/contracts.md +++ b/contracts.md @@ -27,41 +27,41 @@ You may have several questions regarding contracts. Why use interfaces at all? I First, let's review some code that is tightly coupled to a cache implementation. Consider the following: - cache = $cache; - } - - /** - * Retrieve an Order by ID. - * - * @param int $id - * @return Order - */ - public function find($id) - { - if ($this->cache->has($id)) { - // - } - } - } + cache = $cache; + } + + /** + * Retrieve an Order by ID. + * + * @param int $id + * @return Order + */ + public function find($id) + { + if ($this->cache->has($id)) { + // + } + } + } In this class, the code is tightly coupled to a given cache implementation. It is tightly coupled because we are depending on a concrete Cache class from a package vendor. If the API of that package changes our code must change as well. @@ -69,25 +69,25 @@ Likewise, if we want to replace our underlying cache technology (Memcached) with **Instead of this approach, we can improve our code by depending on a simple, vendor agnostic interface:** - cache = $cache; - } - } + class Repository + { + /** + * Create a new repository instance. + * + * @param Cache $cache + * @return void + */ + public function __construct(Cache $cache) + { + $this->cache = $cache; + } + } Now the code is not coupled to any specific vendor, or even Laravel. Since the contracts package contains no implementation and no dependencies, you may easily write an alternative implementation of any given contract, allowing you to replace your cache implementation without modifying any of your cache consuming code. @@ -147,42 +147,42 @@ Many types of classes in Laravel are resolved through the [service container](/d For example, take a look at this event listener: - redis = $redis; - } - - /** - * Handle the event. - * - * @param NewUserRegistered $event - * @return void - */ - public function handle(NewUserRegistered $event) - { - // - } - } + redis = $redis; + } + + /** + * Handle the event. + * + * @param NewUserRegistered $event + * @return void + */ + public function handle(NewUserRegistered $event) + { + // + } + } When the event listener is resolved, the service container will read the type-hints on the constructor of the class, and inject the appropriate value. To learn more about registering things in the service container, check out [its documentation](/docs/{{version}}/container). diff --git a/controllers.md b/controllers.md index fa3b888779..64d8c4676c 100644 --- a/controllers.md +++ b/controllers.md @@ -4,10 +4,10 @@ - [Basic Controllers](#basic-controllers) - [Controller Middleware](#controller-middleware) - [RESTful Resource Controllers](#restful-resource-controllers) - - [Partial Resource Routes](#restful-partial-resource-routes) - - [Naming Resource Routes](#restful-naming-resource-routes) - - [Nested Resources](#restful-nested-resources) - - [Supplementing Resource Controllers](#restful-supplementing-resource-controllers) + - [Partial Resource Routes](#restful-partial-resource-routes) + - [Naming Resource Routes](#restful-naming-resource-routes) + - [Nested Resources](#restful-nested-resources) + - [Supplementing Resource Controllers](#restful-supplementing-resource-controllers) - [Implicit Controllers](#implicit-controllers) - [Dependency Injection & Controllers](#dependency-injection-and-controllers) - [Route Caching](#route-caching) @@ -22,30 +22,30 @@ Instead of defining all of your request handling logic in a single `routes.php` Here is an example of a basic controller class. All Laravel controllers should extend the base controller class included with the default Laravel installation: - User::findOrFail($id)]); - } - } + class UserController extends Controller + { + /** + * Show the profile for the given user. + * + * @param int $id + * @return Response + */ + public function showProfile($id) + { + return view('user.profile', ['user' => User::findOrFail($id)]); + } + } We can route to the controller action like so: - Route::get('user/{id}', 'UserController@showProfile'); + Route::get('user/{id}', 'UserController@showProfile'); Now, when a request matches the specified route URI, the `showProfile` method on the `UserController` class will be executed. Of course, the route parameters will also be passed to the method. @@ -55,63 +55,63 @@ It is very important to note that we did not need to specify the full controller If you choose to nest or organize your controllers using PHP namespaces deeper into the `App\Http\Controllers` directory, simply use the specific class name relative to the `App\Http\Controllers` root namespace. So, if your full controller class is `App\Http\Controllers\Photos\AdminController`, you would register a route like so: - Route::get('foo', 'Photos\AdminController@method'); + Route::get('foo', 'Photos\AdminController@method'); #### Naming Controller Routes Like Closure routes, you may specify names on controller routes: - Route::get('foo', ['uses' => 'FooController@method', 'as' => 'name']); + Route::get('foo', ['uses' => 'FooController@method', 'as' => 'name']); Once you have assigned a name to the controller route, you can easily generate URLs to the action. To generate a URL to a controller action, use the `action` helper method. Again, we only need to specify the part of the controller class name that comes after the base `App\Http\Controllers` namespace: - $url = action('FooController@method'); + $url = action('FooController@method'); You may also use the `route` helper to generate a URL to a named controller route: - $url = route('name'); + $url = route('name'); ## Controller Middleware [Middleware](/docs/{{version}}/middleware) may be assigned to the controller's routes like so: - Route::get('profile', [ - 'middleware' => 'auth', - 'uses' => 'UserController@showProfile' - ]); + Route::get('profile', [ + 'middleware' => 'auth', + 'uses' => 'UserController@showProfile' + ]); However, it is more convenient to specify middleware within your controller's constructor. Using the `middleware` method from your controller's constructor, you may easily assign middleware to the controller. You may even restrict the middleware to only certain methods on the controller class: - class UserController extends Controller - { - /** - * Instantiate a new UserController instance. - * - * @return void - */ - public function __construct() - { - $this->middleware('auth'); + class UserController extends Controller + { + /** + * Instantiate a new UserController instance. + * + * @return void + */ + public function __construct() + { + $this->middleware('auth'); - $this->middleware('log', ['only' => ['fooAction', 'barAction']]); + $this->middleware('log', ['only' => ['fooAction', 'barAction']]); - $this->middleware('subscribed', ['except' => ['fooAction', 'barAction']]); - } - } + $this->middleware('subscribed', ['except' => ['fooAction', 'barAction']]); + } + } ## RESTful Resource Controllers Resource controllers make it painless to build RESTful controllers around resources. For example, you may wish to create a controller that handles HTTP requests regarding "photos" stored by your application. Using the `make:controller` Artisan command, we can quickly create such a controller: - php artisan make:controller PhotoController + php artisan make:controller PhotoController The Artisan command will generate a controller file at `app/Http/Controllers/PhotoController.php`. The controller will contain a method for each of the available resource operations. Next, you may register a resourceful route to the controller: - Route::resource('photo', 'PhotoController'); + Route::resource('photo', 'PhotoController'); This single route declaration creates multiple routes to handle a variety of RESTful actions on the photo resource. Likewise, the generated controller will already have methods stubbed for each of these actions, including notes informing you which URIs and verbs they handle. @@ -132,106 +132,106 @@ DELETE | `/photo/{photo}` | destroy | photo.destroy When declaring a resource route, you may specify a subset of actions to handle on the route: - Route::resource('photo', 'PhotoController', - ['only' => ['index', 'show']]); + Route::resource('photo', 'PhotoController', + ['only' => ['index', 'show']]); - Route::resource('photo', 'PhotoController', - ['except' => ['create', 'store', 'update', 'destroy']]); + Route::resource('photo', 'PhotoController', + ['except' => ['create', 'store', 'update', 'destroy']]); #### Naming Resource Routes By default, all resource controller actions have a route name; however, you can override these names by passing a `names` array with your options: - Route::resource('photo', 'PhotoController', - ['names' => ['create' => 'photo.build']]); + Route::resource('photo', 'PhotoController', + ['names' => ['create' => 'photo.build']]); #### Nested Resources Sometimes you may need to define routes to a "nested" resource. For example, a photo resource may have multiple "comments" that may be attached to the photo. To "nest" resource controllers, use "dot" notation in your route declaration: - Route::resource('photos.comments', 'PhotoCommentController'); + Route::resource('photos.comments', 'PhotoCommentController'); This route will register a "nested" resource that may be accessed with URLs like the following: `photos/{photos}/comments/{comments}`. - #### Supplementing Resource Controllers If it becomes necessary to add additional routes to a resource controller beyond the default resource routes, you should define those routes before your call to `Route::resource`; otherwise, the routes defined by the `resource` method may unintentionally take precedence over your supplemental routes: - Route::get('photos/popular', 'PhotoController@method'); + Route::get('photos/popular', 'PhotoController@method'); - Route::resource('photos', 'PhotoController'); + Route::resource('photos', 'PhotoController'); ## Implicit Controllers Laravel allows you to easily define a single route to handle every action in a controller class. First, define the route using the `Route::controller` method. The `controller` method accepts two arguments. The first is the base URI the controller handles, while the second is the class name of the controller: - Route::controller('users', 'UserController'); + Route::controller('users', 'UserController'); Next, just add methods to your controller. The method names should begin with the HTTP verb they respond to followed by the title case version of the URI: - 'user.show', - ]); + Route::controller('users', 'UserController', [ + 'getShow' => 'user.show', + ]); ## Dependency Injection & Controllers @@ -250,31 +250,31 @@ If you would like to [name](/docs/{{version}}/routing#named-routes) some of the The Laravel [service container](/docs/{{version}}/container) is used to resolve all Laravel controllers. As a result, you are able to type-hint any dependencies your controller may need in its constructor. The dependencies will automatically be resolved and injected into the controller instance: - users = $users; - } - } + /** + * Create a new controller instance. + * + * @param UserRepository $users + * @return void + */ + public function __construct(UserRepository $users) + { + $this->users = $users; + } + } Of course, you may also type-hint any [Laravel contract](/docs/{{version}}/contracts). If the container can resolve it, you can type-hint it. @@ -282,66 +282,66 @@ Of course, you may also type-hint any [Laravel contract](/docs/{{version}}/contr In addition to constructor injection, you may also type-hint dependencies on your controller's action methods. For example, let's type-hint the `Illuminate\Http\Request` instance on one of our methods: - input('name'); + class UserController extends Controller + { + /** + * Store a new user. + * + * @param Request $request + * @return Response + */ + public function store(Request $request) + { + $name = $request->input('name'); - // - } - } + // + } + } If your controller method is also expecting input from a route parameter, simply list your route arguments after your other dependencies. For example, if your route is defined like so: - Route::put('user/{id}', 'UserController@update'); + Route::put('user/{id}', 'UserController@update'); You may still type-hint the `Illuminate\Http\Request` and access your route parameter `id` by defining your controller method like the following: - ## Route Caching If your application is exclusively using controller based routes, you may take advantage of Laravel's route cache. Using the route cache will drastically decrease the amount of time it take to register all of your application's routes. In some cases, your route registration may even be up to 100x faster! To generate a route cache, just execute the `route:cache` Artisan command: - php artisan route:cache + php artisan route:cache That's all there is to it! Your cached routes file will now be used instead of your `app/Http/routes.php` file. Remember, if you add any new routes you will need to generate a fresh route cache. Because of this, you may wish to only run the `route:cache` command during your project's deployment. To remove the cached routes file without generating a new cache, use the `route:clear` command: - php artisan route:clear + php artisan route:clear diff --git a/database.md b/database.md index c3031c2807..d8c3e617c8 100644 --- a/database.md +++ b/database.md @@ -2,7 +2,7 @@ - [Introduction](#introduction) - [Running Raw SQL Queries](#running-queries) - - [Listening For Query Events](#listening-for-query-events) + - [Listening For Query Events](#listening-for-query-events) - [Database Transactions](#database-transactions) - [Using Multiple Database Connections](#accessing-connections) @@ -30,21 +30,21 @@ Sometimes you may wish to use one database connection for SELECT statements, and To see how read / write connections should be configured, let's look at this example: - 'mysql' => [ - 'read' => [ - 'host' => '192.168.1.1', - ], - 'write' => [ - 'host' => '196.168.1.2' - ], - 'driver' => 'mysql', - 'database' => 'database', - 'username' => 'root', - 'password' => '', - 'charset' => 'utf8', - 'collation' => 'utf8_unicode_ci', - 'prefix' => '', - ], + 'mysql' => [ + 'read' => [ + 'host' => '192.168.1.1', + ], + 'write' => [ + 'host' => '196.168.1.2' + ], + 'driver' => 'mysql', + 'database' => 'database', + 'username' => 'root', + 'password' => '', + 'charset' => 'utf8', + 'collation' => 'utf8_unicode_ci', + 'prefix' => '', + ], Note that two keys have been added to the configuration array: `read` and `write`. Both of these keys have array values containing a single key: `host`. The rest of the database options for the `read` and `write` connections will be merged from the main `mysql` array. @@ -59,127 +59,127 @@ Once you have configured your database connection, you may run queries using the To run a basic query, we can use the `select` method on the `DB` facade: - $users]); - } - } + return view('user.index', ['users' => $users]); + } + } The first argument passed to the `select` method is the raw SQL query, while the second argument is any parameter bindings that need to be bound to the query. Typically, these are the values of the `where` clause constraints. Parameter binding provides protection against SQL injection. The `select` method will always return an `array` of results. Each result within the array will be a PHP `StdClass` object, allowing you to access the values of the results: - foreach ($users as $user) { - echo $user->name; - } + foreach ($users as $user) { + echo $user->name; + } #### Using Named Bindings Instead of using `?` to represent your parameter bindings, you may execute a query using named bindings: - $results = DB::select('select * from users where id = :id', ['id' => 1]); + $results = DB::select('select * from users where id = :id', ['id' => 1]); #### Running An Insert Statement To execute an `insert` statement, you may use the `insert` method on the `DB` facade. Like `select`, this method takes the raw SQL query as its first argument, and bindings as the second argument: - DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']); + DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']); #### Running An Update Statement The `update` method should be used to update existing records in the database. The number of rows affected by the statement will be returned by the method: - $affected = DB::update('update users set votes = 100 where name = ?', ['John']); + $affected = DB::update('update users set votes = 100 where name = ?', ['John']); #### Running A Delete Statement The `delete` method should be used to delete records from the database. Like `update`, the number of rows deleted will be returned: - $deleted = DB::delete('delete from users'); + $deleted = DB::delete('delete from users'); #### Running A General Statement Some database statements should not return any value. For these types of operations, you may use the `statement` method on the `DB` facade: - DB::statement('drop table users'); + DB::statement('drop table users'); ### Listening For Query Events If you would like to receive each SQL query executed by your application, you may use the `listen` method. This method is useful for logging queries or debugging. You may register your query listener in a [service provider](/docs/{{version}}/providers): - ## Database Transactions To run a set of operations within a database transaction, you may use the `transaction` method on the `DB` facade. If an exception is thrown within the transaction `Closure`, the transaction will automatically be rolled back. If the `Closure` executes successfully, the transaction will automatically be committed. You don't need to worry about manually rolling back or committing while using the `transaction` method: - DB::transaction(function () { - DB::table('users')->update(['votes' => 1]); + DB::transaction(function () { + DB::table('users')->update(['votes' => 1]); - DB::table('posts')->delete(); - }); + DB::table('posts')->delete(); + }); #### Manually Using Transactions If you would like to begin a transaction manually and have complete control over rollbacks and commits, you may use the `beginTransaction` method on the `DB` facade: - DB::beginTransaction(); + DB::beginTransaction(); You can rollback the transaction via the `rollBack` method: - DB::rollBack(); + DB::rollBack(); Lastly, you can commit a transaction via the `commit` method: - DB::commit(); + DB::commit(); > **Note:** Using the `DB` facade's transaction methods also controls transactions for the [query builder](/docs/{{version}}/queries) and [Eloquent ORM](/docs/{{version}}/eloquent). @@ -188,8 +188,8 @@ Lastly, you can commit a transaction via the `commit` method: When using multiple connections, you may access each connection via the `connection` method on the `DB` facade. The `name` passed to the `connection` method should correspond to one of the connections listed in your `config/database.php` configuration file: - $users = DB::connection('foo')->select(...); + $users = DB::connection('foo')->select(...); You may also access the raw, underlying PDO instance using the `getPdo` method on a connection instance: - $pdo = DB::connection()->getPdo(); + $pdo = DB::connection()->getPdo(); diff --git a/elixir.md b/elixir.md index dcce65152d..2b384357a6 100644 --- a/elixir.md +++ b/elixir.md @@ -4,15 +4,15 @@ - [Installation & Setup](#installation) - [Running Elixir](#running-elixir) - [Working With Stylesheets](#working-with-stylesheets) - - [Less](#less) - - [Sass](#sass) - - [Plain CSS](#plain-css) - - [Source Maps](#css-source-maps) + - [Less](#less) + - [Sass](#sass) + - [Plain CSS](#plain-css) + - [Source Maps](#css-source-maps) - [Working With Scripts](#working-with-scripts) - - [CoffeeScript](#coffeescript) - - [Browserify](#browserify) - - [Babel](#babel) - - [Scripts](#javascript) + - [CoffeeScript](#coffeescript) + - [Browserify](#browserify) + - [Babel](#babel) + - [Scripts](#javascript) - [Versioning / Cache Busting](#versioning-and-cache-busting) - [Calling Existing Gulp Tasks](#calling-existing-gulp-tasks) - [Writing Elixir Extensions](#writing-elixir-extensions) @@ -24,8 +24,8 @@ Laravel Elixir provides a clean, fluent API for defining basic [Gulp](http://gul ```javascript elixir(function(mix) { - mix.sass('app.scss') - .coffee('app.coffee'); + mix.sass('app.scss') + .coffee('app.coffee'); }); ``` @@ -52,28 +52,28 @@ Next, you'll want to pull in [Gulp](http://gulpjs.com) as a global NPM package: The only remaining step is to install Elixir! Within a fresh installation of Laravel, you'll find a `package.json` file in the root. Think of this like your `composer.json` file, except it defines Node dependencies instead of PHP. You may install the dependencies it references by running: - npm install + npm install If you are developing on a Windows system, you may need to run the `npm install` command with the `--no-bin-links` switch enabled: - npm install --no-bin-links + npm install --no-bin-links ## Running Elixir Elixir is built on top of [Gulp](http://gulpjs.com), so to run your Elixir tasks you only need to run the `gulp` command in your terminal. Adding the `--production` flag to the command will instruct Elixir to minify your CSS and JavaScript files: - // Run all tasks... - gulp + // Run all tasks... + gulp - // Run all tasks and minify all CSS and JavaScript... - gulp --production + // Run all tasks and minify all CSS and JavaScript... + gulp --production #### Watching Assets For Changes Since it is inconvenient to run the `gulp` command on your terminal after every change to your assets, you may use the `gulp watch` command. This command will continue running in your terminal and watch your assets for any changes. When changes occur, new files will automatically be compiled: - gulp watch + gulp watch ## Working With Stylesheets @@ -87,7 +87,7 @@ To compile [Less](http://lesscss.org/) into CSS, you may use the `less` method. ```javascript elixir(function(mix) { - mix.less("app.less"); + mix.less("app.less"); }); ``` @@ -95,10 +95,10 @@ You may also combine multiple Less files into a single CSS file. Again, the resu ```javascript elixir(function(mix) { - mix.less([ - "app.less", - "controllers.less" - ], "public/assets/css"); + mix.less([ + "app.less", + "controllers.less" + ], "public/assets/css"); }); ``` @@ -106,12 +106,12 @@ If you wish to customize the output location of the compiled CSS, you may pass a ```javascript elixir(function(mix) { - mix.less('app.less', 'public/stylesheets'); + mix.less('app.less', 'public/stylesheets'); }); // Specifying a specific output filename... elixir(function(mix) { - mix.less('app.less', 'public/stylesheets/style.css'); + mix.less('app.less', 'public/stylesheets/style.css'); }); ``` @@ -122,7 +122,7 @@ The `sass` method allows you to compile [Sass](http://sass-lang.com/) into CSS. ```javascript elixir(function(mix) { - mix.sass("app.scss"); + mix.sass("app.scss"); }); ``` @@ -130,10 +130,10 @@ Again, like the `less` method, you may compile multiple scripts into a single CS ```javascript elixir(function(mix) { - mix.sass([ - "app.scss", - "controllers.scss" - ], "public/assets/css"); + mix.sass([ + "app.scss", + "controllers.scss" + ], "public/assets/css"); }); ``` @@ -143,7 +143,7 @@ Under the hood, Elixir uses the LibSass library for compilation. In some instanc ```javascript elixir(function(mix) { - mix.rubySass("app.scss"); + mix.rubySass("app.scss"); }); ``` @@ -154,10 +154,10 @@ If you would just like to combine some plain CSS stylesheets into a single file, ```javascript elixir(function(mix) { - mix.styles([ - "normalize.css", - "main.css" - ]); + mix.styles([ + "normalize.css", + "main.css" + ]); }); ``` @@ -165,10 +165,10 @@ Of course, you may also output the resulting file to a custom location by passin ```javascript elixir(function(mix) { - mix.styles([ - "normalize.css", - "main.css" - ], "public/assets/css"); + mix.styles([ + "normalize.css", + "main.css" + ], "public/assets/css"); }); ``` @@ -183,7 +183,7 @@ If you do not want source maps generated for your CSS, you may disable them usin elixir.config.sourcemaps = false; elixir(function(mix) { - mix.sass("app.scss"); + mix.sass("app.scss"); }); ``` @@ -199,7 +199,7 @@ The `coffee` method may be used to compile [CoffeeScript](http://coffeescript.or ```javascript elixir(function(mix) { - mix.coffee(['app.coffee', 'controllers.coffee']); + mix.coffee(['app.coffee', 'controllers.coffee']); }); ``` @@ -212,7 +212,7 @@ This task assumes that your scripts are stored in `resources/assets/js` and will ```javascript elixir(function(mix) { - mix.browserify('index.js'); + mix.browserify('index.js'); }); ``` @@ -223,7 +223,7 @@ The `babel` method may be used to compile [EcmaScript 6 and 7](https://babeljs.i ```javascript elixir(function(mix) { - mix.babel([ + mix.babel([ "order.js", "product.js" ]); @@ -242,10 +242,10 @@ The `scripts` method assumes all paths are relative to the `resources/assets/js` ```javascript elixir(function(mix) { - mix.scripts([ - "jquery.js", - "app.js" - ]); + mix.scripts([ + "jquery.js", + "app.js" + ]); }); ``` @@ -262,7 +262,7 @@ If you need to combine all of the scripts in a given directory, you may use the ```javascript elixir(function(mix) { - mix.scriptsIn("public/js/some/directory"); + mix.scriptsIn("public/js/some/directory"); }); ``` @@ -275,13 +275,13 @@ The `version` method accepts a file name relative to the `public` directory, and ```javascript elixir(function(mix) { - mix.version("css/all.css"); + mix.version("css/all.css"); }); ``` After generating the versioned file, you may use Laravel's global `elixir` PHP helper function within your [views](/docs/{{version}}/views) to load the appropriately hashed asset. The `elixir` function will automatically determine the name of the hashed file: - + #### Versioning Multiple Files @@ -289,15 +289,15 @@ You may pass an array to the `version` method to version multiple files: ```javascript elixir(function(mix) { - mix.version(["css/all.css", "js/app.js"]); + mix.version(["css/all.css", "js/app.js"]); }); ``` Once the files have been versioned, you may use the `elixir` helper function to generate links to the proper hashed files. Remember, you only need to pass the name of the un-hashed file to the `elixir` helper function. The helper will use the un-hashed name to determine the current hashed version of the file: - + - + ## Calling Existing Gulp Tasks @@ -306,9 +306,9 @@ If you need to call an existing Gulp task from Elixir, you may use the `task` me ```javascript gulp.task("speak", function() { - var message = "Tea...Earl Grey...Hot"; + var message = "Tea...Earl Grey...Hot"; - gulp.src("").pipe(shell("say " + message)); + gulp.src("").pipe(shell("say " + message)); }); ``` @@ -344,11 +344,11 @@ var elixir = require("laravel-elixir"); elixir.extend("speak", function(message) { - gulp.task("speak", function() { - gulp.src("").pipe(shell("say " + message)); - }); + gulp.task("speak", function() { + gulp.src("").pipe(shell("say " + message)); + }); - return this.queueTask("speak"); + return this.queueTask("speak"); }); ``` @@ -363,7 +363,7 @@ var elixir = require("laravel-elixir"); require("./elixir-extensions") elixir(function(mix) { - mix.speak("Tea, Earl Grey, Hot"); + mix.speak("Tea, Earl Grey, Hot"); }); ``` diff --git a/eloquent-collections.md b/eloquent-collections.md index aab1f5f776..012f64ff35 100644 --- a/eloquent-collections.md +++ b/eloquent-collections.md @@ -11,22 +11,22 @@ All multi-result sets returned by Eloquent are an instance of the `Illuminate\Da Of course, all collections also serve as iterators, allowing you to loop over them as if they were simple PHP arrays: - $users = App\User::where('active', 1)->get(); + $users = App\User::where('active', 1)->get(); - foreach ($users as $user) { - echo $user->name; - } + foreach ($users as $user) { + echo $user->name; + } However, collections are much more powerful than arrays and expose a variety of map / reduce operations using an intuitive interface. For example, let's remove all inactive models and gather the first name for each remaining user: - $users = App\User::where('active', 1)->get(); + $users = App\User::where('active', 1)->get(); - $names = $users->reject(function ($user) { - return $user->active === false; - }) - ->map(function ($user) { - return $user->name; - }); + $names = $users->reject(function ($user) { + return $user->active === false; + }) + ->map(function ($user) { + return $user->name; + }); ## Available Methods @@ -36,14 +36,14 @@ However, collections are much more powerful than arrays and expose a variety of All Eloquent collections extend the base [Laravel collection](/docs/{{version}}/collections) object; therefore, they inherit all of the powerful methods provided by the base collection class:
    @@ -106,25 +106,25 @@ All Eloquent collections extend the base [Laravel collection](/docs/{{version}}/ If you need to use a custom `Collection` object with your own extension methods, you may override the `newCollection` method on your model: - first_name; + $firstName = $user->first_name; #### Defining A Mutator To define a mutator, define a `setFooAttribute` method on your model where `Foo` is the "camel" cased name of the column you wish to access. So, again, let's define a mutator for the `first_name` attribute. This mutator will be automatically called when we attempt to set the value of the `first_name` attribute on the model: - attributes['first_name'] = strtolower($value); - } - } + class User extends Model + { + /** + * Set the user's first name. + * + * @param string $value + * @return string + */ + public function setFirstNameAttribute($value) + { + $this->attributes['first_name'] = strtolower($value); + } + } The mutator will receive the value that is being set on the attribute, allowing you to manipulate the value and set the manipulated value on the Eloquent model's internal `$attributes` property. So, for example, if we attempt to set the `first_name` attribute to `Sally`: - $user = App\User::find(1); + $user = App\User::find(1); - $user->first_name = 'Sally'; + $user->first_name = 'Sally'; In this example, the `setFirstNameAttribute` function will be called with the value `Sally`. The mutator will then apply the `strtolower` function to the name and set its value in the internal `$attributes` array. @@ -84,35 +84,35 @@ By default, Eloquent will convert the `created_at` and `updated_at` columns to i You may customize which fields are automatically mutated, and even completely disable this mutation, by overriding the `$dates` property of your model: - disabled_at = Carbon::now(); + $user->disabled_at = Carbon::now(); - $user->save(); + $user->save(); As noted above, when retrieving attributes that are listed in your `$dates` property, they will automatically be cast to [Carbon](https://github.com/briannesbitt/Carbon) instances, allowing you to use any of Carbon's methods on your attributes: - $user = App\User::find(1); + $user = App\User::find(1); - return $user->disabled_at->getTimestamp(); + return $user->disabled_at->getTimestamp(); ## Attribute Casting @@ -121,62 +121,62 @@ The `$casts` property on your model provides a convenient method of converting a For example, let's cast the `is_admin` attribute, which is stored in our database as an integer (`0` or `1`) to a boolean value: - 'boolean', - ]; - } + class User extends Model + { + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts = [ + 'is_admin' => 'boolean', + ]; + } Now the `is_admin` attribute will always be cast to a boolean when you access it, even if the underlying value is stored in the database as an integer: - $user = App\User::find(1); + $user = App\User::find(1); - if ($user->is_admin) { - // - } + if ($user->is_admin) { + // + } #### Array Casting The `array` cast type is particularly useful when working with columns that are stored as serialized JSON. For example, if your database has a `TEXT` field type that contains serialized JSON, adding the `array` cast to that attribute will automatically deserialize the attribute to a PHP array when you access it on your Eloquent model: - 'array', - ]; - } + class User extends Model + { + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts = [ + 'options' => 'array', + ]; + } Once the cast is defined, you may access the `options` attribute and it will automatically be deserialized from JSON into a PHP array. When you set the value of the `options` attribute, the given array will automatically be serialized back into JSON for storage: - $user = App\User::find(1); + $user = App\User::find(1); - $options = $user->options; + $options = $user->options; - $options['key'] = 'value'; + $options['key'] = 'value'; - $user->options = $options; + $user->options = $options; - $user->save(); + $user->save(); diff --git a/eloquent-relationships.md b/eloquent-relationships.md index 0f83116255..170f1d20a9 100644 --- a/eloquent-relationships.md +++ b/eloquent-relationships.md @@ -2,18 +2,18 @@ - [Introduction](#introduction) - [Defining Relationships](#defining-relationships) - - [One To One](#one-to-one) - - [One To Many](#one-to-many) - - [Many To Many](#many-to-many) - - [Has Many Through](#has-many-through) - - [Polymorphic Relations](#polymorphic-relations) - - [Many To Many Polymorphic Relations](#many-to-many-polymorphic-relations) + - [One To One](#one-to-one) + - [One To Many](#one-to-many) + - [Many To Many](#many-to-many) + - [Has Many Through](#has-many-through) + - [Polymorphic Relations](#polymorphic-relations) + - [Many To Many Polymorphic Relations](#many-to-many-polymorphic-relations) - [Querying Relations](#querying-relations) - - [Eager Loading](#eager-loading) - - [Constraining Eager Loads](#constraining-eager-loads) - - [Lazy Eager Loading](#lazy-eager-loading) + - [Eager Loading](#eager-loading) + - [Constraining Eager Loads](#constraining-eager-loads) + - [Lazy Eager Loading](#lazy-eager-loading) - [Inserting Related Models](#inserting-related-models) - - [Many To Many Relationships](#inserting-many-to-many-relationships) + - [Many To Many Relationships](#inserting-many-to-many-relationships) ## Introduction @@ -32,7 +32,7 @@ Database tables are often related to one another. For example, a blog post may h Eloquent relationships are defined as functions on your Eloquent model classes. Since, like Eloquent models themselves, relationships also serve as powerful [query builders](/docs/{{version}}/queries), defining relationships as functions provides powerful method chaining and querying capabilities. For example: - $user->posts()->where('active', 1)->get(); + $user->posts()->where('active', 1)->get(); But, before diving too deep into using relationships, let's learn how to define each type: @@ -41,164 +41,164 @@ But, before diving too deep into using relationships, let's learn how to define A one-to-one relationship is a very basic relation. For example, a `User` model might be associated with one `Phone`. To define this relationship, we place a `phone` method on the `User` model. The `phone` method should return the results of the `hasOne` method on the base Eloquent model class: - hasOne('App\Phone'); - } - } + class User extends Model + { + /** + * Get the phone record associated with the user. + */ + public function phone() + { + return $this->hasOne('App\Phone'); + } + } The first argument passed to the `hasOne` method is the name of the related model. Once the relationship is defined, we may retrieve the related record using Eloquent's [dynamic properties](#dynamic-properties). Dynamic properties allow you to access relationship functions as if they were properties defined on the model: - $phone = User::find(1)->phone; + $phone = User::find(1)->phone; Eloquent assumes the foreign key of the relationship based on the model name. In this case, the `Phone` model is automatically assumed to have a `user_id` foreign key. If you wish to override this convention, you may pass a second argument to the `hasOne` method: - return $this->hasOne('App\Phone', 'foreign_key'); + return $this->hasOne('App\Phone', 'foreign_key'); Additionally, Eloquent assumes that the foreign key should have a value matching the `id` column of the parent. In other words, Eloquent will look for the value of the user's `id` column in the `user_id` column of the `Phone` record. If you would like the relationship to use a value other than `id`, you may pass a third argument to the `hasOne` method specifying your custom key: - return $this->hasOne('App\Phone', 'foreign_key', 'local_key'); + return $this->hasOne('App\Phone', 'foreign_key', 'local_key'); #### Defining The Inverse Of The Relation So, we can access the `Phone` model from our `User`. Now, let's define a relationship on the `Phone` model that will let us access the `User` the owns the phone. We can define the inverse of a `hasOne` relationship using the `belongsTo` method: - belongsTo('App\User'); - } - } + class Phone extends Model + { + /** + * Get the user that owns the phone. + */ + public function user() + { + return $this->belongsTo('App\User'); + } + } In the example above, Eloquent will try to match the `user_id` from the `Phone` model to an `id` on the `User` model. Eloquent determines the default foreign key name by examining the name of the relationship method and suffixing the method name with `_id`. However, if the foreign key on the `Phone` model is not `user_id`, you may pass a custom key name as the second argument to the `belongsTo` method: - /** - * Get the user that owns the phone. - */ - public function user() - { - return $this->belongsTo('App\User', 'foreign_key'); - } + /** + * Get the user that owns the phone. + */ + public function user() + { + return $this->belongsTo('App\User', 'foreign_key'); + } If your parent model does not use `id` as its primary key, or you wish to join the child model to a different column, you may pass a third argument to the `belongsTo` method specifying your parent table's custom key: - /** - * Get the user that owns the phone. - */ - public function user() - { - return $this->belongsTo('App\User', 'foreign_key', 'other_key'); - } + /** + * Get the user that owns the phone. + */ + public function user() + { + return $this->belongsTo('App\User', 'foreign_key', 'other_key'); + } ### One To Many A "one-to-many" relationship is used to define relationships where a single model owns any amount of other models. For example, a blog post may have an infinite number of comments. Like all other Eloquent relationships, one-to-many relationships are defined by placing a function on your Eloquent model: - hasMany('App\Comment'); - } - } + class Post extends Model + { + /** + * Get the comments for the blog post. + */ + public function comments() + { + return $this->hasMany('App\Comment'); + } + } Remember, Eloquent will automatically determine the proper foreign key column on the `Comment` model. By convention, Eloquent will take the "snake case" name of the owning model and suffix it with `_id`. So, for this example, Eloquent will assume the foreign key on the `Comment` model is `post_id`. Once the relationship has been defined, we can access the collection of comments by accessing the `comments` property. Remember, since Eloquent provides "dynamic properties", we can access relationship functions as if they were defined as properties on the model: - $comments = App\Post::find(1)->comments; + $comments = App\Post::find(1)->comments; - foreach ($comments as $comment) { - // - } + foreach ($comments as $comment) { + // + } Of course, since all relationships also serve as query builders, you can add further constraints to which comments are retrieved by calling the `comments` method and continuing to chain conditions onto the query: - $comments = App\Post::find(1)->comments()->where('title', 'foo')->first(); + $comments = App\Post::find(1)->comments()->where('title', 'foo')->first(); Like the `hasOne` method, you may also override the foreign and local keys by passing additional arguments to the `hasMany` method: - return $this->hasMany('App\Comment', 'foreign_key'); + return $this->hasMany('App\Comment', 'foreign_key'); - return $this->hasMany('App\Comment', 'foreign_key', 'local_key'); + return $this->hasMany('App\Comment', 'foreign_key', 'local_key'); #### Defining The Inverse Of The Relation Now that we can access all of a post's comments, let's define a relationship to allow a comment to access its parent post. To define the inverse of a `hasMany` relationship, define a relationship function on the child model which calls the `belongsTo` method: - belongsTo('App\Post'); - } - } + class Comment extends Model + { + /** + * Get the post that owns the comment. + */ + public function post() + { + return $this->belongsTo('App\Post'); + } + } Once the relationship has been defined, we can retrieve the `Post` model for a `Comment` by accessing the `post` "dynamic property": - $comment = App\Comment::find(1); + $comment = App\Comment::find(1); - echo $comment->post->title; + echo $comment->post->title; In the example above, Eloquent will try to match the `post_id` from the `Comment` model to an `id` on the `Post` model. Eloquent determines the default foreign key name by examining the name of the relationship method and suffixing the method name with `_id`. However, if the foreign key on the `Comment` model is not `post_id`, you may pass a custom key name as the second argument to the `belongsTo` method: - /** - * Get the post that owns the comment. - */ - public function post() - { - return $this->belongsTo('App\Post', 'foreign_key'); - } + /** + * Get the post that owns the comment. + */ + public function post() + { + return $this->belongsTo('App\Post', 'foreign_key'); + } If your parent model does not use `id` as its primary key, or you wish to join the child model to a different column, you may pass a third argument to the `belongsTo` method specifying your parent table's custom key: - /** - * Get the post that owns the comment. - */ - public function post() - { - return $this->belongsTo('App\Post', 'foreign_key', 'other_key'); - } + /** + * Get the post that owns the comment. + */ + public function post() + { + return $this->belongsTo('App\Post', 'foreign_key', 'other_key'); + } ### Many To Many @@ -207,63 +207,63 @@ Many-to-many relations are slightly more complicated than `hasOne` and `hasMany` Many-to-many relationships are defined by writing a method that calls the `belongsToMany` method on the base Eloquent class. For example, let's define the `roles` method on our `User` model: - belongsToMany('App\Role'); - } - } + class User extends Model + { + /** + * The roles that belong to the user. + */ + public function roles() + { + return $this->belongsToMany('App\Role'); + } + } Once the relationship is defined, you may access the user's roles using the `roles` dynamic property: - $user = App\User::find(1); + $user = App\User::find(1); - foreach ($user->roles as $role) { - // - } + foreach ($user->roles as $role) { + // + } Of course, like all other relationship types, you may call the `roles` method to continue chaining query constraints onto the relationship: - $roles = App\User::find(1)->roles()->orderBy('name')->get(); + $roles = App\User::find(1)->roles()->orderBy('name')->get(); As mentioned previously, to determine the table name of the relationship's joining table, Eloquent will join the two related model names in alphabetical order. However, you are free to override this convention. You may do so by passing a second argument to the `belongsToMany` method: - return $this->belongsToMany('App\Role', 'user_roles'); + return $this->belongsToMany('App\Role', 'user_roles'); In addition to customizing the name of the joining table, you may also customize the column names of the keys on the table by passing additional arguments to the `belongsToMany` method. The third argument is the foreign key name of the model on which you are defining the relationship, while the fourth argument is the foreign key name of the model that you are joining to: - return $this->belongsToMany('App\Role', 'user_roles', 'user_id', 'role_id'); + return $this->belongsToMany('App\Role', 'user_roles', 'user_id', 'role_id'); #### Defining The Inverse Of The Relationship To define the inverse of a many-to-many relationship, you simply place another call to `belongsToMany` on your related model. To continue our user roles example, let's define the `users` method on the `Role` model: - belongsToMany('App\User'); - } - } + class Role extends Model + { + /** + * The users that belong to the role. + */ + public function users() + { + return $this->belongsToMany('App\User'); + } + } As you can see, the relationship is defined exactly the same as its `User` counterpart, with the exception of simply referencing the `App\User` model. Since we're reusing the `belongsToMany` method, all of the usual table and key customization options are available when defining the inverse of many-to-many relationships. @@ -271,73 +271,73 @@ As you can see, the relationship is defined exactly the same as its `User` count As you have already learned, working with many-to-many relations requires the presence of an intermediate table. Eloquent provides some very helpful ways of interacting with this table. For example, let's assume our `User` object has many `Role` objects that it is related to. After accessing this relationship, we may access the intermediate table using the `pivot` attribute on the models: - $user = App\User::find(1); + $user = App\User::find(1); - foreach ($user->roles as $role) { - echo $role->pivot->created_at; - } + foreach ($user->roles as $role) { + echo $role->pivot->created_at; + } Notice that each `Role` model we retrieve is automatically assigned a `pivot` attribute. This attribute contains a model representing the intermediate table, and may be used like any other Eloquent model. By default, only the model keys will be present on the `pivot` object. If your pivot table contains extra attributes, you must specify them when defining the relationship: - return $this->belongsToMany('App\Role')->withPivot('column1', 'column2'); + return $this->belongsToMany('App\Role')->withPivot('column1', 'column2'); If you want your pivot table to have automatically maintained `created_at` and `updated_at` timestamps, use the `withTimestamps` method on the relationship definition: - return $this->belongsToMany('App\Role')->withTimestamps(); + return $this->belongsToMany('App\Role')->withTimestamps(); ### Has Many Through The "has-many-through" relationship provides a convenient short-cut for accessing distant relations via an intermediate relation. For example, a `Country` model might have many `Post` models through an intermediate `User` model. In this example, you could easily gather all blog posts for a given country. Let's look at the tables required to define this relationship: - countries - id - integer - name - string + countries + id - integer + name - string - users - id - integer - country_id - integer - name - string + users + id - integer + country_id - integer + name - string - posts - id - integer - user_id - integer - title - string + posts + id - integer + user_id - integer + title - string Though `posts` does not contain a `country_id` column, the `hasManyThrough` relation provides access to a country's posts via `$country->posts`. To perform this query, Eloquent inspects the `country_id` on the intermediate `users` table. After finding the matching user IDs, they are used to query the `posts` table. Now that we have examined the table structure for the relationship, let's define it on the `Country` model: - hasManyThrough('App\Post', 'App\User'); - } - } + class Country extends Model + { + /** + * Get all of the posts for the country. + */ + public function posts() + { + return $this->hasManyThrough('App\Post', 'App\User'); + } + } 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, while the fourth argument is the name of the foreign key on the final model. - class Country extends Model - { - public function posts() - { - return $this->hasManyThrough('App\Post', 'App\User', 'country_id', 'user_id'); - } - } + class Country extends Model + { + public function posts() + { + return $this->hasManyThrough('App\Post', 'App\User', 'country_id', 'user_id'); + } + } ### Polymorphic Relations @@ -346,19 +346,19 @@ Typical Eloquent foreign key conventions will be used when performing the relati Polymorphic relations allow a model to belong to more than one other model on a single association. For example, imagine you want to store photos for your staff members and for your products. Using polymorphic relationships, you can use a single `photos` table for both of these scenarios. First, let's examine the table structure required to build this relationship: - staff - id - integer - name - string + staff + id - integer + name - string - products - id - integer - price - integer + products + id - integer + price - integer - photos - id - integer - path - string - imageable_id - integer - imageable_type - string + photos + id - integer + path - string + imageable_id - integer + imageable_type - string Two important columns to note are the `imageable_id` and `imageable_type` columns on the `photos` table. The `imageable_id` column will contain the ID value of the owning staff or product, while the `imageable_type` column will contain the class name of the owning model. The `imageable_type` column is how the ORM determines which "type" of owning model to return when accessing the `imageable` relation. @@ -366,60 +366,60 @@ Two important columns to note are the `imageable_id` and `imageable_type` column Next, let's examine the model definitions needed to build this relationship: - morphTo(); - } - } - - class Staff extends Model - { - /** - * Get all of the staff member's photos. - */ - public function photos() - { - return $this->morphMany('App\Photo', 'imageable'); - } - } - - class Product extends Model - { - /** - * Get all of the product's photos. - */ - public function photos() - { - return $this->morphMany('App\Photo', 'imageable'); - } - } + morphTo(); + } + } + + class Staff extends Model + { + /** + * Get all of the staff member's photos. + */ + public function photos() + { + return $this->morphMany('App\Photo', 'imageable'); + } + } + + class Product extends Model + { + /** + * Get all of the product's photos. + */ + public function photos() + { + return $this->morphMany('App\Photo', 'imageable'); + } + } #### Retrieving Polymorphic Relations Once your database table and models are defined, you may access the relationships via your models. For example, to access all of the photos for a staff member, we can simply use the `photos` dynamic property: - $staff = App\Staff::find(1); + $staff = App\Staff::find(1); - foreach ($staff->photos as $photo) { - // - } + foreach ($staff->photos as $photo) { + // + } You may also retrieve the owner of a polymorphic relation from the polymorphic model by accessing the name of the method that performs the call to `morphTo`. In our case, that is the `imageable` method on the `Photo` model. So, we will access that method as a dynamic property: - $photo = App\Photo::find(1); + $photo = App\Photo::find(1); - $imageable = $photo->imageable; + $imageable = $photo->imageable; The `imageable` relation on the `Photo` model will return either a `Staff` or `Product` instance, depending on which type of model owns the photo. @@ -430,90 +430,90 @@ The `imageable` relation on the `Photo` model will return either a `Staff` or `P In addition to traditional polymorphic relations, you may also define "many-to-many" polymorphic relations. For example, a blog `Post` and `Video` model could share a polymorphic relation to a `Tag` model. Using a many-to-many polymorphic relation allows you to have a single list of unique tags that are shared across blog posts and videos. First, let's examine the table structure: - posts - id - integer - name - string + posts + id - integer + name - string - videos - id - integer - name - string + videos + id - integer + name - string - tags - id - integer - name - string + tags + id - integer + name - string - taggables - tag_id - integer - taggable_id - integer - taggable_type - string + taggables + tag_id - integer + taggable_id - integer + taggable_type - string #### Model Structure Next, we're ready to define the relationships on the model. The `Post` and `Video` models will both have a `tags` method that calls the `morphToMany` method on the base Eloquent class: - morphToMany('App\Tag', 'taggable'); - } - } + class Post extends Model + { + /** + * Get all of the tags for the post. + */ + public function tags() + { + return $this->morphToMany('App\Tag', 'taggable'); + } + } #### Defining The Inverse Of The Relationship Next, on the `Tag` model, you should define a method for each of its related models. So, for this example, we will define a `posts` method and a `videos` method: - morphedByMany('App\Post', 'taggable'); - } + class Tag extends Model + { + /** + * Get all of the posts that are assigned this tag. + */ + public function posts() + { + return $this->morphedByMany('App\Post', 'taggable'); + } - /** - * Get all of the videos that are assigned this tag. - */ - public function videos() - { - return $this->morphedByMany('App\Video', 'taggable'); - } - } + /** + * Get all of the videos that are assigned this tag. + */ + public function videos() + { + return $this->morphedByMany('App\Video', 'taggable'); + } + } #### Retrieving The Relationship Once your database table and models are defined, you may access the relationships via your models. For example, to access all of the tags for a post, you can simply use the `tags` dynamic property: - $post = App\Post::find(1); + $post = App\Post::find(1); - foreach ($post->tags as $tag) { - // - } + foreach ($post->tags as $tag) { + // + } You may also retrieve the owner of a polymorphic relation from the polymorphic model by accessing the name of the method that performs the call to `morphedByMany`. In our case, that is the `posts` or `videos` methods on the `Tag` model. So, you will access those methods as dynamic properties: - $tag = App\Tag::find(1); + $tag = App\Tag::find(1); - foreach ($tag->videos as $video) { - // - } + foreach ($tag->videos as $video) { + // + } ## Querying Relations @@ -522,28 +522,28 @@ Since all types of Eloquent relationships are defined via functions, you may cal For example, imagine a blog system in which a `User` model has many associated `Post` models: - hasMany('App\Post'); - } - } + class User extends Model + { + /** + * Get all of the posts for the user. + */ + public function posts() + { + return $this->hasMany('App\Post'); + } + } You may query the `posts` relationship and add additional constraints to the relationship like so: - $user = App\User::find(1); + $user = App\User::find(1); - $user->posts()->where('active', 1)->get(); + $user->posts()->where('active', 1)->get(); Note that you are able to use any of the [query builder](/docs/{{version}}/queries) on the relationship! @@ -551,11 +551,11 @@ Note that you are able to use any of the [query builder](/docs/{{version}}/queri If you do not need to add additional constraints to an Eloquent relationship query, you may simply access the relationship as if it were a property. For example, continuing to use our `User` and `Post` example models, we may access all of a user's posts like so: - $user = App\User::find(1); + $user = App\User::find(1); - foreach ($user->posts as $post) { - // - } + foreach ($user->posts as $post) { + // + } Dynamic properties are "lazy loading", meaning they will only load their relationship data when you actually access them. Because of this, developers often use [eager loading](#eager-loading) to pre-load relationships they know will be accessed after loading the model. Eager loading provides a significant reduction in SQL queries that must be executed to load a model's relations. @@ -563,117 +563,117 @@ Dynamic properties are "lazy loading", meaning they will only load their relatio When accessing the records for a model, you may wish to limit your results based on the existence of a relationship. For example, imagine you want to retrieve all blog posts that have at least one comment. To do so, you may pass the name of the relationship to the `has` method: - // Retrieve all posts that have at least one comment... - $posts = App\Post::has('comments')->get(); + // Retrieve all posts that have at least one comment... + $posts = App\Post::has('comments')->get(); You may also specify an operator and count to further customize the query: - // Retrieve all posts that have three or more comments... - $posts = Post::has('comments', '>=', 3)->get(); + // Retrieve all posts that have three or more comments... + $posts = Post::has('comments', '>=', 3)->get(); Nested `has` statements may also be constructed using "dot" notation. For example, you may retrieve all posts that have at least one comment and vote: - // Retrieve all posts that have at least one comment with votes... - $posts = Post::has('comments.votes')->get(); + // Retrieve all posts that have at least one comment with votes... + $posts = Post::has('comments.votes')->get(); If you need even more power, you may use the `whereHas` and `orWhereHas` methods to put "where" conditions on your `has` queries. These methods allow you to add customized constraints to a relationship constraint, such as checking the content of a comment: - // Retrieve all posts with at least one comment containing words like foo% - $posts = Post::whereHas('comments', function ($query) { - $query->where('content', 'like', 'foo%'); - })->get(); + // Retrieve all posts with at least one comment containing words like foo% + $posts = Post::whereHas('comments', function ($query) { + $query->where('content', 'like', 'foo%'); + })->get(); ### Eager Loading When accessing Eloquent relationships as properties, the relationship data is "lazy loaded". This means the relationship data is not actually loaded until you first access the property. However, Eloquent can "eager load" relationships at the time you query the parent model. Eager loading alleviates the N + 1 query problem. To illustrate the N + 1 query problem, consider a `Book` model that is related to `Author`: - belongsTo('App\Author'); - } - } + class Book extends Model + { + /** + * Get the author that wrote the book. + */ + public function author() + { + return $this->belongsTo('App\Author'); + } + } Now, let's retrieve all books and their authors: - $books = App\Book::all(); + $books = App\Book::all(); - foreach ($books as $book) { - echo $book->author->name; - } + foreach ($books as $book) { + echo $book->author->name; + } This loop will execute 1 query to retrieve all of the books on the table, then another query for each book to retrieve the author. So, if we have 25 books, this loop would run 26 queries: 1 for the original book, and 25 additional queries to retrieve the author of each book. Thankfully, we can use eager loading to reduce this operation to just 2 queries. When querying, you may specify which relationships should be eager loaded using the `with` method: - $books = App\Book::with('author')->get(); + $books = App\Book::with('author')->get(); - foreach ($books as $book) { - echo $book->author->name; - } + foreach ($books as $book) { + echo $book->author->name; + } For this operation, only two queries will be executed: - select * from books + select * from books - select * from authors where id in (1, 2, 3, 4, 5, ...) + select * from authors where id in (1, 2, 3, 4, 5, ...) #### Eager Loading Multiple Relationships 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 To eager load nested relationships, you may use "dot" syntax. For example, let's eager load all of the book's authors and all of the author's personal contacts in one Eloquent statement: - $books = App\Book::with('author.contacts')->get(); + $books = App\Book::with('author.contacts')->get(); ### Constraining Eager Loads Sometimes you may wish to eager load a relationship, but also specify additional query constraints for the eager loading query. Here's an example: - $users = App\User::with(['posts' => function ($query) { - $query->where('title', 'like', '%first%'); + $users = App\User::with(['posts' => function ($query) { + $query->where('title', 'like', '%first%'); - }])->get(); + }])->get(); In this example, Eloquent will only eager load posts that if the post's `title` column contains the word `first`. Of course, you may call other [query builder](/docs/{{version}}/queries) to further customize the eager loading operation: - $users = App\User::with(['posts' => function ($query) { - $query->orderBy('created_at', 'desc'); + $users = App\User::with(['posts' => function ($query) { + $query->orderBy('created_at', 'desc'); - }])->get(); + }])->get(); ### Lazy Eager Loading Sometimes you may need to eager load a relationship after the parent model has already been retrieved. For example, this may be useful if you need to dynamically decide whether to load related models: - $books = App\Book::all(); + $books = App\Book::all(); - if ($someCondition) { - $books->load('author', 'publisher'); - } + if ($someCondition) { + $books->load('author', 'publisher'); + } If you need to set additional query constraints on the eager loading query, you may pass a `Closure` to the `load` method: - $books->load(['author' => function ($query) { - $query->orderBy('published_date', 'asc'); - }]); + $books->load(['author' => function ($query) { + $query->orderBy('published_date', 'asc'); + }]); ## Inserting Related Models @@ -682,38 +682,38 @@ If you need to set additional query constraints on the eager loading query, you Eloquent provides convenient methods for adding new models to relationships. For example, perhaps you need to insert a new `Comment` for a `Post` model. Instead of manually setting the `post_id` attribute on the `Comment`, you may insert the `Comment` directly from the relationship's `save` method: - $comment = new App\Comment(['message' => 'A new comment.']); + $comment = new App\Comment(['message' => 'A new comment.']); - $post = App\Post::find(1); + $post = App\Post::find(1); - $comment = $post->comments()->save($comment); + $comment = $post->comments()->save($comment); Notice that we did not access the `comments` relationship as a dynamic property. Instead, we called the `comments` method to obtain an instance of the relationship. The `save` method will automatically add the appropriate `post_id` value to the new `Comment` model. If you need to save multiple related models, you may use the `saveMany` method: - $post = App\Post::find(1); + $post = App\Post::find(1); - $post->comments()->saveMany([ - new App\Comment(['message' => 'A new comment.']), - new App\Comment(['message' => 'Another comment.']), - ]); + $post->comments()->saveMany([ + new App\Comment(['message' => 'A new comment.']), + new App\Comment(['message' => 'Another comment.']), + ]); #### Save & Many To Many Relationships When working with a many-to-many relationship, the `save` method accepts an array of additional intermediate table attributes as its second argument: - App\User::find(1)->roles()->save($role, ['expires' => $expires]); + App\User::find(1)->roles()->save($role, ['expires' => $expires]); #### The Create Method In addition to the `save` and `saveMany` methods, you may also use the `create` method, which accepts an array of attributes, creates a model, and inserts it into the database. Again, the difference between `save` and `create` is that `save` accepts a full Eloquent model instance while `create` accepts a plain PHP `array`: - $post = App\Post::find(1); + $post = App\Post::find(1); - $comment = $post->comments()->create([ - 'message' => 'A new comment.', - ]); + $comment = $post->comments()->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). @@ -722,17 +722,17 @@ Before using the `create` method, be sure to review the documentation on attribu When updating a `belongsTo` relationship, you may use the `associate` method. This method will set the foreign key on the child model: - $account = App\Account::find(10); + $account = App\Account::find(10); - $user->account()->associate($account); + $user->account()->associate($account); - $user->save(); + $user->save(); When removing a `belongsTo` relationship, you may use the `dissociate` method. This method will reset the foreign key as well as the relation on the child model: - $user->account()->dissociate(); + $user->account()->dissociate(); - $user->save(); + $user->save(); ### Many To Many Relationships @@ -741,36 +741,36 @@ When removing a `belongsTo` relationship, you may use the `dissociate` method. T When working with many-to-many relationships, Eloquent provides a few additional helper methods to make working with related models more convenient. For example, let's imagine a user can have many roles and a role can have many users. To attach a role to a user by inserting a record in the intermediate table that joins the models, use the `attach` method: - $user = App\User::find(1); + $user = App\User::find(1); - $user->roles()->attach($roleId); + $user->roles()->attach($roleId); When attaching a relationship to a model, you may also pass an array of additional data to be inserted into the intermediate table: - $user->roles()->attach($roleId, ['expires' => $expires]); + $user->roles()->attach($roleId, ['expires' => $expires]); Of course, sometimes it may be necessary to remove a role from a user. To remove a many-to-many relationship record, use the `detach` method. The `detach` method will remove the appropriate record out of the intermediate table; however, both models will remain in the database: - // Detach a single role from the user... - $user->roles()->detach($roleId); + // Detach a single role from the user... + $user->roles()->detach($roleId); - // Detach all roles from the user... - $user->roles()->detach(); + // Detach all roles from the user... + $user->roles()->detach(); For convenience, `attach` and `detach` also accept arrays of IDs as input: - $user = App\User::find(1); + $user = App\User::find(1); - $user->roles()->detach([1, 2, 3]); + $user->roles()->detach([1, 2, 3]); - $user->roles()->attach([1 => ['expires' => $expires], 2, 3]); + $user->roles()->attach([1 => ['expires' => $expires], 2, 3]); #### Syncing For Convenience You may also use the `sync` method to construct many-to-many associations. The `sync` method accepts an array of IDs to place on the intermediate table. Any IDs that are not in the given array will be removed from the intermediate table. So, after this operation is complete, only the IDs in the array will exist in the intermediate table: - $user->roles()->sync([1, 2, 3]); + $user->roles()->sync([1, 2, 3]); You may also pass additional intermediate table values with the IDs: - $user->roles()->sync([1 => ['expires' => true], 2, 3]); + $user->roles()->sync([1 => ['expires' => true], 2, 3]); diff --git a/eloquent-serialization.md b/eloquent-serialization.md index 153c550231..12b87b46cf 100644 --- a/eloquent-serialization.md +++ b/eloquent-serialization.md @@ -17,117 +17,117 @@ When building JSON APIs, you will often need to convert your models and relation To convert a model and its loaded [relationships](/docs/{{version}}/eloquent-relationships) to an array, you may use the `toArray` method. This method is recursive, so all attributes and all relations (including the relations of relations) will be converted to arrays: - $user = App\User::with('roles')->first(); + $user = App\User::with('roles')->first(); - return $user->toArray(); + return $user->toArray(); You may also convert [collections](/docs/{{version}}/eloquent-collections) to arrays: - $users = App\User::all(); + $users = App\User::all(); - return $users->toArray(); + return $users->toArray(); #### Converting A Model To JSON To convert a model to JSON, you may use the `toJson` method. Like `toArray`, the `toJson` method is recursive, so all attributes and relations will be converted to JSON: - $user = App\User::find(1); + $user = App\User::find(1); - return $user->toJson(); + return $user->toJson(); Alternatively, you may cast a model or collection to a string, which will automatically call the `toJson` method: - $user = App\User::find(1); + $user = App\User::find(1); - return (string) $user; + return (string) $user; Since models and collections are converted to JSON when cast to a string, you can return Eloquent objects directly from your application's routes or controllers: - Route::get('users', function () { - return App\User::all(); - }); + Route::get('users', function () { + return App\User::all(); + }); ## Hiding Attributes From JSON Sometimes you may wish to limit the attributes, such as passwords, that are included in your model's array or JSON representation. To do so, add a `$hidden` property definition to your model: - **Note:** When hiding relationships, use the relationship's **method** name, not its dynamic property 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: - ## Appending Values To JSON Occasionally, you may need to add array attributes that do not have a corresponding column in your database. To do so, first define an [accessor](/docs/{{version}}/eloquent-mutators) for the value: - attributes['admin'] == 'yes'; - } - } + class User extends Model + { + /** + * Get the administrator flag for the user. + * + * @return bool + */ + public function getIsAdminAttribute() + { + return $this->attributes['admin'] == 'yes'; + } + } Once you have created the accessor, add the attribute name to the `appends` property on the model: - ### Eloquent Model Conventions Now, let's look at an example `Flight` model class, which we will use to retrieve and store information from our `flights` database table: - ## Retrieving Multiple Models Once you have created a model and [its associated database table](/docs/{{version}}/schema), you are ready to start retrieving data from your database. Think of each Eloquent model as a powerful [query builder](/docs/{{version}}/queries) allowing you to fluently query the database table associated with the model. For example: - $flights]); - } - } + return view('flight.index', ['flights' => $flights]); + } + } #### Accessing Column Values If you have an Eloquent model instance, you may access the column values of the model by accessing the corresponding property. For example, let's loop through each `Flight` instance returned by our query and echo the value of the `name` column: - foreach ($flights as $flight) { - echo $flight->name; - } + foreach ($flights as $flight) { + echo $flight->name; + } #### Adding Additional Constraints The Eloquent `all` method will return all of the results in the model's table. Since each Eloquent model serves as a [query builder](/docs/{{version}}/queries), you may also add constraints to queries, and then use the `get` method to retrieve the results: - $flights = App\Flight::where('active', 1) - ->orderBy('name', 'desc') - ->take(10) - ->get(); + $flights = App\Flight::where('active', 1) + ->orderBy('name', 'desc') + ->take(10) + ->get(); > **Note:** Since Eloquent models are query builders, you should review all of the methods available on the [query builder](/docs/{{version}}/queries). You may use any of these methods in your Eloquent queries. @@ -167,19 +167,19 @@ The Eloquent `all` method will return all of the results in the model's table. S For Eloquent methods like `all` and `get` which retrieve multiple results, an instance of `Illuminate\Database\Eloquent\Collection` will be returned. The `Collection` class provides [a variety of helpful methods](/docs/{{version}}/eloquent-collections) for working with your Eloquent results. Of course, you may simply loop over this collection like an array: - foreach ($flights as $flight) { - echo $flight->name; - } + foreach ($flights as $flight) { + echo $flight->name; + } #### Chunking Results If you need to process thousands of Eloquent records, use the `chunk` command. The `chunk` method will retrieve a "chunk" of Eloquent models, feeding them to a given `Closure` for processing. Using the `chunk` method will conserve memory when working with large result sets: - Flight::chunk(200, function ($flights) { - foreach ($flights as $flight) { - // - } - }); + Flight::chunk(200, function ($flights) { + foreach ($flights as $flight) { + // + } + }); The first argument passed to the method is the number of records you wish to receive per "chunk". The Closure passed as the second argument will be called for each chunk that is retrieved from the database. @@ -188,34 +188,34 @@ The first argument passed to the method is the number of records you wish to rec 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: - // Retrieve a model by its primary key... - $flight = App\Flight::find(1); + // Retrieve a model by its primary key... + $flight = App\Flight::find(1); - // Retrieve the first model matching the query constraints... - $flight = App\Flight::where('active', 1)->first(); + // Retrieve the first model matching the query constraints... + $flight = App\Flight::where('active', 1)->first(); #### Not Found Exceptions Sometimes you may wish to throw an exception if a model is not found. This is particularly useful in routes or controllers. The `findOrFail` and `firstOrFail` methods will retrieve the first result of the query. However, if no result is found, a `Illuminate\Database\Eloquent\ModelNotFoundException` will be thrown: - $model = App\Flight::findOrFail(1); + $model = App\Flight::findOrFail(1); - $model = App\Flight::where('legs', '>', 100)->firstOrFail(); + $model = App\Flight::where('legs', '>', 100)->firstOrFail(); If the exception is not caught, a `404` HTTP response is automatically sent back to the user, so it is not necessary to write explicit checks to return `404` responses when using these methods: - Route::get('/api/flights/{id}', function ($id) { - return App\Flight::findOrFail($id); - }); + Route::get('/api/flights/{id}', function ($id) { + return App\Flight::findOrFail($id); + }); ### Retrieving Aggregates Of course, you may also use the query builder aggregate functions such as `count`, `sum`, `max`, and the other aggregate functions provided by the [query builder](/docs/{{version}}/queries). These methods return the appropriate scalar value instead of a full model instance: - $count = App\Flight::where('active', 1)->count(); + $count = App\Flight::where('active', 1)->count(); - $max = App\Flight::where('active', 1)->max('price'); + $max = App\Flight::where('active', 1)->max('price'); ## Inserting & Updating Models @@ -225,33 +225,33 @@ Of course, you may also use the query builder aggregate functions such as `count To create a new record in the database, simply create a new model instance, set attributes on the model, then call the `save` method: - name = $request->name; + $flight->name = $request->name; - $flight->save(); - } - } + $flight->save(); + } + } In this example, we simply assign the `name` parameter from the incoming HTTP request to the `name` attribute of the `App\Flight` model instance. When we call the `save` method, a record will be inserted into the database. The `created_at` and `updated_at` timestamps will automatically be set when the `save` method is called, so there is no need to set them manually. @@ -260,17 +260,17 @@ In this example, we simply assign the `name` parameter from the incoming HTTP re The `save` method may also be used to update models that already exist in the database. To update a model, you should retrieve it, set any attributes you wish to update, and then call the `save` method. Again, the `updated_at` timestamp will automatically be updated, so there is no need to manually set its value: - $flight = App\Flight::find(1); + $flight = App\Flight::find(1); - $flight->name = 'New Flight Name'; + $flight->name = 'New Flight Name'; - $flight->save(); + $flight->save(); Updates can also be performed against any number of models that match a given query. In this example, all flights that are `active` and have a `destination` of `San Diego` will be marked as delayed: - App\Flight::where('active', 1) - ->where('destination', 'San Diego') - ->update(['delayed' => 1]); + App\Flight::where('active', 1) + ->where('destination', 'San Diego') + ->update(['delayed' => 1]); The `update` method expects an array of column and value pairs representing the columns that should be updated. @@ -283,43 +283,43 @@ A mass-assignment vulnerability occurs when user's pass unexpected HTTP paramete So, to get started, you should define which model attributes you want to make mass assignable. You may do this using the `$fillable` property on the model. For example, let's make the `name` attribute of our `Flight` model mass assignable: - 'Flight 10']); + $flight = App\Flight::create(['name' => 'Flight 10']); While `$fillable` serves as a "white list" of attributes that should be mass assignable, you may also choose to use `$guarded`. The `$guarded` property should contain an array of attributes that you do not want to be mass assignable. All other attributes not in the array will be mass assignable. So, `$guarded` functions like a "black list". Of course, you should use either `$fillable` or `$guarded` - not both: - 'Flight 10']); + // Retrieve the flight by the attributes, 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... - $flight = App\Flight::firstOrNew(['name' => 'Flight 10']); + // Retrieve the flight by the attributes, or instantiate a new instance... + $flight = App\Flight::firstOrNew(['name' => 'Flight 10']); ## Deleting Models To delete a model, call the `delete` method on a model instance: - $flight = App\Flight::find(1); + $flight = App\Flight::find(1); - $flight->delete(); + $flight->delete(); #### Deleting An Existing Model By Key In the example above, we are retrieving the model from the database before calling the `delete` method. However, if you know the primary key of the model, you may delete the model without retrieving it. To do so, call the `destroy` method: - App\Flight::destroy(1); + App\Flight::destroy(1); - App\Flight::destroy([1, 2, 3]); + App\Flight::destroy([1, 2, 3]); - App\Flight::destroy(1, 2, 3); + App\Flight::destroy(1, 2, 3); #### Deleting Models By Query Of course, you may also run a delete query on a set of models. In this example, we will delete all flights that are marked as inactive: - $deletedRows = App\Flight::where('active', 0)->delete(); + $deletedRows = App\Flight::where('active', 0)->delete(); ### Soft Deleting In addition to actually removing records from your database, Eloquent can also "soft delete" models. When models are soft deleted, they are not actually removed from your database. Instead, a `deleted_at` attribute is set on the model and inserted into the database. If a model has a non-null `deleted_at` value, the model has been soft deleted. To enable soft deletes for a model, use the `Illuminate\Database\Eloquent\SoftDeletes` trait on the model and add the `deleted_at` column to your `$dates` property: - softDeletes(); - }); + Schema::table('flights', function ($table) { + $table->softDeletes(); + }); Now, when you call the `delete` method on the model, the `deleted_at` column will be set to the current date and time. And, when querying a model that uses soft deletes, the soft deleted models will automatically be excluded from all query results. To determine if a given model instance has been soft deleted, use the `trashed` method: - if ($flight->trashed()) { - // - } + if ($flight->trashed()) { + // + } ### Querying Soft Deleted Models @@ -405,114 +405,114 @@ To determine if a given model instance has been soft deleted, use the `trashed` As noted above, soft deleted models will automatically be excluded from query results. However, you may force soft deleted models to appear in a result set using the `withTrashed` method on the query: - $flights = App\Flight::withTrashed() - ->where('account_id', 1) - ->get(); + $flights = App\Flight::withTrashed() + ->where('account_id', 1) + ->get(); The `withTrashed` method may also be used on a [relationship](/docs/{{version}}/eloquent-relationships) query: - $flight->history()->withTrashed()->get(); + $flight->history()->withTrashed()->get(); #### Retrieving Only Soft Deleted Models The `onlyTrashed` method will retrieve **only** soft deleted models: - $flights = App\Flight::onlyTrashed() - ->where('airline_id', 1) - ->get(); + $flights = App\Flight::onlyTrashed() + ->where('airline_id', 1) + ->get(); #### Restoring Soft Deleted Models Sometimes you may wish to "un-delete" a soft deleted model. To restore a soft deleted model into an active state, use the `restore` method on a model instance: - $flight->restore(); + $flight->restore(); You may also use the `restore` method in a query to quickly restore multiple models: - App\Flight::withTrashed() - ->where('airline_id', 1) - ->restore(); + App\Flight::withTrashed() + ->where('airline_id', 1) + ->restore(); Like the `withTrashed` method, the `restore` method may also be used on [relationships](/docs/{{version}}/eloquent-relationships): - $flight->history()->restore(); + $flight->history()->restore(); #### Permanently Deleting Models Sometimes you may need to truly remove a model from your database. To permanently remove a soft deleted model from the database, use the `forceDelete` method: - // Force deleting a single model instance... - $flight->forceDelete(); + // Force deleting a single model instance... + $flight->forceDelete(); - // Force deleting all related models... - $flight->history()->forceDelete(); + // Force deleting all related models... + $flight->history()->forceDelete(); ## Query Scopes Scopes allow you to define common sets of constraints that you may easily re-use throughout your application. For example, you may need to frequently retrieve all users that are considered "popular". To define a scope, simply prefix an Eloquent model method with `scope`: - where('votes', '>', 100); - } - - /** - * Scope a query to only include active users. - * - * @return \Illuminate\Database\Eloquent\Builder - */ - public function scopeActive($query) - { - return $query->where('active', 1); - } - } + where('votes', '>', 100); + } + + /** + * Scope a query to only include active users. + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeActive($query) + { + return $query->where('active', 1); + } + } #### Utilizing A Query Scope Once the scope has been defined, you may call the scope methods when querying the model. However, you do not need to include the `scope` prefix when calling the method. You can even chain calls to various scopes, for example: - $users = App\User::popular()->women()->orderBy('created_at')->get(); + $users = App\User::popular()->women()->orderBy('created_at')->get(); #### Dynamic Scopes Sometimes you may wish to define a scope that accepts parameters. To get started, just add your additional parameters to your scope. Scope parameters should be defined after the `$query` argument: - where('type', $type); - } - } + class User extends Model + { + /** + * Scope a query to only include users of a given type. + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeOfType($query, $type) + { + return $query->where('type', $type); + } + } Now, you may pass the parameters when calling the scope: - $users = App\User::ofType('admin')->get(); + $users = App\User::ofType('admin')->get(); ## Events @@ -526,36 +526,36 @@ Whenever a new model is saved for the first time, the `creating` and `created` e For example, let's define an Eloquent event listener in a [service provider](/docs/{{version}}/providers). Within our event listener, we will call the `isValid` method on the given model, and return `false` if the model is not valid. Returning `false` from an Eloquent event listener will cancel the `save` / `update` operation: - isValid()) { - return false; - } - }); - } - - /** - * Register the service provider. - * - * @return void - */ - public function register() - { - // - } - } + isValid()) { + return false; + } + }); + } + + /** + * Register the service provider. + * + * @return void + */ + public function register() + { + // + } + } diff --git a/encryption.md b/encryption.md index d17b29f2ca..37dfeef623 100644 --- a/encryption.md +++ b/encryption.md @@ -17,42 +17,42 @@ You may encrypt a value using the `Crypt` [facade](/docs/{{version}}/facades). A For example, we may use the `encrypt` method to encrypt a secret and store it on an [Eloquent model](/docs/{{version}}/eloquent): - fill([ - 'secret' => Crypt::encrypt($request->secret) - ])->save(); - } - } + fill([ + 'secret' => Crypt::encrypt($request->secret) + ])->save(); + } + } #### Decrypting A Value Of course, you may decrypt values using the `decrypt` method on the `Crypt` facade. If the value can not be properly decrypted, such as when the MAC is invalid, an `Illuminate\Contracts\Encryption\DecryptException` will be thrown: - use Illuminate\Contracts\Encryption\DecryptException; + use Illuminate\Contracts\Encryption\DecryptException; - try { - $decrypted = Crypt::decrypt($encryptedValue); - } catch (DecryptException $e) { - // - } + try { + $decrypted = Crypt::decrypt($encryptedValue); + } catch (DecryptException $e) { + // + } diff --git a/envoy.md b/envoy.md index dcaa203f5d..7ffccc20d0 100644 --- a/envoy.md +++ b/envoy.md @@ -2,13 +2,13 @@ - [Introduction](#introduction) - [Writing Tasks](#writing-tasks) - - [Task Variables](#task-variables) - - [Multiple Servers](#envoy-multiple-servers) - - [Task Macros](#envoy-task-macros) + - [Task Variables](#task-variables) + - [Multiple Servers](#envoy-multiple-servers) + - [Task Macros](#envoy-task-macros) - [Running Tasks](#envoy-running-tasks) - [Notifications](#envoy-notifications) - - [HipChat](#hipchat) - - [Slack](#slack) + - [HipChat](#hipchat) + - [Slack](#slack) ## Introduction @@ -20,7 +20,7 @@ First, install Envoy using the Composer `global` command: - composer global require "laravel/envoy=~1.0" + composer global require "laravel/envoy=~1.0" Make sure to place the `~/.composer/vendor/bin` directory in your PATH so the `envoy` executable is found when you run the `envoy` command in your terminal. @@ -28,18 +28,18 @@ Make sure to place the `~/.composer/vendor/bin` directory in your PATH so the `e You may also use Composer to keep your Envoy installation up to date: - composer global update + composer global update ## Writing Tasks All of your Envoy tasks should be defined in an `Envoy.blade.php` file in the root of your project. Here's an example to get you started: - @servers(['web' => 'user@192.168.1.1']) + @servers(['web' => 'user@192.168.1.1']) - @task('foo', ['on' => 'web']) - ls -la - @endtask + @task('foo', ['on' => 'web']) + ls -la + @endtask As you can see, an array of `@servers` is defined at the top of the file, allowing you to reference these servers in the `on` option of your task declarations. Within your `@task` declarations, you should place the Bash code that will be run on your server when the task is executed. @@ -47,55 +47,55 @@ As you can see, an array of `@servers` is defined at the top of the file, allowi Sometimes, you may need to execute some PHP code before evaluating your Envoy tasks. You may use the ```@setup``` directive to declare variables and do general PHP work inside the Envoy file: - @setup - $now = new DateTime(); + @setup + $now = new DateTime(); - $environment = isset($env) ? $env : "testing"; - @endsetup + $environment = isset($env) ? $env : "testing"; + @endsetup You may also use ```@include``` to include any outside PHP files: - @include('vendor/autoload.php'); + @include('vendor/autoload.php'); #### Confirming Tasks If you would like to be prompted for confirmation before running a given task on your servers, you may add the `confirm` directive to your task declaration: - @task('deploy', ['on' => 'web', 'confirm' => true]) - cd site - git pull origin {{ $branch }} - php artisan migrate - @endtask + @task('deploy', ['on' => 'web', 'confirm' => true]) + cd site + git pull origin {{ $branch }} + php artisan migrate + @endtask ### Task Variables If needed, you may pass variables into the Envoy file using command line switches, allowing you to customize your tasks: - envoy run deploy --branch=master + envoy run deploy --branch=master You may use the options in your tasks via Blade's "echo" syntax: - @servers(['web' => '192.168.1.1']) + @servers(['web' => '192.168.1.1']) - @task('deploy', ['on' => 'web']) - cd site - git pull origin {{ $branch }} - php artisan migrate - @endtask + @task('deploy', ['on' => 'web']) + cd site + git pull origin {{ $branch }} + php artisan migrate + @endtask ### Multiple Servers You may easily run a task across multiple servers. First, add additional servers to your `@servers` declaration. Each server should be assigned a unique name. Once you have defined your additional servers, simply list the servers in the task declaration's `on` array: - @servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2']) + @servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2']) - @task('deploy', ['on' => ['web-1', 'web-2']]) - cd site - git pull origin {{ $branch }} - php artisan migrate - @endtask + @task('deploy', ['on' => ['web-1', 'web-2']]) + cd site + git pull origin {{ $branch }} + php artisan migrate + @endtask By default, the task will be executed on each server serially. Meaning, the task will finish running on the first server before proceeding to execute on the next server. @@ -103,44 +103,44 @@ By default, the task will be executed on each server serially. Meaning, the task If you would like to run a task across multiple servers in parallel, add the `parallel` option to your task declaration: - @servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2']) + @servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2']) - @task('deploy', ['on' => ['web-1', 'web-2'], 'parallel' => true]) - cd site - git pull origin {{ $branch }} - php artisan migrate - @endtask + @task('deploy', ['on' => ['web-1', 'web-2'], 'parallel' => true]) + cd site + git pull origin {{ $branch }} + php artisan migrate + @endtask ### Task Macros Macros allow you to define a set of tasks to be run in sequence using a single command. For instance, a `deploy` macro may run the `git` and `composer` tasks: - @servers(['web' => '192.168.1.1']) + @servers(['web' => '192.168.1.1']) - @macro('deploy') - git - composer - @endmacro + @macro('deploy') + git + composer + @endmacro - @task('git') - git pull origin master - @endtask + @task('git') + git pull origin master + @endtask - @task('composer') - composer install - @endtask + @task('composer') + composer install + @endtask Once the macro has been defined, you may run it via single, simple command: - envoy run deploy + envoy run deploy ## Running Tasks To run a task from your `Envoy.blade.php` file, execute Envoy's `run` command, passing the command the name of the task or macro you would like to execute. Envoy will run the task and display the output from the servers as the task is running: - envoy run task + envoy run task @@ -151,34 +151,34 @@ To run a task from your `Envoy.blade.php` file, execute Envoy's `run` command, p After running a task, you may send a notification to your team's HipChat room using Envoy's `@hipchat` directive. The directive accepts an API token, the name of the room, and the username to be displayed as the sender of the message: - @servers(['web' => '192.168.1.1']) + @servers(['web' => '192.168.1.1']) - @task('foo', ['on' => 'web']) - ls -la - @endtask + @task('foo', ['on' => 'web']) + ls -la + @endtask - @after - @hipchat('token', 'room', 'Envoy') - @endafter + @after + @hipchat('token', 'room', 'Envoy') + @endafter If you wish, you may also pas a custom message to send to the HipChat room. Any variables available to your Envoy tasks will also be available when constructing the message: - @after - @hipchat('token', 'room', 'Envoy', "{$task} ran in the {$env} environment.") - @endafter + @after + @hipchat('token', 'room', 'Envoy', "{$task} ran in the {$env} environment.") + @endafter ### Slack In addition to HipChat, Envoy also supports sending notifications to [Slack](https://slack.com). The `@slack` directive accepts a Slack hook URL, a channel name, and the message you wish to send to the channel: - @after - @slack('hook', 'channel', 'message') - @endafter + @after + @slack('hook', 'channel', 'message') + @endafter You may retrieve your webhook URL by creating an `Incoming WebHooks` integration on Slack's website. The `hook` argument should be the entire webhook URL provided by the Incoming Webhooks Slack Integration. For example: - https://hooks.slack.com/services/ZZZZZZZZZ/YYYYYYYYY/XXXXXXXXXXXXXXX + https://hooks.slack.com/services/ZZZZZZZZZ/YYYYYYYYY/XXXXXXXXXXXXXXX You may provide one of the following as the channel argument: diff --git a/errors.md b/errors.md index 99f32f5af3..ee79934c79 100644 --- a/errors.md +++ b/errors.md @@ -3,10 +3,10 @@ - [Introduction](#introduction) - [Configuration](#configuration) - [The Exception Handler](#the-exception-handler) - - [Report Method](#report-method) - - [Render Method](#render-method) + - [Report Method](#report-method) + - [Render Method](#render-method) - [HTTP Exceptions](#http-exceptions) - - [Custom HTTP Error Pages](#custom-http-error-pages) + - [Custom HTTP Error Pages](#custom-http-error-pages) - [Logging](#logging) @@ -27,17 +27,17 @@ For local development, you should set the `APP_DEBUG` environment variable to `t Out of the box, Laravel supports `single`, `daily`, `syslog` and `errorlog` logging modes. For example, if you wish to use daily log files instead of a single file, you should simply set the `log` value in your `config/app.php` configuration file: - 'log' => 'daily' + 'log' => 'daily' #### Custom Monolog Configuration If you would like to have complete control over how Monolog is configured for your application, you may use the application's `configureMonologUsing` method. You should place a call to this method in your `bootstrap/app.php` file right before the `$app` variable is returned by the file: - $app->configureMonologUsing(function($monolog) { - $monolog->pushHandler(...); - }); + $app->configureMonologUsing(function($monolog) { + $monolog->pushHandler(...); + }); - return $app; + return $app; ## The Exception Handler @@ -51,22 +51,22 @@ The `report` method is used to log exceptions or send them to an external servic For example, if you need to report different types of exceptions in different ways, you may use the PHP `instanceof` comparison operator: - /** - * Report or log an exception. - * - * This is a great spot to send exceptions to Sentry, Bugsnag, etc. - * - * @param \Exception $e - * @return void - */ - public function report(Exception $e) - { - if ($e instanceof CustomException) { - // - } - - return parent::report($e); - } + /** + * Report or log an exception. + * + * This is a great spot to send exceptions to Sentry, Bugsnag, etc. + * + * @param \Exception $e + * @return void + */ + public function report(Exception $e) + { + if ($e instanceof CustomException) { + // + } + + return parent::report($e); + } #### Ignoring Exceptions By Type @@ -86,9 +86,9 @@ The `render` method is responsible for converting a given exception into an HTTP */ public function render($request, Exception $e) { - if ($e instanceof CustomException) { - return response()->view('errors.custom', [], 500); - } + if ($e instanceof CustomException) { + return response()->view('errors.custom', [], 500); + } return parent::render($request, $e); } @@ -98,11 +98,11 @@ The `render` method is responsible for converting a given exception into an HTTP Some exceptions describe HTTP error codes from the server. For example, this may be a "page not found" error (404), an "unauthorized error" (401) or even a developer generated 500 error. In order to generate such a response from anywhere in your application, use the following: - abort(404); + abort(404); The `abort` method will immediately raise an exception which will be rendered by the exception handler. Optionally, you may provide the response text: - abort(403, 'Unauthorized action.'); + abort(403, 'Unauthorized action.'); This method may be used at any time during the request's lifecycle. @@ -118,48 +118,48 @@ The views within this directory should be named to match the HTTP status code th The Laravel logging facilities provide a simple layer on top of the powerful [Monolog](http://github.com/seldaek/monolog) library. By default, Laravel is configured to create daily log files for your application which are stored in the `storage/logs` directory. You may write information to the logs using the `Log` [facade](/docs/{{version}}/facades): - User::findOrFail($id)]); - } - } + class UserController extends Controller + { + /** + * Show the profile for the given user. + * + * @param int $id + * @return Response + */ + public function showProfile($id) + { + Log::info('Showing user profile for user: '.$id); + + return view('user.profile', ['user' => User::findOrFail($id)]); + } + } The logger provides the seven logging levels defined in [RFC 5424](http://tools.ietf.org/html/rfc5424): **debug**, **info**, **notice**, **warning**, **error**, **critical**, and **alert**. - Log::debug($error); - Log::info($error); - Log::notice($error); - Log::warning($error); - Log::error($error); - Log::critical($error); - Log::alert($error); + Log::debug($error); + Log::info($error); + Log::notice($error); + Log::warning($error); + Log::error($error); + Log::critical($error); + Log::alert($error); #### Contextual Information An array of contextual data may also be passed to the log methods. This contextual data will be formatted and displayed with the log message: - Log::info('User failed to login.', ['id' => $user->id]); + Log::info('User failed to login.', ['id' => $user->id]); #### Accessing The Underlying Monolog Instance Monolog has a variety of additional handlers you may use for logging. If needed, you may access the underlying Monolog instance being used by Laravel: - $monolog = Log::getMonolog(); + $monolog = Log::getMonolog(); diff --git a/events.md b/events.md index 60ce6587f1..9f9079cc18 100644 --- a/events.md +++ b/events.md @@ -4,13 +4,13 @@ - [Registering Events / Listeners](#registering-events-and-listeners) - [Defining Events](#defining-events) - [Defining Listeners](#defining-listeners) - - [Queued Event Listeners](#queued-event-listeners) + - [Queued Event Listeners](#queued-event-listeners) - [Firing Events](#firing-events) - [Broadcasting Events](#broadcasting-events) - - [Configuration](#broadcast-configuration) - - [Marking Events For Broadcast](#marking-events-for-broadcast) - - [Broadcast Data](#broadcast-data) - - [Consuming Event Broadcasts](#consuming-event-broadcasts) + - [Configuration](#broadcast-configuration) + - [Marking Events For Broadcast](#marking-events-for-broadcast) + - [Broadcast Data](#broadcast-data) + - [Consuming Event Broadcasts](#consuming-event-broadcasts) - [Event Subscribers](#event-subscribers) @@ -23,53 +23,53 @@ Laravel's events provides a simple observer implementation, allowing you to subs The `EventServiceProvider` included with your Laravel application provides a convenient place to register all event listeners. The `listen` property contains an array of all events (keys) and their listeners (values). Of course, you may add as many events to this array as your application requires. For example, let's add our `PodcastWasPurchased` event: - /** - * The event listener mappings for the application. - * - * @var array - */ - protected $listen = [ - 'App\Events\PodcastWasPurchased' => [ - 'App\Listeners\EmailPurchaseConfirmation', - ], - ]; + /** + * The event listener mappings for the application. + * + * @var array + */ + protected $listen = [ + 'App\Events\PodcastWasPurchased' => [ + 'App\Listeners\EmailPurchaseConfirmation', + ], + ]; ### Generating Event / Listener Classes Of course, manually creating the files for each event and listener is cumbersome. Instead, simply add listeners and events to your `EventServiceProvider` and use the `event:generate` command. This command will generate any events or listeners that are listed in your `EventServiceProvider`. Of course, events and listeners that already exist will be left untouched: - php artisan event:generate + php artisan event:generate ## Defining Events An event class is simply a data container which holds the information related to the event. For example, let's assume our generated `PodcastWasPurchased` event receives a [Eloquent ORM](/docs/{{version}}/eloquent) object: - podcast = $podcast; - } - } + /** + * Create a new event instance. + * + * @param Podcast $podcast + * @return void + */ + public function __construct(Podcast $podcast) + { + $this->podcast = $podcast; + } + } As you can see, this event class contains no special logic. It is simply a container for the `Podcast` object that was purchased. The `SerializesModels` trait used by the event will gracefully serialize any Eloquent models if the event object is serialized using PHP's `serialize` function. @@ -78,46 +78,46 @@ As you can see, this event class contains no special logic. It is simply a conta Next, let's take a look at the listener for our example event. Event listeners receive the event instance in their `handle` method. The `event:generate` command will automatically import the proper event class and type-hint the event on the `handle` method. Within the `handle` method, you may perform any logic necessary to respond to the event. - podcast... - } - } + podcast... + } + } Your event listeners may also type-hint any dependencies they need on their constructors. All event listeners are resolved via the Laravel [service container](/docs/{{version}}/container), so dependencies will be injected automatically: - use Illuminate\Contracts\Mail\Mailer; + use Illuminate\Contracts\Mail\Mailer; - public function __construct(Mailer $mailer) - { - $this->mailer = $mailer; - } + public function __construct(Mailer $mailer) + { + $this->mailer = $mailer; + } #### Stopping The Propagation Of An Event @@ -128,18 +128,18 @@ Sometimes, you may wish to stop the propagation of an event to other listeners. Need to [queue](/docs/{{version}}/queues) an event listener? It couldn't be any easier. Simply add the `ShouldQueue` interface to the listener class. Listeners generated by the `event:generate` Artisan command already have this interface imported into the current namespace, so you can use it immediately: - release(30); - } - } - } + class EmailPurchaseConfirmation implements ShouldQueue + { + use InteractsWithQueue; + + public function handle(PodcastWasPurchased $event) + { + if (true) { + $this->release(30); + } + } + } ## Firing Events To fire an event, you may use the `Event` [facade](/docs/{{version}}/facades), passing an instance of the event to the `fire` method. The `fire` method will dispatch the event to all of its registered listeners: - ## Broadcasting Events @@ -232,41 +232,41 @@ Before broadcasting events, you will also need to configure and run a [queue lis To inform Laravel that a given event should be broadcast, implement the `Illuminate\Contracts\Broadcasting\ShouldBroadcast` interface on the event class. The `ShouldBroadcast` interface requires you to implement a single method: `broadcastOn`. The `broadcastOn` method should return an array of "channel" names that the event should be broadcast on: - user = $user; - } - - /** - * Get the channels the event should be broadcast on. - * - * @return array - */ - public function broadcastOn() - { - return ['user.'.$this->user->id]; - } - } + user = $user; + } + + /** + * Get the channels the event should be broadcast on. + * + * @return array + */ + public function broadcastOn() + { + return ['user.'.$this->user->id]; + } + } Then, you only need to [fire the event](#firing-events) as you normally would. Once the event has been fired, a [queued job](/docs/{{version}}/queues) will automatically broadcast the event over your specified broadcast driver. @@ -275,13 +275,13 @@ Then, you only need to [fire the event](#firing-events) as you normally would. O When an event is broadcast, all of its `public` properties are automatically serialized and broadcast as the event's payload, allowing you to access any of its public data from your JavaScript application. So, for example, if your event has a single public `$user` property that contains an Eloquent model, the broadcast payload would be: - { - "user": { - "id": 1, - "name": "Jonathan Banks" - ... - } - } + { + "user": { + "id": 1, + "name": "Jonathan Banks" + ... + } + } However, if you wish to have even more fine-grained control over your broadcast payload, you may add a `broadcastWith` method to your event. This method should return the array of data that you wish to broadcast with the event: @@ -302,13 +302,13 @@ However, if you wish to have even more fine-grained control over your broadcast You may conveniently consume events broadcast using the [Pusher](https://pusher.com) driver using Pusher's JavaScript SDK. For example, let's consume the `App\Events\ServerCreated` event from our previous examples: - this.pusher = new Pusher('pusher-key'); + this.pusher = new Pusher('pusher-key'); - this.pusherChannel = this.pusher.subscribe('user.' + USER_ID); + this.pusherChannel = this.pusher.subscribe('user.' + USER_ID); - this.pusherChannel.bind('App\\Events\\ServerCreated', function(message) { - console.log(message.user); - }); + this.pusherChannel.bind('App\\Events\\ServerCreated', function(message) { + console.log(message.user); + }); #### Redis @@ -316,75 +316,75 @@ If you are using the Redis broadcaster, you will need to write your own Redis pu Using the `socket.io` and `ioredis` Node libraries, you can quickly write an event broadcaster to publish all events that are broadcast by your Laravel application: - var app = require('http').createServer(handler); - var io = require('socket.io')(app); + var app = require('http').createServer(handler); + var io = require('socket.io')(app); - var Redis = require('ioredis'); - var redis = new Redis(); + var Redis = require('ioredis'); + var redis = new Redis(); - app.listen(6001, function() { - console.log('Server is running!'); - }); + app.listen(6001, function() { + console.log('Server is running!'); + }); - function handler(req, res) { - res.writeHead(200); - res.end(''); - } + function handler(req, res) { + res.writeHead(200); + res.end(''); + } - io.on('connection', function(socket) { - // - }); + io.on('connection', function(socket) { + // + }); - redis.psubscribe('*', function(err, count) { - // - }); + redis.psubscribe('*', function(err, count) { + // + }); - redis.on('pmessage', function(subscribed, channel, message) { - message = JSON.parse(message); - io.emit(channel + ':' + message.event, message.data); - }); + redis.on('pmessage', function(subscribed, channel, message) { + message = JSON.parse(message); + io.emit(channel + ':' + message.event, message.data); + }); ## Event Subscribers Event subscribers are classes that may subscribe to multiple events from within the class itself, allowing you to define several event handlers within a single class. Subscribers should define a `subscribe` method, which will be passed an event dispatcher instance: - listen( - 'App\Events\UserLoggedIn', - 'App\Listeners\UserEventListener@onUserLogin' - ); - - $events->listen( - 'App\Events\UserLoggedOut', - 'App\Listeners\UserEventListener@onUserLogout' - ); - } - - } + listen( + 'App\Events\UserLoggedIn', + 'App\Listeners\UserEventListener@onUserLogin' + ); + + $events->listen( + 'App\Events\UserLoggedOut', + 'App\Listeners\UserEventListener@onUserLogout' + ); + } + + } #### Registering An Event Subscriber diff --git a/facades.md b/facades.md index 146aa716b6..7e3f671913 100644 --- a/facades.md +++ b/facades.md @@ -18,42 +18,42 @@ A facade class only needs to implement a single method: `getFacadeAccessor`. It' In the example below, a call is made to the Laravel cache system. By glancing at this code, one might assume that the static method `get` is being called on the `Cache` class: - $user]); - } - } + return view('profile', ['user' => $user]); + } + } Notice that near the top of the file we are "importing" the `Cache` facade. This facade serves as a proxy to accessing the underlying implementation of the `Illuminate\Contracts\Cache\Factory` interface. Any calls we make using the facade will be passed to the underlying instance of Laravel's cache service. If we look at that `Illuminate\Support\Facades\Cache` class, you'll see that there is no static method `get`: - class Cache extends Facade - { - /** - * Get the registered name of the component. - * - * @return string - */ - protected static function getFacadeAccessor() { return 'cache'; } - } + class Cache extends Facade + { + /** + * Get the registered name of the component. + * + * @return string + */ + protected static function getFacadeAccessor() { return 'cache'; } + } Instead, the `Cache` facade extends the base `Facade` class and defines the method `getFacadeAccessor()`. Remember, this method's job is to return the name of a service container binding. When a user references any static method on the `Cache` facade, Laravel resolves the `cache` binding from the [service container](/docs/{{version}}/container) and runs the requested method (in this case, `get`) against that object. diff --git a/filesystem.md b/filesystem.md index db6a514da4..8bea041598 100644 --- a/filesystem.md +++ b/filesystem.md @@ -3,11 +3,11 @@ - [Introduction](#introduction) - [Configuration](#configuration) - [Basic Usage](#basic-usage) - - [Obtaining Disk Instances](#obtaining-disk-instances) - - [Retrieving Files](#retrieving-files) - - [Storing Files](#storing-files) - - [Deleting Files](#deleting-files) - - [Directories](#directories) + - [Obtaining Disk Instances](#obtaining-disk-instances) + - [Retrieving Files](#retrieving-files) + - [Storing Files](#storing-files) + - [Deleting Files](#deleting-files) + - [Directories](#directories) - [Custom Filesystems](#custom-filesystems) @@ -26,7 +26,7 @@ Of course, you may configure as many disks as you like, and may even have multip When using the `local` driver, note that all file operations are relative to the `root` directory defined in your configuration file. By default, this value is set to the `storage/app` directory. Therefore, the following method would store a file in `storage/app/file.txt`: - Storage::disk('local')->put('file.txt', 'Contents'); + Storage::disk('local')->put('file.txt', 'Contents'); #### Other Driver Prerequisites @@ -43,94 +43,94 @@ Before using the S3 or Rackspace drivers, you will need to install the appropria The `Storage` facade may be used to interact with any of your configured disks. For example, you may use the `put` method on the facade to store an avatar on the default disk. If you call methods on the `Storage` facade without first calling the `disk` method, the method call will automatically be passed to the default disk: - id, - file_get_contents($request->file('avatar')->getRealPath()) - ); - } - } + id, + file_get_contents($request->file('avatar')->getRealPath()) + ); + } + } When using multiple disks, you may access a particular disk using the `disk` method on the `Storage` facade. Of course, you may continue to chain methods to execute methods on the disk: - $disk = Storage::disk('s3'); + $disk = Storage::disk('s3'); - $contents = Storage::disk('local')->get('file.jpg') + $contents = Storage::disk('local')->get('file.jpg') ### Retrieving Files The `get` method may be used to retrieve the contents of a given file. The raw string contents of the file will be returned by the method: - $contents = Storage::get('file.jpg'); + $contents = Storage::get('file.jpg'); The `exists` method may be used to determine if a given file exists on the disk: - $exists = Storage::disk('s3')->exists('file.jpg'); + $exists = Storage::disk('s3')->exists('file.jpg'); #### File Meta Information The `size` method may be used to get the size of the file in bytes: - $size = Storage::size('file1.jpg'); + $size = Storage::size('file1.jpg'); The `lastModified` method returns the UNIX timestamp of the last time the file was modified: - $time = Storage::lastModified('file1.jpg'); + $time = Storage::lastModified('file1.jpg'); ### Storing Files The `put` method may be used to store a file on disk. You may also pass a PHP `resource` to the `put` method, which will use Flysystem's underlying stream support. Using streams is greatly recommended when dealing with large files: - Storage::put('file.jpg', $contents); + Storage::put('file.jpg', $contents); - Storage::put('file.jpg', $resource); + Storage::put('file.jpg', $resource); The `copy` method may be used to move an existing file to a new location on the disk: - Storage::copy('old/file1.jpg', 'new/file1.jpg'); + Storage::copy('old/file1.jpg', 'new/file1.jpg'); The `move` method may be used to move an existing file to a new location: - Storage::move('old/file1.jpg', 'new/file1.jpg'); + Storage::move('old/file1.jpg', 'new/file1.jpg'); #### Prepending / Appending To Files The `prepend` and `append` methods allow you to easily insert content at the beginning or end of a file: - Storage::prepend('file.log', 'Prepended Text'); + Storage::prepend('file.log', 'Prepended Text'); - Storage::append('file.log', 'Appended Text'); + Storage::append('file.log', 'Appended Text'); ### Deleting Files The `delete` method accepts a single filename or an array of files to remove from the disk: - Storage::delete('file.jpg'); + Storage::delete('file.jpg'); - Storage::delete(['file1.jpg', 'file2.jpg']); + Storage::delete(['file1.jpg', 'file2.jpg']); ### Directories @@ -139,30 +139,30 @@ The `delete` method accepts a single filename or an array of files to remove fro The `files` method returns an array of all of the files in a given directory. If you would like to retrieve a list of all files within a given directory including all sub-directories, you may use the `allFiles` method: - $files = Storage::files($directory); + $files = Storage::files($directory); - $files = Storage::allFiles($directory); + $files = Storage::allFiles($directory); #### Get All Directories Within A Directory The `directories` method returns an array of all the directories within a given directory. Additionally, you may use the `allDirectories` method to get a list of all directories within a given directory and all of its sub-directories: - $directories = Storage::directories($directory); + $directories = Storage::directories($directory); - // Recursive... - $directories = Storage::allDirectories($directory); + // Recursive... + $directories = Storage::allDirectories($directory); #### Create A Directory The `makeDirectory` method will create the given directory, including any needed sub-directories: - Storage::makeDirectory($directory); + Storage::makeDirectory($directory); #### Delete A Directory Finally, the `deleteDirectory` may be used to remove a directory, including all of its files, from the disk: - Storage::deleteDirectory($directory); + Storage::deleteDirectory($directory); ## Custom Filesystems @@ -171,44 +171,44 @@ Laravel's Flysystem integration provides drivers for several "drivers" out of th 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: - fill([ - 'password' => Hash::make($request->newPassword) - ])->save(); - } - } + fill([ + 'password' => Hash::make($request->newPassword) + ])->save(); + } + } Alternatively, you may also use the global `bcrypt` helper function: - bcrypt('plain-text'); + bcrypt('plain-text'); #### Verifying A Password Against A Hash The `check` method allows you to verify that a given plain-text string corresponds to a given hash. However, if you are using the `AuthController` [included with Laravel](/docs/{{version}}/authentication), you will probably not need to use this directly, as the included authentication controller automatically calls this method: - if (Hash::check('plain-text', $hashedPassword)) { - // The passwords match... - } + if (Hash::check('plain-text', $hashedPassword)) { + // The passwords match... + } #### Checking If A Password Needs To Be Rehashed The `needsRehash` function allows you to determine if the work factor used by the hasher has changed since the password was hashed: - if (Hash::needsRehash($hashed)) { - $hashed = Hash::make('plain-text'); - } + if (Hash::needsRehash($hashed)) { + $hashed = Hash::make('plain-text'); + } diff --git a/helpers.md b/helpers.md index 9381deaef3..1549fb7b6f 100644 --- a/helpers.md +++ b/helpers.md @@ -12,14 +12,14 @@ Laravel includes a variety of "helper" PHP functions. Many of these functions ar ## Available Methods ### Arrays @@ -111,13 +111,13 @@ Laravel includes a variety of "helper" PHP functions. Many of these functions ar ## Method Listing @@ -128,234 +128,234 @@ Laravel includes a variety of "helper" PHP functions. Many of these functions ar The `array_add` function adds a given key / value pair to the array if the given key doesn't already exist in the array: - $array = array_add(['name' => 'Desk'], 'price', 100); + $array = array_add(['name' => 'Desk'], 'price', 100); - // ['name' => 'Desk', 'price' => 100] + // ['name' => 'Desk', 'price' => 100] #### `array_divide()` {#collection-method} The `array_divide` function returns two arrays, one containing the keys, and the other containing the values of the original array: - list($keys, $values) = array_divide(['name' => 'Desk']); + list($keys, $values) = array_divide(['name' => 'Desk']); - // $keys: ['name'] + // $keys: ['name'] - // $values: ['Desk'] + // $values: ['Desk'] #### `array_dot()` {#collection-method} The `array_dot` function flattens a multi-dimensional array into a single level array that uses "dot" notation to indicate depth: - $array = array_dot(['foo' => ['bar' => 'baz']]); + $array = array_dot(['foo' => ['bar' => 'baz']]); - // ['foo.bar' => 'baz']; + // ['foo.bar' => 'baz']; #### `array_except()` {#collection-method} The `array_except` method removes the given key / value pairs from the array: - $array = ['name' => 'Desk', 'price' => 100]; + $array = ['name' => 'Desk', 'price' => 100]; - $array = array_except($array, ['price']); + $array = array_except($array, ['price']); - // ['name' => 'Desk'] + // ['name' => 'Desk'] #### `array_first()` {#collection-method} The `array_first` method returns the first element of an array passing a given truth test: - $array = [100, 200, 300]; + $array = [100, 200, 300]; - $value = array_first($array, function ($key, $value) { - return $value >= 150; - }); + $value = array_first($array, function ($key, $value) { + return $value >= 150; + }); - // 200 + // 200 A default value may also be passed as the third parameter to the method. This value will be returned if no value passes the truth test: - $value = array_first($array, $callback, $default); + $value = array_first($array, $callback, $default); #### `array_flatten()` {#collection-method} The `array_flatten` method will flatten a multi-dimensional array into a single level. - $array = ['name' => 'Joe', 'languages' => ['PHP', 'Ruby']]; + $array = ['name' => 'Joe', 'languages' => ['PHP', 'Ruby']]; - $array = array_flatten($array); + $array = array_flatten($array); - // ['Joe', 'PHP', 'Ruby']; + // ['Joe', 'PHP', 'Ruby']; #### `array_forget()` {#collection-method} The `array_forget` method removes a given key / value pair from a deeply nested array using "dot" notation: - $array = ['products' => ['desk' => ['price' => 100]]]; + $array = ['products' => ['desk' => ['price' => 100]]]; - array_forget($array, 'products.desk'); + array_forget($array, 'products.desk'); - // ['products' => []] + // ['products' => []] #### `array_get()` {#collection-method} The `array_get` method retrieves a value from a deeply nested array using "dot" notation: - $array = ['products' => ['desk' => ['price' => 100]]]; + $array = ['products' => ['desk' => ['price' => 100]]]; - $value = array_get($array, 'products.desk'); + $value = array_get($array, 'products.desk'); - // ['price' => 100] + // ['price' => 100] The `array_get` function also accepts a default value, which will be returned if the specific key is not found: - $value = array_get($array, 'names.john', 'default'); + $value = array_get($array, 'names.john', 'default'); #### `array_only()` {#collection-method} The `array_only` method will return only the specified key / value pairs from the given array: - $array = ['name' => 'Desk', 'price' => 100, 'orders' => 10]; + $array = ['name' => 'Desk', 'price' => 100, 'orders' => 10]; - $array = array_only($array, ['name', 'price']); + $array = array_only($array, ['name', 'price']); - // ['name' => 'Desk', 'price' => 100] + // ['name' => 'Desk', 'price' => 100] #### `array_pluck()` {#collection-method} The `array_pluck` method will pluck a list of the given key / value pairs from the array: - $array = [ - ['developer' => ['name' => 'Taylor']], - ['developer' => ['name' => 'Abigail']] - ]; + $array = [ + ['developer' => ['name' => 'Taylor']], + ['developer' => ['name' => 'Abigail']] + ]; - $array = array_pluck($array, 'developer.name'); + $array = array_pluck($array, 'developer.name'); - // ['Taylor', 'Abigail']; + // ['Taylor', 'Abigail']; #### `array_pull()` {#collection-method} The `array_pull` method returns and removes a key / value pair from the array: - $array = ['name' => 'Desk', 'price' => 100]; + $array = ['name' => 'Desk', 'price' => 100]; - $name = array_pull($array, 'name'); + $name = array_pull($array, 'name'); - // $name: Desk + // $name: Desk - // $array: ['price' => 100] + // $array: ['price' => 100] #### `array_set()` {#collection-method} The `array_set` method sets a value within a deeply nested array using "dot" notation: - $array = ['products' => ['desk' => ['price' => 100]]]; + $array = ['products' => ['desk' => ['price' => 100]]]; - array_set($array, 'products.desk.price', 200); + array_set($array, 'products.desk.price', 200); - // ['products' => ['desk' => ['price' => 200]]] + // ['products' => ['desk' => ['price' => 200]]] #### `array_sort()` {#collection-method} The `array_sort` method sorts the array by the results of the given Closure: - $array = [ - ['name' => 'Desk'], - ['name' => 'Chair'], - ]; + $array = [ + ['name' => 'Desk'], + ['name' => 'Chair'], + ]; - $array = array_values(array_sort($array, function ($value) { - return $value['name']; - })); + $array = array_values(array_sort($array, function ($value) { + return $value['name']; + })); - /* - [ - ['name' => 'Chair'], - ['name' => 'Desk'], - ] - */ + /* + [ + ['name' => 'Chair'], + ['name' => 'Desk'], + ] + */ #### `array_sort_recursive()` {#collection-method} The `array_sort_recursive` function recursively sorts the array using the `sort` function: - $array = [ - [ - 'Roman', - 'Taylor', - 'Li', - ], - [ - 'PHP', - 'Ruby', - 'JavaScript', - ], - ]; - - $array = array_sort_recursive($array); - - /* - [ - [ - 'Li', - 'Roman', - 'Taylor', - ], - [ - 'JavaScript', - 'PHP', - 'Ruby', - ] - ]; - */ + $array = [ + [ + 'Roman', + 'Taylor', + 'Li', + ], + [ + 'PHP', + 'Ruby', + 'JavaScript', + ], + ]; + + $array = array_sort_recursive($array); + + /* + [ + [ + 'Li', + 'Roman', + 'Taylor', + ], + [ + 'JavaScript', + 'PHP', + 'Ruby', + ] + ]; + */ #### `array_where()` {#collection-method} The `array_where` function filters the array using the given Closure: - $array = [100, '200', 300, '400', 500]; + $array = [100, '200', 300, '400', 500]; - $array = array_where($array, function ($key, $value) { - return is_string($value); - }); + $array = array_where($array, function ($key, $value) { + return is_string($value); + }); - // [1 => 200, 3 => 400] + // [1 => 200, 3 => 400] #### `head()` {#collection-method} The `head` function simply returns the first element in the given array: - $array = [100, 200, 300]; + $array = [100, 200, 300]; - $first = head($array); + $first = head($array); - // 100 + // 100 #### `last()` {#collection-method} The `last` function returns the last element in the given array: - $array = [100, 200, 300]; + $array = [100, 200, 300]; - $last = last($array); + $last = last($array); - // 300 + // 300 ## Paths @@ -365,54 +365,54 @@ The `last` function returns the last element in the given array: The `app_path` function returns the fully qualified path to the `app` directory: - $path = app_path(); + $path = app_path(); You may also use the `app_path` function to generate a fully qualified path to a given file relative to the application directory: - $path = app_path('Http/Controllers/Controller.php'); + $path = app_path('Http/Controllers/Controller.php'); #### `base_path()` {#collection-method} The `base_path` function returns the fully qualified path to the project root: - $path = base_path(); + $path = base_path(); You may also use the `base_path` function to generate a fully qualified path to a given file relative to the application directory: - $path = base_path('vendor/bin'); + $path = base_path('vendor/bin'); #### `config_path()` {#collection-method} The `config_path` function returns the fully qualified path to the application configuration directory: - $path = config_path(); + $path = config_path(); #### `database_path()` {#collection-method} The `database_path` function returns the fully qualified path to the application's database directory: - $path = database_path(); + $path = database_path(); #### `public_path()` {#collection-method} The `public_path` function returns the fully qualified path to the `public` directory: - $path = public_path(); + $path = public_path(); #### `storage_path()` {#collection-method} The `storage_path` function returns the fully qualified path to the `storage` directory: - $path = storage_path(); + $path = storage_path(); You may also use the `storage_path` function to generate a fully qualified path to a given file relative to the storage directory: - $path = storage_path('app/file.txt'); + $path = storage_path('app/file.txt'); ## Strings @@ -422,153 +422,153 @@ You may also use the `storage_path` function to generate a fully qualified path The `camel_case` function converts the given string to `camelCase`: - $camel = camel_case('foo_bar'); + $camel = camel_case('foo_bar'); - // fooBar + // fooBar #### `class_basename()` {#collection-method} The `class_basename` returns the class name of the given class with the class' namespace removed: - $class = class_basename('Foo\Bar\Baz'); + $class = class_basename('Foo\Bar\Baz'); - // Baz + // Baz #### `e()` {#collection-method} The `e` function runs `htmlentities` over the given string: - echo e('foo'); + echo e('foo'); #### `ends_with()` {#collection-method} The `ends_with` function determines if the given string ends with the given value: - $value = ends_with('This is my name', 'name'); + $value = ends_with('This is my name', 'name'); - // true + // true #### `snake_case()` {#collection-method} The `snake_case` function converts the given string to `snake_case`: - $snake = snake_case('fooBar'); + $snake = snake_case('fooBar'); - // foo_bar + // foo_bar #### `str_limit()` {#collection-method} The `str_limit` function limits the number of characters in a string. The function accepts a string as its first argument and the maximum number of resulting characters as its second argument: - $value = str_limit('The PHP framework for web artisans.', 7); + $value = str_limit('The PHP framework for web artisans.', 7); - // The PHP... + // The PHP... #### `starts_with()` {#collection-method} The `starts_with` function determines if the given string begins with the given value: - $value = starts_with('This is my name', 'This'); + $value = starts_with('This is my name', 'This'); - // true + // true #### `str_contains()` {#collection-method} The `str_contains` function determines if the given string contains the given value: - $value = str_contains('This is my name', 'my'); + $value = str_contains('This is my name', 'my'); - // true + // true #### `str_finish()` {#collection-method} The `str_finish` function adds a single instance of the given value to a string: - $string = str_finish('this/string', '/'); + $string = str_finish('this/string', '/'); - // this/string/ + // this/string/ #### `str_is()` {#collection-method} The `str_is` function determines if a given string matches a given pattern. Asterisks may be used to indicate wildcards: - $value = str_is('foo*', 'foobar'); + $value = str_is('foo*', 'foobar'); - // true + // true - $value = str_is('baz*', 'foobar'); + $value = str_is('baz*', 'foobar'); - // false + // false #### `str_plural()` {#collection-method} The `str_plural` function converts a string to its plural form. This function currently only supports the English language: - $plural = str_plural('car'); + $plural = str_plural('car'); - // cars + // cars - $plural = str_plural('child'); + $plural = str_plural('child'); - // children + // children #### `str_random()` {#collection-method} The `str_random` function generates a random string of the specified length: - $string = str_random(40); + $string = str_random(40); #### `str_singular()` {#collection-method} The `str_singular` function converts a string to its singular form. This function currently only supports the English language: - $singular = str_singular('cars'); + $singular = str_singular('cars'); - // car + // car #### `str_slug()` {#collection-method} The `str_slug` function generates a URL friendly "slug" from the given string: - $title = str_slug("Laravel 5 Framework", "-"); + $title = str_slug("Laravel 5 Framework", "-"); - // laravel-5-framework + // laravel-5-framework #### `studly_case()` {#collection-method} The `studly_case` function converts the given string to `StudlyCase`: - $value = studly_case('foo_bar'); + $value = studly_case('foo_bar'); - // FooBar + // FooBar #### `trans()` {#collection-method} The `trans` function translates the given language line using your [localization files](/docs/{{version}}/localization): - echo trans('validation.required'): + echo trans('validation.required'): #### `trans_choice()` {#collection-method} The `trans_choice` function translates the given language line with inflection: - $value = trans_choice('foo.bar', $count); + $value = trans_choice('foo.bar', $count); ## URLs @@ -578,31 +578,31 @@ The `trans_choice` function translates the given language line with inflection: The `action` function generates a URL for the given controller action. You do not need to pass the full namespace to the controller. Instead, pass the controller class name relative to the `App\Http\Controllers` namespace: - $url = action('HomeController@getIndex'); + $url = action('HomeController@getIndex'); If the method accepts route parameters, you may pass them as the second argument to the method: - $url = action('UserController@profile', ['id' => 1]); + $url = action('UserController@profile', ['id' => 1]); #### `route()` {#collection-method} The `route` function generates a URL for the given named route: - $url = route('routeName'); + $url = route('routeName'); If the route accepts parameters, you may pass them as the second argument to the method: - $url = route('routeName', ['id' => 1]); + $url = route('routeName', ['id' => 1]); #### `url()` {#collection-method} The `url` function generates a fully qualified URL to the given path: - echo url('user/profile'); + echo url('user/profile'); - echo url('user/profile', [1]); + echo url('user/profile', [1]); ## Miscellaneous @@ -612,123 +612,123 @@ The `url` function generates a fully qualified URL to the given path: The `auth` function return an authenticator instance. You may use it instead of the `Auth` facade for convenience: - $user = auth()->user(); + $user = auth()->user(); #### `back()` {#collection-method} The `back()` function generates a redirect response to the user's previous location: - return back(); + return back(); #### `bcrypt()` {#collection-method} The `bcrypt` function hashes the given value using Bcrypt. You may use it as an alternative to the `Hash` facade: - $password = bcrypt('my-secret-password'); + $password = bcrypt('my-secret-password'); #### `config()` {#collection-method} The `config` function gets the value of a configuration variable. The configuration values may be accessed using "dot" syntax, which includes the name of the file and the option you wish to access. A default value may be specified and is returned if the configuration option does not exist: - $value = config('app.timezone'); + $value = config('app.timezone'); - $value = config('app.timezone', $default); + $value = config('app.timezone', $default); #### `csrf_field()` {#collection-method} The `csrf_field` function generates an HTML `hidden` input field containing the value of the CSRF token. For example, using [Blade syntax](/docs/{{version}}/blade): - {!! csrf_field() !!} + {!! csrf_field() !!} #### `csrf_token()` {#collection-method} The `csrf_token` function retrieves the value of the current CSRF token: - $token = csrf_token(); + $token = csrf_token(); #### `dd()` {#collection-method} The `dd` function dumps the given variable and ends execution of the script: - dd($value); + dd($value); #### `elixir()` {#collection-method} The `elixir` function gets the path to the versioned [Elixir](/docs/{{version}}/elixir) file: - elixir($file); + elixir($file); #### `env()` {#collection-method} The `env` function gets the value of an environment variable or returns a default value: - $env = env('APP_ENV'); + $env = env('APP_ENV'); - // Return a default value if the variable doesn't exist... - $env = env('APP_ENV', 'production'); + // Return a default value if the variable doesn't exist... + $env = env('APP_ENV', 'production'); #### `event()` {#collection-method} The `event` function dispatches the given [event](/docs/{{version}}/events) to its listeners: - event(new UserRegistered($user)); + event(new UserRegistered($user)); #### `factory()` {#collection-method} The `factory` function creates a model factory builder for a given class, name, and amount. It can be used while [testing](/docs/{{version}}/testing#model-factories) or [seeding](/docs/{{version}}/seeding#using-model-factories): - $user = factory('App\User')->make(); + $user = factory('App\User')->make(); #### `old()` {#collection-method} The `old` function [retrieves](/docs/{{version}}/requests#retrieving-input) an old input value flashed into the session.: - $value = old('value'); + $value = old('value'); #### `redirect()` {#collection-method} The `redirect` function return an instance of the redirector to do [redirects](/docs/{{version}}/responses#redirects): - return redirect('/home'); + return redirect('/home'); #### `response()` {#collection-method} The `response` function creates a [response](/docs/{{version}}/responses) instance or obtains an instance of the response factory: - return response('Hello World', 200, $headers); + return response('Hello World', 200, $headers); - return response()->json(['foo' => 'bar'], 200, $headers); + return response()->json(['foo' => 'bar'], 200, $headers); #### `value()` {#collection-method} The `value` function's behavior will simply return the value it is given. However, if you pass a `Closure` to the function, the `Closure` will be executed then its result will be returned: - $value = value(function() { return 'bar'; }); + $value = value(function() { return 'bar'; }); #### `view()` {#collection-method} The `view` function retrieves a [view](/docs/{{version}}/views) instance: - return view('auth.login'); + return view('auth.login'); #### `with()` {#collection-method} The `with` function return the value it is given. This function is primarily useful for method chaining where it would otherwise be impossible: - $value = with(new Foo)->work(); + $value = with(new Foo)->work(); diff --git a/homestead.md b/homestead.md index 4e725684f5..e48792c601 100644 --- a/homestead.md +++ b/homestead.md @@ -2,15 +2,15 @@ - [Introduction](#introduction) - [Installation & Setup](#installation-and-setup) - - [First Steps](#first-steps) - - [Configuring Homestead](#configuring-homestead) - - [Launching The Vagrant Box](#launching-the-vagrant-box) - - [Per Project Installation](#per-project-installation) + - [First Steps](#first-steps) + - [Configuring Homestead](#configuring-homestead) + - [Launching The Vagrant Box](#launching-the-vagrant-box) + - [Per Project Installation](#per-project-installation) - [Daily Usage](#daily-usage) - - [Connecting Via SSH](#connecting-via-ssh) - - [Connecting To Databases](#connecting-to-databases) - - [Adding Additional Sites](#adding-additional-sites) - - [Ports](#ports) + - [Connecting Via SSH](#connecting-via-ssh) + - [Connecting To Databases](#connecting-to-databases) + - [Adding Additional Sites](#adding-additional-sites) + - [Ports](#ports) - [Blackfire Profiler](#blackfire-profiler) @@ -56,21 +56,21 @@ To use the VMware provider, you will need to purchase both VMware Fusion / Deskt Once VirtualBox / VMware and Vagrant have been installed, you should add the `laravel/homestead` box to your Vagrant installation using the following command in your terminal. It will take a few minutes to download the box, depending on your Internet connection speed: - vagrant box add laravel/homestead + vagrant box add laravel/homestead If this command fails, you may have an old version of Vagrant that requires the full URL: - vagrant box add laravel/homestead https://atlas.hashicorp.com/laravel/boxes/homestead + vagrant box add laravel/homestead https://atlas.hashicorp.com/laravel/boxes/homestead #### Cloning The Homestead Repository You may install Homestead by simply cloning the repository. Consider cloning the repository into a `Homestead` folder within your "home" directory, as the Homestead box will serve as the host to all of your Laravel projects: - git clone https://github.com/laravel/homestead.git Homestead + 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 your `~/.homestead` directory: - bash init.sh + bash init.sh ### Configuring Homestead @@ -79,13 +79,13 @@ Once you have cloned the Homestead repository, run the `bash init.sh` command fr The `provider` key in your `Homestead.yaml` file indicates which Vagrant provider should be used: `virtualbox` or `vmware_fusion`. You may set this to whichever provider you prefer: - provider: virtualbox + provider: virtualbox #### Setting Your SSH Key In the `Homestead.yaml` file, you should also configure the path to your public SSH key. Don't have an SSH key? On Mac and Linux, you can generally create an SSH key pair using the following command: - ssh-keygen -t rsa -C "you@homestead" + ssh-keygen -t rsa -C "you@homestead" On Windows, you may install [Git](http://git-scm.com/) and use the "Git Bash" shell included with Git to issue the command above. Alternatively, you may use [PuTTY](http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html) and [PuTTYgen](http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html). @@ -95,31 +95,31 @@ Once you have created a SSH key, specify the public key's path in the `authorize The `folders` property of the `Homestead.yaml` file lists all of the folders you wish to share with your Homestead environment. As files within these folders are changed, they will be kept in sync between your local machine and the Homestead environment. You may configure as many shared folders as necessary: - folders: - - map: ~/Code - to: /home/vagrant/Code + folders: + - map: ~/Code + to: /home/vagrant/Code To enable [NFS](http://docs.vagrantup.com/v2/synced-folders/nfs.html), just add a simple flag to your synced folder configuration: - folders: - - map: ~/Code - to: /home/vagrant/Code - type: "nfs" + folders: + - map: ~/Code + to: /home/vagrant/Code + type: "nfs" #### Configuring Nginx Sites Not familiar with Nginx? No problem. The `sites` property allows you to easily map a "domain" to a folder on your Homestead environment. A sample site configuration is included in the `Homestead.yaml` file. Again, you may add as many sites to your Homestead environment as necessary. Homestead can serve as a convenient, virtualized environment for every Laravel project you are working on: - sites: - - map: homestead.app - to: /home/vagrant/Code/Laravel/public + sites: + - map: homestead.app + to: /home/vagrant/Code/Laravel/public You can make any Homestead site use [HHVM](http://hhvm.com) by setting the `hhvm` option to `true`: - sites: - - map: homestead.app - to: /home/vagrant/Code/Laravel/public - hhvm: true + sites: + - map: homestead.app + to: /home/vagrant/Code/Laravel/public + hhvm: true By default, each site will be accessible by HTTP via port 8000 and HTTPS via port 44300. @@ -127,11 +127,11 @@ By default, each site will be accessible by HTTP via port 8000 and HTTPS via por Don't forget to add the "domains" for your Nginx sites to the `hosts` file on your machine! The `hosts` file will redirect your requests for the local domains into your Homestead environment. On Mac and Linux, this file is located at `/etc/hosts`. On Windows, it is located at `C:\Windows\System32\drivers\etc\hosts`. The lines you add to this file will look like the following: - 192.168.10.10 homestead.app + 192.168.10.10 homestead.app Make sure the IP address listed is the one you set in your `Homestead.yaml` file. Once you have added the domain to your `hosts` file, you can access the site via your web browser! - http://homestead.app + http://homestead.app ### Launching The Vagrant Box @@ -147,11 +147,11 @@ Instead of installing Homestead globally and sharing the same Homestead box acro To install Homestead directly into your project, require it using Composer: - composer require laravel/homestead + composer require laravel/homestead Once Homestead has been installed, use the `make` command to generate the `Vagrantfile` and `Homestead.yaml` file in your project root. The `make` command will automatically configure the `sites` and `folders` directives in the `Homestead.yaml` file: - php vendor/bin/homestead make + php vendor/bin/homestead make Next, run the `vagrant up` command in your terminal and access your project at `http://homestead.app` in your browser. Remember, you will still need to add an `/etc/hosts` file entry for `homestead.app` or the domain of your choice. @@ -165,7 +165,7 @@ You can SSH into your virtual machine by issuing the `vagrant ssh` terminal comm But, since you will probably need to SSH into your Homestead machine frequently, consider creating an "alias" on your host machine to quickly SSH into the Homestead box. Once you create this alias, you can simply use the "vm" command to SSH into your Homestead machine from anywhere on your system: - alias vm="ssh vagrant@127.0.0.1 -p 2222" + alias vm="ssh vagrant@127.0.0.1 -p 2222" ### Connecting To Databases @@ -198,12 +198,12 @@ By default, the following ports are forwarded to your Homestead environment: If you wish, you may forward additional ports to the Vagrant box, as well as specify their protocol: - ports: - - send: 93000 - to: 9300 - - send: 7777 - to: 777 - protocol: udp + ports: + - send: 93000 + to: 9300 + - send: 7777 + to: 777 + protocol: udp ## Blackfire Profiler @@ -212,10 +212,10 @@ If you wish, you may forward additional ports to the Vagrant box, as well as spe All of the proper packages have already been installed on your Homestead box, you simply need to set a Blackfire **Server** ID and token in your `Homestead.yaml` file: - blackfire: - - id: your-server-id - token: your-server-token - client-id: your-client-id - client-token: your-client-token + blackfire: + - id: your-server-id + token: your-server-token + client-id: your-client-id + client-token: your-client-token Once you have configured your Blackfire credentials, re-provision the box using `vagrant provision` from your Homestead directory. Of course, be sure to review the [Blackfire documentation](https://blackfire.io/getting-started) to learn how to install the Blackfire companion extension for your web browser. diff --git a/installation.md b/installation.md index c5af15b9b7..7e22325fb5 100644 --- a/installation.md +++ b/installation.md @@ -2,11 +2,11 @@ - [Installation](#installation) - [Configuration](#configuration) - - [Basic Configuration](#basic-configuration) - - [Environment Configuration](#environment-configuration) - - [Configuration Caching](#configuration-caching) - - [Accessing Configuration Values](#accessing-configuration-values) - - [Naming Your Application](#naming-your-application) + - [Basic Configuration](#basic-configuration) + - [Environment Configuration](#environment-configuration) + - [Configuration Caching](#configuration-caching) + - [Accessing Configuration Values](#accessing-configuration-values) + - [Naming Your Application](#naming-your-application) - [Maintenance Mode](#maintenance-mode) @@ -33,19 +33,19 @@ Laravel utilizes [Composer](http://getcomposer.org) to manage its dependencies. First, download the Laravel installer using Composer: - composer global require "laravel/installer=~1.1" + composer global require "laravel/installer=~1.1" Make sure to place the `~/.composer/vendor/bin` directory in your PATH so the `laravel` executable can be located by your system. Once installed, the simple `laravel new` command will create a fresh Laravel installation in the directory you specify. For instance, `laravel new blog` will create a directory named `blog` containing a fresh Laravel installation with all of Laravel's dependencies already installed. This method of installation is much faster than installing via Composer: - laravel new blog + laravel new blog #### Via Composer Create-Project You may also install Laravel by issuing the Composer `create-project` command in your terminal: - composer create-project laravel/laravel --prefer-dist + composer create-project laravel/laravel --prefer-dist ## Configuration @@ -84,20 +84,20 @@ The framework ships with a `public/.htaccess` file that is used to allow URLs wi If the `.htaccess` file that ships with Laravel does not work with your Apache installation, try this one: - Options +FollowSymLinks - RewriteEngine On + Options +FollowSymLinks + RewriteEngine On - RewriteCond %{REQUEST_FILENAME} !-d - RewriteCond %{REQUEST_FILENAME} !-f - RewriteRule ^ index.php [L] + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^ index.php [L] **Nginx** On Nginx, the following directive in your site configuration will allow "pretty" URLs: - location / { - try_files $uri $uri/ /index.php?$query_string; - } + location / { + try_files $uri $uri/ /index.php?$query_string; + } Of course, when using [Homestead](/docs/{{version}}/homestead), pretty URLs will be configured automatically. @@ -118,21 +118,21 @@ If you are developing with a team, you may wish to continue including a `.env.ex The current application environment is determined via the `APP_ENV` variable from your `.env` file. You may access this value via the `environment` method on the `App` [facade](/docs/{{version}}/facades): - $environment = App::environment(); + $environment = App::environment(); You may also pass arguments to the `environment` method to check if the environment matches a given value. You may even pass multiple values if necessary: - if (App::environment('local')) { - // The environment is local - } + if (App::environment('local')) { + // The environment is local + } - if (App::environment('local', 'staging')) { - // The environment is either local OR staging... - } + if (App::environment('local', 'staging')) { + // The environment is either local OR staging... + } An application instance may also be accessed via the `app` helper method: - $environment = app()->environment(); + $environment = app()->environment(); ### Configuration Caching @@ -146,11 +146,11 @@ You should typically run the `config:cache` command as part of your deployment r You may easily access your configuration values using the global `config` helper function. The configuration values may be accessed using "dot" syntax, which includes the name of the file and option you wish to access. A default value may also be specified and will be returned if the configuration option does not exist: - $value = config('app.timezone'); + $value = config('app.timezone'); To set configuration values at runtime, pass an array to the `config` helper: - config(['app.timezone' => 'America/Chicago']); + config(['app.timezone' => 'America/Chicago']); ### Naming Your Application @@ -159,7 +159,7 @@ After installing Laravel, you may wish to "name" your application. By default, t For example, if your application is named "Horsefly", you could run the following command from the root of your installation: - php artisan app:name Horsefly + php artisan app:name Horsefly Renaming your application is entirely optional, and you are free to keep the `App` namespace if you wish. @@ -170,11 +170,11 @@ When your application is in maintenance mode, a custom view will be displayed fo To enable maintenance mode, simply execute the `down` Artisan command: - php artisan down + php artisan down To disable maintenance mode, use the `up` command: - php artisan up + php artisan up ### Maintenance Mode Response Template diff --git a/localization.md b/localization.md index 1ce8e820fe..4608cfac0f 100644 --- a/localization.md +++ b/localization.md @@ -2,7 +2,7 @@ - [Introduction](#introduction) - [Basic Usage](#basic-usage) - - [Pluralization](#pluralization) + - [Pluralization](#pluralization) - [Overriding Vendor Language Files](#overriding-vendor-language-files) @@ -12,45 +12,45 @@ Laravel's localization features provide a convenient way to retrieve strings in Language strings are stored in files within the `resources/lang` directory. Within this directory there should be a subdirectory for each language supported by the application: - /resources - /lang - /en - messages.php - /es - messages.php + /resources + /lang + /en + messages.php + /es + messages.php All language files simply return an array of keyed strings. For example: - 'Welcome to our application' - ]; + return [ + 'welcome' => 'Welcome to our application' + ]; #### Configuring The Locale The default language for your application is stored in the `config/app.php` configuration file. Of course, you may modify this value to suit the needs of your application. You may also change the active language at runtime using the `setLocale` method on the `App` facade: - Route::get('welcome/{locale}', function ($locale) { - App::setLocale($locale); + Route::get('welcome/{locale}', function ($locale) { + App::setLocale($locale); - // - }); + // + }); You may also configure a "fallback language", which will be used when the active language does not contain a given language line. Like the default language, the fallback language is also configured in the `config/app.php` configuration file: - 'fallback_locale' => 'en', + 'fallback_locale' => 'en', ## Basic Usage You may retrieve lines from language files using the `trans` helper function. The `trans` method accepts the file and key of the language line as its first argument. For example, let's retrieve the language line `welcome` in the `resources/lang/messages.php` language file: - echo trans('messages.welcome'); + echo trans('messages.welcome'); Of course if you are using the [Blade templating engine](/docs/{{version}}/blade), you may use the `{{ }}` syntax to echo the language line: - {{ trans('messages.welcome') }} + {{ trans('messages.welcome') }} If the specified language line does not exist, the `trans` function will simply return the language line key. So, using the example above, the `trans` function would return `messages.welcome` if the language line does not exist. @@ -58,26 +58,26 @@ If the specified language line does not exist, the `trans` function will simply If you wish, you may define place-holders in your language lines. All place-holders are prefixed with a `:`. For example, you may define a welcome message with a place-holder name: - 'welcome' => 'Welcome, :name', + 'welcome' => 'Welcome, :name', To replace the place-holders when retrieving a language line, pass an array of replacements as the second argument to the `trans` function: - echo trans('messages.welcome', ['name' => 'Dayle']); + echo trans('messages.welcome', ['name' => 'Dayle']); ### Pluralization Pluralization is a complex problem, as different languages have a variety of complex rules for pluralization. By using a "pipe" character, you may distinguish a singular and plural form of a string: - 'apples' => 'There is one apple|There are many apples', + 'apples' => 'There is one apple|There are many apples', Then, you may then use the `trans_choice` function to retrieve the line for a given "count". In this example, since the count is greater than one, the plural form of the language line is returned: - echo trans_choice('messages.apples', 10); + echo trans_choice('messages.apples', 10); Since the Laravel translator is powered by the Symfony Translation component, you may create even more complex pluralization rules: - 'apples' => '{0} There are none|[1,19] There are some|[20,Inf] There are many', + 'apples' => '{0} There are none|[1,19] There are some|[20,Inf] There are many', ## Overriding Vendor Language Files diff --git a/mail.md b/mail.md index d888cd827e..a092c0d566 100644 --- a/mail.md +++ b/mail.md @@ -2,9 +2,9 @@ - [Introduction](#introduction) - [Sending Mail](#sending-mail) - - [Attachments](#attachments) - - [Inline Attachments](#inline-attachments) - - [Queueing Mail](#queueing-mail) + - [Attachments](#attachments) + - [Inline Attachments](#inline-attachments) + - [Queueing Mail](#queueing-mail) - [Mail & Local Development](#mail-and-local-development) @@ -16,38 +16,38 @@ Laravel provides a clean, simple API over the popular [SwiftMailer](http://swift The API based drivers such as Mailgun and Mandrill are often simpler and faster than SMTP servers. All of the API drivers require that the Guzzle HTTP library be installed for your application. You may install Guzzle to your project by adding the following line to your `composer.json` file: - "guzzlehttp/guzzle": "~5.3|~6.0" + "guzzlehttp/guzzle": "~5.3|~6.0" #### Mailgun Driver To use the Mailgun driver, first install Guzzle, then set the `driver` option in your `config/mail.php` configuration file to `mailgun`. Next, verify that your `config/services.php` configuration file contains the following options: - 'mailgun' => [ - 'domain' => 'your-mailgun-domain', - 'secret' => 'your-mailgun-key', - ], + 'mailgun' => [ + 'domain' => 'your-mailgun-domain', + 'secret' => 'your-mailgun-key', + ], #### Mandrill Driver To use the Mandrill driver, first install Guzzle, then set the `driver` option in your `config/mail.php` configuration file to `mandrill`. Next, verify that your `config/services.php` configuration file contains the following options: - 'mandrill' => [ - 'secret' => 'your-mandrill-key', - ], + 'mandrill' => [ + 'secret' => 'your-mandrill-key', + ], #### SES Driver To use the Amazon SES driver, install the Amazon AWS SDK for PHP. You may install this library by adding the following line to your `composer.json` file's `require` section: - "aws/aws-sdk-php": "~3.0" + "aws/aws-sdk-php": "~3.0" Next, set the `driver` option in your `config/mail.php` configuration file to `ses`. Then, verify that your `config/services.php` configuration file contains the following options: - 'ses' => [ - 'key' => 'your-ses-key', - 'secret' => 'your-ses-secret', - 'region' => 'ses-region', // e.g. us-east-1 - ], + 'ses' => [ + 'key' => 'your-ses-key', + 'secret' => 'your-ses-secret', + 'region' => 'ses-region', // e.g. us-east-1 + ], ## Sending Mail @@ -56,37 +56,37 @@ Laravel allows you to store your e-mail messages in [views](/docs/{{version}}/vi To send a message, use the `send` method on the `Mail` [facade](/docs/{{version}}/facades). The `send` method accepts three arguments. First, the name of a [view](/docs/{{version}}/views) that contains the e-mail message. Secondly, an array of data you wish to pass to the view. Lastly, a `Closure` callback which receives a message instance, allowing you to customize the recipients, subject, and other aspects of the mail message: - $user], function ($m) use ($user) { - $m->to($user->email, $user->name)->subject('Your Reminder!'); - }); - } - } + $user], function ($m) use ($user) { + $m->to($user->email, $user->name)->subject('Your Reminder!'); + }); + } + } Since we are passing an array containing the `user` key in the example above, we could display the user's name within our e-mail view using the following PHP code: - name; ?> + name; ?> > **Note:** A `$message` variable is always passed to e-mail views, and allows the [inline embedding of attachments](#attachments). So, you should avoid passing a `message` variable in your view payload. @@ -94,29 +94,29 @@ Since we are passing an array containing the `user` key in the example above, we As previously discussed, the third argument given to the `send` method is a `Closure` allowing you to specify various options on the e-mail message itself. Using this Closure you may specify other attributes of the message, such as carbon copies, blind carbon copies, etc: - Mail::send('emails.welcome', $data, function ($message) { - $message->from('us@example.com', 'Laravel'); + Mail::send('emails.welcome', $data, function ($message) { + $message->from('us@example.com', 'Laravel'); - $message->to('foo@example.com')->cc('bar@example.com'); - }); + $message->to('foo@example.com')->cc('bar@example.com'); + }); Here is a list of the available methods on the `$message` message builder instance: - $message->from($address, $name = null); - $message->sender($address, $name = null); - $message->to($address, $name = null); - $message->cc($address, $name = null); - $message->bcc($address, $name = null); - $message->replyTo($address, $name = null); - $message->subject($subject); - $message->priority($level); - $message->attach($pathToFile, array $options = []); + $message->from($address, $name = null); + $message->sender($address, $name = null); + $message->to($address, $name = null); + $message->cc($address, $name = null); + $message->bcc($address, $name = null); + $message->replyTo($address, $name = null); + $message->subject($subject); + $message->priority($level); + $message->attach($pathToFile, array $options = []); - // Attach a file from a raw $data string... - $message->attachData($data, $name, array $options = []); + // Attach a file from a raw $data string... + $message->attachData($data, $name, array $options = []); - // Get the underlying SwiftMailer message instance... - $message->getSwiftMessage(); + // Get the underlying SwiftMailer message instance... + $message->getSwiftMessage(); > **Note:** The message instance passed to a `Mail::send` Closure extends the SwiftMailer message class, allowing you to call any method on that class to build your e-mail messages. @@ -124,34 +124,34 @@ Here is a list of the available methods on the `$message` message builder instan By default, the view given to the `send` method is assumed to contain HTML. However, by passing an array as the first argument to the `send` method, you may specify a plain text view to send in addition to the HTML view: - Mail::send(['html.view', 'text.view'], $data, $callback); + Mail::send(['html.view', 'text.view'], $data, $callback); Or, if you only need to send a plain text e-mail, you may specify this using the `text` key in the array: - Mail::send(['text' => 'view'], $data, $callback); + Mail::send(['text' => 'view'], $data, $callback); #### Mailing Raw Strings You may use the `raw` method if you wish to e-mail a raw string directly: - Mail::raw('Text to e-mail', function ($message) { - // - }); + Mail::raw('Text to e-mail', function ($message) { + // + }); ### Attachments To add attachments to an e-mail, use the `attach` method on the `$message` object passed to your Closure. The `attach` method accepts the full path to the file as its first argument: - Mail::send('emails.welcome', $data, function ($message) { - // + Mail::send('emails.welcome', $data, function ($message) { + // - $message->attach($pathToFile); - }); + $message->attach($pathToFile); + }); When attaching files to a message, you may also specify the display name and / or MIME type by passing an `array` as the second argument to the `attach` method: - $message->attach($pathToFile, ['as' => $display, 'mime' => $mime]); + $message->attach($pathToFile, ['as' => $display, 'mime' => $mime]); ### Inline Attachments @@ -160,21 +160,21 @@ When attaching files to a message, you may also specify the display name and / o Embedding inline images into your e-mails is typically cumbersome; however, Laravel provides a convenient way to attach images to your e-mails and retrieving the appropriate CID. To embed an inline image, use the `embed` method on the `$message` variable within your e-mail view. Remember, Laravel automatically makes the `$message` variable available to all of your e-mail views: - - Here is an image: + + Here is an image: - - + + #### Embedding Raw Data In An E-Mail View If you already have a raw data string you wish to embed into an e-mail message, you may use the `embedData` method on the `$message` variable: - - Here is an image from raw data: + + Here is an image from raw data: - - + + ### Queueing Mail @@ -183,9 +183,9 @@ If you already have a raw data string you wish to embed into an e-mail message, Since sending e-mail messages can drastically lengthen the response time of your application, many developers choose to queue e-mail messages for background sending. Laravel makes this easy using its built-in [unified queue API](/docs/{{version}}/queues). To queue a mail message, use the `queue` method on the `Mail` facade: - Mail::queue('emails.welcome', $data, function ($message) { - // - }); + Mail::queue('emails.welcome', $data, function ($message) { + // + }); This method will automatically take care of pushing a job onto the queue to send the mail message in the background. Of course, you will need to [configure your queues](/docs/{{version}}/queues) before using this feature. @@ -193,21 +193,21 @@ This method will automatically take care of pushing a job onto the queue to send If you wish to delay the delivery of a queued e-mail message, you may use the `later` method. To get started, simply pass the number of seconds by which you wish to delay the sending of the message as the first argument to the method: - Mail::later(5, 'emails.welcome', $data, function ($message) { - // - }); + Mail::later(5, 'emails.welcome', $data, function ($message) { + // + }); #### Pushing To Specific Queues If you wish to specify a specific queue on which to push the message, you may do so using the `queueOn` and `laterOn` methods: - Mail::queueOn('queue-name', 'emails.welcome', $data, function ($message) { - // - }); + Mail::queueOn('queue-name', 'emails.welcome', $data, function ($message) { + // + }); - Mail::laterOn('queue-name', 5, 'emails.welcome', $data, function ($message) { - // - }); + Mail::laterOn('queue-name', 5, 'emails.welcome', $data, function ($message) { + // + }); ## Mail & Local Development @@ -222,10 +222,10 @@ One solution is to use the `log` mail driver during local development. This driv Another solution provided by Laravel is to set a universal recipient of all e-mails sent by the framework. This way, all the emails generated by your application will be sent to a specific address, instead of the address actually specified when sending the message. This can be done via the `to` option in your `config/mail.php` configuration file: - 'to' => [ - 'address' => 'dev@domain.com', - 'name' => 'Dev Example' - ], + 'to' => [ + 'address' => 'dev@domain.com', + 'name' => 'Dev Example' + ], #### Mailtrap diff --git a/middleware.md b/middleware.md index 06cc18aad5..96651362d6 100644 --- a/middleware.md +++ b/middleware.md @@ -20,35 +20,35 @@ There are several middleware included in the Laravel framework, including middle To create a new middleware, use the `make:middleware` Artisan command: - php artisan make:middleware OldMiddleware + php artisan make:middleware OldMiddleware This command will place a new `OldMiddleware` class within your `app/Http/Middleware` directory. In this middleware, we will only allow access to the route if the supplied `age` is greater than 200. Otherwise, we will redirect the users back to the "home" URI. - input('age') <= 200) { - return redirect('home'); - } + class OldMiddleware + { + /** + * Run the request filter. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @return mixed + */ + public function handle($request, Closure $next) + { + if ($request->input('age') <= 200) { + return redirect('home'); + } - return $next($request); - } + return $next($request); + } - } + } As you can see, if the given `age` is less than or equal to `200`, the middleware will return an HTTP redirect to the client; otherwise, the request will be passed further into the application. To pass the request deeper into the application (allowing the middleware to "pass"), simply call the `$next` callback with the `$request`. @@ -58,41 +58,41 @@ It's best to envision middleware as a series of "layers" HTTP requests must pass Whether a middleware runs before or after a request depends on the middleware itself. For example, the following middleware would perform some task **before** the request is handled by the application: - ## Registering Middleware @@ -105,7 +105,7 @@ If you want a middleware to be run during every HTTP request to your application If you would like to assign middleware to specific routes, you should first assign the middleware a short-hand key in your `app/Http/Kernel.php` file. By default, the `$routeMiddleware` property of this class contains entries for the middleware included with Laravel. To add your own, simply append it to this list and assign it a key of your choosing. For example: - // Within App\Http\Kernel Class... + // Within App\Http\Kernel Class... protected $routeMiddleware = [ 'auth' => \App\Http\Middleware\Authenticate::class, @@ -115,9 +115,9 @@ If you would like to assign middleware to specific routes, you should first assi Once the middleware has been defined in the HTTP kernel, you may use the `middleware` key in the route options array: - Route::get('admin/profile', ['middleware' => 'auth', function () { - // - }]); + Route::get('admin/profile', ['middleware' => 'auth', function () { + // + }]); ## Middleware Parameters @@ -126,61 +126,61 @@ Middleware can also receive additional custom parameters. For example, if your a Additional middleware parameters will be passed to the middleware after the `$next` argument: - user()->hasRole($role)) { - // Redirect... - } + class RoleMiddleware + { + /** + * Run the request filter. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @param string $role + * @return mixed + */ + public function handle($request, Closure $next, $role) + { + if (! $request->user()->hasRole($role)) { + // Redirect... + } - return $next($request); - } + return $next($request); + } - } + } Middleware parameters may be specified when defining the route by separating the middleware name and parameters with a `:`. Multiple parameters should be delimited by commas: - Route::put('post/{id}', ['middleware' => 'role:editor', function ($id) { - // - }]); + Route::put('post/{id}', ['middleware' => 'role:editor', function ($id) { + // + }]); ## Terminable Middleware Sometimes a middleware may need to do some work after the HTTP response has already been sent to the browser. For example, the "session" middleware included with Laravel writes the session data to storage _after_ the response has been sent to the browser. To accomplish this, define the middleware as "terminable" by adding a `terminate` method to the middleware: - ## Introduction @@ -27,15 +27,15 @@ The Laravel `Schema` [facade](/docs/{{version}}/facades) provides database agnos To create a migration, use the `make:migration` [Artisan command](/docs/{{version}}/artisan): - php artisan make:migration create_users_table + php artisan make:migration create_users_table The new migration will be placed in your `database/migrations` directory. Each migration file name contains a timestamp which allows Laravel to determine the order of the migrations. The `--table` and `--create` options may also be used to indicate the name of the table and whether the migration will be creating a new table. These options simply pre-fill the generated migration stub file with the specified table: - php artisan make:migration add_votes_to_users_table --table=users + php artisan make:migration add_votes_to_users_table --table=users - php artisan make:migration create_users_table --create=users + php artisan make:migration create_users_table --create=users If you would like to specify a custom output path for the generated migration, you may use the `--path` option when executing the `make:migration` command. The provided path should be relative to your application's base path. @@ -46,38 +46,38 @@ A migration class contains two methods: `up` and `down`. The `up` method is used Within both of these methods you may use the Laravel schema builder to expressively create and modify tables. To learn about all of the methods available on the `Schema` builder, [check out its documentation](#creating-tables). For example, let's look at a sample migration that creates a `flights` table: - increments('id'); - $table->string('name'); - $table->string('airline'); - $table->timestamps(); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('flights'); - } - } + increments('id'); + $table->string('name'); + $table->string('airline'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('flights'); + } + } @@ -85,7 +85,7 @@ Within both of these methods you may use the Laravel schema builder to expressiv To run all outstanding migrations for your application, use the `migrate` Artisan command. If you are using the [Homestead virtual machine](/docs/{{version}}/homestead), you should run this command from within your VM: - php artisan migrate + php artisan migrate If you receive a "class not found" error when running migrations, try running the `composer dump-autoload` command and re-issuing the migrate command. @@ -93,26 +93,26 @@ If you receive a "class not found" error when running migrations, try running th Some migration operations are destructive, meaning they may cause you to lose data. In order to protect you from running these commands against your production database, you will be prompted for confirmation before these commands are executed. To force the commands to run without a prompt, use the `--force` flag: - php artisan migrate --force + php artisan migrate --force ### Rolling Back Migrations To rollback the latest migration "operation", you may use the `rollback` command. Note that this rolls back the last "batch" of migrations that ran, which may include multiple migration files: - php artisan migrate:rollback + php artisan migrate:rollback The `migrate:reset` command will roll back all of your application's migrations: - php artisan migrate:reset + php artisan migrate:reset #### Rollback / Migrate In Single Command The `migrate:refresh` command will first roll back all of your database migrations, and then run the `migrate` command. This command effectively re-creates your entire database: - php artisan migrate:refresh + php artisan migrate:refresh - php artisan migrate:refresh --seed + php artisan migrate:refresh --seed ## Writing Migrations @@ -122,9 +122,9 @@ The `migrate:refresh` command will first roll back all of your database migratio To create a new database table, use the `create` method on the `Schema` facade. The `create` method accepts two arguments. The first is the name of the table, while the second is a `Closure` which receives a `Blueprint` object used to define the new table: - Schema::create('users', function ($table) { - $table->increments('id'); - }); + Schema::create('users', function ($table) { + $table->increments('id'); + }); Of course, when creating the table, you may use any of the schema builder's [column methods](#creating-columns) to define the table's columns. @@ -132,51 +132,51 @@ Of course, when creating the table, you may use any of the schema builder's [col You may easily check for the existence of a table or column using the `hasTable` and `hasColumn` methods: - if (Schema::hasTable('users')) { - // - } + if (Schema::hasTable('users')) { + // + } - if (Schema::hasColumn('users', 'email')) { - // - } + if (Schema::hasColumn('users', 'email')) { + // + } #### Connection & Storage Engine If you want to perform a schema operation on a database connection that is not your default connection, use the `connection` method: - Schema::connection('foo')->create('users', function ($table) { - $table->increments('id'); - }); + Schema::connection('foo')->create('users', function ($table) { + $table->increments('id'); + }); To set the storage engine for a table, set the `engine` property on the schema builder: - Schema::create('users', function ($table) { - $table->engine = 'InnoDB'; + Schema::create('users', function ($table) { + $table->engine = 'InnoDB'; - $table->increments('id'); - }); + $table->increments('id'); + }); ### Renaming / Dropping Tables To rename an existing database table, use the `rename` method: - Schema::rename($from, $to); + Schema::rename($from, $to); To drop an existing table, you may use the `drop` or `dropIfExists` methods: - Schema::drop('users'); + Schema::drop('users'); - Schema::dropIfExists('users'); + Schema::dropIfExists('users'); ### Creating Columns To update an existing table, we will use the `table` method on the `Schema` facade. Like the `create` method, the `table` method accepts two arguments: the name of the table and a `Closure` that receives a `Blueprint` instance we can use to add columns to the table: - Schema::table('users', function ($table) { - $table->string('email'); - }); + Schema::table('users', function ($table) { + $table->string('email'); + }); #### Available Column Types @@ -219,9 +219,9 @@ Command | Description In addition to the column types listed above, there are several other column "modifiers" which you may use while adding the column. For example, to make the column "nullable", you may use the `nullable` method: - Schema::table('users', function ($table) { - $table->string('email')->nullable(); - }); + Schema::table('users', function ($table) { + $table->string('email')->nullable(); + }); Below is a list of all the available column modifiers. This list does not include the [index modifiers](#adding-indexes): @@ -245,24 +245,24 @@ Before modifying a column, be sure to add the `doctrine/dbal` dependency to your The `change` method allows you to modify an existing column to a new type, or modify the column's attributes. For example, you may wish to increase the size of a string column. To see the `change` method in action, let's increase the size of the `name` column from 25 to 50: - Schema::table('users', function ($table) { - $table->string('name', 50)->change(); - }); + Schema::table('users', function ($table) { + $table->string('name', 50)->change(); + }); We could also modify a column to be nullable: - Schema::table('users', function ($table) { - $table->string('name', 50)->nullable()->change(); - }); + Schema::table('users', function ($table) { + $table->string('name', 50)->nullable()->change(); + }); #### Renaming Columns To rename a column, you may use the `renameColumn` method on the Schema builder. Before renaming a column, be sure to add the `doctrine/dbal` dependency to your `composer.json` file: - Schema::table('users', function ($table) { - $table->renameColumn('from', 'to'); - }); + Schema::table('users', function ($table) { + $table->renameColumn('from', 'to'); + }); > **Note:** Renaming columns in a table with a `enum` column is not currently supported. @@ -271,15 +271,15 @@ To rename a column, you may use the `renameColumn` method on the Schema builder. To drop a column, use the `dropColumn` method on the Schema builder: - Schema::table('users', function ($table) { - $table->dropColumn('votes'); - }); + Schema::table('users', function ($table) { + $table->dropColumn('votes'); + }); You may drop multiple columns from a table by passing an array of column names to the `dropColumn` method: - Schema::table('users', function ($table) { - $table->dropColumn(['votes', 'avatar', 'location']); - }); + Schema::table('users', function ($table) { + $table->dropColumn(['votes', 'avatar', 'location']); + }); > **Note:** Before dropping columns from a SQLite database, you will need to add the `doctrine/dbal` dependency to your `composer.json` file and run the `composer update` command in your terminal to install the library. @@ -288,15 +288,15 @@ You may drop multiple columns from a table by passing an array of column names t The schema builder supports several types of indexes. First, let's look at an example that specifies a column's values should be unique. To create the index, we can simply chain the `unique` method onto the column definition: - $table->string('email')->unique(); + $table->string('email')->unique(); Alternatively, you may create the index after defining the column. For example: - $table->unique('email'); + $table->unique('email'); You may even pass an array of columns to an index method to create a compound index: - $table->index(['account_id', 'created_at']); + $table->index(['account_id', 'created_at']); #### Available Index Types @@ -323,18 +323,18 @@ Command | Description Laravel also provides support for creating foreign key constraints, which are used to force referential integrity at the database level. For example, let's define a `user_id` column on the `posts` table that references the `id` column on a `users` table: - Schema::table('posts', function ($table) { - $table->integer('user_id')->unsigned(); + Schema::table('posts', function ($table) { + $table->integer('user_id')->unsigned(); - $table->foreign('user_id')->references('id')->on('users'); - }); + $table->foreign('user_id')->references('id')->on('users'); + }); You may also specify the desired action for the "on delete" and "on update" properties of the constraint: - $table->foreign('user_id') + $table->foreign('user_id') ->references('id')->on('users') ->onDelete('cascade'); To drop a foreign key, you may use the `dropForeign` method. Foreign key constraints use the same naming convention as indexes. So, we will concatenate the table name and the columns in the constraint then suffix the name with "_foreign": - $table->dropForeign('posts_user_id_foreign'); + $table->dropForeign('posts_user_id_foreign'); diff --git a/packages.md b/packages.md index 22b916f0cd..fcbc3be484 100644 --- a/packages.md +++ b/packages.md @@ -4,9 +4,9 @@ - [Service Providers](#service-providers) - [Routing](#routing) - [Resources](#resources) - - [Views](#views) - - [Translations](#translations) - - [Configuration](#configuration) + - [Views](#views) + - [Translations](#translations) + - [Configuration](#configuration) - [Public Assets](#public-assets) - [Publishing File Groups](#publishing-file-groups) @@ -33,17 +33,17 @@ To learn more about the structure and purpose of service providers, check out [t To define routes for your package, simply `require` the routes file from within your package service provider's `boot` method. From within your routes file, you may use the `Route` facade to [register routes](/docs/{{version}}/routing) just as you would within a typical Laravel application: - /** - * Perform post-registration booting of services. - * - * @return void - */ - public function boot() - { - if (! $this->app->routesAreCached()) { - require __DIR__.'/../../routes.php'; - } - } + /** + * Perform post-registration booting of services. + * + * @return void + */ + public function boot() + { + if (! $this->app->routesAreCached()) { + require __DIR__.'/../../routes.php'; + } + } ## Resources @@ -53,21 +53,21 @@ To define routes for your package, simply `require` the routes file from within To register your package's [views](/docs/{{version}}/views) with Laravel, you need to tell Laravel where the views are located. You may do this using the service provider's `loadViewsFrom` method. The `loadViewsFrom` method accepts two arguments: the path to your view templates and your package's name. For example, if your package name is "courier", add the following to your service provider's `boot` method: - /** - * Perform post-registration booting of services. - * - * @return void - */ - public function boot() - { - $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier'); - } + /** + * Perform post-registration booting of services. + * + * @return void + */ + public function boot() + { + $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier'); + } Package views are referenced using a double-colon `package::view` syntax. So, you may load the `admin` view from the `courier` package like so: - Route::get('admin', function () { - return view('courier::admin'); - }); + Route::get('admin', function () { + return view('courier::admin'); + }); #### Overriding Package Views @@ -77,19 +77,19 @@ When you use the `loadViewsFrom` method, Laravel actually registers **two** loca If you would like to make your views available for publishing to the application's `resources/views/vendor` directory, you may use the service provider's `publishes` method. The `publishes` method accepts an array of package view paths and their corresponding publish locations. - /** - * Perform post-registration booting of services. - * - * @return void - */ - public function boot() - { - $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier'); + /** + * Perform post-registration booting of services. + * + * @return void + */ + public function boot() + { + $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier'); - $this->publishes([ - __DIR__.'/path/to/views' => base_path('resources/views/vendor/courier'), - ]); - } + $this->publishes([ + __DIR__.'/path/to/views' => base_path('resources/views/vendor/courier'), + ]); + } Now, when users of your package execute Laravel's `vendor:publish` Artisan command, your views package's will be copied to the specified location. @@ -98,77 +98,77 @@ Now, when users of your package execute Laravel's `vendor:publish` Artisan comma If your package contains [translation files](/docs/{{version}}/localization), you may use the `loadTranslationsFrom` method to inform Laravel how to load them. For example, if your package is named "courier", you should add the following to your service provider's `boot` method: - /** - * Perform post-registration booting of services. - * - * @return void - */ - public function boot() - { - $this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier'); - } + /** + * Perform post-registration booting of services. + * + * @return void + */ + public function boot() + { + $this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier'); + } Package translations are referenced using a double-colon `package::file.line` syntax. So, you may load the `courier` package's `welcome` line from the `messages` file like so: - echo trans('courier::messages.welcome'); + echo trans('courier::messages.welcome'); ### Configuration Typically, you will want to publish your package's configuration file to the application's own `config` directory. This will allow users of your package to easily override your default configuration options. To publish a configuration file, just use the `publishes` method from the `boot` method of your service provider: - /** - * Perform post-registration booting of services. - * - * @return void - */ - public function boot() - { - $this->publishes([ - __DIR__.'/path/to/config/courier.php' => config_path('courier.php'), - ]); - } + /** + * Perform post-registration booting of services. + * + * @return void + */ + public function boot() + { + $this->publishes([ + __DIR__.'/path/to/config/courier.php' => config_path('courier.php'), + ]); + } Now, when users of your package execute Laravel's `vendor:publish` command, your file will be copied to the specified location. Of course, once your configuration has been published, it can be accessed like any other configuration file: - $value = config('courier.option'); + $value = config('courier.option'); #### Default Package Configuration You may also choose to merge your own package configuration file with the application's copy. This allows your users to include only the options they actually want to override in the published copy of the configuration. To merge the configurations, use the `mergeConfigFrom` method within your service provider's `register` method: - /** - * Register bindings in the container. - * - * @return void - */ - public function register() - { - $this->mergeConfigFrom( - __DIR__.'/path/to/config/courier.php', 'courier' - ); - } + /** + * Register bindings in the container. + * + * @return void + */ + public function register() + { + $this->mergeConfigFrom( + __DIR__.'/path/to/config/courier.php', 'courier' + ); + } ## Public Assets Your packages may have assets such as JavaScript, CSS, and images. To publish these assets to the application's `public` directory, use the service provider's `publishes` method. In this example, we will also add a `public` asset group tag, which may be used to publish groups of related assets: - /** - * Perform post-registration booting of services. - * - * @return void - */ - public function boot() - { - $this->publishes([ - __DIR__.'/path/to/assets' => public_path('vendor/courier'), - ], 'public'); - } + /** + * Perform post-registration booting of services. + * + * @return void + */ + public function boot() + { + $this->publishes([ + __DIR__.'/path/to/assets' => public_path('vendor/courier'), + ], 'public'); + } Now, when your package's users execute the `vendor:publish` command, your assets will be copied to the specified location. Since you typically will need to overwrite the assets every time the package is updated, you may use the `--force` flag: - php artisan vendor:publish --tag=public --force + php artisan vendor:publish --tag=public --force If you would like to make sure your public assets are always up-to-date, you can add this command to the `post-update-cmd` list in your `composer.json` file. @@ -177,22 +177,22 @@ If you would like to make sure your public assets are always up-to-date, you can You may want to publish groups of package assets and resources separately. For instance, you might want your users to be able to publish your package's configuration files without being forced to publish your package's assets at the same time. You may do this by "tagging" them when calling the `publishes` method. For example, let's define two publish groups in the `boot` method of a package service provider: - /** - * Perform post-registration booting of services. - * - * @return void - */ - public function boot() - { - $this->publishes([ - __DIR__.'/../config/package.php' => config_path('package.php') - ], 'config'); - - $this->publishes([ - __DIR__.'/../database/migrations/' => database_path('/migrations') - ], 'migrations'); - } + /** + * Perform post-registration booting of services. + * + * @return void + */ + public function boot() + { + $this->publishes([ + __DIR__.'/../config/package.php' => config_path('package.php') + ], 'config'); + + $this->publishes([ + __DIR__.'/../database/migrations/' => database_path('/migrations') + ], 'migrations'); + } Now your users may publish these groups separately by referencing their tag name when using the `vendor:publish` Artisan command: - php artisan vendor:publish --provider="Vendor\Providers\PackageServiceProvider" --tag="config" + php artisan vendor:publish --provider="Vendor\Providers\PackageServiceProvider" --tag="config" diff --git a/pagination.md b/pagination.md index 1c2ba23661..6b4c6ba6ab 100644 --- a/pagination.md +++ b/pagination.md @@ -2,9 +2,9 @@ - [Introduction](#introduction) - [Basic Usage](#basic-usage) - - [Paginating Query Builder Results](#paginating-query-builder-results) - - [Paginating Eloquent Results](#paginating-eloquent-results) - - [Manually Creating A Paginator](#manually-creating-a-paginator) + - [Paginating Query Builder Results](#paginating-query-builder-results) + - [Paginating Eloquent Results](#paginating-eloquent-results) + - [Manually Creating A Paginator](#manually-creating-a-paginator) - [Displaying Results In A View](#displaying-results-in-a-view) - [Converting Results To JSON](#converting-results-to-json) @@ -23,27 +23,27 @@ There are several ways to paginate items. The simplest is by using the `paginate First, let's take a look at calling the `paginate` method on a query. In this example, the only argument passed to `paginate` is the number of items you would like displayed "per page". In this case, let's specify that we would like to display `15` items per page: - paginate(15); + class UserController extends Controller + { + /** + * Show all of the users for the application. + * + * @return Response + */ + public function index() + { + $users = DB::table('users')->paginate(15); - return view('user.index', ['users' => $users]); - } - } + return view('user.index', ['users' => $users]); + } + } > **Note:** Currently, pagination operations that use a `groupBy` statement cannot be executed efficiently by Laravel. If you need to use a `groupBy` with a paginated result set, it is recommended that you query the database and create a paginator manually. @@ -51,22 +51,22 @@ First, let's take a look at calling the `paginate` method on a query. In this ex If you only need to display simple "Next" and "Previous" links in your pagination view, you have the option of using the `simplePaginate` method to perform a more efficient query. This is very useful for large datasets if you do not need to display a link for each page number when rendering your view: - $users = DB::table('users')->simplePaginate(15); + $users = DB::table('users')->simplePaginate(15); ### Paginating Eloquent Results You may also paginate [Eloquent](/docs/{{version}}/eloquent) queries. In this example, we will paginate the `User` model with `15` items per page. As you can see, the syntax is nearly identical to paginating query builder results: - $users = App\User::paginate(15); + $users = App\User::paginate(15); Of course, you may call `paginate` after setting other constraints on the query, such as `where` clauses: - $users = User::where('votes', '>', 100)->paginate(15); + $users = User::where('votes', '>', 100)->paginate(15); You may also use the `simplePaginate` method when paginating Eloquent models: - $users = User::where('votes', '>', 100)->simplePaginate(15); + $users = User::where('votes', '>', 100)->simplePaginate(15); ### Manually Creating A Paginator @@ -86,13 +86,13 @@ When you call the `paginate` or `simplePaginate` methods on a query builder or E So, once you have retrieved the results, you may display the results and render the page links using [Blade](/docs/{{version}}/blade): -
    - @foreach ($users as $user) - {{ $user->name }} - @endforeach -
    +
    + @foreach ($users as $user) + {{ $user->name }} + @endforeach +
    - {!! $users->render() !!} + {!! $users->render() !!} The `render` method will render the links to the rest of the pages in the result set. Each of these links will already contain the proper `?page` query string variable. Remember, the HTML generated by the `render` method is compatible with the [Bootstrap CSS framework](https://getbootstrap.com). @@ -102,23 +102,23 @@ The `render` method will render the links to the rest of the pages in the result The `setPath` method allows you to customize the URI used by the paginator when generating links. For example, if you want the paginator to generate links like `http://example.com/custom/url?page=N`, you should pass `custom/url` to the `setPath` method: - Route::get('users', function () { - $users = App\User::paginate(15); + Route::get('users', function () { + $users = App\User::paginate(15); - $users->setPath('custom/url'); + $users->setPath('custom/url'); - // - }); + // + }); #### Appending To Pagination Links You may add to the query string of pagination links using the `appends` method. For example, to append `&sort=votes` to each pagination link, you should make the following call to `appends`: - {!! $users->appends(['sort' => 'votes'])->render() !!} + {!! $users->appends(['sort' => 'votes'])->render() !!} If you wish to append a "hash fragment" to the paginator's URLs, you may use the `fragment` method. For example, to append `#foo` to the end of each pagination link, make the following call to the `fragment` method: - {!! $users->fragment('foo')->render() !!} + {!! $users->fragment('foo')->render() !!} #### Additional Helper Methods @@ -140,29 +140,29 @@ The Laravel paginator result classes implement the `Illuminate\Contracts\Support You may also convert a paginator instance to JSON by simply returning it from a route or controller action: - Route::get('users', function () { - return App\User::paginate(); - }); + Route::get('users', function () { + return App\User::paginate(); + }); The JSON from the paginator will include meta information such as `total`, `current_page`, `last_page`, and more. The actual result objects will be available via the `data` key in the JSON array. Here is an example of the JSON created by returning a paginator instance from a route: #### Example Paginator JSON - { - "total": 50, - "per_page": 15, - "current_page": 1, - "last_page": 4, - "next_page_url": "http://laravel.app?page=2", - "prev_page_url": null, - "from": 1, - "to": 15, - "data":[ - { - // Result Object - }, - { - // Result Object - } - ] - } + { + "total": 50, + "per_page": 15, + "current_page": 1, + "last_page": 4, + "next_page_url": "http://laravel.app?page=2", + "prev_page_url": null, + "from": 1, + "to": 15, + "data":[ + { + // Result Object + }, + { + // Result Object + } + ] + } diff --git a/providers.md b/providers.md index f19d53e74c..9cdf4951a8 100644 --- a/providers.md +++ b/providers.md @@ -2,8 +2,8 @@ - [Introduction](#introduction) - [Writing Service Providers](#writing-service-providers) - - [The Register Method](#the-register-method) - - [The Boot Method](#the-boot-method) + - [The Register Method](#the-register-method) + - [The Boot Method](#the-boot-method) - [Registering Providers](#registering-providers) - [Deferred Providers](#deferred-providers) @@ -25,7 +25,7 @@ All service providers extend the `Illuminate\Support\ServiceProvider` class. Thi The Artisan CLI can easily generate a new provider via the `make:provider` command: - php artisan make:provider RiakServiceProvider + php artisan make:provider RiakServiceProvider ### The Register Method @@ -34,27 +34,27 @@ As mentioned previously, within the `register` method, you should only bind thin Now, let's take a look at a basic service provider: - app->singleton('Riak\Contracts\Connection', function ($app) { - return new Connection(config('riak')); - }); - } - } + class RiakServiceProvider extends ServiceProvider + { + /** + * Register bindings in the container. + * + * @return void + */ + public function register() + { + $this->app->singleton('Riak\Contracts\Connection', function ($app) { + return new Connection(config('riak')); + }); + } + } This service provider only defines a `register` method, and uses that method to define an implementation of `Riak\Contracts\Connection` in the service container. If you don't understand how the service container works, check out [its documentation](/docs/{{version}}/container). @@ -63,49 +63,49 @@ This service provider only defines a `register` method, and uses that method to So, what if we need to register a view composer within our service provider? This should be done within the `boot` method. **This method is called after all other service providers have been registered**, meaning you have access to all other services that have been registered by the framework: - composer('view', function () { - // - }); - } - - /** - * Register bindings in the container. - * - * @return void - */ - public function register() - { - // - } - } + composer('view', function () { + // + }); + } + + /** + * Register bindings in the container. + * + * @return void + */ + public function register() + { + // + } + } #### Boot Method Dependency Injection We are able to type-hint dependencies for our `boot` method. The [service container](/docs/{{version}}/container) will automatically inject any dependencies you need: - use Illuminate\Contracts\Routing\ResponseFactory; + use Illuminate\Contracts\Routing\ResponseFactory; - public function boot(ResponseFactory $factory) - { - $factory->macro('caps', function ($value) { - // - }); - } + public function boot(ResponseFactory $factory) + { + $factory->macro('caps', function ($value) { + // + }); + } ## Registering Providers @@ -114,11 +114,11 @@ All service providers are registered in the `config/app.php` configuration file. To register your provider, simply add it to the array: - 'providers' => [ - // Other Service Providers + 'providers' => [ + // Other Service Providers - 'App\Providers\AppServiceProvider', - ], + 'App\Providers\AppServiceProvider', + ], ## Deferred Providers @@ -127,44 +127,44 @@ If your provider is **only** registering bindings in the [service container](/do To defer the loading of a provider, set the `defer` property to `true` and define a `provides` method. The `provides` method returns the service container bindings that the provider registers: - app->singleton('Riak\Contracts\Connection', function ($app) { - return new Connection($app['config']['riak']); - }); - } - - /** - * Get the services provided by the provider. - * - * @return array - */ - public function provides() - { - return ['Riak\Contracts\Connection']; - } - - } + app->singleton('Riak\Contracts\Connection', function ($app) { + return new Connection($app['config']['riak']); + }); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return ['Riak\Contracts\Connection']; + } + + } Laravel compiles and stores a list of all of the services supplied by deferred service providers, along with the name of its service provider class. Then, only when you attempt to resolve one of these services does Laravel load the service provider. diff --git a/queries.md b/queries.md index c8e2f48ec5..c6f5c2eec3 100644 --- a/queries.md +++ b/queries.md @@ -2,12 +2,12 @@ - [Introduction](#introduction) - [Retrieving Results](#retrieving-results) - - [Aggregates](#aggregates) + - [Aggregates](#aggregates) - [Selects](#selects) - [Joins](#joins) - [Unions](#unions) - [Where Clauses](#where-clauses) - - [Advanced Where Clauses](#advanced-where-clauses) + - [Advanced Where Clauses](#advanced-where-clauses) - [Ordering, Grouping, Limit, & Offset](#ordering-grouping-limit-and-offset) - [Inserts](#inserts) - [Updates](#updates) @@ -28,96 +28,96 @@ The database query builder provides a convenient, fluent interface to creating a To begin a fluent query, use the `table` method on the `DB` facade. The `table` method returns a fluent query builder instance for the given table, allowing you to chain more constraints onto the query and then finally get the results. In this example, let's just `get` all records from a table: - get(); + class UserController extends Controller + { + /** + * Show a list of all of the application's users. + * + * @return Response + */ + public function index() + { + $users = DB::table('users')->get(); - return view('user.index', ['users' => $users]); - } - } + return view('user.index', ['users' => $users]); + } + } Like [raw queries](/docs/{{version}}/database), the `get` method returns an `array` of results where each result is an instance of the PHP `StdClass` object. You may access each column's value by accessing the column as a property of the object: - foreach ($users as $user) { - echo $user->name; - } + foreach ($users as $user) { + echo $user->name; + } #### Retrieving A Single Row / Column From A Table If you just need to retrieve a single row from the database table, you may use the `first` method. This method will return a single `StdClass` object: - $user = DB::table('users')->where('name', 'John')->first(); + $user = DB::table('users')->where('name', 'John')->first(); - echo $user->name; + echo $user->name; If you don't even need an entire row, you may extract a single value from a record using the `value` method. This method will return the value of the column directly: - $email = DB::table('users')->where('name', 'John')->value('email'); + $email = DB::table('users')->where('name', 'John')->value('email'); #### Chunking Results From A Table If you need to work with thousands of database records, consider using the `chunk` method. This method retrieves a small "chunk" of the results at a time, and feeds each chunk into a `Closure` for processing. This method is very useful for writing [Artisan commands](/docs/{{version}}/artisan) that process thousands of records. For example, let's work with the entire `users` table in chunks of 100 records at a time: - DB::table('users')->chunk(100, function($users) { - foreach ($users as $user) { - // - } - }); + DB::table('users')->chunk(100, function($users) { + foreach ($users as $user) { + // + } + }); You may stop further chunks from being processed by returning `false` from the `Closure`: - DB::table('users')->chunk(100, function($users) { - // Process the records... + DB::table('users')->chunk(100, function($users) { + // Process the records... - return false; - }); + return false; + }); #### Retrieving A List Of Column Values If you would like to retrieve an array containing the values of a single column, you may use the `lists` method. In this example, we'll retrieve an array of role titles: - $titles = DB::table('roles')->lists('title'); + $titles = DB::table('roles')->lists('title'); - foreach ($titles as $title) { - echo $title; - } + foreach ($titles as $title) { + echo $title; + } You may also specify a custom key column for the returned array: - $roles = DB::table('roles')->lists('title', 'name'); + $roles = DB::table('roles')->lists('title', 'name'); - foreach ($roles as $name => $title) { - echo $title; - } + foreach ($roles as $name => $title) { + echo $title; + } ### Aggregates The query builder also provides a variety of aggregate methods, such as `count`, `max`, `min`, `avg`, and `sum`. You may call any of these methods after constructing your query: - $users = DB::table('users')->count(); + $users = DB::table('users')->count(); - $price = DB::table('orders')->max('price'); + $price = DB::table('orders')->max('price'); Of course, you may combine these methods with other clauses to build your query: - $price = DB::table('orders') - ->where('finalized', 1) - ->avg('price'); + $price = DB::table('orders') + ->where('finalized', 1) + ->avg('price'); ## Selects @@ -126,27 +126,27 @@ Of course, you may combine these methods with other clauses to build your query: Of course, you may not always want to select all columns from a database table. Using the `select` method, you can specify a custom `select` clause for the query: - $users = DB::table('users')->select('name', 'email as user_email')->get(); + $users = DB::table('users')->select('name', 'email as user_email')->get(); The `distinct` method allows you to force the query to return distinct results: - $users = DB::table('users')->distinct()->get(); + $users = DB::table('users')->distinct()->get(); If you already have a query builder instance and you wish to add a column to its existing select clause, you may use the `addSelect` method: - $query = DB::table('users')->select('name'); + $query = DB::table('users')->select('name'); - $users = $query->addSelect('age')->get(); + $users = $query->addSelect('age')->get(); #### Raw Expressions Sometimes you may need to use a raw expression in a query. These expressions will be injected into the query as strings, so be careful not to create any SQL injection points! To create a raw expression, you may use the `DB::raw` method: - $users = DB::table('users') - ->select(DB::raw('count(*) as user_count, status')) - ->where('status', '<>', 1) - ->groupBy('status') - ->get(); + $users = DB::table('users') + ->select(DB::raw('count(*) as user_count, status')) + ->where('status', '<>', 1) + ->groupBy('status') + ->get(); ## Joins @@ -155,51 +155,51 @@ Sometimes you may need to use a raw expression in a query. These expressions wil The query builder may also be used to write join statements. To perform a basic SQL "inner join", you may use the `join` method on a query builder instance. The first argument passed to the `join` method is the name of the table you need to join to, while the remaining arguments specify the column constraints for the join. Of course, as you can see, you can join to multiple tables in a single query: - $users = DB::table('users') - ->join('contacts', 'users.id', '=', 'contacts.user_id') - ->join('orders', 'users.id', '=', 'orders.user_id') - ->select('users.*', 'contacts.phone', 'orders.price') - ->get(); + $users = DB::table('users') + ->join('contacts', 'users.id', '=', 'contacts.user_id') + ->join('orders', 'users.id', '=', 'orders.user_id') + ->select('users.*', 'contacts.phone', 'orders.price') + ->get(); #### Left Join Statement If you would like to perform a "left join" instead of an "inner join", use the `leftJoin` method. The `leftJoin` method has the same signature as the `join` method: - $users = DB::table('users') - ->leftJoin('posts', 'users.id', '=', 'posts.user_id') - ->get(); + $users = DB::table('users') + ->leftJoin('posts', 'users.id', '=', 'posts.user_id') + ->get(); #### Advanced Join Statements You may also specify more advanced join clauses. To get started, pass a `Closure` as the second argument into the `join` method. The `Closure` will receive a `JoinClause` object which allows you to specify constraints on the `join` clause: - DB::table('users') - ->join('contacts', function ($join) { - $join->on('users.id', '=', 'contacts.user_id')->orOn(...); - }) - ->get(); + DB::table('users') + ->join('contacts', function ($join) { + $join->on('users.id', '=', 'contacts.user_id')->orOn(...); + }) + ->get(); If you would like to use a "where" style clause on your joins, you may use the `where` and `orWhere` methods on a join. Instead of comparing two columns, these methods will compare the column against a value: - DB::table('users') - ->join('contacts', function ($join) { - $join->on('users.id', '=', 'contacts.user_id') - ->where('contacts.user_id', '>', 5); - }) - ->get(); + DB::table('users') + ->join('contacts', function ($join) { + $join->on('users.id', '=', 'contacts.user_id') + ->where('contacts.user_id', '>', 5); + }) + ->get(); ## Unions The query builder also provides a quick way to "union" two queries together. For example, you may create an initial query, and then use the `union` method to union it with a second query: - $first = DB::table('users') - ->whereNull('first_name'); + $first = DB::table('users') + ->whereNull('first_name'); - $users = DB::table('users') - ->whereNull('last_name') - ->union($first) - ->get(); + $users = DB::table('users') + ->whereNull('last_name') + ->union($first) + ->get(); The `unionAll` method is also available and has the same method signature as `union`. @@ -212,34 +212,34 @@ To add `where` clauses to the query, use the `where` method on a query builder i For example, here is a query that verifies the value of the "votes" column is equal to 100: - $users = DB::table('users')->where('votes', '=', 100)->get(); + $users = DB::table('users')->where('votes', '=', 100)->get(); For convenience, if you simply want to verify that a column is equal to a given value, you may pass the value directly as the second argument to the `where` method: - $users = DB::table('users')->where('votes', 100)->get(); + $users = DB::table('users')->where('votes', 100)->get(); Of course, you may use a variety of other operators when writing a `where` clause: - $users = DB::table('users') - ->where('votes', '>=', 100) - ->get(); + $users = DB::table('users') + ->where('votes', '>=', 100) + ->get(); - $users = DB::table('users') - ->where('votes', '<>', 100) - ->get(); + $users = DB::table('users') + ->where('votes', '<>', 100) + ->get(); - $users = DB::table('users') - ->where('name', 'like', 'T%') - ->get(); + $users = DB::table('users') + ->where('name', 'like', 'T%') + ->get(); #### Or Statements You may chain where constraints together, as well as add `or` clauses to the query. The `orWhere` method accepts the same arguments as the `where` method: - $users = DB::table('users') - ->where('votes', '>', 100) - ->orWhere('name', 'John') - ->get(); + $users = DB::table('users') + ->where('votes', '>', 100) + ->orWhere('name', 'John') + ->get(); #### Additional Where Clauses @@ -247,44 +247,44 @@ You may chain where constraints together, as well as add `or` clauses to the que The `whereBetween` method verifies that a column's value is between two values: - $users = DB::table('users') - ->whereBetween('votes', [1, 100])->get(); + $users = DB::table('users') + ->whereBetween('votes', [1, 100])->get(); **whereNotBetween** The `whereNotBetween` method verifies that a column's value lies outside of two values: - $users = DB::table('users') - ->whereNotBetween('votes', [1, 100]) - ->get(); + $users = DB::table('users') + ->whereNotBetween('votes', [1, 100]) + ->get(); **whereIn / whereNotIn** The `whereIn` method verifies that a given column's value is contained within the given array: - $users = DB::table('users') - ->whereIn('id', [1, 2, 3]) - ->get(); + $users = DB::table('users') + ->whereIn('id', [1, 2, 3]) + ->get(); The `whereNotIn` method verifies that the given column's value is **not** contained in the given array: - $users = DB::table('users') - ->whereNotIn('id', [1, 2, 3]) - ->get(); + $users = DB::table('users') + ->whereNotIn('id', [1, 2, 3]) + ->get(); **whereNull / whereNotNull** The `whereNull` method verifies that the value of the given column is `NULL`: - $users = DB::table('users') - ->whereNull('updated_at') - ->get(); + $users = DB::table('users') + ->whereNull('updated_at') + ->get(); The `whereNotNull` method verifies that the column's value is **not** `NULL`: - $users = DB::table('users') - ->whereNotNull('updated_at') - ->get(); + $users = DB::table('users') + ->whereNotNull('updated_at') + ->get(); ## Advanced Where Clauses @@ -293,36 +293,36 @@ The `whereNotNull` method verifies that the column's value is **not** `NULL`: Sometimes you may need to create more advanced where clauses such as "where exists" or nested parameter groupings. The Laravel query builder can handle these as well. To get started, let's look at an example of grouping constraints within parenthesis: - DB::table('users') - ->where('name', '=', 'John') - ->orWhere(function ($query) { - $query->where('votes', '>', 100) - ->where('title', '<>', 'Admin'); - }) - ->get(); + DB::table('users') + ->where('name', '=', 'John') + ->orWhere(function ($query) { + $query->where('votes', '>', 100) + ->where('title', '<>', 'Admin'); + }) + ->get(); As you can see, passing `Closure` into the `orWhere` method instructs the query builder to begin a constraint group. The `Closure` will receive a query builder instance which you can use to set the constraints that should be contained within the parenthesis group. The example above will produce the following SQL: - select * from users where name = 'John' or (votes > 100 and title <> 'Admin') + select * from users where name = 'John' or (votes > 100 and title <> 'Admin') #### Exists Statements The `whereExists` method allows you to write `where exist` SQL clauses. The `whereExists` method accepts a `Closure` argument, which will receive a query builder instance allowing you to define the query that should be placed inside of the "exists" clause: - DB::table('users') - ->whereExists(function ($query) { - $query->select(DB::raw(1)) - ->from('orders') - ->whereRaw('orders.user_id = users.id'); - }) - ->get(); + DB::table('users') + ->whereExists(function ($query) { + $query->select(DB::raw(1)) + ->from('orders') + ->whereRaw('orders.user_id = users.id'); + }) + ->get(); The query above will produce the following SQL: - select * from users - where exists ( - select 1 from orders where orders.user_id = users.id - ) + select * from users + where exists ( + select 1 from orders where orders.user_id = users.id + ) ## Ordering, Grouping, Limit, & Offset @@ -331,23 +331,23 @@ The query above will produce the following SQL: The `orderBy` method allows you to sort the result of the query by a given column. The first argument to the `orderBy` method should be the column you wish to sort by, while the second argument controls the direction of the sort and may be either `asc` or `desc`: - $users = DB::table('users') - ->orderBy('name', 'desc') - ->get(); + $users = DB::table('users') + ->orderBy('name', 'desc') + ->get(); #### groupBy / having / havingRaw The `groupBy` and `having` methods may be used to group the query results. The `having` method's signature is similar to that of the `where` method: - $users = DB::table('users') + $users = DB::table('users') ->groupBy('account_id') ->having('account_id', '>', 100) ->get(); The `havingRaw` method may be used to set a raw string as the value of the `having` clause. For example, we can find all of the departments with sales greater than $2,500: - $users = DB::table('orders') - ->select('department', DB::raw('SUM(price) as total_sales')) + $users = DB::table('orders') + ->select('department', DB::raw('SUM(price) as total_sales')) ->groupBy('department') ->havingRaw('SUM(price) > 2500') ->get(); @@ -356,31 +356,31 @@ The `havingRaw` method may be used to set a raw string as the value of the `havi To limit the number of results returned from the query, or to skip a given number of results in the query (`OFFSET`), you may use the `skip` and `take` methods: - $users = DB::table('users')->skip(10)->take(5)->get(); + $users = DB::table('users')->skip(10)->take(5)->get(); ## Inserts The query builder also provides an `insert` method for inserting records into the database table. The `insert` method accepts an array of column names and values to insert: - DB::table('users')->insert( - ['email' => 'john@example.com', 'votes' => 0] - ); + DB::table('users')->insert( + ['email' => 'john@example.com', 'votes' => 0] + ); You may even insert several records into the table with a single call to `insert` by passing an array of arrays. Each array represents a row to be inserted into the table: - DB::table('users')->insert([ - ['email' => 'taylor@example.com', 'votes' => 0], - ['email' => 'dayle@example.com', 'votes' => 0] - ]); + DB::table('users')->insert([ + ['email' => 'taylor@example.com', 'votes' => 0], + ['email' => 'dayle@example.com', 'votes' => 0] + ]); #### Auto-Incrementing IDs If the table has an auto-incrementing id, use the `insertGetId` method to insert a record and then retrieve the ID: - $id = DB::table('users')->insertGetId( - ['email' => 'john@example.com', 'votes' => 0] - ); + $id = DB::table('users')->insertGetId( + ['email' => 'john@example.com', 'votes' => 0] + ); > **Note:** When using PostgreSQL the insertGetId method expects the auto-incrementing column to be named `id`. If you would like to retrieve the ID from a different "sequence", you may pass the sequence name as the second parameter to the `insertGetId` method. @@ -389,9 +389,9 @@ If the table has an auto-incrementing id, use the `insertGetId` method to insert Of course, in addition to inserting records into the database, the query builder can also update existing records using the `update` method. The `update` method, like the `insert` method, accepts an array of column and value pairs containing the columns to be updated. You may constrain the `update` query using `where` clauses: - DB::table('users') - ->where('id', 1) - ->update(['votes' => 1]); + DB::table('users') + ->where('id', 1) + ->update(['votes' => 1]); #### Increment / Decrement @@ -399,40 +399,40 @@ The query builder also provides convenient methods for incrementing or decrement Both of these methods accept at least one argument: the column to modify. An second argument may optionally be passed to control the amount by which the column should be incremented / decremented. - DB::table('users')->increment('votes'); + DB::table('users')->increment('votes'); - DB::table('users')->increment('votes', 5); + DB::table('users')->increment('votes', 5); - DB::table('users')->decrement('votes'); + DB::table('users')->decrement('votes'); - DB::table('users')->decrement('votes', 5); + DB::table('users')->decrement('votes', 5); You may also specify additional columns to update during the operation: - DB::table('users')->increment('votes', 1, ['name' => 'John']); + DB::table('users')->increment('votes', 1, ['name' => 'John']); ## Deletes Of course, the query builder may also be used to delete records from the table via the `delete` method: - DB::table('users')->delete(); + DB::table('users')->delete(); You may constrain `delete` statements by adding `where` clauses before calling the `delete` method: - DB::table('users')->where('votes', '<', 100)->delete(); + DB::table('users')->where('votes', '<', 100)->delete(); If you wish to truncate the entire table, which will remove all rows and reset the auto-incrementing ID to zero, you may use the `truncate` method: - DB::table('users')->truncate(); + DB::table('users')->truncate(); ## Pessimistic Locking The query builder also includes a few functions to help you do "pessimistic locking" on your `select` statements. To run the statement with a "shared lock", you may use the `sharedLock` method on a query. A shared lock prevents the selected rows from being modified until your transaction commits: - DB::table('users')->where('votes', '>', 100)->sharedLock()->get(); + DB::table('users')->where('votes', '>', 100)->sharedLock()->get(); Alternatively, you may use the `lockForUpdate` method. A "for update" lock prevents the rows from being modified or from being selected with another shared lock: - DB::table('users')->where('votes', '>', 100)->lockForUpdate()->get(); + DB::table('users')->where('votes', '>', 100)->lockForUpdate()->get(); diff --git a/queues.md b/queues.md index 082e2a8868..1a937873ee 100644 --- a/queues.md +++ b/queues.md @@ -2,18 +2,18 @@ - [Introduction](#introduction) - [Writing Job Classes](#writing-job-classes) - - [Generating Job Classes](#generating-job-classes) - - [Job Class Structure](#job-class-structure) + - [Generating Job Classes](#generating-job-classes) + - [Job Class Structure](#job-class-structure) - [Pushing Jobs Onto The Queue](#pushing-jobs-onto-the-queue) - - [Delayed Jobs](#delayed-jobs) - - [Dispatching Jobs From Requests](#dispatching-jobs-from-requests) + - [Delayed Jobs](#delayed-jobs) + - [Dispatching Jobs From Requests](#dispatching-jobs-from-requests) - [Running The Queue Listener](#running-the-queue-listener) - - [Supervisor Configuration](#supervisor-configuration) - - [Daemon Queue Listener](#daemon-queue-listener) - - [Deploying With Daemon Queue Listeners](#deploying-with-daemon-queue-listeners) + - [Supervisor Configuration](#supervisor-configuration) + - [Daemon Queue Listener](#daemon-queue-listener) + - [Deploying With Daemon Queue Listeners](#deploying-with-daemon-queue-listeners) - [Dealing With Failed Jobs](#dealing-with-failed-jobs) - - [Failed Job Events](#failed-job-events) - - [Retrying Failed Jobs](#retrying-failed-jobs) + - [Failed Job Events](#failed-job-events) + - [Retrying Failed Jobs](#retrying-failed-jobs) ## Introduction @@ -33,9 +33,9 @@ A `null` queue driver is also included which simply discards queued jobs. In order to use the `database` queue driver, you will need a database table to hold the jobs. To generate a migration that creates this table, run the `queue:table` Artisan command. Once the migration is created, you may migrate your database using the `migrate` command: - php artisan queue:table + php artisan queue:table - php artisan migrate + php artisan migrate #### Other Queue Dependencies @@ -54,7 +54,7 @@ The following dependencies are needed for the listed queue drivers: By default, all of the queueable jobs for your application are stored in the `app/Jobs` directory. You may generate a new queued job using the Artisan CLI: - php artisan make:job SendReminderEmail --queued + php artisan make:job SendReminderEmail --queued This command will generate a new class in the `app/Jobs` directory, and the class will implement the `Illuminate\Contracts\Queue\ShouldQueue` interface, indicating to Laravel that the job should be pushed onto the queue instead of run synchronously. @@ -63,50 +63,50 @@ This command will generate a new class in the `app/Jobs` directory, and the clas Job classes are very simple, normally containing only a `handle` method which is called when the job is processed by the queue. To get started, let's take a look at an example job class: - user = $user; - } - - /** - * Execute the job. - * - * @param Mailer $mailer - * @return void - */ - public function handle(Mailer $mailer) - { - $mailer->send('emails.reminder', ['user' => $this->user], function ($m) { - // - }); - - $this->user->reminders()->create(...); - } - } + user = $user; + } + + /** + * Execute the job. + * + * @param Mailer $mailer + * @return void + */ + public function handle(Mailer $mailer) + { + $mailer->send('emails.reminder', ['user' => $this->user], function ($m) { + // + }); + + $this->user->reminders()->create(...); + } + } In this example, note that we were able to pass an [Eloquent model](/docs/{{version}}/eloquent) directly into the queued job's constructor. Because of the `SerializesModels` trait that the job is using, Eloquent models will be gracefully serialized and unserialized when the job is processing. If your queued job accepts an Eloquent model in its constructor, only the identifier for the model will be serialized onto the queue. When the job is actually handled, the queue system will automatically re-retrieve the full model instance from the database. It's all totally transparent to your application and prevents issues that can arise from serializing full Eloquent model instances. @@ -120,67 +120,67 @@ If an exception is thrown while the job is being processed, it will automaticall If you would like to `release` the job manually, the `InteractsWithQueue` trait, which is already included in your generated job class, provides access to the queue job `release` method. The `release` method accepts one argument: the number of seconds you wish to wait until the job is made available again: - public function handle(Mailer $mailer) - { - if (condition) { - $this->release(10); - } - } + public function handle(Mailer $mailer) + { + if (condition) { + $this->release(10); + } + } #### Checking The Number Of Run Attempts As noted above, if an exception occurs while the job is being processed, it will automatically be released back onto the queue. You may check the number of attempts that have been made to run the job using the `attempts` method: - public function handle(Mailer $mailer) - { - if ($this->attempts() > 3) { - // - } - } + public function handle(Mailer $mailer) + { + if ($this->attempts() > 3) { + // + } + } ## Pushing Jobs Onto The Queue The default Laravel controller located in `app/Http/Controllers/Controller.php` uses a `DispatchesJob` trait. This trait provides several methods allowing you to conveniently push jobs onto the queue, such as the `dispatch` method: - dispatch(new SendReminderEmail($user)); - } - } + $this->dispatch(new SendReminderEmail($user)); + } + } Of course, sometimes you may wish to dispatch a job from somewhere in your application besides a route or controller. For that reason, you can include the `DispatchesJobs` trait on any of the classes in your application to gain access to its various dispatch methods. For example, here is a sample class that uses the trait: - onQueue('emails'); + $job = (new SendReminderEmail($user))->onQueue('emails'); - $this->dispatch($job); - } - } + $this->dispatch($job); + } + } ### Delayed Jobs Sometimes you may wish to delay the execution of a queued job. For instance, you may wish to queue a job that sends a customer a reminder e-mail 15 minutes after sign-up. You may accomplish this using the `delay` method on your job class, which is provided by the `Illuminate\Bus\Queueable` trait: - delay(60); + $job = (new SendReminderEmail($user))->delay(60); - $this->dispatch($job); - } - } + $this->dispatch($job); + } + } In this example, we're specifying that the job should be delayed in the queue for 60 seconds before being made available to workers. @@ -258,37 +258,37 @@ In this example, we're specifying that the job should be delayed in the queue fo It is very common to map HTTP request variables into jobs. So, instead of forcing you to do this manually for each request, Laravel provides some helper methods to make it a cinch. Let's take a look at the `dispatchFrom` method available on the `DispatchesJobs` trait. By default, this trait is included on the base Laravel controller class: - dispatchFrom('App\Jobs\ProcessOrder', $request); - } - } + $this->dispatchFrom('App\Jobs\ProcessOrder', $request); + } + } This method will examine the constructor of the given job class and extract variables from the HTTP request (or any other `ArrayAccess` object) to fill the needed constructor parameters of the job. So, if our job class accepts a `productId` variable in its constructor, the job bus will attempt to pull the `productId` parameter from the HTTP request. You may also pass an array as the third argument to the `dispatchFrom` method. This array will be used to fill any constructor parameters that are not available on the request: - $this->dispatchFrom('App\Jobs\ProcessOrder', $request, [ - 'taxPercentage' => 20, - ]); + $this->dispatchFrom('App\Jobs\ProcessOrder', $request, [ + 'taxPercentage' => 20, + ]); ## Running The Queue Listener @@ -297,11 +297,11 @@ You may also pass an array as the third argument to the `dispatchFrom` method. T Laravel includes an Artisan command that will run new jobs as they are pushed onto the queue. You may run the listener using the `queue:listen` command: - php artisan queue:listen + php artisan queue:listen You may also specify which queue connection the listener should utilize: - php artisan queue:listen connection + php artisan queue:listen connection Note that once this task has started, it will continue to run until it is manually stopped. You may use a process monitor such as [Supervisor](http://supervisord.org/) to ensure that the queue listener does not stop running. @@ -309,7 +309,7 @@ Note that once this task has started, it will continue to run until it is manual You may pass a comma-delimited list of queue connections to the `listen` job to set queue priorities: - php artisan queue:listen --queue=high,low + php artisan queue:listen --queue=high,low In this example, jobs on the `high` queue will always be processed before moving onto jobs from the `low` queue. @@ -317,13 +317,13 @@ In this example, jobs on the `high` queue will always be processed before moving You may also set the length of time (in seconds) each job should be allowed to run: - php artisan queue:listen --timeout=60 + php artisan queue:listen --timeout=60 #### Specifying Queue Sleep Duration In addition, you may specify the number of seconds to wait before polling for new jobs: - php artisan queue:listen --sleep=5 + php artisan queue:listen --sleep=5 Note that the queue only "sleeps" if no jobs are on the queue. If more jobs are available, the queue will continue to work them without sleeping. @@ -332,27 +332,27 @@ Note that the queue only "sleeps" if no jobs are on the queue. If more jobs are Supervisor is a process monitor for the Linux operating system, and will automatically restart your `queue:listen` or `queue:work` commands if they fail. To install Supervisor on Ubuntu, you may use the following command: - sudo apt-get install supervisor + sudo apt-get install supervisor Supervisor configuration files are typically stored in the `/etc/supervisor/conf.d` directory. Within this directory, you may create any number of configuration files that instruct supervisor how your processes should be monitored. For example, let's create a `laravel-worker.conf` file that starts and monitors a `queue:work` process: - [program:laravel-worker] - process_name=%(program_name)s_%(process_num)02d - command=php /home/forge/app.com/artisan queue:work sqs --sleep=3 --tries=3 --daemon - autostart=true - autorestart=true - user=forge - numprocs=8 - redirect_stderr=true - stdout_logfile=/home/forge/app.com/worker.log + [program:laravel-worker] + process_name=%(program_name)s_%(process_num)02d + command=php /home/forge/app.com/artisan queue:work sqs --sleep=3 --tries=3 --daemon + autostart=true + autorestart=true + user=forge + numprocs=8 + redirect_stderr=true + stdout_logfile=/home/forge/app.com/worker.log In this example, the `numprocs` directive will instruct Supervisor to run 8 `queue:work` processes and monitor all of them, automatically restarting them if they fail. Once the configuration file has been created, you may update the Supervisor configuration and start the processes using the following commands: - sudo supervisorctl reread + sudo supervisorctl reread - sudo supervisorctl update + sudo supervisorctl update - sudo supervisorctl start laravel-worker:* + sudo supervisorctl start laravel-worker:* For more information on configuring and using Supervisor, consult the [Supervisor documentation](http://supervisord.org/index.html). Alternatively, you may use [Laravel Forge](https://forge.laravel.com) to automatically configure and manage your Supervisor configuration from a convenient web interface. @@ -363,11 +363,11 @@ The `queue:work` Artisan command includes a `--daemon` option for forcing the qu To start a queue worker in daemon mode, use the `--daemon` flag: - php artisan queue:work connection --daemon + php artisan queue:work connection --daemon - php artisan queue:work connection --daemon --sleep=3 + php artisan queue:work connection --daemon --sleep=3 - php artisan queue:work connection --daemon --sleep=3 --tries=3 + php artisan queue:work connection --daemon --sleep=3 --tries=3 As you can see, the `queue:work` job supports most of the same options available to `queue:listen`. You may use the `php artisan help queue:work` job to view all of the available options. @@ -382,7 +382,7 @@ Similarly, your database connection may disconnect when being used by long-runni Since daemon queue workers are long-lived processes, they will not pick up changes in your code without being restarted. So, the simplest way to deploy an application using daemon queue workers is to restart the workers during your deployment script. You may gracefully restart all of the workers by including the following command in your deployment script: - php artisan queue:restart + php artisan queue:restart This command will gracefully instruct all queue workers to restart after they finish processing their current job so that no existing jobs are lost. @@ -395,104 +395,104 @@ Since things don't always go as planned, sometimes your queued jobs will fail. D To create a migration for the `failed_jobs` table, you may use the `queue:failed-table` command: - php artisan queue:failed-table + php artisan queue:failed-table When running your [queue listener](#running-the-queue-listener), you may specify the maximum number of times a job should be attempted using the `--tries` switch on the `queue:listen` command: - php artisan queue:listen connection-name --tries=3 + php artisan queue:listen connection-name --tries=3 ### Failed Job Events If you would like to register an event that will be called when a queued job fails, you may use the `Queue::failing` method. This event is a great opportunity to notify your team via e-mail or [HipChat](https://www.hipchat.com). For example, we may attach a callback to this event from the `AppServiceProvider` that is included with Laravel: - ### Retrying Failed Jobs To view all of your failed jobs that have been inserted into your `failed_jobs` database table, you may use the `queue:failed` Artisan command: - php artisan queue:failed + php artisan queue:failed The `queue:failed` command will list the job ID, connection, queue, and failure time. The job ID may be used to retry the failed job. For instance, to retry a failed job that has an ID of 5, the following command should be issued: - php artisan queue:retry 5 + php artisan queue:retry 5 If you would like to delete a failed job, you may use the `queue:forget` command: - php artisan queue:forget 5 + php artisan queue:forget 5 To delete all of your failed jobs, you may use the `queue:flush` command: - php artisan queue:flush + php artisan queue:flush diff --git a/redis.md b/redis.md index 7bd64c43bd..678be5e4d1 100644 --- a/redis.md +++ b/redis.md @@ -2,7 +2,7 @@ - [Introduction](#introduction) - [Basic Usage](#basic-usage) - - [Pipelining Commands](#pipelining-commands) + - [Pipelining Commands](#pipelining-commands) - [Pub / Sub](#pubsub) @@ -42,59 +42,59 @@ If your Redis server requires authentication, you may supply a password by addin You may interact with Redis by calling various methods on the `Redis` [facade](/docs/{{version}}/facades). The `Redis` facade supports dynamic methods, meaning you may call any [Redis command](http://redis.io/commands) on the facade and the command will be passed directly to Redis. In this example, we will call the `GET` command on Redis by calling the `get` method on the `Redis` facade: - $user]); - } - } + return view('user.profile', ['user' => $user]); + } + } Of course, as mentioned above, you may call any of the Redis commands on the `Redis` facade. Laravel uses magic methods to pass the commands to the Redis server, so simply pass the arguments the Redis command expects: - Redis::set('name', 'Taylor'); + Redis::set('name', 'Taylor'); - $values = Redis::lrange('names', 5, 10); + $values = Redis::lrange('names', 5, 10); Alternatively, you may also pass commands to the server using the `command` method, which accepts the name of the command as its first argument, and an array of values as its second argument: - $values = Redis::command('lrange', [5, 10]); + $values = Redis::command('lrange', [5, 10]); #### Using Multiple Redis Connections You may get a Redis instance by calling the `Redis::connection` method: - $redis = Redis::connection(); + $redis = Redis::connection(); This will give you an instance of the default Redis server. If you are not using server clustering, you may pass the server name to the `connection` method to get a specific server as defined in your Redis configuration: - $redis = Redis::connection('other'); + $redis = Redis::connection('other'); ### Pipelining Commands Pipelining should be used when you need to send many commands to the server in one operation. The `pipeline` method accepts one argument: a `Closure` that receives a Redis instance. You may issue all of your commands to this Redis instance and they will all be executed within a single operation: - Redis::pipeline(function ($pipe) { - for ($i = 0; $i < 1000; $i++) { - $pipe->set("key:$i", $i); - } - }); + Redis::pipeline(function ($pipe) { + for ($i = 0; $i < 1000; $i++) { + $pipe->set("key:$i", $i); + } + }); ## Pub / Sub @@ -103,15 +103,15 @@ Laravel also provides a convenient interface to the Redis `publish` and `subscri First, let's setup a listener on a channel via Redis using the `subscribe` method. We will place this method call within an [Artisan command](/docs/{{version}}/commands) since calling the `subscribe` method begins a long-running process: - 'bar'])); - }); + Redis::publish('test-channel', json_encode(['foo' => 'bar'])); + }); #### Wildcard Subscriptions Using the `psubscribe` method, you may subscribe to a wildcard channel, which is useful for catching all messages on all channels. The `$channel` name will be passed as the second argument to the provided callback `Closure`: - Redis::psubscribe(['*'], function($message, $channel) { - echo $message; - }); + Redis::psubscribe(['*'], function($message, $channel) { + echo $message; + }); - Redis::psubscribe(['users.*'], function($message, $channel) { - echo $message; - }); + Redis::psubscribe(['users.*'], function($message, $channel) { + echo $message; + }); diff --git a/releases.md b/releases.md index e603ed231f..5fd92a0e7c 100644 --- a/releases.md +++ b/releases.md @@ -52,38 +52,38 @@ To learn more about event broadcasting, check out the [event documentation](/doc Middleware can now receive additional custom parameters. For example, if your application needs to verify that the authenticated user has a given "role" before performing a given action, you could create a `RoleMiddleware` that receives a role name as an additional argument: - user()->hasRole($role)) { - // Redirect... - } - - return $next($request); - } + class RoleMiddleware + { + /** + * Run the request filter. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @param string $role + * @return mixed + */ + public function handle($request, Closure $next, $role) + { + if (! $request->user()->hasRole($role)) { + // Redirect... + } + + return $next($request); + } - } + } Middleware parameters may be specified when defining the route by separating the middleware name and parameters with a `:`. Multiple parameters should be delimited by commas: - Route::put('post/{id}', ['middleware' => 'role:editor', function ($id) { - // - }]); + Route::put('post/{id}', ['middleware' => 'role:editor', function ($id) { + // + }]); For more information on middleware, check out the [middleware documentation](/docs/{{version}}/middleware). @@ -106,14 +106,14 @@ For more information on testing, check out the [testing documentation](/docs/{{v Laravel now ships with an easy way to create stub Eloquent models using [model factories](/docs/{{version}}/testing#model-factories). Model factories allow you to easily define a set of "default" attributes for your Eloquent model, and then generate test model instances for your tests or database seeds. Model factories also take advantage of the powerful [Faker](https://github.com/fzaninotto/Faker) PHP library for generating random attribute data: - $factory->define('App\User', function ($faker) { - return [ - 'name' => $faker->name, - 'email' => $faker->email, - 'password' => str_random(10), - 'remember_token' => str_random(10), - ]; - }); + $factory->define('App\User', function ($faker) { + return [ + 'name' => $faker->name, + 'email' => $faker->email, + 'password' => str_random(10), + 'remember_token' => str_random(10), + ]; + }); For more information on model factories, check out [the documentation](/docs/{{version}}/testing#model-factories). @@ -173,10 +173,10 @@ For more information on middleware, check out [the documentation](/docs/{{versio In addition to the existing constructor injection, you may now type-hint dependencies on controller methods. The [service container](/docs/{{version}}/container) will automatically inject the dependencies, even if the route contains other parameters: - public function createPost(Request $request, PostRepository $posts) - { - // - } + public function createPost(Request $request, PostRepository $posts) + { + // + } ### Authentication Scaffolding @@ -186,33 +186,33 @@ User registration, authentication, and password reset controllers are now includ You may now define events as objects instead of simply using strings. For example, check out the following event: - podcast = $podcast; - } - } + public function __construct(Podcast $podcast) + { + $this->podcast = $podcast; + } + } The event may be dispatched like normal: - Event::fire(new PodcastWasPurchased($podcast)); + Event::fire(new PodcastWasPurchased($podcast)); Of course, your event handler will receive the event object instead of a list of data: - user = $user; - $this->podcast = $podcast; - } - - /** - * Execute the command. - * - * @return void - */ - public function handle() - { - // Handle the logic to purchase the podcast... - - event(new PodcastWasPurchased($this->user, $this->podcast)); - } - } + user = $user; + $this->podcast = $podcast; + } + + /** + * Execute the command. + * + * @return void + */ + public function handle() + { + // Handle the logic to purchase the podcast... + + event(new PodcastWasPurchased($this->user, $this->podcast)); + } + } The base Laravel controller utilizes the new `DispatchesCommands` trait, allowing you to easily dispatch your commands for execution: - $this->dispatch(new PurchasePodcastCommand($user, $podcast)); + $this->dispatch(new PurchasePodcastCommand($user, $podcast)); Of course, you may also use commands for tasks that are executed synchronously (are not queued). In fact, using commands is a great way to encapsulate complex tasks your application needs to perform. For more information, check out the [command bus](/docs/{{version}}/bus) documentation. @@ -268,7 +268,7 @@ In the past, developers have generated a Cron entry for each console command the It looks like this: - $schedule->command('artisan:command')->dailyAt('15:00'); + $schedule->command('artisan:command')->dailyAt('15:00'); Of course, check out the [full documentation](/docs/{{version}}/scheduling) to learn all about the scheduler! @@ -276,7 +276,7 @@ Of course, check out the [full documentation](/docs/{{version}}/scheduling) to l The `php artisan tinker` command now utilizes [Psysh](https://github.com/bobthecow/psysh) by Justin Hileman, a more robust REPL for PHP. If you liked Boris in Laravel 4, you're going to love Psysh. Even better, it works on Windows! To get started, just try: - php artisan tinker + php artisan tinker ### DotEnv @@ -292,15 +292,15 @@ For more information on Elixir, check out the [full documentation](/docs/{{versi Laravel Socialite is an optional, Laravel 5.0+ compatible package that provides totally painless authentication with OAuth providers. Currently, Socialite supports Facebook, Twitter, Google, and GitHub. Here's what it looks like: - public function redirectForAuth() - { - return Socialize::with('twitter')->redirect(); - } + public function redirectForAuth() + { + return Socialize::with('twitter')->redirect(); + } - public function getUserFromProvider() - { - $user = Socialize::with('twitter')->user(); - } + public function getUserFromProvider() + { + $user = Socialize::with('twitter')->user(); + } No more spending hours writing OAuth authentication flows. Get started in minutes! The [full documentation](/docs/{{version}}/authentication#social-authentication) has all the details. @@ -308,7 +308,7 @@ No more spending hours writing OAuth authentication flows. Get started in minute Laravel now includes the powerful [Flysystem](https://github.com/thephpleague/flysystem) filesystem abstraction library, providing pain free integration with local, Amazon S3, and Rackspace cloud storage - all with one, unified and elegant API! Storing a file in Amazon S3 is now as simple as: - Storage::put('file.txt', 'contents'); + Storage::put('file.txt', 'contents'); For more information on the Laravel Flysystem integration, consult the [full documentation](/docs/{{version}}/filesystem). @@ -316,32 +316,32 @@ For more information on the Laravel Flysystem integration, consult the [full doc Laravel 5.0 introduces **form requests**, which extend the `Illuminate\Foundation\Http\FormRequest` class. These request objects can be combined with controller method injection to provide a boiler-plate free method of validating user input. Let's dig in and look at a sample `FormRequest`: - 'required|email|unique:users', - 'password' => 'required|confirmed|min:8', - ]; - } + namespace App\Http\Requests; - public function authorize() - { - return true; - } - } + class RegisterRequest extends FormRequest + { + public function rules() + { + return [ + 'email' => 'required|email|unique:users', + 'password' => 'required|confirmed|min:8', + ]; + } + + public function authorize() + { + return true; + } + } Once the class has been defined, we can type-hint it on our controller action: - public function register(RegisterRequest $request) - { - var_dump($request->input()); - } + public function register(RegisterRequest $request) + { + var_dump($request->input()); + } When the Laravel service container identifies that the class it is injecting is a `FormRequest` instance, the request will **automatically be validated**. This means that if your controller action is called, you can safely assume the HTTP request input has been validated according to the rules you specified in your form request class. Even more, if the request is invalid, an HTTP redirect, which you may customize, will automatically be issued, and the error messages will be either flashed to the session or converted to JSON. **Form validation has never been more simple.** For more information on `FormRequest` validation, check out the [documentation](/docs/{{version}}/validation#form-request-validation). @@ -349,13 +349,13 @@ When the Laravel service container identifies that the class it is injecting is The Laravel 5 base controller now includes a `ValidatesRequests` trait. This trait provides a simple `validate` method to validate incoming requests. If `FormRequests` are a little too much for your application, check this out: - public function createPost(Request $request) - { - $this->validate($request, [ - 'title' => 'required|max:255', - 'body' => 'required', - ]); - } + public function createPost(Request $request) + { + $this->validate($request, [ + 'title' => 'required|max:255', + 'body' => 'required', + ]); + } If the validation fails, an exception will be thrown and the proper HTTP response will automatically be sent back to the browser. The validation errors will even be flashed to the session! If the request was an AJAX request, Laravel even takes care of sending a JSON representation of the validation errors back to you. @@ -373,7 +373,7 @@ You may now cache all of your configuration in a single file using the `config:c The popular `dd` helper function, which dumps variable debug information, has been upgraded to use the amazing Symfony VarDumper. This provides color-coded output and even collapsing of arrays. Just try the following in your project: - dd([1, 2, 3]); + dd([1, 2, 3]); ## Laravel 4.2 diff --git a/requests.md b/requests.md index 5e5e29fd7f..1a378aaf5b 100644 --- a/requests.md +++ b/requests.md @@ -1,68 +1,68 @@ # HTTP Requests - [Accessing The Request](#accessing-the-request) - - [Basic Request Information](#basic-request-information) - - [PSR-7 Requests](#psr7-requests) + - [Basic Request Information](#basic-request-information) + - [PSR-7 Requests](#psr7-requests) - [Retrieving Input](#retrieving-input) - - [Old Input](#old-input) - - [Cookies](#cookies) - - [Files](#files) + - [Old Input](#old-input) + - [Cookies](#cookies) + - [Files](#files) ## Accessing The Request To obtain an instance of the current HTTP request via dependency injection, you should type-hint the `Illuminate\Http\Request` class on your controller constructor or method. The current request instance will automatically be injected by the [service container](/docs/{{version}}/container): - input('name'); + class UserController extends Controller + { + /** + * Store a new user. + * + * @param Request $request + * @return Response + */ + public function store(Request $request) + { + $name = $request->input('name'); - // - } - } + // + } + } If your controller method is also expecting input from a route parameter, simply list your route arguments after your other dependencies. For example, if your route is defined like so: - Route::put('user/{id}', 'UserController@update'); + Route::put('user/{id}', 'UserController@update'); You may still type-hint the `Illuminate\Http\Request` and access your route parameter `id` by defining your controller method like the following: - ### Basic Request Information @@ -73,44 +73,44 @@ The `Illuminate\Http\Request` instance provides a variety of methods for examini The `path` method returns the request's URI. So, if the incoming request is targeted at `http://domain.com/foo/bar`, the `path` method will return `foo/bar`: - $uri = $request->path(); + $uri = $request->path(); The `is` method allows you to verify that the incoming request URI matches a given pattern. You may use the `*` character as a wildcard when utilizing this method: - if ($request->is('admin/*')) { - // - } + if ($request->is('admin/*')) { + // + } To get the full URL, not just the path info, you may use the `url` method on the request instance: - $url = $request->url(); + $url = $request->url(); #### Retrieving The Request Method The `method` method will return the HTTP verb for the request. You may also use the `isMethod` method to verify that the HTTP verb matches a given string: - $method = $request->method(); + $method = $request->method(); - if ($request->isMethod('post')) { - // - } + if ($request->isMethod('post')) { + // + } ### PSR-7 Requests The PSR-7 standard specifies interfaces for HTTP messages, including requests and responses. If you would like to obtain an instance of a PSR-7 request, you will first need to install a few libraries. Laravel uses the Symfony HTTP Message Bridge component to convert typical Laravel requests and responses into PSR-7 compatible implementations: - composer require symfony/psr-http-message-bridge + composer require symfony/psr-http-message-bridge - composer require zendframework/zend-diactoros + composer require zendframework/zend-diactoros Once you have installed these libraries, you may obtain a PSR-7 request by simply type-hinting the request type on your route or controller: - use Psr\Http\Message\ServerRequestInterface; + use Psr\Http\Message\ServerRequestInterface; - Route::get('/', function (ServerRequestInterface $request) { - // - }); + Route::get('/', function (ServerRequestInterface $request) { + // + }); If you return a PSR-7 response instance from a route or controller, it will automatically be converted back to a Laravel response instance and be displayed by the framework. @@ -121,37 +121,37 @@ If you return a PSR-7 response instance from a route or controller, it will auto Using a few simple methods, you may access all user input from your `Illuminate\Http\Request` instance. You do not need to worry about the HTTP verb used for the request, as input is accessed in the same way for all verbs. - $name = $request->input('name'); + $name = $request->input('name'); You may pass a default value as the second argument to the `input` method. This value will be returned if the requested input value is not present on the request: - $name = $request->input('name', 'Sally'); + $name = $request->input('name', 'Sally'); When working on forms with array inputs, you may use "dot" notation to access the arrays: - $input = $request->input('products.0.name'); + $input = $request->input('products.0.name'); #### Determining If An Input Value Is Present To determine if a value is present on the request, you may use the `has` method. The `has` method returns `true` if the value is present **and** is not an empty string: - if ($request->has('name')) { - // - } + if ($request->has('name')) { + // + } #### Retrieving All Input Data You may also retrieve all of the input data as an `array` using the `all` method: - $input = $request->all(); + $input = $request->all(); #### Retrieving A Portion Of The Input Data If you need to retrieve a sub-set of the input data, you may use the `only` and `except` methods. Both of these methods accept a single `array` as their only argument: - $input = $request->only('username', 'password'); + $input = $request->only('username', 'password'); - $input = $request->except('credit_card'); + $input = $request->except('credit_card'); ### Old Input @@ -162,31 +162,31 @@ Laravel allows you to keep input from one request during the next request. This The `flash` method on the `Illuminate\Http\Request` instance will flash the current input to the [session](/docs/{{version}}/session) so that it is available during the user's next request to the application: - $request->flash(); + $request->flash(); You may also use the `flashOnly` and `flashExcept` methods to flash a sub-set of the request data into the session: - $request->flashOnly('username', 'email'); + $request->flashOnly('username', 'email'); - $request->flashExcept('password'); + $request->flashExcept('password'); #### Flash Input Into Session Then Redirect Since you often will want to flash input in association with a redirect to the previous page, you may easily chain input flashing onto a redirect using the `withInput` method: - return redirect('form')->withInput(); + return redirect('form')->withInput(); - return redirect('form')->withInput($request->except('password')); + return redirect('form')->withInput($request->except('password')); #### Retrieving Old Data To retrieve flashed input from the previous request, use the `old` method on the `Request` instance. The `old` method provides a convenient helper for pulling the flashed input data out of the [session](/docs/{{version}}/session): - $username = $request->old('username'); + $username = $request->old('username'); Laravel also provides a global `old` helper function. If you are displaying old input within a [Blade template](/docs/{{version}}/blade), it is more convenient to use the `old` helper: - {{ old('username') }} + {{ old('username') }} ### Cookies @@ -195,21 +195,21 @@ Laravel also provides a global `old` helper function. If you are displaying old All cookies created by the Laravel framework are encrypted and signed with an authentication code, meaning they will be considered invalid if they have been changed by the client. To retrieve a cookie value from the request, you may use the `cookie` method on the `Illuminate\Http\Request` instance: - $value = $request->cookie('name'); + $value = $request->cookie('name'); #### Attaching A New Cookie To A Response Laravel provides a global `cookie` helper function which serves as a simple factory for generating new `Symfony\Component\HttpFoundation\Cookie` instances. The cookies may be attached to a `Illuminate\Http\Response` instance using the `withCookie` method: - $response = new Illuminate\Http\Response('Hello World'); + $response = new Illuminate\Http\Response('Hello World'); - $response->withCookie(cookie('name', 'value', $minutes)); + $response->withCookie(cookie('name', 'value', $minutes)); - return $response; + return $response; To create a long-lived cookie, which lasts for five years, you may use the `forever` method on the cookie factory by first calling the `cookie` helper with no arguments, and then chaining the `forever` method onto the returned cookie factory: - $response->withCookie(cookie()->forever('name', 'value')); + $response->withCookie(cookie()->forever('name', 'value')); ### Files @@ -218,32 +218,32 @@ To create a long-lived cookie, which lasts for five years, you may use the `fore You may access uploaded files that are included with the `Illuminate\Http\Request` instance using the `file` method. The object returned by the `file` method is an instance of the `Symfony\Component\HttpFoundation\File\UploadedFile` class, which extends the PHP `SplFileInfo` class and provides a variety of methods for interacting with the file: - $file = $request->file('photo'); + $file = $request->file('photo'); #### Verifying File Presence You may also determine if a file is present on the request using the `hasFile` method: - if ($request->hasFile('photo')) { - // - } + if ($request->hasFile('photo')) { + // + } #### Validating Successful Uploads In addition to checking if the file is present, you may verify that there were no problems uploading the file via the `isValid` method: - if ($request->file('photo')->isValid()) - { - // - } + if ($request->file('photo')->isValid()) + { + // + } #### Moving Uploaded Files To move the uploaded file to a new location, you should use the `move` method. This method will move the file from its temporary upload location (as determined by your PHP configuration) to a more permanent destination of your choosing: - $request->file('photo')->move($destinationPath); + $request->file('photo')->move($destinationPath); - $request->file('photo')->move($destinationPath, $fileName); + $request->file('photo')->move($destinationPath, $fileName); #### Other File Methods diff --git a/responses.md b/responses.md index 0493545924..3a1632c060 100644 --- a/responses.md +++ b/responses.md @@ -1,16 +1,16 @@ # HTTP Responses - [Basic Responses](#basic-responses) - - [Attaching Headers To Responses](#attaching-headers-to-responses) - - [Attaching Cookies To Responses](#attaching-cookies-to-responses) + - [Attaching Headers To Responses](#attaching-headers-to-responses) + - [Attaching Cookies To Responses](#attaching-cookies-to-responses) - [Other Response Types](#other-response-types) - - [View Responses](#view-responses) - - [JSON Responses](#json-responses) - - [File Downloads](#file-downloads) + - [View Responses](#view-responses) + - [JSON Responses](#json-responses) + - [File Downloads](#file-downloads) - [Redirects](#redirects) - - [Redirecting To Named Routes](#redirecting-named-routes) - - [Redirecting To Controller Actions](#redirecting-controller-actions) - - [Redirecting With Flashed Session Data](#redirecting-with-flashed-session-data) + - [Redirecting To Named Routes](#redirecting-named-routes) + - [Redirecting To Controller Actions](#redirecting-controller-actions) + - [Redirecting With Flashed Session Data](#redirecting-with-flashed-session-data) - [Response Macros](#response-macros) @@ -18,27 +18,27 @@ Of course, all routes and controllers should return some kind of response to be sent back to the user's browser. Laravel provides several different ways to return responses. The most basic response is simply returning a string from a route or controller: - Route::get('/', function () { - return 'Hello World'; - }); + Route::get('/', function () { + return 'Hello World'; + }); The given string will automatically be converted into an HTTP response by the framework. However, for most routes and controller actions, you will be returning a full `Illuminate\Http\Response` instance or a [view](/docs/{{version}}/views). Returning a full `Response` instance allows you to customize the response's HTTP status code and headers. A `Response` instance inherits from the `Symfony\Component\HttpFoundation\Response` class, providing a variety of methods for building HTTP responses: - use Illuminate\Http\Response; + use Illuminate\Http\Response; - Route::get('home', function () { - return (new Response($content, $status)) - ->header('Content-Type', $value); - }); + Route::get('home', function () { + return (new Response($content, $status)) + ->header('Content-Type', $value); + }); For convenience, you may also use the `response` helper: - Route::get('home', function () { - return response($content, $status) - ->header('Content-Type', $value); - }); + Route::get('home', function () { + return response($content, $status) + ->header('Content-Type', $value); + }); > **Note:** For a full list of available `Response` methods, check out its [API documentation](http://laravel.com/api/master/Illuminate/Http/Response.html) and the [Symfony API documentation](http://api.symfony.com/2.7/Symfony/Component/HttpFoundation/Response.html). @@ -47,10 +47,10 @@ For convenience, you may also use the `response` helper: Keep in mind that most response methods are chainable, allowing for the fluent building of responses. For example, you may use the `header` method to add a series of headers to the response before sending it back to the user: - return response($content) - ->header('Content-Type', $type) - ->header('X-Header-One', 'Header Value') - ->header('X-Header-Two', 'Header Value'); + return response($content) + ->header('Content-Type', $type) + ->header('X-Header-One', 'Header Value') + ->header('X-Header-Two', 'Header Value'); @@ -58,12 +58,12 @@ Keep in mind that most response methods are chainable, allowing for the fluent b The `withCookie` helper method on the response instance allows you to easily attach cookies to the response. For example, you may use the `withCookie` method to generate a cookie and attach it to the response instance: - return response($content)->header('Content-Type', $type) + return response($content)->header('Content-Type', $type) ->withCookie('name', 'value'); The `withCookie` method accepts additional optional arguments which allow you to further customize your cookie's properties: - ->withCookie($name, $value, $minutes, $path, $domain, $secure, $httpOnly) + ->withCookie($name, $value, $minutes, $path, $domain, $secure, $httpOnly) By default, all cookies generated by Laravel are encrypted and signed so that they can't be modified or read by the client. If you would like to disable encryption for a certain subset of cookies generated by your application, you may use the `$except` property of the `App\Http\Middleware\EncryptCookies` middleware: @@ -86,7 +86,7 @@ The `response` helper may be used to conveniently generate other types of respon If you need control over the response status and headers, but also need to return a [view](/docs/{{version}}/views) as the response content, you may use the `view` method: - return response()->view('hello', $data)->header('Content-Type', $type); + return response()->view('hello', $data)->header('Content-Type', $type); Of course, if you do not need to pass a custom HTTP status code or custom headers, you may simply use the global `view` helper function. @@ -95,21 +95,21 @@ Of course, if you do not need to pass a custom HTTP status code or custom header The `json` method will automatically set the `Content-Type` header to `application/json`, as well as convert the given array into JSON using the `json_encode` PHP function: - return response()->json(['name' => 'Abigail', 'state' => 'CA']); + return response()->json(['name' => 'Abigail', 'state' => 'CA']); If you would like to create a JSONP response, you may use the `json` method in addition to `setCallback`: - return response()->json(['name' => 'Abigail', 'state' => 'CA']) - ->setCallback($request->input('callback')); + return response()->json(['name' => 'Abigail', 'state' => 'CA']) + ->setCallback($request->input('callback')); #### File Downloads The `download` method may be used to generate a response that forces the user's browser to download the file at the given path. The `download` method accepts a file name as the second argument to the method, which will determine the file name that is seen by the user downloading the file. Finally, you may pass an array of HTTP headers as the third argument to the method: - return response()->download($pathToFile); + return response()->download($pathToFile); - return response()->download($pathToFile, $name, $headers); + return response()->download($pathToFile, $name, $headers); > **Note:** Symfony HttpFoundation, which manages file downloads, requires the file being downloaded to have an ASCII file name. @@ -118,64 +118,64 @@ The `download` method may be used to generate a response that forces the user's Redirect responses are instances of the `Illuminate\Http\RedirectResponse` class, and contain the proper headers needed to redirect the user to another URL. There are several ways to generate a `RedirectResponse` instance. The simplest method is to use the global `redirect` helper method: - Route::get('dashboard', function () { - return redirect('home/dashboard'); - }); + Route::get('dashboard', function () { + return redirect('home/dashboard'); + }); Sometimes you may wish to redirect the user to their previous location, for example, after a form submission that is invalid. You may do so by using the global `back` helper function: - Route::post('user/profile', function () { - // Validate the request... + Route::post('user/profile', function () { + // Validate the request... - return back()->withInput(); - }); + return back()->withInput(); + }); #### Redirecting To Named Routes When you call the `redirect` helper with no parameters, an instance of `Illuminate\Routing\Redirector` is returned, allowing you to call any method on the `Redirector` instance. For example, to generate a `RedirectResponse` to a named route, you may use the `route` method: - return redirect()->route('login'); + return redirect()->route('login'); If your route has parameters, you may pass them as the second argument to the `route` method: - // For a route with the following URI: profile/{id} + // For a route with the following URI: profile/{id} - return redirect()->route('profile', [1]); + return redirect()->route('profile', [1]); If you are redirecting to a route with an "ID" parameter that is being populated from an Eloquent model, you may simply pass the model itself. The ID will be extracted automatically: - return redirect()->route('profile', [$user]); + return redirect()->route('profile', [$user]); #### Redirecting To Controller Actions You may also generate redirects to [controller actions](/docs/{{version}}/controllers). To do so, simply pass the controller and action name to the `action` method. Remember, you do not need to specify the full namespace to the controller since Laravel's `RouteServiceProvider` will automatically set the default controller namespace: - return redirect()->action('HomeController@index'); + return redirect()->action('HomeController@index'); Of course, if your controller route requires parameters, you may pass them as the second argument to the `action` method: - return redirect()->action('UserController@profile', [1]); + return redirect()->action('UserController@profile', [1]); #### Redirecting With Flashed Session Data Redirecting to a new URL and [flashing data to the session](/docs/{{version}}/session#flash-data) are typically done at the same time. So, for convenience, you may create a `RedirectResponse` instance **and** flash data to the session in a single method chain. This is particularly convenient for storing status messages after an action: - Route::post('user/profile', function () { - // Update the user's profile... + Route::post('user/profile', function () { + // Update the user's profile... - return redirect('dashboard')->with('status', 'Profile updated!'); - }); + return redirect('dashboard')->with('status', 'Profile updated!'); + }); Of course, after the user is redirected to a new page, you may retrieve and display the flashed message from the [session](/docs/{{version}}/session). For example, using [Blade syntax](/docs/{{version}}/blade): - @if (session('status')) -
    - {{ session('status') }} -
    - @endif + @if (session('status')) +
    + {{ session('status') }} +
    + @endif ## Response Macros @@ -184,29 +184,29 @@ If you would like to define a custom response that you can re-use in a variety o For example, from a [service provider's](/docs/{{version}}/providers) `boot` method: - macro('caps', function ($value) use ($factory) { - return $factory->make(strtoupper($value)); - }); - } - } + macro('caps', function ($value) use ($factory) { + return $factory->make(strtoupper($value)); + }); + } + } The `macro` function accepts a name as its first argument, and a Closure as its second. The macro's Closure will be executed when calling the macro name from a `ResponseFactory` implementation or the `response` helper: - return response()->caps('foo'); + return response()->caps('foo'); diff --git a/routing.md b/routing.md index 2702646440..dfca6f4422 100644 --- a/routing.md +++ b/routing.md @@ -2,20 +2,20 @@ - [Basic Routing](#basic-routing) - [Route Parameters](#route-parameters) - - [Required Parameters](#required-parameters) - - [Optional Parameters](#parameters-optional-parameters) - - [Regular Expression Constraints](#parameters-regular-expression-constraints) + - [Required Parameters](#required-parameters) + - [Optional Parameters](#parameters-optional-parameters) + - [Regular Expression Constraints](#parameters-regular-expression-constraints) - [Named Routes](#named-routes) - [Route Groups](#route-groups) - - [Middleware](#route-group-middleware) - - [Namespaces](#route-group-namespaces) - - [Sub-Domain Routing](#route-group-sub-domain-routing) - - [Route Prefixes](#route-group-prefixes) + - [Middleware](#route-group-middleware) + - [Namespaces](#route-group-namespaces) + - [Sub-Domain Routing](#route-group-sub-domain-routing) + - [Route Prefixes](#route-group-prefixes) - [CSRF Protection](#csrf-protection) - - [Introduction](#csrf-introduction) - - [Excluding URIs](#csrf-excluding-uris) - - [X-CSRF-Token](#csrf-x-csrf-token) - - [X-XSRF-Token](#csrf-x-xsrf-token) + - [Introduction](#csrf-introduction) + - [Excluding URIs](#csrf-excluding-uris) + - [X-CSRF-Token](#csrf-x-csrf-token) + - [X-XSRF-Token](#csrf-x-xsrf-token) - [Form Method Spoofing](#form-method-spoofing) - [Throwing 404 Errors](#throwing-404-errors) @@ -24,41 +24,41 @@ You will define most of the routes for your application in the `app/Http/routes.php` file, which is loaded by the `App\Providers\RouteServiceProvider` class. The most basic Laravel routes simply accept a URI and a `Closure`: - Route::get('/', function () { - return 'Hello World'; - }); + Route::get('/', function () { + return 'Hello World'; + }); - Route::post('foo/bar', function () { - return 'Hello World'; - }); + Route::post('foo/bar', function () { + return 'Hello World'; + }); - Route::put('foo/bar', function () { - // - }); + Route::put('foo/bar', function () { + // + }); - Route::delete('foo/bar', function () { - // - }); + Route::delete('foo/bar', function () { + // + }); #### Registering A Route For Multiple Verbs Sometimes you may need to register a route that responds to multiple HTTP verbs. You may do so using the `match` method on the `Route` [facade](/docs/{{version}}/facades): - Route::match(['get', 'post'], '/', function () { - return 'Hello World'; - }); + Route::match(['get', 'post'], '/', function () { + return 'Hello World'; + }); Or, you may even register a route that responds to all HTTP verbs using the `any` method: - Route::any('foo', function () { - return 'Hello World'; - }); + Route::any('foo', function () { + return 'Hello World'; + }); #### Generating URLs To Routes You may generate URLs to your application's routes using the `url` helper: - $url = url('foo'); + $url = url('foo'); ## Route Parameters @@ -68,15 +68,15 @@ You may generate URLs to your application's routes using the `url` helper: Of course, sometimes you will need to capture segments of the URI within your route. For example, you may need to capture a user's ID from the URL. You may do so by defining route parameters: - Route::get('user/{id}', function ($id) { - return 'User '.$id; - }); + Route::get('user/{id}', function ($id) { + return 'User '.$id; + }); You may define as many route parameters as required by your route: - Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) { - // - }); + Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) { + // + }); Route parameters are always encased within "curly" braces. The parameters will be passed into your route's `Closure` when the route is executed. @@ -87,33 +87,33 @@ Route parameters are always encased within "curly" braces. The parameters will b Occasionally you may need to specify a route parameter, but make the presence of that route parameter optional. You may do so by placing a `?` mark after the parameter name: - Route::get('user/{name?}', function ($name = null) { - return $name; - }); + Route::get('user/{name?}', function ($name = null) { + return $name; + }); - Route::get('user/{name?}', function ($name = 'John') { - return $name; - }); + Route::get('user/{name?}', function ($name = 'John') { + return $name; + }); ### Regular Expression Constraints You may constrain the format of your route parameters using the `where` method on a route instance. The `where` method accepts the name of the parameter and a regular expression defining how the parameter should be constrained: - Route::get('user/{name}', function ($name) { - // - }) - ->where('name', '[A-Za-z]+'); + Route::get('user/{name}', function ($name) { + // + }) + ->where('name', '[A-Za-z]+'); - Route::get('user/{id}', function ($id) { - // - }) - ->where('id', '[0-9]+'); + Route::get('user/{id}', function ($id) { + // + }) + ->where('id', '[0-9]+'); - Route::get('user/{id}/{name}', function ($id, $name) { - // - }) - ->where(['id' => '[0-9]+', 'name' => '[a-z]+']); + Route::get('user/{id}/{name}', function ($id, $name) { + // + }) + ->where(['id' => '[0-9]+', 'name' => '[a-z]+']); #### Global Constraints @@ -128,57 +128,57 @@ If you would like a route parameter to always be constrained by a given regular */ public function boot(Router $router) { - $router->pattern('id', '[0-9]+'); + $router->pattern('id', '[0-9]+'); parent::boot($router); } Once the pattern has been defined, it is automatically applied to all routes using that parameter name: - Route::get('user/{id}', function ($id) { - // Only called if {id} is numeric. - }); + Route::get('user/{id}', function ($id) { + // Only called if {id} is numeric. + }); ## Named Routes Named routes allow you to conveniently generate URLs or redirects for a specific route. You may specify a name for a route using the `as` array key when defining the route: - Route::get('user/profile', ['as' => 'profile', function () { - // - }]); + Route::get('user/profile', ['as' => 'profile', function () { + // + }]); You may also specify route names for controller actions: - Route::get('user/profile', [ - 'as' => 'profile', 'uses' => 'UserController@showProfile' - ]); + Route::get('user/profile', [ + 'as' => 'profile', 'uses' => 'UserController@showProfile' + ]); #### Route Groups & Named Routes If you are using [route groups](#route-groups), you may specify an `as` keyword in the route group attribute array, allowing you to set a common route name prefix for all routes within the group: - Route::group(['as' => 'admin::'], function () { - Route::get('dashboard', ['as' => 'dashboard', function () { - // Route named "admin::dashboard" - }]); - }); + Route::group(['as' => 'admin::'], function () { + Route::get('dashboard', ['as' => 'dashboard', function () { + // Route named "admin::dashboard" + }]); + }); #### Generating URLs To Named Routes Once you have assigned a name to a given route, you may use the route's name when generating URLs or redirects via the `route` function: - $url = route('profile'); + $url = route('profile'); - $redirect = redirect()->route('profile'); + $redirect = redirect()->route('profile'); If the route defines parameters, you may pass the parameters as the second argument to the `route` method. The given parameters will automatically be inserted into the URL: - Route::get('user/{id}/profile', ['as' => 'profile', function ($id) { - // - }]); + Route::get('user/{id}/profile', ['as' => 'profile', function ($id) { + // + }]); - $url = route('profile', ['id' => 1]); + $url = route('profile', ['id' => 1]); ## Route Groups @@ -192,30 +192,30 @@ To learn more about route groups, we'll walk through several common use-cases fo To assign middleware to all routes within a group, you may use the `middleware` key in the group attribute array. Middleware will be executed in the order you define this array: - Route::group(['middleware' => 'auth'], function () { - Route::get('/', function () { - // Uses Auth Middleware - }); + Route::group(['middleware' => 'auth'], function () { + Route::get('/', function () { + // Uses Auth Middleware + }); - Route::get('user/profile', function () { - // Uses Auth Middleware - }); - }); + Route::get('user/profile', function () { + // Uses Auth Middleware + }); + }); ### Namespaces Another common use-case for route groups is assigning the same PHP namespace to a group of controllers. You may use the `namespace` parameter in your group attribute array to specify the namespace for all controllers within the group: - Route::group(['namespace' => 'Admin'], function() - { - // Controllers Within The "App\Http\Controllers\Admin" Namespace + Route::group(['namespace' => 'Admin'], function() + { + // Controllers Within The "App\Http\Controllers\Admin" Namespace - Route::group(['namespace' => 'User'], function() - { - // Controllers Within The "App\Http\Controllers\Admin\User" Namespace - }); - }); + Route::group(['namespace' => 'User'], function() + { + // Controllers Within The "App\Http\Controllers\Admin\User" Namespace + }); + }); Remember, by default, the `RouteServiceProvider` includes your `routes.php` file within a namespace group, allowing you to register controller routes without specifying the full `App\Http\Controllers` namespace prefix. So, we only need to specify the portion of the namespace that comes after the base `App\Http\Controllers` namespace root. @@ -224,30 +224,30 @@ Remember, by default, the `RouteServiceProvider` includes your `routes.php` file Route groups may also be used to route wildcard sub-domains. Sub-domains may be assigned route parameters just like route URIs, allowing you to capture a portion of the sub-domain for usage in your route or controller. The sub-domain may be specified using the `domain` key on the group attribute array: - Route::group(['domain' => '{account}.myapp.com'], function () { - Route::get('user/{id}', function ($account, $id) { - // - }); - }); + Route::group(['domain' => '{account}.myapp.com'], function () { + Route::get('user/{id}', function ($account, $id) { + // + }); + }); ### Route Prefixes The `prefix` group array attribute may be used to prefix each route in the group with a given URI. For example, you may want to prefix all route URIs within the group with `admin`: - Route::group(['prefix' => 'admin'], function () { - Route::get('users', function () { - // Matches The "/admin/users" URL - }); - }); + Route::group(['prefix' => 'admin'], function () { + Route::get('users', function () { + // Matches The "/admin/users" URL + }); + }); You may also use the `prefix` parameter to specify common parameters for your grouped routes: - Route::group(['prefix' => 'accounts/{account_id}'], function () { - Route::get('detail', function ($account_id) { - // Matches The accounts/{account_id}/detail URL - }); - }); + Route::group(['prefix' => 'accounts/{account_id}'], function () { + Route::get('detail', function ($account_id) { + // Matches The accounts/{account_id}/detail URL + }); + }); ## CSRF Protection @@ -259,15 +259,15 @@ Laravel makes it easy to protect your application from [cross-site request forge Laravel automatically generates a CSRF "token" for each active user session managed by the application. This token is used to verify that the authenticated user is the one actually making the requests to the application. To generate a hidden input field `_token` containing the CSRF token, you may use the `csrf_field` helper function: - + The `csrf_field` helper function generates the following HTML: - + Of course, using the Blade [templating engine](/docs/{{version}}/blade): - {!! csrf_field() !!} + {!! csrf_field() !!} You do not need to manually verify the CSRF token on POST, PUT, or DELETE requests. The `VerifyCsrfToken` [HTTP middleware](/docs/{{version}}/middleware) will verify token in the request input matches the token stored in the session. @@ -278,38 +278,38 @@ Sometimes you may wish to exclude a set of URIs from CSRF protection. For exampl You may exclude URIs by adding them to the `$except` property of the `VerifyCsrfToken` middleware: - ### X-CSRF-TOKEN In addition to checking for the CSRF token as a POST parameter, the Laravel `VerifyCsrfToken` middleware will also check for the `X-CSRF-TOKEN` request header. You could, for example, store the token in a "meta" tag: - + Once you have created the `meta` tag, you can instruct a library like jQuery to add the token to all request headers. This provides simple, convenient CSRF protection for your AJAX based applications: - $.ajaxSetup({ - headers: { - 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') - } - }); + $.ajaxSetup({ + headers: { + 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') + } + }); ### X-XSRF-TOKEN @@ -321,17 +321,17 @@ Laravel also stores the CSRF token in a `XSRF-TOKEN` cookie. You can use the coo HTML forms do not support `PUT`, `PATCH` or `DELETE` actions. So, when defining `PUT`, `PATCH` or `DELETE` routes that are called from an HTML form, you will need to add a hidden `_method` field to the form. The value sent with the `_method` field will be used as the HTTP request method: -
    - - -
    +
    + + +
    ## Throwing 404 Errors There are two ways to manually trigger a 404 error from a route. First, you may use the `abort` helper. The `abort` helper simply throws a `Symfony\Component\HttpFoundation\Exception\HttpException` with the specified status code: - abort(404); + abort(404); Secondly, you may manually throw an instance of `Symfony\Component\HttpKernel\Exception\NotFoundHttpException`. diff --git a/scheduling.md b/scheduling.md index 46910f0936..b6f3ae7421 100644 --- a/scheduling.md +++ b/scheduling.md @@ -2,8 +2,8 @@ - [Introduction](#introduction) - [Defining Schedules](#defining-schedules) - - [Schedule Frequency Options](#schedule-frequency-options) - - [Preventing Task Overlaps](#preventing-task-overlaps) + - [Schedule Frequency Options](#schedule-frequency-options) + - [Preventing Task Overlaps](#preventing-task-overlaps) - [Task Output](#task-output) - [Task Hooks](#task-hooks) @@ -18,7 +18,7 @@ Your task schedule is defined in the `app/Console/Kernel.php` file's `schedule` Here is the only Cron entry you need to add to your server: - * * * * * php /path/to/artisan schedule:run 1>> /dev/null 2>&1 + * * * * * php /path/to/artisan schedule:run 1>> /dev/null 2>&1 This Cron will call the Laravel command scheduler every minute. Then, Laravel evaluates your scheduled tasks and runs the tasks that are due. @@ -27,38 +27,38 @@ This Cron will call the Laravel command scheduler every minute. Then, Laravel ev You may define all of your scheduled tasks in the `schedule` method of the `App\Console\Kernel` class. To get started, let's look at an example of scheduling a task. In this example, we will schedule a `Closure` to be called every day at midnight. Within the `Closure` we will execute a database query to clear a table: - call(function () { - DB::table('recent_users')->delete(); - })->daily(); - } - } + call(function () { + DB::table('recent_users')->delete(); + })->daily(); + } + } In addition to scheduling `Closure` calls, you may also schedule [Artisan commands](/docs/{{version}}/artisan) and operating system commands. For example, you may use the `command` method to schedule an Artisan command: @@ -89,9 +89,9 @@ Method | Description These methods may be combined with additional constraints to create even more finely tuned schedules that only run on certain days of the week. For example, to schedule a command to run weekly on Monday: - $schedule->call(function () { - // Runs once a week on Monday at 13:00... - })->weekly()->mondays()->at('13:00'); + $schedule->call(function () { + // Runs once a week on Monday at 13:00... + })->weekly()->mondays()->at('13:00'); Below is a list of the additional schedule constraints: @@ -111,16 +111,16 @@ Method | Description The `when` method may be used to limit the execution of a task based on the result of a given truth test. In other words, if the given `Closure` return `true`, the task will execute as long as no other constraining conditions prevent the task from running: - $schedule->command('emails:send')->daily()->when(function () { - return true; - }); + $schedule->command('emails:send')->daily()->when(function () { + return true; + }); ### Preventing Task Overlaps By default, scheduled tasks will be run even if the previous instance of the task is still running. To prevent this, you may use the `withoutOverlapping` method: - $schedule->command('emails:send')->withoutOverlapping(); + $schedule->command('emails:send')->withoutOverlapping(); In this example, the `emails:send` [Artisan command](/docs/{{version}}/artisan) will be run every minute if it is not already running. The `withoutOverlapping` method is especially useful if you have tasks that vary drastically in their execution time, preventing you from predicting exactly how long a given task will take. @@ -129,16 +129,16 @@ In this example, the `emails:send` [Artisan command](/docs/{{version}}/artisan) The Laravel scheduler provides several convenient methods for working with the output generated by scheduled tasks. First, using the `sendOutputTo` method, you may send the output to a file for later inspection: - $schedule->command('emails:send') - ->daily() - ->sendOutputTo($filePath); + $schedule->command('emails:send') + ->daily() + ->sendOutputTo($filePath); Using the `emailOutputTo` method, you may e-mail the output to an e-mail address of your choice. Note that the output must first be sent to a file using the `sendOutputTo` method. Also, before e-mailing the output of a task, you should configure Laravel's [e-mail services](/docs/{{version}}/mail): - $schedule->command('foo') - ->daily() - ->sendOutputTo($filePath) - ->emailOutputTo('foo@example.com'); + $schedule->command('foo') + ->daily() + ->sendOutputTo($filePath) + ->emailOutputTo('foo@example.com'); > **Note:** The `emailOutputTo` and `sendOutputTo` methods are exclusive to the `command` method and are not supported for `call`. @@ -147,24 +147,24 @@ Using the `emailOutputTo` method, you may e-mail the output to an e-mail address Using the `before` and `after` methods, you may specify code to be executed before and after the scheduled task is complete: - $schedule->command('emails:send') - ->daily() - ->before(function () { - // Task is about to start... - }) - ->after(function () { - // Task is complete... - }); + $schedule->command('emails:send') + ->daily() + ->before(function () { + // Task is about to start... + }) + ->after(function () { + // Task is complete... + }); #### Pinging URLs Using the `pingBefore` and `thenPing` methods, the scheduler can automatically ping a given URL before or after a task is complete. This method is useful for notifying an external service, such as [Laravel Envoyer](https://envoyer.io), that your scheduled task is commencing or complete: - $schedule->command('emails:send') - ->daily() - ->pingBefore($url) - ->thenPing($url); + $schedule->command('emails:send') + ->daily() + ->pingBefore($url) + ->thenPing($url); Using either the `pingBefore($url)` or `thenPing($url)` feature requires the Guzzle HTTP library. You can add Guzzle to your project by adding the following line to your `composer.json` file: - "guzzlehttp/guzzle": "~5.3|~6.0" + "guzzlehttp/guzzle": "~5.3|~6.0" diff --git a/seeding.md b/seeding.md index ba5fb02e50..17d5e38068 100644 --- a/seeding.md +++ b/seeding.md @@ -2,8 +2,8 @@ - [Introduction](#introduction) - [Writing Seeders](#writing-seeders) - - [Using Model Factories](#using-model-factories) - - [Calling Additional Seeders](#calling-additional-seeders) + - [Using Model Factories](#using-model-factories) + - [Calling Additional Seeders](#calling-additional-seeders) - [Running Seeders](#running-seeders) @@ -16,34 +16,34 @@ Laravel includes a simple method of seeding your database with test data using s To generate a seeder, you may issue the `make:seeder` [Artisan command](/docs/{{version}}/artisan). All seeders generated by the framework will be placed in the `database/seeders` directory: - php artisan make:seeder UserTableSeeder + php artisan make:seeder UserTableSeeder A seeder class only contains one method by default: `run`. This method is called when the `db:seed` [Artisan command](/docs/{{version}}/artisan) is executed. Within the `run` method, you may insert data into your database however you wish. You may use the [query builder](/docs/{{version}}/queries) to manually insert data or you may use [Eloquent model factories](/docs/{{version}}/testing#model-factories). As an example, let's modify the `DatabaseSeeder` class which is included with a default installation of Laravel. Let's add a database insert statement to the `run` method: - insert([ - 'name' => str_random(10), - 'email' => str_random(10).'@gmail.com', - 'password' => bcrypt('secret'), - ]); - } - } + insert([ + 'name' => str_random(10), + 'email' => str_random(10).'@gmail.com', + 'password' => bcrypt('secret'), + ]); + } + } ### Using Model Factories @@ -60,7 +60,7 @@ For example, let's create 50 users and attach a relationship to each user: public function run() { factory('App\User', 50)->create()->each(function($u) { - $u->posts()->save(factory('App\Post')->make()); + $u->posts()->save(factory('App\Post')->make()); }); } @@ -88,10 +88,10 @@ Within the `DatabaseSeeder` class, you may use the `call` method to execute addi Once you have written your seeder classes, you may use the `db:seed` Artisan command to seed your database. By default, the `db:seed` command runs the `DatabaseSeeder` class, which may be used to call other seed classes. However, you may use the `--class` option to specify a specific seeder class to run individually: - php artisan db:seed + php artisan db:seed - php artisan db:seed --class=UserTableSeeder + php artisan db:seed --class=UserTableSeeder You may also seed your database using the `migrate:refresh` command, which will also rollback and re-run all of your migrations. This command is useful for completely re-building your database: - php artisan migrate:refresh --seed + php artisan migrate:refresh --seed diff --git a/session.md b/session.md index 2b9cce189c..fec1a5f96c 100644 --- a/session.md +++ b/session.md @@ -2,7 +2,7 @@ - [Introduction](#introduction) - [Basic Usage](#basic-usage) - - [Flash Data](#flash-data) + - [Flash Data](#flash-data) - [Adding Custom Session Drivers](#adding-custom-session-drivers) @@ -32,19 +32,19 @@ The session `driver` defines where session data will be stored for each request. When using the `database` session driver, you will need to setup a table to contain the session items. Below is an example `Schema` declaration for the table: - Schema::create('sessions', function ($table) { - $table->string('id')->unique(); - $table->text('payload'); - $table->integer('last_activity'); - }); + Schema::create('sessions', function ($table) { + $table->string('id')->unique(); + $table->text('payload'); + $table->integer('last_activity'); + }); You may use the `session:table` Artisan command to generate this migration for you! - php artisan session:table + php artisan session:table - composer dump-autoload + composer dump-autoload - php artisan migrate + php artisan migrate #### Redis @@ -63,104 +63,104 @@ If you need all stored session data to be encrypted, set the `encrypt` configura First, let's access the session. We can access the session instance via the HTTP request, which can be type-hinted on a controller method. Remember, controller method dependencies are injected via the Laravel [service container](/docs/{{version}}/container): - session()->get('key'); + class UserController extends Controller + { + /** + * Show the profile for the given user. + * + * @param Request $request + * @param int $id + * @return Response + */ + public function showProfile(Request $request, $id) + { + $value = $request->session()->get('key'); - // - } - } + // + } + } When you retrieve a value from the session, you may also pass a default value as the second argument to the `get` method. This default value will be returned if the specified key does not exist in the session. If you pass a `Closure` as the default value to the `get` method, the `Closure` will be executed and its result returned: - $value = $request->session()->get('key', 'default'); + $value = $request->session()->get('key', 'default'); - $value = $request->session()->get('key', function() { - return 'default'; - }); + $value = $request->session()->get('key', function() { + return 'default'; + }); If you would like to retrieve all data from the session, you may use the `all` method: - $data = $request->session()->all(); + $data = $request->session()->all(); You may also use the global `session` PHP function to retrieve and store data in the session: - Route::get('home', function () { - // Retrieve a piece of data from the session... - $value = session('key'); + Route::get('home', function () { + // Retrieve a piece of data from the session... + $value = session('key'); - // Store a piece of data in the session... - session(['key' => 'value']); - }); + // Store a piece of data in the session... + session(['key' => 'value']); + }); #### Determining If An Item Exists In The Session The `has` method may be used to check if an item exists in the session. This method will return `true` if the item exists: - if ($request->session()->has('users')) { - // - } + if ($request->session()->has('users')) { + // + } #### Storing Data In The Session Once you have access to the session instance, you may call a variety of functions to interact with the underlying data. For example, the `put` method stores a new piece of data in the session: - $request->session()->put('key', 'value'); + $request->session()->put('key', 'value'); #### Pushing To Array Session Values The `push` method may be used to push a new value onto a session value that is an array. For example, if the `user.teams` key contains an array of team names, you may push a new value onto the array like so: - $request->session()->push('user.teams', 'developers'); + $request->session()->push('user.teams', 'developers'); #### Retrieving And Deleting An Item The `pull` method will retrieve and delete an item from the session: - $value = $request->session()->pull('key', 'default'); + $value = $request->session()->pull('key', 'default'); #### Deleting Items From The Session The `forget` method will remove a piece of data from the session. If you would like to remove all data from the session, you may use the `flush` method: - $request->session()->forget('key'); + $request->session()->forget('key'); - $request->session()->flush(); + $request->session()->flush(); #### Regenerating The Session ID If you need to regenerate the session ID, you may use the `regenerate` method: - $request->session()->regenerate(); + $request->session()->regenerate(); ### Flash Data Sometimes you may wish to store items in the session only for the next request. You may do so using the `flash` method. Method stored in the session using this method will only be available during the subsequent HTTP request, and then will be deleted. Flash data is primarily useful for short-lived status messages: - $request->session()->flash('status', 'Task was successful!'); + $request->session()->flash('status', 'Task was successful!'); If you need to keep your flash data around for even more requests, you may use the `reflash` method, which will keep all of the flash data around for an additional request. If you only need to keep specific flash data around, you may use the `keep` method: - $request->session()->reflash(); + $request->session()->reflash(); - $request->session()->keep(['username', 'email']); + $request->session()->keep(['username', 'email']); ## Adding Custom Session Drivers @@ -184,10 +184,10 @@ To add additional drivers to Laravel's session back-end, you may use the `extend */ public function boot() { - Session::extend('mongo', function($app) { - // Return implementation of SessionHandlerInterface... - return new MongoSessionStore; - }); + Session::extend('mongo', function($app) { + // Return implementation of SessionHandlerInterface... + return new MongoSessionStore; + }); } /** @@ -203,19 +203,19 @@ To add additional drivers to Laravel's session back-end, you may use the `extend Note that your custom session driver should implement the `SessionHandlerInterface`. This interface contains just a few simple methods we need to implement. A stubbed MongoDB implementation looks something like this: - ## Introduction @@ -32,15 +32,15 @@ You are free to create other testing environment configurations as necessary. Th To create a test case, simply create a new test file in the `tests` directory. The test class should extend `TestCase`. You may then define test methods as you normally would using PHPUnit. To run your tests, simply execute the `phpunit` command from your terminal: - assertTrue(true); - } - } + class FooTest extends TestCase + { + public function testSomethingIsTrue() + { + $this->assertTrue(true); + } + } > **Note:** If you define your own `setUp` method within a test class, be sure to call `parent::setUp`. @@ -49,24 +49,24 @@ To create a test case, simply create a new test file in the `tests` directory. T Laravel provides a very fluent API for making HTTP requests to your application, examining the output, and even filling out forms. For example, take a look at the `ExampleTest.php` file included in your `tests` directory: - visit('/') - ->see('Laravel 5'); - } - } + visit('/') + ->see('Laravel 5'); + } + } The `visit` method makes a `GET` request into the application. The `see` method asserts that we should see the given text in the response returned by the application. This is the most basic application test available in Laravel. @@ -79,7 +79,7 @@ Of course, you can do much more than simply assert that text appears in a given In this test, we will make a request to the application, "click" a link in the returned response, and then assert that we landed on a given URI. For example, let's assume there is a link in our response that has a text value of "About Us": - About Us + About Us Now, let's write a test that clicks the link and asserts the user lands on the correct page: @@ -94,21 +94,21 @@ Now, let's write a test that clicks the link and asserts the user lands on the c Laravel also provides several methods for testing forms. The `type`, `select`, `check`, `attach`, and `press` methods allow you to interact with all of your form's inputs. For example, let's imagine this form exists on the application's registration page: -
    - {!! csrf_field() !!} + + {!! csrf_field() !!} -
    - Name: -
    +
    + Name: +
    -
    - Accept Terms -
    +
    + Accept Terms +
    -
    - -
    -
    +
    + +
    + We can write a test to complete this form and inspect the result: @@ -149,23 +149,23 @@ If your form contains `file` input types, you may attach files to the form using Laravel also provides several helpers for testing JSON APIs and their responses. For example, the `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 a given array was returned in JSON format: - post('/user', ['name' => 'Sally']) - ->seeJson([ - 'created' => true, - ]); - } - } + post('/user', ['name' => 'Sally']) + ->seeJson([ + 'created' => true, + ]); + } + } The `seeJson` method converts the given array into JSON, and then verifies that the JSON fragment occurs **anywhere** within the entire 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. @@ -173,93 +173,93 @@ The `seeJson` method converts the given array into JSON, and then verifies that If you would like to verify that the given array is an **exact** match for the JSON returned by the application, you should use the `seeJsonEquals` method: - post('/user', ['name' => 'Sally']) - ->seeJsonEquals([ - 'created' => true, - ]); - } - } + post('/user', ['name' => 'Sally']) + ->seeJsonEquals([ + 'created' => true, + ]); + } + } ### Sessions / Authentication Laravel provides several helpers for working with the session during 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 testing a request to your application: - withSession(['foo' => 'bar']) - ->visit('/'); - } - } + class ExampleTest extends TestCase + { + public function testApplication() + { + $this->withSession(['foo' => 'bar']) + ->visit('/'); + } + } Of course, one common use of the session is for maintaining user state, such as the authenticated user. The `actingAs` helper method provides a simple way to authenticate a given user as the current user. For example, we may use a [model factory](#model-factories) to generate and authenticate a user: - create(); + actingAs($user) - ->withSession(['foo' => 'bar']) - ->visit('/') - ->see('Hello, '.$user->name); - } - } + class ExampleTest extends TestCase + { + public function testApplication() + { + $user = factory('App\User')->create(); + + $this->actingAs($user) + ->withSession(['foo' => 'bar']) + ->visit('/') + ->see('Hello, '.$user->name); + } + } ### Disabling Middleware When testing your application, you may find it convenient to disable [middleware](/docs/{{version}}/middleware) for some of your tests. This will allow you to test your routes and controller in isolation from any middleware concerns. Laravel includes a simple `WithoutMiddleware` trait that you can use to automatically disable all middleware for the test class: - withoutMiddleware(); + visit('/') - ->see('Laravel 5'); - } - } + class ExampleTest extends TestCase + { + /** + * A basic functional test example. + * + * @return void + */ + public function testBasicExample() + { + $this->withoutMiddleware(); + + $this->visit('/') + ->see('Laravel 5'); + } + } ### Custom HTTP Requests @@ -268,14 +268,14 @@ If you would like to make a custom HTTP request into your application and get th public function testApplication() { - $response = $this->call('GET', '/'); + $response = $this->call('GET', '/'); - $this->assertEquals(200, $response->status()); + $this->assertEquals(200, $response->status()); } If you are making `POST`, `PUT`, or `PATCH` requests you may pass an array of input data with the request. Of course, this data will be available in your routes and controller via the [Request instance](/docs/{{version}}/requests): - $response = $this->call('POST', '/user', ['name' => 'Taylor']); + $response = $this->call('POST', '/user', ['name' => 'Taylor']); ## Working With Databases @@ -284,9 +284,9 @@ Laravel also provides a variety of helpful tools to make it easier to test your public function testDatabase() { - // Make call to application... + // Make call to application... - $this->seeInDatabase('users', ['email' => 'sally@foo.com']); + $this->seeInDatabase('users', ['email' => 'sally@foo.com']); } Of course, the `seeInDatabase` 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. @@ -300,67 +300,67 @@ It is often useful to reset your database after each test so that data from a pr One option is to rollback the database after each test and migrate it before the next test. Laravel provides a simple `DatabaseMigrations` trait that will automatically handle this for you. Simply use the trait on your test class: - visit('/') - ->see('Laravel 5'); - } - } + class ExampleTest extends TestCase + { + use DatabaseMigrations; + + /** + * A basic functional test example. + * + * @return void + */ + public function testBasicExample() + { + $this->visit('/') + ->see('Laravel 5'); + } + } #### Using Transactions Another option is to wrap every test case in a database transaction. Again, Laravel provides a convenient `DatabaseTransactions` trait that will automatically handle this: - visit('/') - ->see('Laravel 5'); - } - } + class ExampleTest extends TestCase + { + use DatabaseTransactions; + + /** + * A basic functional test example. + * + * @return void + */ + public function testBasicExample() + { + $this->visit('/') + ->see('Laravel 5'); + } + } ### Model Factories When testing, it is common to need to insert a few records into your database before executing your test. Instead of manually specifying the value of each column when you create this test data, Laravel allows you to define a default set of attributes for each of your [Eloquent models](/docs/{{version}}/eloquent) using "factories". To get started, take a look at the `database/factories/ModelFactory.php` file in your application. Out of the box, this file contains one factory definition: - $factory->define(App\User::class, function ($faker) { - return [ - 'name' => $faker->name, - 'email' => $faker->email, - 'password' => str_random(10), - 'remember_token' => str_random(10), - ]; - }); + $factory->define(App\User::class, function ($faker) { + return [ + 'name' => $faker->name, + 'email' => $faker->email, + 'password' => str_random(10), + 'remember_token' => str_random(10), + ]; + }); Within the Closure, which serves as the factory definition, you may return the default test values of all attributes on the model. The Closure will receive an instance of the [Faker](https://github.com/fzaninotto/Faker) PHP library, which allows you to conveniently generate various kinds of random data for testing. @@ -370,23 +370,23 @@ Of course, you are free to add your own additional factories to the `ModelFactor Sometimes you may wish to have multiple factories for the same Eloquent model class. For example, perhaps you would like to have a factory for "Administrator" users in addition to normal users. You may define these factories using the `defineAs` method: - $factory->defineAs(App\User::class, 'admin', function ($faker) { - return [ - 'name' => $faker->name, - 'email' => $faker->email, - 'password' => str_random(10), - 'remember_token' => str_random(10), - 'admin' => true, - ]; - }); + $factory->defineAs(App\User::class, 'admin', function ($faker) { + return [ + 'name' => $faker->name, + 'email' => $faker->email, + 'password' => str_random(10), + 'remember_token' => str_random(10), + 'admin' => true, + ]; + }); Instead of duplicating all of the attributes from your base user factory, you may use the `raw` method to retrieve the base attributes. Once you have the attributes, simply supplement them with any additional values you require: - $factory->defineAs(App\User::class, 'admin', function ($faker) use ($factory) { - $user = $factory->raw(App\User::class); + $factory->defineAs(App\User::class, 'admin', function ($faker) use ($factory) { + $user = $factory->raw(App\User::class); - return array_merge($user, ['admin' => true]); - }); + return array_merge($user, ['admin' => true]); + }); #### Using Factories In Tests @@ -394,27 +394,27 @@ Once you have defined your factories, you may use them in your tests or database public function testDatabase() { - $user = factory(App\User::class)->make(); + $user = factory(App\User::class)->make(); - // Use model in tests... + // Use model in tests... } If you would like to override some of the default values of your models, you may pass an array of values to the `make` method. Only the specified values will be replaced while the rest of the values remain set to their default values as specified by the factory: $user = factory(App\User::class)->make([ - 'name' => 'Abigail', - ]); + 'name' => 'Abigail', + ]); You may also create a Collection of many models or create models of a given type: - // Create three App\User instances... - $users = factory(App\User::class, 3)->make(); + // Create three App\User instances... + $users = factory(App\User::class, 3)->make(); - // Create an App\User "admin" instance... - $user = factory(App\User::class, 'admin')->make(); + // Create an App\User "admin" instance... + $user = factory(App\User::class, 'admin')->make(); - // Create three App\User "admin" instances... - $users = factory(App\User::class, 'admin', 3)->make(); + // Create three App\User "admin" instances... + $users = factory(App\User::class, 'admin', 3)->make(); #### Persisting Factory Models @@ -422,16 +422,16 @@ The `create` method not only creates the model instances, but also saves them to public function testDatabase() { - $user = factory(App\User::class)->create(); + $user = factory(App\User::class)->create(); - // Use model in tests... + // Use model in tests... } Again, you may override attributes on the model by passing an array to the `create` method: $user = factory(App\User::class)->create([ - 'name' => 'Abigail', - ]); + 'name' => 'Abigail', + ]); #### Adding Relations To Models @@ -440,8 +440,8 @@ You may even persist multiple models to the database. In this example, we'll eve $users = factory(App\User::class, 3) ->create() ->each(function($u) { - $u->posts()->save(factory(App\Post::class)->make()); - }); + $u->posts()->save(factory(App\Post::class)->make()); + }); ## Mocking @@ -453,31 +453,31 @@ If you are making heavy use of Laravel's event system, you may wish to silence o Laravel provides a convenient `expectsEvents` method that verifies the expected events are fired, but prevents any handlers for those events from running: - expectsEvents(App\Events\UserRegistered::class); + class ExampleTest extends TestCase + { + public function testUserRegistration() + { + $this->expectsEvents(App\Events\UserRegistered::class); - // Test user registration code... - } - } + // Test user registration code... + } + } If you would like to prevent all event handlers from running, you may use the `withoutEvents` method: - withoutEvents(); + class ExampleTest extends TestCase + { + public function testUserRegistration() + { + $this->withoutEvents(); - // Test user registration code... - } - } + // Test user registration code... + } + } ### Mocking Jobs @@ -486,17 +486,17 @@ Sometimes, you may wish to simply test that specific jobs are dispatched by your Laravel provides a convenient `expectsJobs` method that will verify that the expected jobs are dispatched, but the job itself will not be executed: - expectsJobs(App\Jobs\PurchasePodcast::class); + class ExampleTest extends TestCase + { + public function testPurchasePodcast() + { + $this->expectsJobs(App\Jobs\PurchasePodcast::class); - // Test purchase podcast code... - } - } + // Test purchase podcast code... + } + } > **Note:** This method only detects jobs that are dispatched via the `DispatchesJobs` trait's dispatch methods. It does not detect jobs that are sent directly to `Queue::push`. @@ -505,43 +505,43 @@ Laravel provides a convenient `expectsJobs` method that will verify that the exp When testing, you may often want to mock a call to a Laravel [facade](/docs/{{version}}/facades). For example, consider the following controller action: - once() - ->with('key') - ->andReturn('value'); + visit('/users')->see('value'); - } - } + class FooTest extends TestCase + { + public function testGetIndex() + { + Cache::shouldReceive('get') + ->once() + ->with('key') + ->andReturn('value'); + + $this->visit('/users')->see('value'); + } + } > **Note:** You should not mock the `Request` facade. Instead, pass the input you desire into the HTTP helper methods such as `call` and `post` when running your test. diff --git a/upgrade.md b/upgrade.md index 23fe1b5c65..30c48a6c12 100644 --- a/upgrade.md +++ b/upgrade.md @@ -17,14 +17,14 @@ Update the `$compiledPath` variable in `bootstrap/autoload.php` to the following: - $compiledPath = __DIR__.'/cache/compiled.php'; + $compiledPath = __DIR__.'/cache/compiled.php'; ### Create `bootstrap/cache` Directory Within your `bootstrap` directory, create a `cache` directory (`bootstrap/cache`). Place a `.gitignore` file in this directory with the following contents: - * - !.gitignore + * + !.gitignore This directory should be writable, and will be used by the framework to store temporary optimization files like `compiled.php`, `routes.php`, `config.php`, and `services.json`. @@ -56,29 +56,29 @@ Likewise, if you are overriding the `formatErrors` method on the base form reque Eloquent's `create` method can now be called without any parameters. If you are overriding the `create` method in your own models, set the default value of the `$attributes` parameter to an array: - public static function create(array $attributes = []) - { - // Your custom implementation - } + public static function create(array $attributes = []) + { + // Your custom implementation + } #### The `find` Method If you are overriding the `find` method in your own models and calling `parent::find()` within your custom method, you should now change it to call the `find` method on the Eloquent query builder: - public static function find($id, $columns = ['*']) - { - $model = static::query()->find($id, $columns); + public static function find($id, $columns = ['*']) + { + $model = static::query()->find($id, $columns); - // ... + // ... - return $model; - } + return $model; + } #### The `lists` Method The `lists` method now returns a `Collection` instance instead of a plain array for Eloquent queries. If you would like to convert the `Collection` into a plain array, use the `all` method: - User::lists('id')->all(); + User::lists('id')->all(); Be aware that the Query Builder `lists` method still returns an array. @@ -94,22 +94,22 @@ The date format is also now applied when serializing a model to an `array` or JS The `sortBy` method now returns a fresh collection instance instead of modifying the existing collection: - $collection = $collection->sortBy('name'); + $collection = $collection->sortBy('name'); #### The `groupBy` Method The `groupBy` method now returns `Collection` instances for each item in the parent `Collection`. If you would like to convert all of the items back to plain arrays, you may `map` over them: - $collection->groupBy('type')->map(function($item) - { - return $item->all(); - }); + $collection->groupBy('type')->map(function($item) + { + return $item->all(); + }); #### The `lists` Method The `lists` method now returns a `Collection` instance instead of a plain array. If you would like to convert the `Collection` into a plain array, use the `all` method: - $collection->lists('id')->all(); + $collection->lists('id')->all(); ### Commands & Handlers @@ -127,7 +127,7 @@ The `createMatcher`, `createOpenMatcher`, and `createPlainMatcher` methods have Add the protected `$baseUrl` property to the `tests/TestCase.php` file: - protected $baseUrl = 'http://localhost'; + protected $baseUrl = 'http://localhost'; ### Translation Files @@ -163,7 +163,7 @@ The following Laravel features have been deprecated and will be removed entirely In your `bootstrap/autoload.php` file, update the `$compiledPath` variable to: - $compiledPath = __DIR__.'/../vendor/compiled.php'; + $compiledPath = __DIR__.'/../vendor/compiled.php'; ## Upgrading To 5.0 From 4.2 @@ -226,11 +226,11 @@ Filters are not removed in Laravel 5. You can still bind and use your own custom By default, [CSRF protection](/docs/{{version}}/routing#csrf-protection) is enabled on all routes. If you'd like to disable this, or only manually enable it on certain routes, remove this line from `App\Http\Kernel`'s `middleware` array: - 'App\Http\Middleware\VerifyCsrfToken', + 'App\Http\Middleware\VerifyCsrfToken', If you want to use it elsewhere, add this line to `$routeMiddleware`: - 'csrf' => 'App\Http\Middleware\VerifyCsrfToken', + 'csrf' => 'App\Http\Middleware\VerifyCsrfToken', Now you can add the middleware to individual routes / controllers using `['middleware' => 'csrf']` on the route. For more information on middleware, consult the [full documentation](/docs/{{version}}/middleware). @@ -346,12 +346,12 @@ For example, you may add `"laravelcollective/html": "~5.0"` to your `composer.js You'll also need to add the Form and HTML facades and service provider. Edit `config/app.php` and add this line to the 'providers' array: - 'Collective\Html\HtmlServiceProvider', + 'Collective\Html\HtmlServiceProvider', Next, add these lines to the 'aliases' array: - 'Form' => 'Collective\Html\FormFacade', - 'Html' => 'Collective\Html\HtmlFacade', + 'Form' => 'Collective\Html\FormFacade', + 'Html' => 'Collective\Html\HtmlFacade', ### CacheManager @@ -388,7 +388,7 @@ Laravel 4.2 requires PHP 5.4.0 or greater. Add a new `cipher` option in your `app/config/app.php` configuration file. The value of this option should be `MCRYPT_RIJNDAEL_256`. - 'cipher' => MCRYPT_RIJNDAEL_256 + 'cipher' => MCRYPT_RIJNDAEL_256 This setting may be used to control the default cipher used by the Laravel encryption facilities. @@ -398,21 +398,21 @@ This setting may be used to control the default cipher used by the Laravel encry If you are using soft deleting models, the `softDeletes` property has been removed. You must now use the `SoftDeletingTrait` like so: - use Illuminate\Database\Eloquent\SoftDeletingTrait; + use Illuminate\Database\Eloquent\SoftDeletingTrait; - class User extends Eloquent - { - use SoftDeletingTrait; - } + class User extends Eloquent + { + use SoftDeletingTrait; + } You must also manually add the `deleted_at` column to your `dates` property: - class User extends Eloquent - { - use SoftDeletingTrait; + class User extends Eloquent + { + use SoftDeletingTrait; - protected $dates = ['deleted_at']; - } + protected $dates = ['deleted_at']; + } The API for all soft delete operations remains the same. @@ -426,13 +426,13 @@ If you are directly referencing the `Illuminate\View\Environment` class or `Illu If you are extending the `Illuminate\Pagination\Presenter` class, the abstract method `getPageLinkWrapper` signature has changed to add the `rel` argument: - abstract public function getPageLinkWrapper($url, $page, $rel = null); + abstract public function getPageLinkWrapper($url, $page, $rel = null); ### Iron.Io Queue Encryption If you are using the Iron.io queue driver, you will need to add a new `encrypt` option to your queue configuration file: - 'encrypt' => true + 'encrypt' => true ## Upgrading To 4.1.29 From <= 4.1.x @@ -454,20 +454,20 @@ First, add a new, nullable `remember_token` of VARCHAR(100), TEXT, or equivalent Next, if you are using the Eloquent authentication driver, update your `User` class with the following three methods: - public function getRememberToken() - { - return $this->remember_token; - } + public function getRememberToken() + { + return $this->remember_token; + } - public function setRememberToken($value) - { - $this->remember_token = $value; - } + public function setRememberToken($value) + { + $this->remember_token = $value; + } - public function getRememberTokenName() - { - return 'remember_token'; - } + public function getRememberTokenName() + { + return 'remember_token'; + } > **Note:** All existing "remember me" sessions will be invalidated by this change, so all users will be forced to re-authenticate with your application. @@ -475,9 +475,9 @@ Next, if you are using the Eloquent authentication driver, update your `User` cl Two new methods were added to the `Illuminate\Auth\UserProviderInterface` interface. Sample implementations may be found in the default drivers: - public function retrieveByToken($identifier, $token); + public function retrieveByToken($identifier, $token); - public function updateRememberToken(UserInterface $user, $token); + public function updateRememberToken(UserInterface $user, $token); The `Illuminate\Auth\UserInterface` also received the three new methods described in the "Upgrade Path". @@ -504,9 +504,9 @@ Add the new `expire_on_close` configuration option to your `app/config/session.p Add the new `failed` configuration section to your `app/config/queue.php` file. Here are the default values for the section: - 'failed' => [ - 'database' => 'mysql', 'table' => 'failed_jobs', - ], + 'failed' => [ + 'database' => 'mysql', 'table' => 'failed_jobs', + ], **(Optional)** Update the `pagination` configuration option in your `app/config/view.php` file to `pagination::slider-3`. diff --git a/validation.md b/validation.md index 04138fff8a..9ae02b96f8 100644 --- a/validation.md +++ b/validation.md @@ -3,10 +3,10 @@ - [Introduction](#introduction) - [Validation Quickstart](#validation-quickstart) - [Other Validation Approaches](#foo) - - [Manually Creating Validators](#manually-creating-validators) - - [Form Request Validation](#form-request-validation) + - [Manually Creating Validators](#manually-creating-validators) + - [Form Request Validation](#form-request-validation) - [Working With Error Messages](#working-with-error-messages) - - [Custom Error Messages](#custom-error-messages) + - [Custom Error Messages](#custom-error-messages) - [Available Validation Rules](#available-validation-rules) - [Conditionally Adding Rules](#conditionally-adding-rules) - [Custom Validation Rules](#custom-validation-rules) @@ -25,11 +25,11 @@ To learn about Laravel's powerful validation features, let's look at a complete First, let's assume we have the following routes defined in our `app/Http/routes.php` file: - // Display a form to create a blog post... - Route::get('post/create', 'PostController@create'); + // Display a form to create a blog post... + Route::get('post/create', 'PostController@create'); - // Store a new blog post... - Route::post('post', 'PostController@store'); + // Store a new blog post... + Route::post('post', 'PostController@store'); Of course, the `GET` route will display a form for the user to create a new blog post, while the `POST` route will store the new blog post in the database. @@ -37,36 +37,36 @@ Of course, the `GET` route will display a form for the user to create a new blog Next, let's take a look at a simple controller that handles these routes. We'll leave the `store` method empty for now: - validate($request, [ - 'title' => 'required|unique:posts|max:255', - 'body' => 'required', - ]); - - // The blog post is valid, store in database... - } + /** + * Store a new blog post. + * + * @param Request $request + * @return Response + */ + public function store(Request $request) + { + $this->validate($request, [ + 'title' => 'required|unique:posts|max:255', + 'body' => 'required', + ]); + + // The blog post is valid, store in database... + } As you can see, we simply pass the incoming HTTP request and desired validation rules into the `validate` method. Again, if the validation fails, the proper response will automatically be generated. If the validation passes, our controller will continue executing normally. @@ -102,47 +102,47 @@ Again, notice that we did not have to explicitly bind the error messages to the So, in our example, the user will be redirected to our controller's `create` method when validation fails, allowing us to display the error messages in the view: - + -

    Create Post

    +

    Create Post

    - @if (count($errors) > 0) -
    -
      - @foreach ($errors->all() as $error) -
    • {{ $error }}
    • - @endforeach -
    -
    - @endif + @if (count($errors) > 0) +
    +
      + @foreach ($errors->all() as $error) +
    • {{ $error }}
    • + @endforeach +
    +
    + @endif - + #### Customizing The Flashed Error Format If you wish to customize the format of the validation errors that are flashed to the session when validation fails, override the `formatValidationErrors` on your base controller. Don't forget to import the `Illuminate\Contracts\Validation\Validator` class at the top of the file: - errors()->all(); - } - } + /** + * {@inheritdoc} + */ + protected function formatValidationErrors(Validator $validator) + { + return $validator->errors()->all(); + } + } ### AJAX Requests & Validation @@ -156,38 +156,38 @@ In this example, we used a traditional form to send data to the application. How If you do not want to use the `ValidatesRequests` trait's `validate` method, you may create a validator instance manually using the `Validator` [facade](/docs/{{version}}/facades). The `make` method on the facade generates a new validator instance: - all(), [ - 'title' => 'required|unique:posts|max:255', - 'body' => 'required', - ]); - - if ($validator->fails()) { - return redirect('post/create') - ->withErrors($validator) - ->withInput(); - } - - // Store the blog post... - } - } + all(), [ + 'title' => 'required|unique:posts|max:255', + 'body' => 'required', + ]); + + if ($validator->fails()) { + return redirect('post/create') + ->withErrors($validator) + ->withInput(); + } + + // Store the blog post... + } + } The first argument passed to the `make` method is the data under validation. The second argument is the validation rules that should be applied to the data. @@ -197,63 +197,63 @@ After checking if the request failed to pass validation, you may use the `withEr If you have multiple forms on a single page, you may wish to name the `MessageBag` of errors, allowing you to retrieve the error messages for a specific form. Simply pass a name as the second argument to `withErrors`: - return redirect('register') - ->withErrors($validator, 'login'); + return redirect('register') + ->withErrors($validator, 'login'); You may then access the named `MessageBag` instance from the `$errors` variable: - {{ $errors->login->first('email') }} + {{ $errors->login->first('email') }} #### After Validation Hook The validator also allows you to attach callbacks to be run after validation is completed. This allows you to easily perform further validation and even add more error messages to the message collection. To get started, use the `after` method on a validator instance: - $validator = Validator::make(...); + $validator = Validator::make(...); - $validator->after(function($validator) { - if ($this->somethingElseIsInvalid()) { - $validator->errors()->add('field', 'Something is wrong with this field!'); - } - }); + $validator->after(function($validator) { + if ($this->somethingElseIsInvalid()) { + $validator->errors()->add('field', 'Something is wrong with this field!'); + } + }); - if ($validator->fails()) { - // - } + if ($validator->fails()) { + // + } ### Form Request Validation For more complex validation scenarios, you may wish to create a "form request". Form requests are custom request classes that contain validation logic. To create a form request class, use the `make:request` Artisan CLI command: - php artisan make:request StoreBlogPostRequest + php artisan make:request StoreBlogPostRequest The generated class will be placed in the `app/Http/Requests` directory. Let's add a few validation rules to the `rules` method: - /** - * Get the validation rules that apply to the request. - * - * @return array - */ - public function rules() - { - return [ - 'title' => 'required|unique:posts|max:255', - 'body' => 'required', - ]; - } + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + return [ + 'title' => 'required|unique:posts|max:255', + 'body' => 'required', + ]; + } So, how are the validation rules evaluated? All you need to do is type-hint the request on your controller method. The incoming form request is validated before the controller method is called, meaning you do not need to clutter your controller with any validation logic: - /** - * Store the incoming blog post. - * - * @param StoreBlogPostRequest $request - * @return Response - */ - public function store(StoreBlogPostRequest $request) - { - // The incoming request is valid... - } + /** + * Store the incoming blog post. + * + * @param StoreBlogPostRequest $request + * @return Response + */ + public function store(StoreBlogPostRequest $request) + { + // The incoming request is valid... + } If validation fails, a redirect response will be generated to send the user back to their previous location. The errors will also be flashed to the session so they are available for display. If the request was an AJAX request, a HTTP response with a 422 status code will be returned to the user including a JSON representation of the validation errors. @@ -261,48 +261,48 @@ If validation fails, a redirect response will be generated to send the user back The form request class also contains an `authorize` method. Within this method, you may check if the authenticated user actually has the authority to update a given resource. For example, if a user is attempting to update a blog post comment, do they actually own that comment? For example: - /** - * Determine if the user is authorized to make this request. - * - * @return bool - */ - public function authorize() - { - $commentId = $this->route('comment'); + /** + * Determine if the user is authorized to make this request. + * + * @return bool + */ + public function authorize() + { + $commentId = $this->route('comment'); - return Comment::where('id', $commentId) + return Comment::where('id', $commentId) ->where('user_id', Auth::id())->exists(); - } + } Note the call to the `route` method in the example above. This method grants you access to the URI parameters defined on the route being called, such as the `{comment}` parameter in the example below: - Route::post('comment/{comment}'); + Route::post('comment/{comment}'); If the `authorize` method returns `false`, a HTTP response with a 403 status code will automatically be returned and your controller method will not execute. If you plan to have authorization logic in another part of your application, simply return `true` from the `authorize` method: - /** - * Determine if the user is authorized to make this request. - * - * @return bool - */ - public function authorize() - { - return true; - } + /** + * Determine if the user is authorized to make this request. + * + * @return bool + */ + public function authorize() + { + return true; + } #### Customizing The Flashed Error Format If you wish to customize the format of the validation errors that are flashed to the session when validation fails, override the `formatErrors` on your base request (`App\Http\Requests\Request`). Don't forget to import the `Illuminate\Contracts\Validation\Validator` class at the top of the file: - /** - * {@inheritdoc} - */ - protected function formatErrors(Validator $validator) - { - return $validator->errors()->all(); - } + /** + * {@inheritdoc} + */ + protected function formatErrors(Validator $validator) + { + return $validator->errors()->all(); + } ## Working With Error Messages @@ -313,80 +313,80 @@ After calling the `errors` method on a `Validator` instance, you will receive an To retrieve the first error message for a given field, use the `first` method: - $messages = $validator->errors(); + $messages = $validator->errors(); - echo $messages->first('email'); + echo $messages->first('email'); #### Retrieving All Error Messages For A Field If you wish to simply retrieve an array of all of the messages for a given field, use the `get` method: - foreach ($messages->get('email') as $message) { - // - } + foreach ($messages->get('email') as $message) { + // + } #### Retrieving All Error Messages For All Fields To retrieve an array of all messages for all fields, use the `all` method: - foreach ($messages->all() as $message) { - // - } + foreach ($messages->all() as $message) { + // + } #### Determining If Messages Exist For A Field - if ($messages->has('email')) { - // - } + if ($messages->has('email')) { + // + } #### Retrieving An Error Message With A Format - echo $messages->first('email', '

    :message

    '); + echo $messages->first('email', '

    :message

    '); #### Retrieving All Error Messages With A Format - foreach ($messages->all('
  • :message
  • ') as $message) { - // - } + foreach ($messages->all('
  • :message
  • ') as $message) { + // + } ### Custom Error Messages If needed, you may use custom error messages for validation instead of the defaults. There are several ways to specify custom messages. First, you may pass the custom messages as the third argument to the `Validator::make` method: - $messages = [ - 'required' => 'The :attribute field is required.', - ]; + $messages = [ + 'required' => 'The :attribute field is required.', + ]; - $validator = Validator::make($input, $rules, $messages); + $validator = Validator::make($input, $rules, $messages); In this example, the `:attribute` place-holder will be replaced by the actual name of the field under validation. You may also utilize other place-holders in validation messages. For example: - $messages = [ - 'same' => 'The :attribute and :other must match.', - 'size' => 'The :attribute must be exactly :size.', - 'between' => 'The :attribute must be between :min - :max.', - 'in' => 'The :attribute must be one of the following types: :values', - ]; + $messages = [ + 'same' => 'The :attribute and :other must match.', + 'size' => 'The :attribute must be exactly :size.', + 'between' => 'The :attribute must be between :min - :max.', + 'in' => 'The :attribute must be one of the following types: :values', + ]; #### Specifying A Custom Message For A Given Attribute Sometimes you may wish to specify a custom error messages only for a specific field. You may do so using "dot" notation. Specify the attribute's name first, followed by the rule: - $messages = [ - 'email.required' => 'We need to know your e-mail address!', - ]; + $messages = [ + 'email.required' => 'We need to know your e-mail address!', + ]; #### Specifying Custom Messages In Language Files In many cases, you may wish to specify your attribute specific custom messages in a language file instead of passing them directly to the `Validator`. To do so, add your messages to `custom` array in the `resources/lang/xx/validation.php` language file. - 'custom' => [ - 'email' => [ - 'required' => 'We need to know your e-mail address!', - ], - ], + 'custom' => [ + 'email' => [ + 'required' => 'We need to know your e-mail address!', + ], + ], ## Available Validation Rules @@ -394,14 +394,14 @@ In many cases, you may wish to specify your attribute specific custom messages i Below is a list of all available validation rules and their function:
    @@ -539,19 +539,19 @@ The field under validation must exist on a given database table. #### Basic Usage Of Exists Rule - 'state' => 'exists:states' + 'state' => 'exists:states' #### Specifying A Custom Column Name - 'state' => 'exists:states,abbreviation' + 'state' => 'exists:states,abbreviation' You may also specify more conditions that will be added as "where" clauses to the query: - 'email' => 'exists:staff,email,account_id,1' + 'email' => 'exists:staff,email,account_id,1' Passing `NULL` as a "where" clause value will add a check for a `NULL` database value: - 'email' => 'exists:staff,email,deleted_at,NULL' + 'email' => 'exists:staff,email,deleted_at,NULL' #### image @@ -585,7 +585,7 @@ The file under validation must have a MIME type corresponding to one of the list #### Basic Usage Of MIME Rule - 'photo' => 'mimes:jpeg,bmp,png' + 'photo' => 'mimes:jpeg,bmp,png' #### min:_value_ @@ -666,25 +666,25 @@ The field under validation must be unique on a given database table. If the `col **Specifying A Custom Column Name:** - 'email' => 'unique:users,email_address' + 'email' => 'unique:users,email_address' **Custom Database Connection** Occasionally, you may need to set a custom connection for database queries made by the Validator. As seen above, setting `unique:users` as a validation rule will use the default database connection to query the database. To override this, specify the connection followed by the table name using "dot" syntax: - 'email' => 'unique:connection.users,email_address' + 'email' => 'unique:connection.users,email_address' **Forcing A Unique Rule To Ignore A Given ID:** Sometimes, you may wish to ignore a given ID during the unique check. For example, consider an "update profile" screen that includes the user's name, e-mail address, and location. Of course, you will want to verify that the e-mail address is unique. However, if the user only changes the name field and not the e-mail field, you do not want a validation error to be thrown because the user is already the owner of the e-mail address. You only want to throw a validation error if the user provides an e-mail address that is already used by a different user. To tell the unique rule to ignore the user's ID, you may pass the ID as the third parameter: - 'email' => 'unique:users,email_address,'.$user->id + 'email' => 'unique:users,email_address,'.$user->id **Adding Additional Where Clauses:** You may also specify more conditions that will be added as "where" clauses to the query: - 'email' => 'unique:users,email_address,NULL,id,account_id,1' + 'email' => 'unique:users,email_address,NULL,id,account_id,1' In the rule above, only rows with an `account_id` of `1` would be included in the unique check. @@ -698,9 +698,9 @@ The field under validation must be a valid URL according to PHP's `filter_var` f In some situations, you may wish to run validation checks against a field **only** if that field is present in the input array. To quickly accomplish this, add the `sometimes` rule to your rule list: - $v = Validator::make($data, [ - 'email' => 'sometimes|required|email', - ]); + $v = Validator::make($data, [ + 'email' => 'sometimes|required|email', + ]); In the example above, the `email` field will only be validated if it is present in the `$data` array. @@ -708,22 +708,22 @@ In the example above, the `email` field will only be validated if it is present Sometimes you may wish to add validation rules based on more complex conditional logic. For example, you may wish to require a given field only if another field has a greater value than 100. Or, you may need two fields to have a given value only when another field is present. Adding these validation rules doesn't have to be a pain. First, create a `Validator` instance with your _static rules_ that never change: - $v = Validator::make($data, [ - 'email' => 'required|email', - 'games' => 'required|numeric', - ]); + $v = Validator::make($data, [ + 'email' => 'required|email', + 'games' => 'required|numeric', + ]); Let's assume our web application is for game collectors. If a game collector registers with our application and they own more than 100 games, we want them to explain why they own so many games. For example, perhaps they run a game re-sell shop, or maybe they just enjoy collecting. To conditionally add this requirement, we can use the `sometimes` method on the `Validator` instance. - $v->sometimes('reason', 'required|max:500', function($input) { - return $input->games >= 100; - }); + $v->sometimes('reason', 'required|max:500', function($input) { + return $input->games >= 100; + }); The first argument passed to the `sometimes` method is the name of the field we are conditionally validating. The second argument is the rules we want to add. If the `Closure` passed as the third argument returns `true`, the rules will be added. This method makes it a breeze to build complex conditional validations. You may even add conditional validations for several fields at once: - $v->sometimes(['reason', 'cost'], 'required', function($input) { - return $input->games >= 100; - }); + $v->sometimes(['reason', 'cost'], 'required', function($input) { + return $input->games >= 100; + }); > **Note:** The `$input` parameter passed to your `Closure` will be an instance of `Illuminate\Support\Fluent` and may be used to access your input and files. @@ -732,49 +732,49 @@ The first argument passed to the `sometimes` method is the name of the field we Laravel provides a variety of helpful validation rules; however, you may wish to specify some of your own. One method of registering custom validation rules is using the `extend` method on the `Validator` [facade](/docs/{{version}}/facades). Let's use this method within a [service provider](/docs/{{version}}/providers) to register a custom validation rule: - "Your input was invalid!", + "foo" => "Your input was invalid!", "accepted" => "The :attribute must be accepted.", @@ -787,11 +787,11 @@ When creating a custom validation rule, you may sometimes need to define custom * * @return void */ - public function boot() - { - Validator::extend(...); - - Validator::replacer('foo', function($message, $attribute, $rule, $parameters) { - return str_replace(...); - }); - } + public function boot() + { + Validator::extend(...); + + Validator::replacer('foo', function($message, $attribute, $rule, $parameters) { + return str_replace(...); + }); + } diff --git a/views.md b/views.md index 2384bc3cc3..9c2a9dd3af 100644 --- a/views.md +++ b/views.md @@ -1,8 +1,8 @@ # Views - [Basic Usage](#basic-usage) - - [Passing Data To Views](#passing-data-to-views) - - [Sharing Data With All Views](#sharing-data-with-all-views) + - [Passing Data To Views](#passing-data-to-views) + - [Sharing Data With All Views](#sharing-data-with-all-views) - [View Composers](#view-composers) @@ -12,33 +12,33 @@ Views contain the HTML served by your application and separate your controller / A simple view might look something like this: - + - - -

    Hello,

    - - + + +

    Hello,

    + + Since this view is stored at `resources/views/greeting.php`, we may return it using the global `view` helper function like so: - Route::get('/', function () { - return view('greeting', ['name' => 'James']); - }); + Route::get('/', function () { + return view('greeting', ['name' => 'James']); + }); As you can see, the first argument passed to the `view` helper corresponds to the name of the view file in the `resources/views` directory. The second argument passed to helper is an array of data that should be made available to the view. In this case, we are passing the `name` variable, which is displayed in the view by simply executing `echo` on the variable. Of course, views may also be nested within sub-directories of the `resources/views` directory. "Dot" notation may be used to reference nested views. For example, if your view is stored at `resources/views/admin/profile.php`, you may reference it like so: - return view('admin.profile', $data); + return view('admin.profile', $data); #### Determining If A View Exists If you need to determine if a view exists, you may use the `exists` method after calling the `view` helper with no arguments. This method will return `true` if the view exists on disk: - if (view()->exists('emails.customer')) { - // - } + if (view()->exists('emails.customer')) { + // + } When the `view` helper is called without arguments, an instance of `Illuminate\Contracts\View\Factory` is returned, giving you access to any of the factory's methods. @@ -50,43 +50,43 @@ When the `view` helper is called without arguments, an instance of `Illuminate\C As you saw in the previous examples, you may easily pass an array of data to views: - return view('greetings', ['name' => 'Victoria']); + return view('greetings', ['name' => 'Victoria']); When passing information in this manner, `$data` should be an array with key/value pairs. Inside your view, you can then access each value using it's corresponding key, such as ``. As an alternative to passing a complete array of data to the `view` helper function, you may use the `with` method to add individual pieces of data to the view: - $view = view('greeting')->with('name', 'Victoria'); + $view = view('greeting')->with('name', 'Victoria'); #### Sharing Data With All Views Occasionally, you may need to share a piece of data with all views that are rendered by your application. You may do so using the view factory's `share` method. Typically, you would place calls to `share` within a service provider's `boot` method. You are free to add them to the `AppServiceProvider` or generate a separate service provider to house them: - share('key', 'value'); - } - - /** - * Register the service provider. - * - * @return void - */ - public function register() - { - // - } - } + share('key', 'value'); + } + + /** + * Register the service provider. + * + * @return void + */ + public function register() + { + // + } + } ## View Composers @@ -95,86 +95,86 @@ View composers are callbacks or class methods that are called when a view is ren Let's register our view composers within a [service provider](/docs/{{version}}/providers). We'll use the `view` helper to access the underlying `Illuminate\Contracts\View\Factory` contract implementation. Remember, Laravel does not include a default directory for view composers. You are free to organize them however you wish. For example, you could create an `App\Http\ViewComposers` directory: - composer( - 'profile', 'App\Http\ViewComposers\ProfileComposer' - ); - - // Using Closure based composers... - view()->composer('dashboard', function ($view) { - - }); - } - - /** - * Register the service provider. - * - * @return void - */ - public function register() - { - // - } - } + composer( + 'profile', 'App\Http\ViewComposers\ProfileComposer' + ); + + // Using Closure based composers... + view()->composer('dashboard', function ($view) { + + }); + } + + /** + * Register the service provider. + * + * @return void + */ + public function register() + { + // + } + } Remember, if you create a new service provider to contain your view composer registrations, you will need to add the service provider to the `providers` array in the `config/app.php` configuration file. Now that we have registered the composer, the `ProfileComposer@compose` method will be executed each time the `profile` view is being rendered. So, let's define the composer class: - users = $users; - } - - /** - * Bind data to the view. - * - * @param View $view - * @return void - */ - public function compose(View $view) - { - $view->with('count', $this->users->count()); - } - } + users = $users; + } + + /** + * Bind data to the view. + * + * @param View $view + * @return void + */ + public function compose(View $view) + { + $view->with('count', $this->users->count()); + } + } Just before the view is rendered, the composer's `compose` method is called with the `Illuminate\Contracts\View\View` instance. You may use the `with` method to bind data to the view. @@ -184,19 +184,19 @@ Just before the view is rendered, the composer's `compose` method is called with You may attach a view composer to multiple views at once by passing an array of views as the first argument to the `composer` method: - view()->composer( - ['profile', 'dashboard'], - 'App\Http\ViewComposers\MyViewComposer' - ); + view()->composer( + ['profile', 'dashboard'], + 'App\Http\ViewComposers\MyViewComposer' + ); The `composer` method accepts the `*` character as a wildcard, allowing you to attach a composer to all views: - view()->composer('*', function ($view) { - // - }); + view()->composer('*', function ($view) { + // + }); ### View Creators View **creators** are very similar to view composers; however, they are fired immediately when the view is instantiated instead of waiting until the view is about to render. To register a view creator, use the `creator` method: - view()->creator('profile', 'App\Http\ViewCreators\ProfileCreator'); + view()->creator('profile', 'App\Http\ViewCreators\ProfileCreator');