diff --git a/artisan.md b/artisan.md index be40f90f116..8477bd86a87 100644 --- a/artisan.md +++ b/artisan.md @@ -49,7 +49,7 @@ Sometimes you may wish to execute an Artisan command outside of the CLI. For exa // }); -You may even queue Artisan commands so they are processed in the background by your [queue workers](/docs/5.0/queues): +You may even queue Artisan commands so they are processed in the background by your [queue workers](/docs/{{version}}/queues): Route::get('/foo', function() { @@ -124,6 +124,24 @@ Let's look at a few more scheduling examples: $schedule->command('foo')->monthly(); +#### Job That Runs On Specific Days + + $schedule->command('foo')->mondays(); + $schedule->command('foo')->tuesdays(); + $schedule->command('foo')->wednesdays(); + $schedule->command('foo')->thursdays(); + $schedule->command('foo')->fridays(); + $schedule->command('foo')->saturdays(); + $schedule->command('foo')->sundays(); + +#### Prevent Jobs From Overlapping + +By default, scheduled jobs will be run even if the previous instance of the job is still running. To prevent this, you may use the `withoutOverlapping` method: + + $schedule->command('foo')->withoutOverlapping(); + +In this example, the `foo` command will be run every minute if it is not already running. + #### Limit The Environment The Jobs Should Run In $schedule->command('foo')->monthly()->environments('production'); @@ -138,3 +156,21 @@ Let's look at a few more scheduling examples: { return true; }); + +#### E-mail The Output Of A Scheduled Job + + $schedule->command('foo')->sendOutputTo($filePath)->emailOutputTo('foo@example.com'); + +> **Note:** You must send the output to a file before it can be mailed. + +#### Send The Output Of The Scheduled Job To A Given Location + + $schedule->command('foo')->sendOutputTo($filePath); + +#### Ping A Given URL After The Job Runs + + $schedule->command('foo')->thenPing($url); + +Using the `thenPing($url)` feature requires the Guzzle HTTP library. You can add Guzzle 5 to your project by adding the following line to your `composer.json` file: + + "guzzlehttp/guzzle": "~5.0" diff --git a/authentication.md b/authentication.md index 4bd075cfee5..882d2c3dbd5 100644 --- a/authentication.md +++ b/authentication.md @@ -58,7 +58,7 @@ If you choose not to use the provided `AuthController` implementation, you will } -The `attempt` method accepts an array of key / value pairs as its first argument. The `password` value will be [hashed](/docs/5.0/hashing). The other values in the array will be used to find the user in your database table. So, in the example above, the user will be retrieved by the value of the `email` column. If the user is found, the hashed password stored in the database will be compared with the hashed `password` value passed to the method via the array. If the two hashed passwords match, a new authenticated session will be started for the user. +The `attempt` method accepts an array of key / value pairs as its first argument. The `password` value will be [hashed](/docs/{{version}}/hashing). The other values in the array will be used to find the user in your database table. So, in the example above, the user will be retrieved by the value of the `email` column. If the user is found, the hashed password stored in the database will be compared with the hashed `password` value passed to the method via the array. If the two hashed passwords match, a new authenticated session will be started for the user. The `attempt` method will return `true` if authentication was successful. Otherwise, `false` will be returned. @@ -70,10 +70,10 @@ The `intended` redirect function will redirect the user to the URL they were att You also may add extra conditions to the authentication query: - if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) - { - // The user is active, not suspended, and exists. - } + if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) + { + // The user is active, not suspended, and exists. + } #### Determining If A User Is Authenticated @@ -140,7 +140,7 @@ Of course, if you are using the built-in Laravel authentication controllers, a c #### Authentication Events -When the `attempt` method is called, the `auth.attempt` [event](/docs/5.0/events) will be fired. If the authentication attempt is successful and the user is logged in, the `auth.login` event will be fired as well. +When the `attempt` method is called, the `auth.attempt` [event](/docs/{{version}}/events) will be fired. If the authentication attempt is successful and the user is logged in, the `auth.login` event will be fired as well. ## Retrieving The Authenticated User @@ -149,8 +149,11 @@ Once a user is authenticated, there are several ways to obtain an instance of th First, you may access the user from the `Auth` facade: - ## Protecting Routes -[Route middleware](/docs/5.0/middleware) can be used to allow only authenticated users to access a given route. Laravel provides the `auth` middleware by default, and it is defined in `app\Http\Middleware\Authenticate.php`. All you need to do is attach it to a route definition: +[Route middleware](/docs/{{version}}/middleware) can be used to allow only authenticated users to access a given route. Laravel provides the `auth` middleware by default, and it is defined in `app\Http\Middleware\Authenticate.php`. All you need to do is attach it to a route definition: // With A Route Closure... @@ -247,7 +254,7 @@ By default, the `basic` middleware will use the `email` column on the user recor #### Setting Up A Stateless HTTP Basic Filter -You may also use HTTP Basic Authentication without setting a user identifier cookie in the session, which is particularly useful for API authentication. To do so, [define a middleware](/docs/5.0/middleware) that calls the `onceBasic` method: +You may also use HTTP Basic Authentication without setting a user identifier cookie in the session, which is particularly useful for API authentication. To do so, [define a middleware](/docs/{{version}}/middleware) that calls the `onceBasic` method: public function handle($request, Closure $next) { @@ -282,18 +289,18 @@ Your user will receive an e-mail with a link that points to the `getReset` metho protected $redirectTo = '/dashboard'; -> **Note:** By default, password reset tokens expire after one hour. You may change this via the `reminder.expire` option of your `config/auth.php` file. +> **Note:** By default, password reset tokens expire after one hour. You may change this via the `reminder.expire` option in your `config/auth.php` file. ## Social Authentication -In addition to typical, form based authentication, Laravel also provides a simple, convenient way to authenticate with OAuth providers using [Laravel Socialite](https://github.com/laravel/socialite). **Socialite currently supports authentication with Facebook, Twitter, Google, and GitHub.** +In addition to typical, form based authentication, Laravel also provides a simple, convenient way to authenticate with OAuth providers using [Laravel Socialite](https://github.com/laravel/socialite). **Socialite currently supports authentication with Facebook, Twitter, Google, GitHub and Bitbucket.** To get started with Socialite, include the package in your `composer.json` file: "laravel/socialite": "~2.0" -Next, register the `Laravel\Socialite\SocialiteServiceProvider` in your `config/app.php` configuration file. You may also register a [facade](/docs/5.0/facades): +Next, register the `Laravel\Socialite\SocialiteServiceProvider` in your `config/app.php` configuration file. You may also register a [facade](/docs/{{version}}/facades): 'Socialize' => 'Laravel\Socialite\Facades\Socialite', @@ -337,6 +344,7 @@ Once you have a user instance, you can grab a few more details about the user: $tokenSecret = $user->tokenSecret; // All Providers + $user->getId(); $user->getNickname(); $user->getName(); $user->getEmail(); diff --git a/billing.md b/billing.md index 460119f2136..dc195850f9d 100644 --- a/billing.md +++ b/billing.md @@ -3,13 +3,15 @@ - [Introduction](#introduction) - [Configuration](#configuration) - [Subscribing To A Plan](#subscribing-to-a-plan) +- [Single Charges](#single-charges) - [No Card Up Front](#no-card-up-front) - [Swapping Subscriptions](#swapping-subscriptions) - [Subscription Quantity](#subscription-quantity) +- [Subscription Tax](#subscription-tax) - [Cancelling A Subscription](#cancelling-a-subscription) - [Resuming A Subscription](#resuming-a-subscription) - [Checking Subscription Status](#checking-subscription-status) -- [Handling Failed Payments](#handling-failed-payments) +- [Handling Failed Subscriptions](#handling-failed-subscriptions) - [Handling Other Stripe Webhooks](#handling-other-stripe-webhooks) - [Invoices](#invoices) @@ -25,7 +27,9 @@ Laravel Cashier provides an expressive, fluent interface to [Stripe's](https://s First, add the Cashier package to your `composer.json` file: - "laravel/cashier": "~3.0" + "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 @@ -42,7 +46,7 @@ Next, add the `Billable` trait and appropriate date mutators to your model defin use Laravel\Cashier\Billable; use Laravel\Cashier\Contracts\Billable as BillableContract; - class User extends Eloquent implements BillableContract { + class User extends Model implements BillableContract { use Billable; @@ -52,7 +56,14 @@ Next, add the `Billable` trait and appropriate date mutators to your model defin #### Stripe Key -Finally, set your Stripe key in one of your bootstrap files or service providers, such as the `AppServiceProvider`: +Finally, set your Stripe key in your `services.php` config file: + + 'stripe' => [ + 'model' => 'User', + 'secret' => env('STRIPE_API_SECRET'), + ], + +Alternatively you can store it in one of your bootstrap files or service providers, such as the `AppServiceProvider`: User::setStripeKey('stripe-key'); @@ -89,6 +100,31 @@ If you would like to specify additional customer details, you may do so by passi 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). + +## 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: + + $user->charge(100); + +The `charge` method accepts the amount you would like to charge in the **lowest denominator of the currency**. So, for example, the example above will charge 100 cents, or $1.00, against the user's credit card. + +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, + ]); + +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 the charge is successful, the full Stripe response will be returned from the method. + ## No Card Up Front @@ -123,11 +159,23 @@ Sometimes subscriptions are affected by "quantity". For example, your applicatio // 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); + +## Subscription Tax + +With Cashier, it's easy to override the `tax_percent` value sent to Stripe. To specify the tax percentage a user pays on a subscription, implement the `getTaxPercent` method on your model, and return a numeric value between 0 and 100, with no more than 2 decimal places. + + 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. + ## Cancelling A Subscription @@ -149,14 +197,14 @@ If the user cancels a subscription and then resumes that subscription before the ## Checking Subscription Status -To verify that a user is subscribed to your application, use the `subscribed` command: +To verify that a user is subscribed to your application, use the `subscribed` method: if ($user->subscribed()) { // } -The `subscribed` method makes a great candidate for a [route middleware](/docs/5.0/middleware): +The `subscribed` method makes a great candidate for a [route middleware](/docs/{{version}}/middleware): public function handle($request, Closure $next) { @@ -203,14 +251,14 @@ The `onPlan` method may be used to determine if the user is subscribed to a give // } - -## Handling Failed Payments + +## Handling Failed Subscriptions 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'); -That's it! Failed payments will be captured and handled by the controller. The controller will cancel the customer's subscription after three failed payment attempts. The `stripe/webhook` URI in this example is just for example. You will need to configure the URI in your Stripe settings. +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). The `stripe/webhook` URI in this example is just for example. You will need to configure the URI in your Stripe settings. ## Handling Other Stripe Webhooks diff --git a/bus.md b/bus.md index c001454f2bf..78b2367dbfe 100644 --- a/bus.md +++ b/bus.md @@ -55,7 +55,7 @@ The newly generated class will be placed in the `app/Commands` directory. By def } -The `handle` method may also type-hint dependencies, and they will be automatically injected by the [IoC container](/docs/5.0/container). For example: +The `handle` method may also type-hint dependencies, and they will be automatically injected by the [service container](/docs/{{version}}/container). For example: /** * Execute the command. @@ -116,7 +116,7 @@ If you would like to convert an existing command into a queued command, simply i Then, just write your command normally. When you dispatch it to the bus that bus will automatically queue the command for background processing. It doesn't get any easier than that. -For more information on interacting with queued commands, view the full [queue documentation](/docs/5.0/queues). +For more information on interacting with queued commands, view the full [queue documentation](/docs/{{version}}/queues). ## Command Pipeline @@ -136,12 +136,12 @@ A command pipe is defined with a `handle` method, just like a middleware: return DB::transaction(function() use ($command, $next) { return $next($command); - } + }); } } -Command pipe classes are resolved through the [IoC container](/docs/5.0/container), so feel free to type-hint any dependencies you need within their constructors. +Command pipe classes are resolved through the [IoC container](/docs/{{version}}/container), so feel free to type-hint any dependencies you need within their constructors. You may even define a `Closure` as a command pipe: @@ -150,5 +150,5 @@ You may even define a `Closure` as a command pipe: return DB::transaction(function() use ($command, $next) { return $next($command); - } + }); }]); diff --git a/cache.md b/cache.md index 4ea3c0a5542..682efae904d 100644 --- a/cache.md +++ b/cache.md @@ -4,7 +4,10 @@ - [Cache Usage](#cache-usage) - [Increments & Decrements](#increments-and-decrements) - [Cache Tags](#cache-tags) +- [Cache Events](#cache-events) - [Database Cache](#database-cache) +- [Memcached Cache](#memcached-cache) +- [Redis Cache](#redis-cache) ## Configuration @@ -81,10 +84,16 @@ If you need to retrieve an item from the cache and then delete it, you may use t Cache::forget('key'); +#### Access Specific Cache Stores + +When using multiple cache stores, you may access them via the `store` method: + + $value = Cache::store('foo')->get('key'); + ## Increments & Decrements -All drivers except `file` and `database` support the `increment` and `decrement` operations: +All drivers except `database` support the `increment` and `decrement` operations: #### Incrementing A Value @@ -131,6 +140,27 @@ In contrast, this statement would remove only caches tagged with `authors`, so " Cache::tags('authors')->flush(); + +## Cache Events + +To execute code on every cache operation, you may listen for the events fired by the cache: + + Event::listen('cache.hit', function($key, $value) { + // + }); + + Event::listen('cache.missed', function($key) { + // + }); + + Event::listen('cache.write', function($key, $value, $minutes) { + // + }); + + Event::listen('cache.delete', function($key) { + // + }); + ## Database Cache @@ -142,3 +172,25 @@ When using the `database` cache driver, you will need to setup a table to contai $table->text('value'); $table->integer('expiration'); }); + + +#### Memcached Cache + +Using the Memcached cache requires the [Memcached PECL package](http://pecl.php.net/package/memcached) to be installed. + +The default [configuration](#configuration) uses TCP/IP based on [Memcached::addServer](http://php.net/manual/en/memcached.addserver.php): + + 'memcached' => array( + array('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' => array( + array('host' => '/var/run/memcached/memcached.sock', 'port' => 0, 'weight' => 100), + ), + + +#### Redis Cache + +See [Redis Configuration](/docs/redis#configuration) diff --git a/collections.md b/collections.md index 1d09c70ac26..12d861eb261 100644 --- a/collections.md +++ b/collections.md @@ -14,7 +14,7 @@ The `Illuminate\Support\Collection` class provides a fluent, convenient wrapper }) ->reject(function($name) { - return is_null($value); + return empty($name); }); @@ -31,7 +31,7 @@ As mentioned above, the `collect` helper will return a new `Illuminate\Support\C $collection = Collection::make([1, 2, 3]); -Of course, collections of [Eloquent](/docs/5.0/eloquent) objects are always returned as `Collection` instances; however, you should feel free to use the `Collection` class wherever it is convenient for your application. +Of course, collections of [Eloquent](/docs/{{version}}/eloquent) objects are always returned as `Collection` instances; however, you should feel free to use the `Collection` class wherever it is convenient for your application. #### Explore The Collection diff --git a/commands.md b/commands.md index e37f189eb0d..ee077afb7e5 100644 --- a/commands.md +++ b/commands.md @@ -20,7 +20,7 @@ To create a new command, you may use the `make:console` Artisan command, which w php artisan make:console FooCommand -The command above would generate a class at `app/Console/FooCommand.php`. +The command above would generate a class at `app/Console/Commands/FooCommand.php`. When creating the command, the `--command` option may be used to assign the terminal command name: @@ -50,6 +50,10 @@ For options, the argument `mode` may be: `InputOption::VALUE_REQUIRED`, `InputOp The `VALUE_IS_ARRAY` mode indicates that the switch may be used multiple times when calling the command: + InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY + +Would then allow for this command: + php artisan foo --option=bar --option=baz The `VALUE_NONE` option indicates that the option is simply used as a "switch": @@ -122,4 +126,10 @@ Sometimes you may wish to call other commands from your command. You may do so u #### Registering An Artisan Command -Once your command is finished, you need to register it with Artisan so it will be available for use. This is typically done in the `app/Console/Kernel.php` file. Within this file, you will find a list of commands in the `commands` property. To register your command, simply add it to this list. When Artisan boots, all the commands listed in this property will be resolved by the [IoC container](/docs/5.0/container) and registered with Artisan. +Once your command is finished, you need to register it with Artisan so it will be available for use. This is typically done in the `app/Console/Kernel.php` file. Within this file, you will find a list of commands in the `commands` property. To register your command, simply add it to this list. + + protected $commands = [ + 'App\Console\Commands\FooCommand' + ]; + +When Artisan boots, all the commands listed in this property will be resolved by the [service container](/docs/{{version}}/container) and registered with Artisan. diff --git a/configuration.md b/configuration.md index 717bef0c641..7d190b67b54 100644 --- a/configuration.md +++ b/configuration.md @@ -30,14 +30,14 @@ Renaming your application is entirely optional, and you are free to keep the `Ap Laravel needs very little configuration out of the box. You are free to get started developing! However, you may wish to review the `config/app.php` file and its documentation. It contains several options such as `timezone` and `locale` that you may wish to change according to your location. -Once Laravel is installed, you should also [configure your local environment](/docs/5.0/configuration#environment-configuration). +Once Laravel is installed, you should also [configure your local environment](/docs/{{version}}/configuration#environment-configuration). > **Note:** You should never have the `app.debug` configuration option set to `true` for a production application. ### Permissions -Laravel may require one set of permissions to be configured: folders within `storage` require write access by the web server. +Laravel may require one set of permissions to be configured: folders within `storage` and `vendor` require write access by the web server. ## Accessing Configuration Values @@ -83,7 +83,7 @@ You may also pass arguments to the `environment` method to check if the environm // The environment is either local OR staging... } -To obtain an instance of the application, resolve the `Illuminate\Contracts\Foundation\Application` contract via the [service container](/docs/5.0/container). Of course, if you are within a [service provider](/docs/5.0/providers), the application instance is available via the `$this->app` instance variable. +To obtain an instance of the application, resolve the `Illuminate\Contracts\Foundation\Application` contract via the [service container](/docs/{{version}}/container). Of course, if you are within a [service provider](/docs/{{version}}/providers), the application instance is available via the `$this->app` instance variable. An application instance may also be accessed via the `app` helper or the `App` facade: @@ -117,7 +117,7 @@ The default template for maintenance mode responses is located in `resources/vie ### Maintenance Mode & Queues -While your application is in maintenance mode, no [queued jobs](/docs/5.0/queues) will be handled. The jobs will continue to be handled as normal once the application is out of maintenance mode. +While your application is in maintenance mode, no [queued jobs](/docs/{{version}}/queues) will be handled. The jobs will continue to be handled as normal once the application is out of maintenance mode. ## Pretty URLs @@ -135,12 +135,14 @@ If the `.htaccess` file that ships with Laravel does not work with your Apache i RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] +If your web host doesn't allow the `FollowSymlinks` option, try replacing it with `Options +SymLinksIfOwnerMatch`. + ### 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/5.0/homestead), pretty URLs will be configured automatically. +Of course, when using [Homestead](/docs/{{version}}/homestead), pretty URLs will be configured automatically. diff --git a/container.md b/container.md index f5ea60d84ec..74c250304b9 100644 --- a/container.md +++ b/container.md @@ -18,7 +18,7 @@ Let's look at a simple example: ## 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 definining this behavior: +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') @@ -295,7 +295,7 @@ Laravel provides several opportunities to use the service container to increase } -In this example, the `OrderRepository` class will automatically be injected into the controller. This means that a "mock" `OrderRepository` may be bound into the container when [unit testing](/docs/5.0/testing), allowing for painless stubbing of database layer interaction. +In this example, the `OrderRepository` class will automatically be injected into the controller. This means that a "mock" `OrderRepository` may be bound into the container when [unit testing](/docs/{{version}}/testing), allowing for painless stubbing of database layer interaction. #### Other Examples Of Container Usage diff --git a/contracts.md b/contracts.md index 93df76458e2..463629a8568 100644 --- a/contracts.md +++ b/contracts.md @@ -103,6 +103,7 @@ Contract | Laravel 4.x Facade ------------- | ------------- [Illuminate\Contracts\Auth\Guard](https://github.com/illuminate/contracts/blob/master/Auth/Guard.php) | Auth [Illuminate\Contracts\Auth\PasswordBroker](https://github.com/illuminate/contracts/blob/master/Auth/PasswordBroker.php) | Password +[Illuminate\Contracts\Bus\Dispatcher](https://github.com/illuminate/contracts/blob/master/Bus/Dispatcher.php) | Bus [Illuminate\Contracts\Cache\Repository](https://github.com/illuminate/contracts/blob/master/Cache/Repository.php) | Cache [Illuminate\Contracts\Cache\Factory](https://github.com/illuminate/contracts/blob/master/Cache/Factory.php) | Cache::driver() [Illuminate\Contracts\Config\Repository](https://github.com/illuminate/contracts/blob/master/Config/Repository.php) | Config @@ -136,7 +137,7 @@ Contract | Laravel 4.x Facade ## How To Use Contracts -So, how do you get an implementation of a contract? It's actually quite simple. Many types of classes in Laravel are resolved through the [service container](/docs/5.0/container), including controllers, event listeners, filters, queue jobs, and even route Closures. So, to get an implementation of a contract, you can just "type-hint" the interface in the constructor of the class being resolved. For example, take a look at this event handler: +So, how do you get an implementation of a contract? It's actually quite simple. Many types of classes in Laravel are resolved through the [service container](/docs/{{version}}/container), including controllers, event listeners, filters, queue jobs, and even route Closures. So, to get an implementation of a contract, you can just "type-hint" the interface in the constructor of the class being resolved. For example, take a look at this event handler: ## Security Vulnerabilities -If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell at taylorotwell@gmail.com. All security vulnerabilities will be promptly addressed. +If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell at taylor@laravel.com. All security vulnerabilities will be promptly addressed. ## Coding Style -Laravel follows the [PSR-0](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md) and [PSR-1](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md) coding standards. In addition to these standards, the following coding standards should be followed: +Laravel follows the [PSR-4](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md) and [PSR-1](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md) coding standards. In addition to these standards, the following coding standards should be followed: - The class namespace declaration must be on the same line as ` ## Controller Middleware -[Middleware](/docs/5.0/middleware) may be specified on controller routes like so: +[Middleware](/docs/{{version}}/middleware) may be specified on controller routes like so: Route::get('profile', [ 'middleware' => 'auth', @@ -110,7 +110,7 @@ Laravel allows you to easily define a single route to handle every action in a c 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. Next, just add methods to your controller, prefixed with the HTTP verb they respond to: - class UserController extends BaseController { + class UserController extends Controller { public function getIndex() { @@ -135,6 +135,14 @@ If your controller action contains multiple words, you may access the action usi public function getAdminProfile() {} +#### Assigning Route Names + +If you would like to "name" some of the routes on the controller, you may pass a third argument to the `controller` method: + + Route::controller('users', 'UserController', [ + 'anyLogin' => 'user.login', + ]); + ## RESTful Resource Controllers @@ -150,15 +158,15 @@ This single route declaration creates multiple routes to handle a variety of RES #### Actions Handled By Resource Controller -Verb | Path | Action | Route Name -----------|-----------------------------|--------------|--------------------- -GET | /resource | index | resource.index -GET | /resource/create | create | resource.create -POST | /resource | store | resource.store -GET | /resource/{resource} | show | resource.show -GET | /resource/{resource}/edit | edit | resource.edit -PUT/PATCH | /resource/{resource} | update | resource.update -DELETE | /resource/{resource} | destroy | resource.destroy +Verb | Path | Action | Route Name +----------|-----------------------|--------------|--------------------- +GET | /photo | index | photo.index +GET | /photo/create | create | photo.create +POST | /photo | store | photo.store +GET | /photo/{photo} | show | photo.show +GET | /photo/{photo}/edit | edit | photo.edit +PUT/PATCH | /photo/{photo} | update | photo.update +DELETE | /photo/{photo} | destroy | photo.destroy #### Customizing Resource Routes @@ -203,7 +211,7 @@ This route will register a "nested" resource that may be accessed with URLs like 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`: - Route::get('photos/popular'); + Route::get('photos/popular', 'PhotoController@method'); Route::resource('photos', 'PhotoController'); @@ -212,7 +220,7 @@ If it becomes necessary to add additional routes to a resource controller beyond #### Constructor Injection -The Laravel [service container](/docs/5.0/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 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: **Note:** Method injection is fully compatible with [model binding](/docs/5.0/routing#route-model-binding). The container will intelligently determine which arguments are model bound and which arguments should be injected. +> **Note:** Method injection is fully compatible with [model binding](/docs/{{version}}/routing#route-model-binding). The container will intelligently determine which arguments are model bound and which arguments should be injected. ## Route Caching diff --git a/database.md b/database.md index f605bd84767..62ad062427c 100644 --- a/database.md +++ b/database.md @@ -50,6 +50,10 @@ Once you have configured your database connection, you may run queries using the The `select` method will always return an `array` of results. +You may also execute a query using named bindings: + + $results = DB::select('select * from users where id = :id', ['id' => 1]); + #### Running An Insert Statement DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']); diff --git a/documentation.md b/documentation.md old mode 100755 new mode 100644 index b05cccfba27..e831b49107c --- a/documentation.md +++ b/documentation.md @@ -1,55 +1,56 @@ -- Prologue - - [Release Notes](/docs/5.0/releases) - - [Upgrade Guide](/docs/5.0/upgrade) - - [Contribution Guide](/docs/5.0/contributions) -- Setup - - [Installation](/docs/5.0/installation) - - [Configuration](/docs/5.0/configuration) - - [Homestead](/docs/5.0/homestead) -- The Basics - - [Routing](/docs/5.0/routing) - - [Middleware](/docs/5.0/middleware) - - [Controllers](/docs/5.0/controllers) - - [Requests](/docs/5.0/requests) - - [Responses](/docs/5.0/responses) - - [Views](/docs/5.0/views) -- Architecture Foundations - - [Service Providers](/docs/5.0/providers) - - [Service Container](/docs/5.0/container) - - [Contracts](/docs/5.0/contracts) - - [Facades](/docs/5.0/facades) - - [Request Lifecycle](/docs/5.0/lifecycle) - - [Application Structure](/docs/5.0/structure) -- Services - - [Authentication](/docs/5.0/authentication) - - [Billing](/docs/5.0/billing) - - [Cache](/docs/5.0/cache) - - [Collections](/docs/5.0/collections) - - [Command Bus](/docs/5.0/bus) - - [Core Extension](/docs/5.0/extending) - - [Elixir](/docs/5.0/elixir) - - [Encryption](/docs/5.0/encryption) - - [Errors & Logging](/docs/5.0/errors) - - [Events](/docs/5.0/events) - - [Filesystem / Cloud Storage](/docs/5.0/filesystem) - - [Hashing](/docs/5.0/hashing) - - [Helpers](/docs/5.0/helpers) - - [Localization](/docs/5.0/localization) - - [Mail](/docs/5.0/mail) - - [Package Development](/docs/5.0/packages) - - [Pagination](/docs/5.0/pagination) - - [Queues](/docs/5.0/queues) - - [Session](/docs/5.0/session) - - [Templates](/docs/5.0/templates) - - [Unit Testing](/docs/5.0/testing) - - [Validation](/docs/5.0/validation) -- Database - - [Basic Usage](/docs/5.0/database) - - [Query Builder](/docs/5.0/queries) - - [Eloquent ORM](/docs/5.0/eloquent) - - [Schema Builder](/docs/5.0/schema) - - [Migrations & Seeding](/docs/5.0/migrations) - - [Redis](/docs/5.0/redis) -- Artisan CLI - - [Overview](/docs/5.0/artisan) - - [Development](/docs/5.0/commands) +- ## Prologue + - [Release Notes](/docs/{{version}}/releases) + - [Upgrade Guide](/docs/{{version}}/upgrade) + - [Contribution Guide](/docs/{{version}}/contributions) +- ## Setup + - [Installation](/docs/{{version}}/installation) + - [Configuration](/docs/{{version}}/configuration) + - [Homestead](/docs/{{version}}/homestead) +- ## The Basics + - [Routing](/docs/{{version}}/routing) + - [Middleware](/docs/{{version}}/middleware) + - [Controllers](/docs/{{version}}/controllers) + - [Requests](/docs/{{version}}/requests) + - [Responses](/docs/{{version}}/responses) + - [Views](/docs/{{version}}/views) +- ## Architecture Foundations + - [Service Providers](/docs/{{version}}/providers) + - [Service Container](/docs/{{version}}/container) + - [Contracts](/docs/{{version}}/contracts) + - [Facades](/docs/{{version}}/facades) + - [Request Lifecycle](/docs/{{version}}/lifecycle) + - [Application Structure](/docs/{{version}}/structure) +- ## Services + - [Authentication](/docs/{{version}}/authentication) + - [Billing](/docs/{{version}}/billing) + - [Cache](/docs/{{version}}/cache) + - [Collections](/docs/{{version}}/collections) + - [Command Bus](/docs/{{version}}/bus) + - [Core Extension](/docs/{{version}}/extending) + - [Elixir](/docs/{{version}}/elixir) + - [Encryption](/docs/{{version}}/encryption) + - [Envoy](/docs/{{version}}/envoy) + - [Errors & Logging](/docs/{{version}}/errors) + - [Events](/docs/{{version}}/events) + - [Filesystem / Cloud Storage](/docs/{{version}}/filesystem) + - [Hashing](/docs/{{version}}/hashing) + - [Helpers](/docs/{{version}}/helpers) + - [Localization](/docs/{{version}}/localization) + - [Mail](/docs/{{version}}/mail) + - [Package Development](/docs/{{version}}/packages) + - [Pagination](/docs/{{version}}/pagination) + - [Queues](/docs/{{version}}/queues) + - [Session](/docs/{{version}}/session) + - [Templates](/docs/{{version}}/templates) + - [Unit Testing](/docs/{{version}}/testing) + - [Validation](/docs/{{version}}/validation) +- ## Database + - [Basic Usage](/docs/{{version}}/database) + - [Query Builder](/docs/{{version}}/queries) + - [Eloquent ORM](/docs/{{version}}/eloquent) + - [Schema Builder](/docs/{{version}}/schema) + - [Migrations & Seeding](/docs/{{version}}/migrations) + - [Redis](/docs/{{version}}/redis) +- ## Artisan CLI + - [Overview](/docs/{{version}}/artisan) + - [Development](/docs/{{version}}/commands) diff --git a/elixir.md b/elixir.md index 43abd3ac194..27479ea4a81 100644 --- a/elixir.md +++ b/elixir.md @@ -9,8 +9,7 @@ ## Introduction -Laravel Elixir provides a clean, fluent API for defining basic [Gulp](http://gulpjs.com) tasks for your -Laravel application. Elixir supports several common CSS and JavaScript pre-processors, and even testing tools. +Laravel Elixir provides a clean, fluent API for defining basic [Gulp](http://gulpjs.com) tasks for your Laravel application. Elixir supports several common CSS and JavaScript pre-processors, and even testing tools. If you've ever been confused about how to get started with Gulp and asset compilation, you will love Laravel Elixir! @@ -23,9 +22,7 @@ Before triggering Elixir, you must first ensure that Node.js is installed on you node -v -By default, Laravel Homestead includes everything you need; however, if you aren't using Vagrant, then you -can easily install Node by visiting [their download page](http://nodejs.org/download/). Don't worry, it's -quick and easy! +By default, Laravel Homestead includes everything you need; however, if you aren't using Vagrant, then you can easily install Node by visiting [their download page](http://nodejs.org/download/). Don't worry, it's quick and easy! ### Gulp @@ -37,38 +34,69 @@ Next, you'll want to pull in [Gulp](http://gulpjs.com) as a global NPM package l The only remaining step is to install Elixir! With a new install 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 ## Usage -Now that you've installed Elixir, you'll be compiling and concatenating in no time! +Now that you've installed Elixir, you'll be compiling and concatenating in no time! The `gulpfile.js` file in your project's root directory contains all of your Elixir tasks. #### Compile Less ```javascript elixir(function(mix) { - mix.less("app.less"); + mix.less("app.less"); }); ``` In the example above, Elixir assumes that your Less files are stored in `resources/assets/less`. +#### Compile Multiple Less Files + +```javascript +elixir(function(mix) { + mix.less([ + 'app.less', + 'something-else.less' + ]); +}); +``` + #### Compile Sass ```javascript elixir(function(mix) { - mix.sass("app.sass"); + mix.sass("app.scss"); }); ``` This assumes that your Sass files are stored in `resources/assets/sass`. +By default, Elixir, underneath the hood, uses the LibSass library for compilation. In some instances, it might prove advantageous to instead leverage the Ruby version, which, though slower, is more feature rich. Assuming that you have both Ruby and the Sass gem installed (`gem install sass`), you may enable Ruby-mode, like so: + +```javascript +elixir(function(mix) { + mix.rubySass("app.sass"); +}); +``` + +#### Compile Without Source Maps + +```javascript +elixir.config.sourcemaps = false; + +elixir(function(mix) { + mix.sass("app.scss"); +}); +``` + +Source maps are enabled out of the box. As such, for each file that is compiled, you'll find a companion `*.css.map` file in the same directory. This mapping allows you to, when debugging, trace your compiled stylesheet selectors back to your original Sass or Less partials! Should you need to disable this functionality, however, the code sample above will do the trick. + #### Compile CoffeeScript ```javascript elixir(function(mix) { - mix.coffee(); + mix.coffee(); }); ``` @@ -87,7 +115,7 @@ elixir(function(mix) { ```javascript elixir(function(mix) { - mix.phpUnit(); + mix.phpUnit(); }); ``` @@ -95,7 +123,7 @@ elixir(function(mix) { ```javascript elixir(function(mix) { - mix.phpSpec(); + mix.phpSpec(); }); ``` @@ -103,23 +131,23 @@ elixir(function(mix) { ```javascript elixir(function(mix) { - mix.styles([ - "normalize.css", - "main.css" - ]); + mix.styles([ + "normalize.css", + "main.css" + ]); }); ``` -Paths passed to this method are relative to the `resources/css` directory. +Paths passed to this method are relative to the `resources/assets/css` directory. #### Combine Stylesheets and Save to a Custom Directory ```javascript elixir(function(mix) { - mix.styles([ - "normalize.css", - "main.css" - ], 'public/build/css/everything.css'); + mix.styles([ + "normalize.css", + "main.css" + ], 'public/build/css/everything.css'); }); ``` @@ -127,10 +155,10 @@ elixir(function(mix) { ```javascript elixir(function(mix) { - mix.styles([ - "normalize.css", - "main.css" - ], 'public/build/css/everything.css', 'public/css'); + mix.styles([ + "normalize.css", + "main.css" + ], 'public/build/css/everything.css', 'public/css'); }); ``` @@ -140,7 +168,7 @@ The third argument to both the `styles` and `scripts` methods determines the rel ```javascript elixir(function(mix) { - mix.stylesIn("public/css"); + mix.stylesIn("public/css"); }); ``` @@ -148,20 +176,20 @@ elixir(function(mix) { ```javascript elixir(function(mix) { - mix.scripts([ - "jquery.js", - "app.js" - ]); + mix.scripts([ + "jquery.js", + "app.js" + ]); }); ``` -Again, this assumes all paths are relative to the `resources/js` directory. +Again, this assumes all paths are relative to the `resources/assets/js` directory. #### Combine All Scripts in a Directory ```javascript elixir(function(mix) { - mix.scriptsIn("public/js/some/directory"); + mix.scriptsIn("public/js/some/directory"); }); ``` @@ -178,7 +206,7 @@ elixir(function(mix) { ```javascript elixir(function(mix) { - mix.version("css/all.css"); + mix.version("css/all.css"); }); ``` @@ -186,9 +214,7 @@ This will append a unique hash to the filename, allowing for cache-busting. For Within your views, you may use the `elixir()` function to load the appropriately hashed asset. Here's an example: -```html - -``` + Behind the scenes, the `elixir()` function will determine the name of the hashed file that should be included. Don't you feel the weight lifting off your shoulders already? @@ -196,20 +222,18 @@ You may also 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"]); }); ``` -```html - - -``` + + #### Copy a File to a New Location ```javascript elixir(function(mix) { - mix.copy('vendor/foo/bar.css', 'public/css/bar.css'); + mix.copy('vendor/foo/bar.css', 'public/css/bar.css'); }); ``` @@ -217,10 +241,22 @@ elixir(function(mix) { ```javascript elixir(function(mix) { - mix.copy('vendor/package/views', 'resources/views'); + mix.copy('vendor/package/views', 'resources/views'); +}); +``` + +#### Trigger Browserify + +```javascript +elixir(function(mix) { + mix.browserify('index.js'); }); ``` +Want to require modules in the browser? Hoping to use EcmaScript 6 sooner than later? Need a built-in JSX transformer? If so, [Browserify](http://browserify.org/), along with the `browserify` Elixir task, will handle the job nicely. + +This task assumes that your scripts are stored in `resources/assets/js`, though you're free to override the default. + #### Method Chaining Of course, you may chain almost all of Elixir's methods together to build your recipe: @@ -241,49 +277,87 @@ Now that you've told Elixir which tasks to execute, you only need to trigger Gul #### Execute All Registered Tasks Once - gulp + gulp #### Watch Assets For Changes - gulp watch + gulp watch + +#### Only Compile Scripts + + gulp scripts + +#### Only Compile Styles + + gulp styles #### Watch Tests And PHP Classes for Changes - gulp tdd + gulp tdd > **Note:** All tasks will assume a development environment, and will exclude minification. For production, use `gulp --production`. -## Extensions +## Custom Tasks and Extensions + +Sometimes, you'll want to hook your own Gulp tasks into Elixir. Perhaps you have a special bit of functionality that you'd like Elixir to mix and watch for you. No problem! + +As an example, imagine that you have a general task that simply speaks a bit of text when called. + +```javascript +gulp.task("speak", function() { + var message = "Tea...Earl Grey...Hot"; + + gulp.src("").pipe(shell("say " + message)); +}); +``` + +Easy enough. From the command line, you may, of course, call `gulp speak` to trigger the task. To add it to Elixir, however, use the `mix.task()` method: + +```javascript +elixir(function(mix) { + mix.task('speak'); +}); +``` + +That's it! Now, each time you run Gulp, your custom "speak" task will be executed alongside any other Elixir tasks that you've mixed in. To additionally register a watcher, so that your custom tasks will be re-triggered each time one or more files are modified, you may pass a regular expression as the second argument. + +```javascript +elixir(function(mix) { + mix.task('speak', 'app/**/*.php'); +}); +``` + +By adding this second argument, we've instructed Elixir to re-trigger the "speak" task each time a PHP file in the "app/" directory is saved. + -You can even create your own Gulp tasks, and hook them into Elixir. Imagine that you want to add a fun task that - uses the Terminal to verbally notify you with some message. Here's what that might look like: +For even more flexibility, you can create full Elixir extensions. Using the previous "speak" example, you may write an extension, like so: ```javascript - var gulp = require("gulp"); - var shell = require("gulp-shell"); - var elixir = require("laravel-elixir"); +var gulp = require("gulp"); +var shell = require("gulp-shell"); +var elixir = require("laravel-elixir"); - elixir.extend("message", function(message) { +elixir.extend("speak", function(message) { - gulp.task("say", function() { - gulp.src("").pipe(shell("say " + message)); - }); + gulp.task("speak", function() { + gulp.src("").pipe(shell("say " + message)); + }); - return this.queueTask("say"); + return this.queueTask("speak"); }); ``` -Notice that we `extend` Elixir's API by passing the key that we will use within our Gulpfile, as well as a callback function that will create the Gulp task. +Notice that we `extend` Elixir's API by passing the name that we will reference within our Gulpfile, as well as a callback function that will create the Gulp task. -If you want your custom task to be monitored, then register a watcher as well. +As before, if you want your custom task to be monitored, then register a watcher. ```javascript -this.registerWatcher("message", "**/*.php"); +this.registerWatcher("speak", "app/**/*.php"); ``` -This lines designates that when any file that matches the regex, `**/*.php` is modified, we want to trigger the `message` task. +This lines designates that when any file that matches the regular expression, `app/**/*.php`, is modified, we want to trigger the `speak` task. That's it! You may either place this at the top of your Gulpfile, or instead extract it to a custom tasks file. If you choose the latter approach, simply require it into your Gulpfile, like so: @@ -295,7 +369,7 @@ You're done! Now, you can mix it in. ```javascript elixir(function(mix) { - mix.message("Tea, Earl Grey, Hot"); + mix.speak("Tea, Earl Grey, Hot"); }); ``` diff --git a/eloquent.md b/eloquent.md index b98c8aa2f0f..e1f0a913204 100644 --- a/eloquent.md +++ b/eloquent.md @@ -20,6 +20,7 @@ - [Attribute Casting](#attribute-casting) - [Model Events](#model-events) - [Model Observers](#model-observers) +- [Model URL Generation](#model-url-generation) - [Converting To Arrays / JSON](#converting-to-arrays-or-json) @@ -42,7 +43,7 @@ You may also generate Eloquent models using the `make:model` command: php artisan make:model User -Note that we did not tell Eloquent which table to use for our `User` model. The lower-case, plural name of the class will be used as the table name unless another name is explicitly specified. So, in this case, Eloquent will assume the `User` model stores records in the `users` table. You may specify a custom table by defining a `table` property on your model: +Note that we did not tell Eloquent which table to use for our `User` model. The "snake case", plural name of the class will be used as the table name unless another name is explicitly specified. So, in this case, Eloquent will assume the `User` model stores records in the `users` table. You may specify a custom table by defining a `table` property on your model: class User extends Model { @@ -54,7 +55,7 @@ Note that we did not tell Eloquent which table to use for our `User` model. The Once a model is defined, you are ready to start retrieving and creating records in your table. Note that you will need to place `updated_at` and `created_at` columns on your table by default. If you do not wish to have these columns automatically maintained, set the `$timestamps` property on your model to `false`. -#### Retrieving All Models +#### Retrieving All Records $users = User::all(); @@ -68,20 +69,29 @@ Once a model is defined, you are ready to start retrieving and creating records #### Retrieving A Model By Primary Key Or Throw An Exception -Sometimes you may wish to throw an exception if a model is not found, allowing you to catch the exceptions using an `App::error` handler and display a 404 page. +Sometimes you may wish to throw an exception if a model is not found. To do this, you may use the `firstOrFail` method: $model = User::findOrFail(1); $model = User::where('votes', '>', 100)->firstOrFail(); -To register the error handler, listen for the `ModelNotFoundException` +Doing this will let you catch the exception so you can log and display an error page as necessary. To catch the `ModelNotFoundException`, add some logic to your `app/Exceptions/Handler.php` file. use Illuminate\Database\Eloquent\ModelNotFoundException; - App::error(function(ModelNotFoundException $e) - { - return Response::make('Not Found', 404); - }); + class Handler extends ExceptionHandler { + + public function render($request, Exception $e) + { + if ($e instanceof ModelNotFoundException) + { + // Custom logic for model not found... + } + + return parent::render($request, $e); + } + + } #### Querying Using Eloquent Models @@ -122,7 +132,7 @@ You may also specify which database connection should be used when running an El $user = User::on('connection-name')->find(1); -If you are using [read / write connections](/docs/5.0/database#read-write-connections), you may force the query to use the "write" connection with the following method: +If you are using [read / write connections](/docs/{{version}}/database#read-write-connections), you may force the query to use the "write" connection with the following method: $user = User::onWriteConnection()->find(1); @@ -633,7 +643,7 @@ Even though the `posts` table does not contain a `country_id` column, the `hasMa public function posts() { - return $this->hasManyThrough('App\Post', 'User'); + return $this->hasManyThrough('App\Post', 'App\User'); } } @@ -644,7 +654,7 @@ If you would like to manually specify the keys of the relationship, you may pass public function posts() { - return $this->hasManyThrough('App\Post', 'User', 'country_id', 'user_id'); + return $this->hasManyThrough('App\Post', 'App\User', 'country_id', 'user_id'); } } @@ -900,6 +910,13 @@ It is also possible to eagerly load related models directly from an already exis $books->load('author', 'publisher'); +You may also pass a Closure to set constraints on the query: + + $books->load(['author' => function($query) + { + $query->orderBy('published_date', 'asc'); + }]); + ## Inserting Related Models @@ -1118,10 +1135,17 @@ When filtering collections, the callback provided will be used as callback for [ return $role->created_at; }); + $roles = $roles->sortByDesc(function($role) + { + return $role->created_at; + }); + #### Sorting A Collection By A Value $roles = $roles->sortBy('created_at'); + $roles = $roles->sortByDesc('created_at'); + #### Returning A Custom Collection Type Sometimes, you may wish to return a custom Collection object with your own added methods. You may specify this on your Eloquent model by overriding the `newCollection` method: @@ -1201,7 +1225,7 @@ If you have some attributes that you want to always convert to another data-type '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. Other supported cast types are: `integer`, `real`, `float`, `double`, `string`, `boolean`, and `array`. +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. Other supported cast types are: `integer`, `real`, `float`, `double`, `string`, `boolean`, `object` and `array`. The `array` cast is particularly useful for working with columns that are stored as serialized JSON. For example, if your database has a TEXT type field 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: @@ -1285,6 +1309,22 @@ You may register an observer instance using the `observe` method: User::observe(new UserObserver); + +## Model URL Generation + +When you pass a model to the `route` or `action` methods, it's primary key is inserted into the generated URI. For example: + + Route::get('user/{user}', 'UserController@show'); + + action('UserController@show', [$user]); + +In this example the `$user->id` property will be inserted into the `{user}` place-holder of the generated URL. However, if you would like to use another property instead of the ID, you may override the `getRouteKey` method on your model: + + public function getRouteKey() + { + return $this->slug; + } + ## Converting To Arrays / JSON @@ -1331,7 +1371,6 @@ Alternatively, you may use the `visible` property to define a white-list: protected $visible = ['first_name', 'last_name']; - Occasionally, you may need to add array attributes that do not have a corresponding column in your database. To do so, simply define an accessor for the value: public function getIsAdminAttribute() diff --git a/ssh.md b/envoy.md similarity index 53% rename from ssh.md rename to envoy.md index b1b53f7e907..13330d9647a 100644 --- a/ssh.md +++ b/envoy.md @@ -1,100 +1,6 @@ -# SSH - -- [Configuration](#configuration) -- [Basic Usage](#basic-usage) -- [Tasks](#tasks) -- [SFTP Downloads](#sftp-downloads) -- [SFTP Uploads](#sftp-uploads) -- [Tailing Remote Logs](#tailing-remote-logs) -- [Envoy Task Runner](#envoy-task-runner) - - -## Configuration - -Laravel includes a simple way to SSH into remote servers and run commands, allowing you to easily build Artisan tasks that work on remote servers. The `SSH` facade provides the access point to connecting to your remote servers and running commands. - -The configuration file is located at `config/remote.php`, and contains all of the options you need to configure your remote connections. The `connections` array contains a list of your servers keyed by name. Simply populate the credentials in the `connections` array and you will be ready to start running remote tasks. Note that the `SSH` can authenticate using either a password or an SSH key. - -> **Note:** Need to easily run a variety of tasks on your remote server? Check out the [Envoy task runner](#envoy-task-runner)! - - -## Basic Usage - -#### Running Commands On The Default Server - -To run commands on your `default` remote connection, use the `SSH::run` method: - - SSH::run([ - 'cd /var/www', - 'git pull origin master', - ]); - -#### Running Commands On A Specific Connection - -Alternatively, you may run commands on a specific connection using the `into` method: - - SSH::into('staging')->run([ - 'cd /var/www', - 'git pull origin master', - ]); - -#### Catching Output From Commands - -You may catch the "live" output of your remote commands by passing a Closure into the `run` method: - - SSH::run($commands, function($line) - { - echo $line.PHP_EOL; - }); - -## Tasks - - -If you need to define a group of commands that should always be run together, you may use the `define` method to define a `task`: - - SSH::into('staging')->define('deploy', [ - 'cd /var/www', - 'git pull origin master', - 'php artisan migrate', - ]); - -Once the task has been defined, you may use the `task` method to run it: - - SSH::into('staging')->task('deploy', function($line) - { - echo $line.PHP_EOL; - }); - - -## SFTP Downloads - -The `SSH` class includes a simple way to download files using the `get` and `getString` methods: - - SSH::into('staging')->get($remotePath, $localPath); - - $contents = SSH::into('staging')->getString($remotePath); - - -## SFTP Uploads - -The `SSH` class also includes a simple way to upload files, or even strings, to the server using the `put` and `putString` methods: - - SSH::into('staging')->put($localFile, $remotePath); - - SSH::into('staging')->putString($remotePath, 'Foo'); - - -## Tailing Remote Logs - -Laravel includes a helpful command for tailing the `laravel.log` files on any of your remote connections. Simply use the `tail` Artisan command and specify the name of the remote connection you would like to tail: - - php artisan tail staging - - php artisan tail staging --path=/path/to/log.file - - -## Envoy Task Runner +# Envoy Task Runner +- [Introduction](#introduction) - [Installation](#envoy-installation) - [Running Tasks](#envoy-running-tasks) - [Multiple Servers](#envoy-multiple-servers) @@ -103,12 +9,15 @@ Laravel includes a helpful command for tailing the `laravel.log` files on any of - [Notifications](#envoy-notifications) - [Updating Envoy](#envoy-updating-envoy) -Laravel Envoy provides a clean, minimal syntax for defining common tasks you run on your remote servers. Using a [Blade](/docs/templates#blade-templating) style syntax, you can easily setup tasks for deployment, Artisan commands, and more. + +## Introduction + +[Laravel Envoy](https://github.com/laravel/envoy) provides a clean, minimal syntax for defining common tasks you run on your remote servers. Using a Blade style syntax, you can easily setup tasks for deployment, Artisan commands, and more. > **Note:** Envoy requires PHP version 5.4 or greater, and only runs on Mac / Linux operating systems. -### Installation +## Installation First, install Envoy using the Composer `global` command: @@ -131,7 +40,7 @@ The `init` command may be used to easily create a stub Envoy file: envoy init user@192.168.1.1 -### Running Tasks +## Running Tasks To run a task, use the `run` command of your Envoy installation: @@ -165,8 +74,18 @@ You may also use ```@include``` to include any PHP files: @include('vendor/autoload.php'); +#### Confirming Tasks Before Running + +If you would like to be prompted for confirmation before running a given task on your servers, you may use the `confirm` directive: + + @task('deploy', ['on' => 'web', 'confirm' => true]) + cd site + git pull origin {{ $branch }} + php artisan migrate + @endtask + -### Multiple Servers +## Multiple Servers You may easily run a task across multiple servers. Simply list the servers in the task declaration: @@ -181,7 +100,7 @@ You may easily run a task across multiple servers. Simply list the servers in th 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. -### Parallel Execution +## Parallel Execution If you would like to run a task across multiple servers in parallel, simply add the `parallel` option to your task declaration: @@ -194,7 +113,7 @@ If you would like to run a task across multiple servers in parallel, simply add @endtask -### Task Macros +## Task Macros Macros allow you to define a set of tasks to be run in sequence using a single command. For instance: @@ -218,8 +137,7 @@ The `deploy` macro can now be run via a single, simple command: envoy run deploy - -### Notifications +## Notifications #### HipChat @@ -248,16 +166,26 @@ This is an amazingly simple way to keep your team notified of the tasks being ru The following syntax may be used to send a notification to [Slack](https://slack.com): @after - @slack('team', 'token', 'channel') + @slack('hook', 'channel', 'message') @endafter - -### Updating Envoy +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: -To update Envoy, simply run the `self-update` command: + https://hooks.slack.com/services/ZZZZZZZZZ/YYYYYYYYY/XXXXXXXXXXXXXXX - envoy self-update +You may provide one of the following for the channel argument: -If your Envoy installation is in `/usr/local/bin`, you may need to use `sudo`: +- To send the notification to a channel: `#channel` +- To send the notification to a user: `@user` + +If no `channel` argument is provided the default channel will be used. + +> Note: Slack notifications will only be sent if all tasks complete successfully. + + +## Updating Envoy + +To update Envoy, simply use Composer: composer global update + diff --git a/errors.md b/errors.md index 218cbc886f1..bb96fee49ec 100644 --- a/errors.md +++ b/errors.md @@ -16,7 +16,7 @@ For example, if you wish to use a single log file instead of daily files, you ca 'log' => 'single' -Out of the box, Laravel supported `single`, `daily`, and `syslog` logging modes. However, you are free to customize the logging for your application as you wish by overriding the `ConfigureLogging` bootstrapper class. +Out of the box, Laravel supported `single`, `daily`, `syslog` and `errorlog` logging modes. However, you are free to customize the logging for your application as you wish by overriding the `ConfigureLogging` bootstrapper class. ### Error Detail diff --git a/events.md b/events.md index 5db87ee2b33..c384291dd87 100644 --- a/events.md +++ b/events.md @@ -24,7 +24,7 @@ The `EventServiceProvider` included with your Laravel application provides a con */ protected $listen = [ 'App\Events\PodcastWasPurchased' => [ - 'App\Handlers\Events\EmailPurchaseConfirmation@handle', + 'App\Handlers\Events\EmailPurchaseConfirmation', ], ]; @@ -71,7 +71,7 @@ Sometimes, you may wish to stop the propagation of an event to other listeners. ## Queued Event Handlers -Need to [queue](/docs/5.0/queues) an event handler? It couldn't be any easier. When generating the handler, simply use the `--queued` flag: +Need to [queue](/docs/{{version}}/queues) an event handler? It couldn't be any easier. When generating the handler, simply use the `--queued` flag: php artisan handler:event SendPurchaseConfirmation --event=PodcastWasPurchased --queued @@ -118,7 +118,7 @@ Event subscribers are classes that may subscribe to multiple events from within * Register the listeners for the subscriber. * * @param Illuminate\Events\Dispatcher $events - * @return array + * @return void */ public function subscribe($events) { @@ -137,7 +137,7 @@ Once the subscriber has been defined, it may be registered with the `Event` clas Event::subscribe($subscriber); -You may also use the [Laravel IoC container](/docs/5.0/container) to resolve your subscriber. To do so, simply pass the name of your subscriber to the `subscribe` method: +You may also use the [service container](/docs/{{version}}/container) to resolve your subscriber. To do so, simply pass the name of your subscriber to the `subscribe` method: Event::subscribe('UserEventHandler'); diff --git a/extending.md b/extending.md index 03b554c90e7..bf67b21e4b3 100644 --- a/extending.md +++ b/extending.md @@ -4,7 +4,7 @@ - [Cache](#cache) - [Session](#session) - [Authentication](#authentication) -- [IoC Based Extension](#ioc-based-extension) +- [Service Container Based Extension](#container-based-extension) ## Managers & Factories @@ -25,7 +25,7 @@ To extend the Laravel cache facility, we will use the `extend` method on the `Ca return Cache::repository(new MongoStore); }); -The first argument passed to the `extend` method is the name of the driver. This will correspond to your `driver` option in the `config/cache.php` configuration file. The second argument is a Closure that should return an `Illuminate\Cache\Repository` instance. The Closure will be passed an `$app` instance, which is an instance of `Illuminate\Foundation\Application` and an IoC container. +The first argument passed to the `extend` method is the name of the driver. This will correspond to your `driver` option in the `config/cache.php` configuration file. The second argument is a Closure that should return an `Illuminate\Cache\Repository` instance. The Closure will be passed an `$app` instance, which is an instance of `Illuminate\Foundation\Application` and a service container. The call to `Cache::extend` could be done in the `boot` method of the default `App\Providers\AppServiceProvider` that ships with fresh Laravel applications, or you may create your own service provider to house the extension - just don't forget to register the provider in the `config/app.php` provider array. @@ -129,7 +129,7 @@ The `retrieveById` function typically receives a numeric key representing the us The `retrieveByToken` function retrieves a user by their unique `$identifier` and "remember me" `$token`, stored in a field `remember_token`. As with the previous method, the `Authenticatable` implementation should be returned. -The `updateRememberToken` method updates the `$user` field `remember_token` with the new `$token`. The new token can be either a fresh token, assigned on successfull "remember me" login attempt, or a null when user is logged out. +The `updateRememberToken` method updates the `$user` field `remember_token` with the new `$token`. The new token can be either a fresh token, assigned on successful "remember me" login attempt, or a null when user is logged out. The `retrieveByCredentials` method receives the array of credentials passed to the `Auth::attempt` method when attempting to sign into an application. The method should then "query" the underlying persistent storage for the user matching those credentials. Typically, this method will run a query with a "where" condition on `$credentials['username']`. The method should then return an implementation of `UserInterface`. **This method should not attempt to do any password validation or authentication.** @@ -158,12 +158,12 @@ Finally, once we have implemented the `UserProvider`, we are ready to register o After you have registered the driver with the `extend` method, you switch to the new driver in your `config/auth.php` configuration file. - -## IoC Based Extension + +## Service Container Based Extension -Almost every service provider included with the Laravel framework binds objects into the IoC container. You can find a list of your application's service providers in the `config/app.php` configuration file. As you have time, you should skim through each of these provider's source code. By doing so, you will gain a much better understanding of what each provider adds to the framework, as well as what keys are used to bind various services into the IoC container. +Almost every service provider included with the Laravel framework binds objects into the service container. You can find a list of your application's service providers in the `config/app.php` configuration file. As you have time, you should skim through each of these provider's source code. By doing so, you will gain a much better understanding of what each provider adds to the framework, as well as what keys are used to bind various services into the service container. -For example, the `HashServiceProvider` binds a `hash` key into the IoC container, which resolves into a `Illuminate\Hashing\BcryptHasher` instance. You can easily extend and override this class within your own application by overriding this IoC binding. For example: +For example, the `HashServiceProvider` binds a `hash` key into the service container, which resolves into a `Illuminate\Hashing\BcryptHasher` instance. You can easily extend and override this class within your own application by overriding this binding. For example: app->bindShared('hash', function() { return new \Snappy\Hashing\ScryptHasher; }); - - parent::boot(); } } diff --git a/facades.md b/facades.md index bd75033afa5..5d21b64468d 100644 --- a/facades.md +++ b/facades.md @@ -10,11 +10,11 @@ ## Introduction -Facades provide a "static" interface to classes that are available in the application's [IoC container](/docs/5.0/container). Laravel ships with many facades, and you have probably been using them without even knowing it! Laravel "facades" serve as "static proxies" to underlying classes in the IoC container, providing the benefit of a terse, expressive syntax while maintaining more testability and flexibility than traditional static methods. +Facades provide a "static" interface to classes that are available in the application's [service container](/docs/{{version}}/container). Laravel ships with many facades, and you have probably been using them without even knowing it! Laravel "facades" serve as "static proxies" to underlying classes in the service container, providing the benefit of a terse, expressive syntax while maintaining more testability and flexibility than traditional static methods. Occasionally, you may wish to create your own facades for your application's and packages, so let's explore the concept, development and usage of these classes. -> **Note:** Before digging into facades, it is strongly recommended that you become very familiar with the Laravel [IoC container](/docs/5.0/container). +> **Note:** Before digging into facades, it is strongly recommended that you become very familiar with the Laravel [service container](/docs/{{version}}/container). ## Explanation @@ -23,7 +23,7 @@ In the context of a Laravel application, a facade is a class that provides acces Your facade class only needs to implement a single method: `getFacadeAccessor`. It's the `getFacadeAccessor` method's job to define what to resolve from the container. The `Facade` base class makes use of the `__callStatic()` magic-method to defer calls from your facade to the resolved object. -So, when you make a facade call like `Cache::get`, Laravel resolves the Cache manager class out of the IoC container and calls the `get` method on the class. In technical terms, Laravel Facades are a convenient syntax for using the Laravel IoC container as a service locator. +So, when you make a facade call like `Cache::get`, Laravel resolves the Cache manager class out of the service container and calls the `get` method on the class. In technical terms, Laravel Facades are a convenient syntax for using the Laravel service container as a service locator. ## Practical Usage @@ -45,9 +45,9 @@ However, if we look at that `Illuminate\Support\Facades\Cache` class, you'll see } -The Cache class extends the base `Facade` class and defines a method `getFacadeAccessor()`. Remember, this method's job is to return the name of an IoC binding. +The Cache class extends the base `Facade` class and defines a 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 IoC container and runs the requested method (in this case, `get`) against that object. +When a user references any static method on the `Cache` facade, Laravel resolves the `cache` binding from the service container and runs the requested method (in this case, `get`) against that object. So, our `Cache::get` call could be re-written like so: @@ -82,7 +82,7 @@ Remember, if you are using a facade in a controller that is namespaced, you will Creating a facade for your own application or package is simple. You only need 3 things: -- An IoC binding. +- A service container binding. - A facade class. - A facade alias configuration. @@ -99,14 +99,14 @@ Let's look at an example. Here, we have a class defined as `PaymentGateway\Payme } -We need to be able to resolve this class from the IoC container. So, let's add a binding to a service provider: +We need to be able to resolve this class from the service container. So, let's add a binding to a service provider: App::bind('payment', function() { return new \PaymentGateway\Payment; }); -A great place to register this binding would be to create a new [service provider](/docs/5.0/container#service-providers) named `PaymentServiceProvider`, and add this binding to the `register` method. You can then configure Laravel to load your service provider from the `config/app.php` configuration file. +A great place to register this binding would be to create a new [service provider](/docs/{{version}}/container#service-providers) named `PaymentServiceProvider`, and add this binding to the `register` method. You can then configure Laravel to load your service provider from the `config/app.php` configuration file. Next, we can create our own facade class: @@ -129,53 +129,49 @@ Classes in the `aliases` array are not available in some instances because [PHP ## Mocking Facades -Unit testing is an important aspect of why facades work the way that they do. In fact, testability is the primary reason for facades to even exist. For more information, check out the [mocking facades](/docs/testing#mocking-facades) section of the documentation. +Unit testing is an important aspect of why facades work the way that they do. In fact, testability is the primary reason for facades to even exist. For more information, check out the [mocking facades](/docs/{{version}}/testing#mocking-facades) section of the documentation. ## Facade Class Reference -Below you will find every facade and its underlying class. This is a useful tool for quickly digging into the API documentation for a given facade root. The [IoC binding](/docs/5.0/container) key is also included where applicable. +Below you will find every facade and its underlying class. This is a useful tool for quickly digging into the API documentation for a given facade root. The [service container binding](/docs/{{version}}/container) key is also included where applicable. -Facade | Class | IoC Binding +Facade | Class | Service Container Binding ------------- | ------------- | ------------- -App | [Illuminate\Foundation\Application](http://laravel.com/api/5.0/Illuminate/Foundation/Application.html) | `app` -Artisan | [Illuminate\Console\Application](http://laravel.com/api/5.0/Illuminate/Console/Application.html) | `artisan` -Auth | [Illuminate\Auth\AuthManager](http://laravel.com/api/5.0/Illuminate/Auth/AuthManager.html) | `auth` -Auth (Instance) | [Illuminate\Auth\Guard](http://laravel.com/api/5.0/Illuminate/Auth/Guard.html) | -Blade | [Illuminate\View\Compilers\BladeCompiler](http://laravel.com/api/5.0/Illuminate/View/Compilers/BladeCompiler.html) | `blade.compiler` -Cache | [Illuminate\Cache\Repository](http://laravel.com/api/5.0/Illuminate/Cache/Repository.html) | `cache` -Config | [Illuminate\Config\Repository](http://laravel.com/api/5.0/Illuminate/Config/Repository.html) | `config` -Cookie | [Illuminate\Cookie\CookieJar](http://laravel.com/api/5.0/Illuminate/Cookie/CookieJar.html) | `cookie` -Crypt | [Illuminate\Encryption\Encrypter](http://laravel.com/api/5.0/Illuminate/Encryption/Encrypter.html) | `encrypter` -DB | [Illuminate\Database\DatabaseManager](http://laravel.com/api/5.0/Illuminate/Database/DatabaseManager.html) | `db` -DB (Instance) | [Illuminate\Database\Connection](http://laravel.com/api/5.0/Illuminate/Database/Connection.html) | -Event | [Illuminate\Events\Dispatcher](http://laravel.com/api/5.0/Illuminate/Events/Dispatcher.html) | `events` -File | [Illuminate\Filesystem\Filesystem](http://laravel.com/api/5.0/Illuminate/Filesystem/Filesystem.html) | `files` -Form | [Illuminate\Html\FormBuilder](http://laravel.com/api/5.0/Illuminate/Html/FormBuilder.html) | `form` -Hash | [Illuminate\Hashing\HasherInterface](http://laravel.com/api/5.0/Illuminate/Hashing/HasherInterface.html) | `hash` -HTML | [Illuminate\Html\HtmlBuilder](http://laravel.com/api/5.0/Illuminate/Html/HtmlBuilder.html) | `html` -Input | [Illuminate\Http\Request](http://laravel.com/api/5.0/Illuminate/Http/Request.html) | `request` -Lang | [Illuminate\Translation\Translator](http://laravel.com/api/5.0/Illuminate/Translation/Translator.html) | `translator` -Log | [Illuminate\Log\Writer](http://laravel.com/api/5.0/Illuminate/Log/Writer.html) | `log` -Mail | [Illuminate\Mail\Mailer](http://laravel.com/api/5.0/Illuminate/Mail/Mailer.html) | `mailer` -Paginator | [Illuminate\Pagination\Factory](http://laravel.com/api/5.0/Illuminate/Pagination/Factory.html) | `paginator` -Paginator (Instance) | [Illuminate\Pagination\Paginator](http://laravel.com/api/5.0/Illuminate/Pagination/Paginator.html) | -Password | [Illuminate\Auth\Passwords\PasswordBroker](http://laravel.com/api/5.0/Illuminate/Auth/Passwords/PasswordBroker.html) | `auth.password` -Queue | [Illuminate\Queue\QueueManager](http://laravel.com/api/5.0/Illuminate/Queue/QueueManager.html) | `queue` -Queue (Instance) | [Illuminate\Queue\QueueInterface](http://laravel.com/api/5.0/Illuminate/Queue/QueueInterface.html) | -Queue (Base Class) | [Illuminate\Queue\Queue](http://laravel.com/api/5.0/Illuminate/Queue/Queue.html) | -Redirect | [Illuminate\Routing\Redirector](http://laravel.com/api/5.0/Illuminate/Routing/Redirector.html) | `redirect` -Redis | [Illuminate\Redis\Database](http://laravel.com/api/5.0/Illuminate/Redis/Database.html) | `redis` -Request | [Illuminate\Http\Request](http://laravel.com/api/5.0/Illuminate/Http/Request.html) | `request` -Response | [Illuminate\Support\Facades\Response](http://laravel.com/api/5.0/Illuminate/Support/Facades/Response.html) | -Route | [Illuminate\Routing\Router](http://laravel.com/api/5.0/Illuminate/Routing/Router.html) | `router` -Schema | [Illuminate\Database\Schema\Blueprint](http://laravel.com/api/5.0/Illuminate/Database/Schema/Blueprint.html) | -Session | [Illuminate\Session\SessionManager](http://laravel.com/api/5.0/Illuminate/Session/SessionManager.html) | `session` -Session (Instance) | [Illuminate\Session\Store](http://laravel.com/api/5.0/Illuminate/Session/Store.html) | -SSH | [Illuminate\Remote\RemoteManager](http://laravel.com/api/5.0/Illuminate/Remote/RemoteManager.html) | `remote` -SSH (Instance) | [Illuminate\Remote\Connection](http://laravel.com/api/5.0/Illuminate/Remote/Connection.html) | -URL | [Illuminate\Routing\UrlGenerator](http://laravel.com/api/5.0/Illuminate/Routing/UrlGenerator.html) | `url` -Validator | [Illuminate\Validation\Factory](http://laravel.com/api/5.0/Illuminate/Validation/Factory.html) | `validator` -Validator (Instance) | [Illuminate\Validation\Validator](http://laravel.com/api/5.0/Illuminate/Validation/Validator.html) | -View | [Illuminate\View\Factory](http://laravel.com/api/5.0/Illuminate/View/Factory.html) | `view` -View (Instance) | [Illuminate\View\View](http://laravel.com/api/5.0/Illuminate/View/View.html) | +App | [Illuminate\Foundation\Application](http://laravel.com/api/{{version}}/Illuminate/Foundation/Application.html) | `app` +Artisan | [Illuminate\Console\Application](http://laravel.com/api/{{version}}/Illuminate/Console/Application.html) | `artisan` +Auth | [Illuminate\Auth\AuthManager](http://laravel.com/api/{{version}}/Illuminate/Auth/AuthManager.html) | `auth` +Auth (Instance) | [Illuminate\Auth\Guard](http://laravel.com/api/{{version}}/Illuminate/Auth/Guard.html) | +Blade | [Illuminate\View\Compilers\BladeCompiler](http://laravel.com/api/{{version}}/Illuminate/View/Compilers/BladeCompiler.html) | `blade.compiler` +Bus | [Illuminate\Contracts\Bus\Dispatcher](http://laravel.com/api/{{version}}/Illuminate/Contracts/Bus/Dispatcher.html) | +Cache | [Illuminate\Cache\CacheManager](http://laravel.com/api/{{version}}/Illuminate/Cache/Repository.html) | `cache` +Config | [Illuminate\Config\Repository](http://laravel.com/api/{{version}}/Illuminate/Config/Repository.html) | `config` +Cookie | [Illuminate\Cookie\CookieJar](http://laravel.com/api/{{version}}/Illuminate/Cookie/CookieJar.html) | `cookie` +Crypt | [Illuminate\Encryption\Encrypter](http://laravel.com/api/{{version}}/Illuminate/Encryption/Encrypter.html) | `encrypter` +DB | [Illuminate\Database\DatabaseManager](http://laravel.com/api/{{version}}/Illuminate/Database/DatabaseManager.html) | `db` +DB (Instance) | [Illuminate\Database\Connection](http://laravel.com/api/{{version}}/Illuminate/Database/Connection.html) | +Event | [Illuminate\Events\Dispatcher](http://laravel.com/api/{{version}}/Illuminate/Events/Dispatcher.html) | `events` +File | [Illuminate\Filesystem\Filesystem](http://laravel.com/api/{{version}}/Illuminate/Filesystem/Filesystem.html) | `files` +Hash | [Illuminate\Contracts\Hashing\Hasher](http://laravel.com/api/{{version}}/Illuminate/Contracts/Hashing/Hasher.html) | `hash` +Input | [Illuminate\Http\Request](http://laravel.com/api/{{version}}/Illuminate/Http/Request.html) | `request` +Lang | [Illuminate\Translation\Translator](http://laravel.com/api/{{version}}/Illuminate/Translation/Translator.html) | `translator` +Log | [Illuminate\Log\Writer](http://laravel.com/api/{{version}}/Illuminate/Log/Writer.html) | `log` +Mail | [Illuminate\Mail\Mailer](http://laravel.com/api/{{version}}/Illuminate/Mail/Mailer.html) | `mailer` +Password | [Illuminate\Auth\Passwords\PasswordBroker](http://laravel.com/api/{{version}}/Illuminate/Auth/Passwords/PasswordBroker.html) | `auth.password` +Queue | [Illuminate\Queue\QueueManager](http://laravel.com/api/{{version}}/Illuminate/Queue/QueueManager.html) | `queue` +Queue (Instance) | [Illuminate\Queue\QueueInterface](http://laravel.com/api/{{version}}/Illuminate/Queue/QueueInterface.html) | +Queue (Base Class) | [Illuminate\Queue\Queue](http://laravel.com/api/{{version}}/Illuminate/Queue/Queue.html) | +Redirect | [Illuminate\Routing\Redirector](http://laravel.com/api/{{version}}/Illuminate/Routing/Redirector.html) | `redirect` +Redis | [Illuminate\Redis\Database](http://laravel.com/api/{{version}}/Illuminate/Redis/Database.html) | `redis` +Request | [Illuminate\Http\Request](http://laravel.com/api/{{version}}/Illuminate/Http/Request.html) | `request` +Response | [Illuminate\Contracts\Routing\ResponseFactory](http://laravel.com/api/{{version}}/Illuminate/Contracts/Routing/ResponseFactory.html) | +Route | [Illuminate\Routing\Router](http://laravel.com/api/{{version}}/Illuminate/Routing/Router.html) | `router` +Schema | [Illuminate\Database\Schema\Blueprint](http://laravel.com/api/{{version}}/Illuminate/Database/Schema/Blueprint.html) | +Session | [Illuminate\Session\SessionManager](http://laravel.com/api/{{version}}/Illuminate/Session/SessionManager.html) | `session` +Session (Instance) | [Illuminate\Session\Store](http://laravel.com/api/{{version}}/Illuminate/Session/Store.html) | +Storage | [Illuminate\Contracts\Filesystem\Factory](http://laravel.com/api/{{version}}/Illuminate/Contracts/Filesystem/Factory.html) | `filesystem` +URL | [Illuminate\Routing\UrlGenerator](http://laravel.com/api/{{version}}/Illuminate/Routing/UrlGenerator.html) | `url` +Validator | [Illuminate\Validation\Factory](http://laravel.com/api/{{version}}/Illuminate/Validation/Factory.html) | `validator` +Validator (Instance) | [Illuminate\Validation\Validator](http://laravel.com/api/{{version}}/Illuminate/Validation/Validator.html) | +View | [Illuminate\View\Factory](http://laravel.com/api/{{version}}/Illuminate/View/Factory.html) | `view` +View (Instance) | [Illuminate\View\View](http://laravel.com/api/{{version}}/Illuminate/View/View.html) | diff --git a/filesystem.md b/filesystem.md index 44134e33001..03c8a28be61 100644 --- a/filesystem.md +++ b/filesystem.md @@ -3,6 +3,7 @@ - [Introduction](#introduction) - [Configuration](#configuration) - [Basic Usage](#basic-usage) +- [Custom Filesystems](#custom-filesystems) ## Introduction @@ -28,7 +29,7 @@ When using the `local` driver, note that all file operations are relative to the ## Basic Usage -The `Storage` facade may be used to interact with any of your configured disks. Alternatively, you may type-hint the `Illuminate\Contracts\Filesystem\Factory` contract on any class that is resolved via the [IoC container](/docs/5.0/container). +The `Storage` facade may be used to interact with any of your configured disks. Alternatively, you may type-hint the `Illuminate\Contracts\Filesystem\Factory` contract on any class that is resolved via the Laravel [service container](/docs/{{version}}/container). #### Retrieving A Particular Disk @@ -106,3 +107,43 @@ The `Storage` facade may be used to interact with any of your configured disks. #### Delete A Directory Storage::deleteDirectory($directory); + + +## Custom Filesystems + +Laravel's Flysystem integration provides drivers for several "drivers" out of the box; however, Flysystem is not limited to these and has adapters for many other storage systems. You can create a custom driver if you want to use one of these additional adapters in your Laravel application. Don't worry, it's not too hard! + +In order to set up the custom filesystem you will need to create a service provider such as `DropboxFilesystemServiceProvider`. In the provider's `boot` method, you can inject an instance of the `Illuminate\Contracts\Filesystem\Factory` contract and call the `extend` method of the injected instance. Alternatively, you may use the `Disk` facade's `extend` method. + +The first argument of the `extend` method is the name of the driver and the second is a Closure that receives the `$app` and `$config` variables. The resolver Closure must return an instance of `League\Flysystem\Filesystem`. + +> **Note:** The $config variable will already contain the values defined in `config/filesystems.php` for the specified disk. + +#### Dropbox Example + + ['name' => 'Taylor']], ['developer' => ['name' => 'Dayle']] - ); + ]; $array = array_fetch($array, 'developer.name'); @@ -179,7 +180,7 @@ Filter the array using the given Closure. ### head -Return the first element in the array. Useful for method chaining in PHP 5.3.x. +Return the first element in the array. $first = head($this->returnsArray('foo')); @@ -202,6 +203,10 @@ Get the fully qualified path to the `app` directory. Get the fully qualified path to the root of the application install. +### config_path + +Get the fully qualified path to the `config` directory. + ### public_path Get the fully qualified path to the `public` directory. @@ -210,6 +215,45 @@ Get the fully qualified path to the `public` directory. Get the fully qualified path to the `storage` directory. + +## Routing + +### get + +Register a new GET route with the router. + + get('/', function() { return 'Hello World'; }); + +### post + +Register a new POST route with the router. + + post('foo/bar', 'FooController@action'); + +### put + +Register a new PUT route with the router. + + put('foo/bar', 'FooController@action'); + +### patch + +Register a new PATCH route with the router. + + patch('foo/bar', 'FooController@action'); + +### delete + +Register a new DELETE route with the router. + + delete('foo/bar', 'FooController@action'); + +### resource + +Register a new RESTful resource route with the router. + + resource('foo', 'FooController'); + ## Strings @@ -304,7 +348,7 @@ Generate a random string of the given length. Convert a string to its singular form (English only). $singular = str_singular('cars'); - + ### str_slug Generate a URL friendly "slug" from a given string. @@ -312,9 +356,9 @@ Generate a URL friendly "slug" from a given string. str_slug($title, $separator); Example: - + $title = str_slug("Laravel 5 Framework", "-"); - + // laravel-5-framework ### studly_case @@ -358,33 +402,9 @@ Generate a URL for an asset. $url = asset('img/photo.jpg'); -### link_to - -Generate a HTML link to the given URL. - - echo link_to('foo/bar', $title, $attributes = [], $secure = null); - -### link_to_asset - -Generate a HTML link to the given asset. - - echo link_to_asset('foo/bar.zip', $title, $attributes = [], $secure = null); - -### link_to_route - -Generate a HTML link to the given route. - - echo link_to_route('route.name', $title, $parameters = [], $attributes = []); - -### link_to_action - -Generate a HTML link to the given controller action. - - echo link_to_action('HomeController@getIndex', $title, $parameters = [], $attributes = []); - ### secure_asset -Generate a HTML link to the given asset using HTTPS. +Generate a URL for an asset using HTTPS. echo secure_asset('foo/bar.zip', $title, $attributes = []); @@ -415,14 +435,38 @@ Dump the given variable and end execution of the script. dd($value); +### elixir + +Get the path to a versioned Elixir file. + + elixir($file); + +### env + +Gets the value of an environment variable or return a default value. + + env('APP_ENV', 'production') + +### event + +Fire an event. + + event('my.event'); + ### value If the given value is a `Closure`, return the value returned by the `Closure`. Otherwise, return the value. $value = value(function() { return 'bar'; }); +### view + +Get a View instance for the given view path. + + return view('auth.login'); + ### with -Return the given object. Useful for method chaining constructors in PHP 5.3.x. +Return the given object. $value = with(new Foo)->doWork(); diff --git a/homestead.md b/homestead.md index e7229782078..f678822f2f4 100644 --- a/homestead.md +++ b/homestead.md @@ -5,6 +5,7 @@ - [Installation & Setup](#installation-and-setup) - [Daily Usage](#daily-usage) - [Ports](#ports) +- [Blackfire Profiler](#blackfire-profiler) ## Introduction @@ -17,7 +18,7 @@ Homestead runs on any Windows, Mac, or Linux system, and includes the Nginx web > **Note:** If you are using Windows, you may need to enable hardware virtualization (VT-x). It can usually be enabled via your BIOS. -Homestead is currently built and tested using Vagrant 1.6. +Homestead is currently built and tested using Vagrant 1.7. ## Included Software @@ -32,19 +33,23 @@ Homestead is currently built and tested using Vagrant 1.6. - Redis - Memcached - Beanstalkd -- [Laravel Envoy](/docs/ssh#envoy-task-runner) -- Fabric + HipChat Extension +- [Laravel Envoy](/docs/{{version}}/envoy) +- [Blackfire Profiler](#blackfire-profiler) ## Installation & Setup -### Installing VirtualBox & Vagrant +### Installing VirtualBox / VMware & Vagrant Before launching your Homestead environment, you must install [VirtualBox](https://www.virtualbox.org/wiki/Downloads) and [Vagrant](http://www.vagrantup.com/downloads.html). Both of these software packages provide easy-to-use visual installers for all popular operating systems. +#### VMware + +In addition to VirtualBox, Homestead also supports VMware. To use the VMware provider, you will need to purchase both VMware Fusion / Desktop and the [VMware Vagrant plug-in](http://www.vagrantup.com/vmware). VMware provides much faster shared folder performance out of the box. + ### Adding The Vagrant Box -Once VirtualBox 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: +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 @@ -54,33 +59,21 @@ If this command fails, you may have an old version of Vagrant that requires the ### Installing Homestead -#### Manually Via Git (No Local PHP) - -Alternatively, if you do not want to install PHP on your local machine, you may install Homestead manually 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 (and PHP) projects: +You may install Homestead manually 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 (and PHP) projects: git clone https://github.com/laravel/homestead.git Homestead -Once you have installed the Homestead CLI tool, run the `bash init.sh` command to create the `Homestead.yaml` configuration file: +Once you have cloned the Homestead repository, run the `bash init.sh` command from the Homestead directory to create the `Homestead.yaml` configuration file: bash init.sh The `Homestead.yaml` file will be placed in your `~/.homestead` directory. -#### With Composer + PHP Tool - -Once the box has been added to your Vagrant installation, you are ready to install the Homestead CLI tool using the Composer `global` command: - - composer global require "laravel/homestead=~2.0" - -Make sure to place the `~/.composer/vendor/bin` directory in your PATH so the `homestead` executable is found when you run the `homestead` command in your terminal. +### Configure Your Provider -Once you have installed the Homestead CLI tool, run the `init` command to create the `Homestead.yaml` configuration file: +The `provider` key in your `Homestead.yaml` file indicates which Vagrant provider should be used: `virtualbox`, `vmware_fusion` (Mac OS X) or `vmware_workstation` (Windows). You may set this to whichever provider you prefer. - homestead init - -The `Homestead.yaml` file will be placed in the `~/.homestead` directory. If you're using a Mac or Linux system, you may edit `Homestead.yaml` file by running the `homestead edit` command in your terminal: - - homestead edit + provider: virtualbox ### Set Your SSH Key @@ -98,6 +91,13 @@ Once you have created a SSH key, specify the key's path in the `authorize` prope 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! +To enable [NFS](http://docs.vagrantup.com/v2/synced-folders/nfs.html), just add a simple flag to your synced folder: + + folders: + - map: ~/Code + to: /home/vagrant/Code + type: "nfs" + ### Configure Your 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! @@ -109,6 +109,8 @@ You can make any Homestead site use [HHVM](http://hhvm.com) by setting the `hhvm to: /home/vagrant/Code/Laravel/public hhvm: true +Each site will be accessible by HTTP via port 8000 and HTTPS via port 44300. + ### Bash Aliases To add Bash aliases to your Homestead box, simply add to the `aliases` file in the root of the `~/.homestead` directory. @@ -134,14 +136,14 @@ To learn how to connect to your databases, read on! ### Connecting Via SSH -To connect to your Homestead environment via SSH, issue the `vagrant ssh` command from your Homestead directory. - -Since you will probably need to SSH into your Homestead machine frequently, consider creating an "alias" on your host machine: +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: alias vm="ssh vagrant@127.0.0.1 -p 2222" Once you create this alias, you can simply use the "vm" command to SSH into your Homestead machine from anywhere on your system. +Alternatively, you can use the `vagrant ssh` command from your Homestead directory. + ### Connecting To Your Databases A `homestead` database is configured for both MySQL and Postgres out of the box. For even more convenience, Laravel's `local` database configuration is set to use this database by default. @@ -152,11 +154,13 @@ To connect to your MySQL or Postgres database from your main machine via Navicat ### Adding Additional Sites -Once your Homestead environment is provisioned and running, you may want to add additional Nginx sites for your Laravel applications. You can run as many Laravel installations as you wish on a single Homestead environment. There are two ways to do this: First, you may simply add the sites to your `Homestead.yaml` file and then run `vagrant provision`. +Once your Homestead environment is provisioned and running, you may want to add additional Nginx sites for your Laravel applications. You can run as many Laravel installations as you wish on a single Homestead environment. There are two ways to do this: First, you may simply add the sites to your `Homestead.yaml` file and then run `vagrant provision` from your Homestead directory. + +> **Note:** This process is destructive. When running the `provision` command, your existing databases will be destroyed and recreated. Alternatively, you may use the `serve` script that is available on your Homestead environment. To use the `serve` script, SSH into your Homestead environment and run the following command: - serve domain.app /home/vagrant/Code/path/to/public/directory + serve domain.app /home/vagrant/Code/path/to/public/directory 80 > **Note:** After running the `serve` command, do not forget to add the new site to the `hosts` file on your main machine! @@ -167,5 +171,32 @@ The following ports are forwarded to your Homestead environment: - **SSH:** 2222 → Forwards To 22 - **HTTP:** 8000 → Forwards To 80 +- **HTTPS:** 44300 → Forwards To 443 - **MySQL:** 33060 → Forwards To 3306 - **Postgres:** 54320 → Forwards To 5432 + +### Adding Additional Ports + +If you wish, you may forward additional ports to the Vagrant box, as well as specify their protocol: + + ports: + - send: 93000 + to: 9300 + - send: 7777 + to: 777 + protocol: udp + + +## Blackfire Profiler + +[Blackfire Profiler](https://blackfire.io) by SensioLabs automatically gathers data about your code's execution, such as RAM, CPU time, and disk I/O. Homestead makes it a breeze to use this profiler for your own applications. + +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 + +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/html.md b/html.md deleted file mode 100644 index be9f2daf166..00000000000 --- a/html.md +++ /dev/null @@ -1,204 +0,0 @@ -# Forms & HTML - -- [Opening A Form](#opening-a-form) -- [CSRF Protection](#csrf-protection) -- [Form Model Binding](#form-model-binding) -- [Labels](#labels) -- [Text, Text Area, Password & Hidden Fields](#text) -- [Checkboxes and Radio Buttons](#checkboxes-and-radio-buttons) -- [File Input](#file-input) -- [Number Input](#number) -- [Drop-Down Lists](#drop-down-lists) -- [Buttons](#buttons) -- [Custom Macros](#custom-macros) -- [Generating URLs](#generating-urls) - - -## Opening A Form - -#### Opening A Form - - {{ Form::open(['url' => 'foo/bar']) }} - // - {{ Form::close() }} - -By default, a `POST` method will be assumed; however, you are free to specify another method: - - echo Form::open(['url' => 'foo/bar', 'method' => 'put']) - -> **Note:** Since HTML forms only support `POST` and `GET`, `PUT` and `DELETE` methods will be spoofed by automatically adding a `_method` hidden field to your form. - -You may also open forms that point to named routes or controller actions: - - echo Form::open(['route' => 'route.name']) - - echo Form::open(['action' => 'Controller@method']) - -You may pass in route parameters as well: - - echo Form::open(['route' => ['route.name', $user->id]]) - - echo Form::open(['action' => ['Controller@method', $user->id]]) - -If your form is going to accept file uploads, add a `files` option to your array: - - echo Form::open(['url' => 'foo/bar', 'files' => true]) - - -## CSRF Protection - -#### Adding The CSRF Token To A Form - -Laravel provides an easy method of protecting your application from cross-site request forgeries. First, a random token is placed in your user's session. If you use the `Form::open` method with `POST`, `PUT` or `DELETE` the CSRF token will be added to your forms as a hidden field automatically. Alternatively, if you wish to generate the HTML for the hidden CSRF field, you may use the `token` method: - - echo Form::token(); - -#### Attaching The CSRF Filter To A Route - - Route::post('profile', ['before' => 'csrf', function() - { - // - }]); - - -## Form Model Binding - -#### Opening A Model Form - -Often, you will want to populate a form based on the contents of a model. To do so, use the `Form::model` method: - - echo Form::model($user, ['route' => ['user.update', $user->id]]) - -Now, when you generate a form element, like a text input, the model's value matching the field's name will automatically be set as the field value. So, for example, for a text input named `email`, the user model's `email` attribute would be set as the value. However, there's more! If there is an item in the Session flash data matching the input name, that will take precedence over the model's value. So, the priority looks like this: - -1. Session Flash Data (Old Input) -2. Explicitly Passed Value -3. Model Attribute Data - -This allows you to quickly build forms that not only bind to model values, but easily re-populate if there is a validation error on the server! - -> **Note:** When using `Form::model`, be sure to close your form with `Form::close`! - - -## Labels - -#### Generating A Label Element - - echo Form::label('email', 'E-Mail Address'); - -#### Specifying Extra HTML Attributes - - echo Form::label('email', 'E-Mail Address', ['class' => 'awesome']); - -> **Note:** After creating a label, any form element you create with a name matching the label name will automatically receive an ID matching the label name as well. - - -## Text, Text Area, Password & Hidden Fields - -#### Generating A Text Input - - echo Form::text('username'); - -#### Specifying A Default Value - - echo Form::text('email', 'example@gmail.com'); - -> **Note:** The *hidden* and *textarea* methods have the same signature as the *text* method. - -#### Generating A Password Input - - echo Form::password('password'); - -#### Generating Other Inputs - - echo Form::email($name, $value = null, $attributes = []); - echo Form::file($name, $attributes = []); - - -## Checkboxes and Radio Buttons - -#### Generating A Checkbox Or Radio Input - - echo Form::checkbox('name', 'value'); - - echo Form::radio('name', 'value'); - -#### Generating A Checkbox Or Radio Input That Is Checked - - echo Form::checkbox('name', 'value', true); - - echo Form::radio('name', 'value', true); - - -## Number - -#### Generating A Number Input - - echo Form::number('name', 'value'); - - -## File Input - -#### Generating A File Input - - echo Form::file('image'); - -> **Note:** The form must have been opened with the `files` option set to `true`. - - -## Drop-Down Lists - -#### Generating A Drop-Down List - - echo Form::select('size', ['L' => 'Large', 'S' => 'Small']); - -#### Generating A Drop-Down List With Selected Default - - echo Form::select('size', ['L' => 'Large', 'S' => 'Small'], 'S'); - -#### Generating A Grouped List - - echo Form::select('animal', [ - 'Cats' => ['leopard' => 'Leopard'], - 'Dogs' => ['spaniel' => 'Spaniel'] - ]); - -#### Generating A Drop-Down List With A Range - - echo Form::selectRange('number', 10, 20); - -#### Generating A List With Month Names - - echo Form::selectMonth('month'); - - -## Buttons - -#### Generating A Submit Button - - echo Form::submit('Click Me!'); - -> **Note:** Need to create a button element? Try the *button* method. It has the same signature as *submit*. - - -## Custom Macros - -#### Registering A Form Macro - -It's easy to define your own custom Form class helpers called "macros". Here's how it works. First, simply register the macro with a given name and a Closure: - - Form::macro('myField', function() - { - return ''; - }); - -Now you can call your macro using its name: - -#### Calling A Custom Form Macro - - echo Form::myField(); - - -## Generating URLs - -For more information on generating URL's, check out the documentation on [helpers](/docs/helpers#urls). diff --git a/installation.md b/installation.md index 43e984fba21..ae5b1a73dc2 100644 --- a/installation.md +++ b/installation.md @@ -28,17 +28,26 @@ Once installed, the simple `laravel new` command will create a fresh Laravel ins 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 {directory} "5.0.*" --prefer-dist + +Once installed, you should upgrade to the latest packages. First, remove `{directory}/vendor/compiled.php` file then change your current directory to `{directory}` and issue `composer update` command. + +### Scaffolding + +Laravel ships with scaffolding for user registration and authentication. If you would like to remove this scaffolding, use the `fresh` Artisan command: + + php artisan fresh ## Server Requirements The Laravel framework has a few system requirements: -- PHP >= 5.4 +- PHP >= 5.4, PHP < 7 - Mcrypt PHP Extension - OpenSSL PHP Extension - Mbstring PHP Extension +- Tokenizer PHP Extension As of PHP 5.5, some OS distributions may require you to manually install the PHP JSON extension. When using Ubuntu, this can be done via `apt-get install php5-json`. @@ -51,14 +60,14 @@ Typically, this string should be 32 characters long. The key can be set in the ` Laravel needs almost no other configuration out of the box. You are free to get started developing! However, you may wish to review the `config/app.php` file and its documentation. It contains several options such as `timezone` and `locale` that you may wish to change according to your application. -Once Laravel is installed, you should also [configure your local environment](/docs/5.0/configuration#environment-configuration). +Once Laravel is installed, you should also [configure your local environment](/docs/{{version}}/configuration#environment-configuration). > **Note:** You should never have the `app.debug` configuration option set to `true` for a production application. ### Permissions -Laravel may require some permissions to be configured: folders within `storage` require write access by the web server. +Laravel may require some permissions to be configured: folders within `storage` and `vendor` require write access by the web server. ## Pretty URLs @@ -80,8 +89,8 @@ If the `.htaccess` file that ships with Laravel does not work with your Apache i 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/5.0/homestead), pretty URLs will be configured automatically. +Of course, when using [Homestead](/docs/{{version}}/homestead), pretty URLs will be configured automatically. diff --git a/lifecycle.md b/lifecycle.md index fac198aedfc..2d977963866 100644 --- a/lifecycle.md +++ b/lifecycle.md @@ -20,7 +20,7 @@ If you don't understand all of the terms right away, don't lose heart! Just try The entry point for all requests to a Laravel application is the `public/index.php` file. All requests are directed to this file by your web server (Apache / Nginx) configuration. The `index.php` file doesn't contain much code. Rather, it is simply a starting point for loading the rest of the framework. -The `index.php` file loads the Composer generated autoloader definition, and then retrieves an instance of the Laravel application from `bootstrap/app.php` script. The first action taken by Laravel itself is to create an instance of the application / [service container](/docs/5.0/container). +The `index.php` file loads the Composer generated autoloader definition, and then retrieves an instance of the Laravel application from `bootstrap/app.php` script. The first action taken by Laravel itself is to create an instance of the application / [service container](/docs/{{version}}/container). #### HTTP / Console Kernels @@ -28,7 +28,7 @@ Next, the incoming request is sent to either the HTTP kernel or the console kern The HTTP kernel extends the `Illuminate\Foundation\Http\Kernel` class, which defines an array of `bootstrappers` that will be run before the request is executed. These bootstrappers configure error handling, configure logging, detect the application environment, and perform other tasks that need to be done before the request is actually handled. -The HTTP kernel also defines a list of HTTP [middleware](/docs/5.0/middleware) that all requests must pass through before being handled by the application. These middleware handle reading and writing the HTTP session, determine if the application is in maintenance mode, verifying the CSRF token, and more. +The HTTP kernel also defines a list of HTTP [middleware](/docs/{{version}}/middleware) that all requests must pass through before being handled by the application. These middleware handle reading and writing the HTTP session, determine if the application is in maintenance mode, verifying the CSRF token, and more. The method signature for the HTTP kernel's `handle` method is quite simple: receive a `Request` and return a `Response`. Think of the Kernel as being a big black box that represents your entire application. Feed it HTTP requests and it will return HTTP responses. diff --git a/localization.md b/localization.md index c64bcca6ed9..f57a6fef889 100644 --- a/localization.md +++ b/localization.md @@ -101,7 +101,7 @@ Since the Laravel translator is powered by the Symfony Translation component, yo ## Validation -For localization for validation errors and messages, take a look at the documentation on Validation. +For localization for validation errors and messages, take a look at the documentation on Validation. ## Overriding Package Language Files diff --git a/mail.md b/mail.md index 2e159f64a34..98a90ba4a19 100644 --- a/mail.md +++ b/mail.md @@ -13,9 +13,9 @@ Laravel provides a clean, simple API over the popular [SwiftMailer](http://swift ### API Drivers -Laravel also includes drivers for the Mailgun and Mandrill HTTP APIs. These APIs are often simpler and quicker than the SMTP servers. Both of these drivers require that the Guzzle 4 HTTP library be installed into your application. You can add Guzzle 4 to your project by adding the following line to your `composer.json` file: +Laravel also includes drivers for the Mailgun and Mandrill HTTP APIs. These APIs are often simpler and quicker than the SMTP servers. Both of these drivers require that the Guzzle 5 HTTP library be installed into your application. You can add Guzzle 5 to your project by adding the following line to your `composer.json` file: - "guzzlehttp/guzzle": "~4.0" + "guzzlehttp/guzzle": "~5.0" #### Mailgun Driver @@ -114,7 +114,7 @@ Note that the `$message` variable is always passed to e-mail views by the `Mail` #### Queueing A 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/5.0/queues). To queue a mail message, simply use the `queue` method on the `Mail` facade: +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, simply use the `queue` method on the `Mail` facade: Mail::queue('emails.welcome', $data, function($message) { diff --git a/middleware.md b/middleware.md index e496b811c47..ded207223ac 100644 --- a/middleware.md +++ b/middleware.md @@ -24,6 +24,8 @@ To create a new middleware, use the `make:middleware` Artisan command: 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. ## Registering Middleware @@ -73,11 +111,12 @@ Once the middleware has been defined in the HTTP kernel, you may use the `middle 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, you may define the middleware as "terminable". + use Closure; use Illuminate\Contracts\Routing\TerminableMiddleware; class StartSession implements TerminableMiddleware { - public function handle($request, $next) + public function handle($request, Closure $next) { return $next($request); } diff --git a/migrations.md b/migrations.md index b1013d98bde..357e05444f5 100644 --- a/migrations.md +++ b/migrations.md @@ -9,7 +9,7 @@ ## Introduction -Migrations are a type of version control for your database. They allow a team to modify the database schema and stay up to date on the current schema state. Migrations are typically paired with the [Schema Builder](/docs/5.0/schema) to easily manage your application's schema. +Migrations are a type of version control for your database. They allow a team to modify the database schema and stay up to date on the current schema state. Migrations are typically paired with the [Schema Builder](/docs/{{version}}/schema) to easily manage your application's schema. ## Creating Migrations @@ -22,7 +22,7 @@ The migration will be placed in your `database/migrations` folder, and will cont 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: - php artisan make:migration add_votes_to_user_table --table=users + php artisan make:migration add_votes_to_users_table --table=users php artisan make:migration create_users_table --create=users @@ -37,7 +37,7 @@ The `--table` and `--create` options may also be used to indicate the name of th ### Forcing Migrations In Production -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 prompted for confirmation before these commands are executed. To force the commands to run without a prompt, use the `--force` flag: +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 diff --git a/packages.md b/packages.md index a3e7ae58d81..a1aa12b51fa 100644 --- a/packages.md +++ b/packages.md @@ -4,6 +4,7 @@ - [Views](#views) - [Translations](#translations) - [Configuration](#configuration) +- [Public Assets](#public-assets) - [Publishing File Groups](#publishing-file-groups) - [Routing](#routing) @@ -21,7 +22,7 @@ All Laravel packages are distributed via [Packagist](http://packagist.org) and [ ## Views -Your package's internal structure is entirely up to you; however, typically each package will contain one or more [service providers](/docs/5.0/providers). The service provider contains any [IoC](/docs/5.0/container) bindings, as well as instructions as to where package configuration, views, and translation files are located. +Your package's internal structure is entirely up to you; however, typically each package will contain one or more [service providers](/docs/{{version}}/providers). The service provider contains any [service container](/docs/{{version}}/container) bindings, as well as instructions as to where package configuration, views, and translation files are located. ### Views @@ -104,6 +105,21 @@ You may also choose to merge your own package configuration file with the applic __DIR__.'/path/to/config/courier.php', 'courier' ); + +## Public Assets + +Your packages may have assets such as JavaScript, CSS, and images. To publish assets, use the `publishes` method from your service provider's `boot` method. In this example, we will also add a "public" asset group tag. + + $this->publishes([ + __DIR__.'/path/to/assets' => public_path('vendor/courier'), + ], 'public'); + +Now, when your package's users execute the `vendor:publish` command, your files 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 + +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. + ## Publishing File Groups @@ -116,7 +132,7 @@ You may want to publish groups of files separately. For instance, you might want // Publish your migrations $this->publishes([ - __DIR__.'/../database/migrations/' => base_path('/database/migrations') + __DIR__.'/../database/migrations/' => database_path('/migrations') ], 'migrations'); You can then publish these files separately by referencing their tag like so: diff --git a/pagination.md b/pagination.md index 20f01ad0cce..1637ef6d676 100644 --- a/pagination.md +++ b/pagination.md @@ -27,7 +27,7 @@ Sometimes you may wish to create a pagination instance manually, passing it an a #### Paginating An Eloquent Model -You may also paginate [Eloquent](/docs/5.0/eloquent) models: +You may also paginate [Eloquent](/docs/{{version}}/eloquent) models: $allUsers = User::paginate(15); @@ -53,6 +53,8 @@ You may also access additional pagination information via the following methods: - `hasMorePages` - `url` - `nextPageUrl` +- `firstItem` +- `lastItem` - `total` - `count` diff --git a/providers.md b/providers.md index d78f5a12e7a..3228e8aaa83 100644 --- a/providers.md +++ b/providers.md @@ -19,7 +19,7 @@ In this overview you will learn how to write your own service providers and regi ## Basic Provider Example -All service providers extend the `Illuminate\Support\ServiceProvider` class. This abstract class requires that you define at least one method on your provider: `register`. Within the `register` method, you should **only bind things into the [service container](/docs/5.0/container)**. You should never attempt to register any event listeners, routes, or any other piece of functionality within the `register` method. +All service providers extend the `Illuminate\Support\ServiceProvider` class. This abstract class requires that you define at least one method on your provider: `register`. Within the `register` method, you should **only bind things into the [service container](/docs/{{version}}/container)**. You should never attempt to register any event listeners, routes, or any other piece of functionality within the `register` method. The Artisan CLI can easily generate a new provider via the `make:provider` command: @@ -51,7 +51,7 @@ Now, let's take a look at a basic service provider: } -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, don't worry, [we'll cover that soon](/docs/5.0/container). +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, don't worry, [we'll cover that soon](/docs/{{version}}/container). This class is namespaced under `App\Providers` since that is the default location for service providers in Laravel. However, you are free to change this as you wish. Your service providers may be placed anywhere that Composer can autoload them. @@ -113,7 +113,7 @@ To register your provider, simply add it to the array: ## Deferred Providers -If your provider is **only** registering bindings in the [service container](/docs/5.0/container), you may choose to defer its registration until one of the registered bindings is actually needed. Deferring the loading of such a provider will improve the performance of your application, since it is not loaded from the filesystem on every request. +If your provider is **only** registering bindings in the [service container](/docs/{{version}}/container), you may choose to defer its registration until one of the registered bindings is actually needed. Deferring the loading of such a provider will improve the performance of your application, since it is not loaded from the filesystem on every request. 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: diff --git a/queries.md b/queries.md index 9f3aaac1384..7fe5e5866f6 100644 --- a/queries.md +++ b/queries.md @@ -116,6 +116,20 @@ This method will return an array of role titles. You may also specify a custom k $users = DB::table('users') ->whereNull('updated_at')->get(); +#### Dynamic Where Clauses + +You may even use "dynamic" where statements to fluently build where statements using magic methods: + + $admin = DB::table('users')->whereId(1)->first(); + + $john = DB::table('users') + ->whereIdAndEmail(2, 'john@doe.com') + ->first(); + + $jane = DB::table('users') + ->whereNameOrAge('Jane', 22) + ->first(); + #### Order By, Group By, And Having $users = DB::table('users') diff --git a/queues.md b/queues.md index 32e05a17d3e..d1850de0ac0 100644 --- a/queues.md +++ b/queues.md @@ -27,7 +27,7 @@ The following dependencies are needed for the listed queue drivers: - Amazon SQS: `aws/aws-sdk-php` - Beanstalkd: `pda/pheanstalk ~3.0` -- IronMQ: `iron-io/iron_mq` +- IronMQ: `iron-io/iron_mq ~1.5` - Redis: `predis/predis ~1.0` @@ -43,9 +43,9 @@ To push a new job onto the queue, use the `Queue::push` method: Queue::push(new SendEmail($message)); -> **Note:** In this example, we are using the `Queue` facade directly; however, typically you would dispatch queued command via the [Command Bus](/docs/5.0/bus). We will continue to use the `Queue` facade throughout this page; however, familiarize with the command bus as well, since it is used to dispatch both queued and synchronous commands for your application. +> **Note:** In this example, we are using the `Queue` facade directly; however, typically you would dispatch queued command via the [Command Bus](/docs/{{version}}/bus). We will continue to use the `Queue` facade throughout this page; however, familiarize with the command bus as well, since it is used to dispatch both queued and synchronous commands for your application. -By default, the `make:command` Artisan command generates a "self-handling" command, meaning a `handle` method is added to the command itself. This method will be called when the job is executed by the queue. You may type-hint any dependencies you need on the `handle` method and the [IoC container](/docs/5.0/container) will automatically inject them: +By default, the `make:command` Artisan command generates a "self-handling" command, meaning a `handle` method is added to the command itself. This method will be called when the job is executed by the queue. You may type-hint any dependencies you need on the `handle` method and the [service container](/docs/{{version}}/container) will automatically inject them: public function handle(UserRepository $users) { @@ -152,7 +152,7 @@ You may pass a comma-delimited list of queue connections to the `listen` command php artisan queue:listen --queue=high,low -In this example, jobs on the `high-connection` will always be processed before moving onto jobs from the `low-connection`. +In this example, jobs on the `high` connection will always be processed before moving onto jobs from the `low` connection. #### Specifying The Job Timeout Parameter @@ -210,12 +210,14 @@ Similarly, your database connection may disconnect when being used by long-runni ## Push Queues -Push queues allow you to utilize the powerful Laravel 4 queue facilities without running any daemons or background listeners. Currently, push queues are only supported by the [Iron.io](http://iron.io) driver. Before getting started, create an Iron.io account, and add your Iron credentials to the `config/queue.php` configuration file. +Push queues allow you to utilize the powerful Laravel 5 queue facilities without running any daemons or background listeners. Currently, push queues are only supported by the [Iron.io](http://iron.io) driver. Before getting started, create an Iron.io account, and add your Iron credentials to the `config/queue.php` configuration file. #### Registering A Push Queue Subscriber Next, you may use the `queue:subscribe` Artisan command to register a URL end-point that will receive newly pushed queue jobs: + php artisan queue:subscribe queue_name queue/receive + php artisan queue:subscribe queue_name http://foo.com/queue/receive Now, when you login to your Iron dashboard, you will see your new push queue, as well as the subscribed URL. You may subscribe as many URLs as you wish to a given queue. Next, create a route for your `queue/receive` end-point and return the response from the `Queue::marshal` method: @@ -253,6 +255,8 @@ You may also define a `failed` method directly on a queue job class, allowing yo { // Called when the job is failing... } + +If your job is not self-handling and has a seperate handler class the `failed` method needs to be defined there instead. ### Retrying Failed Jobs diff --git a/redis.md b/redis.md index 24ba0a8e212..b919688d850 100644 --- a/redis.md +++ b/redis.md @@ -64,7 +64,7 @@ When you are simply executing commands against the default connection, just use $values = Redis::lrange('names', 5, 10); -> **Note:** Redis [cache](/docs/5.0/cache) and [session](/docs/5.0/session) drivers are included with Laravel. +> **Note:** Redis [cache](/docs/{{version}}/cache) and [session](/docs/{{version}}/session) drivers are included with Laravel. ## Pipelining diff --git a/releases.md b/releases.md index b400cc69da8..f8af2209588 100644 --- a/releases.md +++ b/releases.md @@ -1,9 +1,17 @@ # Release Notes +- [Support Policy](#support-policy) - [Laravel 5.0](#laravel-5.0) - [Laravel 4.2](#laravel-4.2) - [Laravel 4.1](#laravel-4.1) + +## Support Policy + +Security fixes are **always** applied to the previous major version of Laravel. Currently, **all** security fixes and patches will be applied to both Laravel 5.x **and** Laravel 4.x. + +When feasible, security fixes will also be applied to even older releases of the framework, such as Laravel 3.x. + ## Laravel 5.0 @@ -23,7 +31,7 @@ Application language files and views have been moved to the `resources` director All major Laravel components implement interfaces which are located in the `illuminate/contracts` repository. This repository has no external dependencies. Having a convenient, centrally located set of interfaces you may use for decoupling and dependency injection will serve as an easy alternative option to Laravel Facades. -For more information on contracts, consult the [full documentation](/docs/5.0/contracts). +For more information on contracts, consult the [full documentation](/docs/{{version}}/contracts). ### Route Cache @@ -33,11 +41,11 @@ If your application is made up entirely of controller routes, you may utilize th In addition to Laravel 4 style route "filters", Laravel 5 now supports HTTP middleware, and the included authentication and CSRF "filters" have been converted to middleware. Middleware provides a single, consistent interface to replace all types of filters, allowing you to easily inspect, and even reject, requests before they enter your application. -For more information on middleware, check out [the documentation](/docs/5.0/middleware). +For more information on middleware, check out [the documentation](/docs/{{version}}/middleware). ### Controller Method Injection -In addition to the existing constructor injection, you may now type-hint dependencies on controller methods. The [IoC container](/docs/5.0/container) will automatically inject the dependencies, even if the route contains other parameters: +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) { @@ -78,7 +86,7 @@ Of course, your event handler will receive the event object instead of a list of } -For more information on working with events, check out the [full documentation](/docs/5.0/events). +For more information on working with events, check out the [full documentation](/docs/{{version}}/events). ### Commands / Queueing @@ -119,7 +127,7 @@ The base Laravel controller utilizes the new `DispatchesCommands` trait, allowin $this->dispatch(new PurchasePodcastCommand($user, $podcast)); -Of course, you may also use commands for tasks that are executed synchonrously (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/5.0/bus) documentation. +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. ### Database Queue @@ -133,7 +141,7 @@ It looks like this: $schedule->command('artisan:command')->dailyAt('15:00'); -Of course, check out the [full documentation](/docs/5.0/artisan#scheduling-artisan-commands) to learn all about the scheduler! +Of course, check out the [full documentation](/docs/{{version}}/artisan#scheduling-artisan-commands) to learn all about the scheduler! ### Tinker / Psysh @@ -143,13 +151,13 @@ The `php artisan tinker` command now utilizes [Psysh](https://github.com/bobthec ### DotEnv -Instead of a variety of confusing, nested environment configuration directories, Laravel 5 now utilizes [DotEnv](https://github.com/vlucas/phpdotenv) by Vance Lucas. This library provides a super simple way to manage your environment configuration, and makes environment detection in Laravel 5 a breeze. For more details, check out the full [configuration documentation](/docs/5.0/configuration#environment-configuration). +Instead of a variety of confusing, nested environment configuration directories, Laravel 5 now utilizes [DotEnv](https://github.com/vlucas/phpdotenv) by Vance Lucas. This library provides a super simple way to manage your environment configuration, and makes environment detection in Laravel 5 a breeze. For more details, check out the full [configuration documentation](/docs/{{version}}/configuration#environment-configuration). ### Laravel Elixir Laravel Elixir, by Jeffrey Way, provides a fluent, expressive interface to compiling and concatenating your assets. If you've ever been intimidated by learning Grunt or Gulp, fear no more. Elixir makes it a cinch to get started using Gulp to compile your Less, Sass, and CoffeeScript. It can even run your tests for you! -For more information on Elixir, check out the [full documentation](/docs/5.0/elixir). +For more information on Elixir, check out the [full documentation](/docs/{{version}}/elixir). ### Laravel Socialite @@ -165,7 +173,7 @@ Laravel Socialite is an optional, Laravel 5.0+ compatible package that provides $user = Socialize::with('twitter')->user(); } -No more spending hours writing OAuth authentication flows. Get started in minutes! The [full documentation](/docs/5.0/authentication#social-authentication) has all the details. +No more spending hours writing OAuth authentication flows. Get started in minutes! The [full documentation](/docs/{{version}}/authentication#social-authentication) has all the details. ### Flysystem Integration @@ -173,7 +181,7 @@ Laravel now includes the powerful [Flysystem](https://github.com/thephpleague/fl Storage::put('file.txt', 'contents'); -For more information on the Laravel Flysystem integration, consult the [full documentation](/docs/5.0/filesystem). +For more information on the Laravel Flysystem integration, consult the [full documentation](/docs/{{version}}/filesystem). ### Form Requests @@ -205,7 +213,7 @@ Once the class has been defined, we can type-hint it on our controller action: var_dump($request->input()); } -When the Laravel IoC 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/5.0/validation#form-request-validation). +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). ### Simple Controller Request Validation @@ -221,7 +229,7 @@ The Laravel 5 base controller now includes a `ValidatesRequests` trait. This tra 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. -For more information on this new method, check out [the documentation](/docs/5.0/validation#controller-validation). +For more information on this new method, check out [the documentation](/docs/{{version}}/validation#controller-validation). ### New Generators @@ -305,9 +313,9 @@ The full change list for this release by running the `php artisan changes` comma ### New SSH Component -An entirely new `SSH` component has been introduced with this release. This feature allows you to easily SSH into remote servers and run commands. To learn more, consult the [SSH component documentation](/docs/ssh). +An entirely new `SSH` component has been introduced with this release. This feature allows you to easily SSH into remote servers and run commands. To learn more, consult the [SSH component documentation](/docs/4.1/ssh). -The new `php artisan tail` command utilizes the new SSH component. For more information, consult the `tail` [command documentation](http://laravel.com/docs/ssh#tailing-remote-logs). +The new `php artisan tail` command utilizes the new SSH component. For more information, consult the `tail` [command documentation](http://laravel.com/docs/4.1/ssh#tailing-remote-logs). ### Boris In Tinker @@ -337,7 +345,7 @@ Cache "sections" have been superseded by "tags". Cache tags allow you to assign ### Flexible Password Reminders -The password reminder engine has been changed to provide greater developer flexibility when validating passwords, flashing status messages to the session, etc. For more information on using the enhanced password reminder engine, [consult the documentation](/docs/security#password-reminders-and-reset). +The password reminder engine has been changed to provide greater developer flexibility when validating passwords, flashing status messages to the session, etc. For more information on using the enhanced password reminder engine, [consult the documentation](/docs/4.1/security#password-reminders-and-reset). ### Improved Routing Engine diff --git a/requests.md b/requests.md index edce281512e..3c7b85b2272 100644 --- a/requests.md +++ b/requests.md @@ -20,7 +20,7 @@ Remember, if you are in a namespace, you will have to import the `Request` facad ### Via Dependency Injection -To obtain an instance of the current HTTP request via dependency injection, you should type-hint the class on your controller constructor or method. The current request instance will automatically be injected by the [service container](/docs/5.0/container): +To obtain an instance of the current HTTP request via dependency injection, you should type-hint the class on your controller constructor or method. The current request instance will automatically be injected by the [service container](/docs/{{version}}/container): withCookie(cookie()->forever('name', 'value')); +#### Queueing Cookies + +You may also "queue" a cookie to be added to the outgoing response, even before that response has been created: + + ## Files @@ -200,6 +224,13 @@ The `Request` class provides many methods for examining the HTTP request for you #### Retrieving The Request URI $uri = Request::path(); + +#### Determine If The Request Is Using AJAX + + if (Request::ajax()) + { + // + } #### Retrieving The Request Method diff --git a/responses.md b/responses.md index f6b413014dd..22d7ab3d04c 100644 --- a/responses.md +++ b/responses.md @@ -19,7 +19,7 @@ The most basic response from a Laravel route is a string: #### Creating Custom Responses -However, for most routes and controller actions, you will be returning a full `Illuminate\Http\Response` instance or a [view](/docs/5.0/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: +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; @@ -31,7 +31,7 @@ For convenience, you may also use the `response` helper: 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.5/Symfony/Component/HttpFoundation/Response.html). +> **Note:** For a full list of available `Response` methods, check out its [API documentation](http://laravel.com/api/{{version}}/Illuminate/Http/Response.html) and the [Symfony API documentation](http://api.symfony.com/2.5/Symfony/Component/HttpFoundation/Response.html). #### Sending A View In A Response @@ -63,7 +63,7 @@ There are several ways to generate a `RedirectResponse` instance. The simplest m #### Returning A Redirect With Flash Data -Redirecting to a new URL and [flashing data to the session](/docs/5.0/session) 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: +Redirecting to a new URL and [flashing data to the session](/docs/{{version}}/session) 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: return redirect('user/login')->with('message', 'Login Failed'); @@ -101,7 +101,7 @@ If you are redirecting to a route with an "ID" parameter that is being populated #### Returning A Redirect To A Controller Action -Similarly to generating `RedirectResponse` instances to named routes, you may also generate redirects to [controller actions](/docs/5.0/controllers): +Similarly to generating `RedirectResponse` instances to named routes, you may also generate redirects to [controller actions](/docs/{{version}}/controllers): return redirect()->action('App\Http\Controllers\HomeController@index'); @@ -118,7 +118,7 @@ Similarly to generating `RedirectResponse` instances to named routes, you may al ## Other Responses -The `response` helper may be used to conveniently generate other types of response instances. When the `response` helper is called without arguments, an implementation of the `Illuminate\Contracts\Routing\ResponseFactory` [contract](/docs/5.0/contracts) is returned. This contract provides several helpful methods for generating responses. +The `response` helper may be used to conveniently generate other types of response instances. When the `response` helper is called without arguments, an implementation of the `Illuminate\Contracts\Routing\ResponseFactory` [contract](/docs/{{version}}/contracts) is returned. This contract provides several helpful methods for generating responses. #### Creating A JSON Response @@ -137,6 +137,8 @@ The `json` method will automatically set the `Content-Type` header to `applicati return response()->download($pathToFile, $name, $headers); + return response()->download($pathToFile)->deleteFileAfterSend(true); + > **Note:** Symfony HttpFoundation, which manages file downloads, requires the file being downloaded to have an ASCII file name. @@ -144,7 +146,7 @@ The `json` method will automatically set the `Content-Type` header to `applicati If you would like to define a custom response that you can re-use in a variety of your routes and controllers, you may use the `macro` method on an implementation of `Illuminate\Contracts\Routing\ResponseFactory`. -For example, from a [service provider's](/docs/5.0/providers) `boot` method: +For example, from a [service provider's](/docs/{{version}}/providers) `boot` method: "> + -Of course, using the Blade [templating engine](/docs/5.0/templates): +Of course, using the Blade [templating engine](/docs/{{version}}/templates): -You do not need to manually verify the CSRF token on POST, PUT, or DELETE requests. The `VerifyCsrfToken` [HTTP middleware](/docs/5.0/middleware) will verify token in the request input matches the token stored in the session. +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. -In addition to looking for the CSRF token as a "POST" parameter, the middleware will also check for the `X-XSRF-TOKEN` request header, which is commonly used by JavaScript frameworks. +#### X-CSRF-TOKEN + +In addition to looking for the CSRF token as a "POST" parameter, the middleware will also check for the `X-CSRF-TOKEN` request header. You could, for example, store the token in a "meta" tag and instruct jQuery to add it to all request headers: + + + + $.ajaxSetup({ + headers: { + 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') + } + }); + +Now all AJAX requests will automatically include the CSRF token: + + $.ajax({ + url: "/foo/bar", + }) + +#### X-XSRF-TOKEN + +Laravel also stores the CSRF token in a `XSRF-TOKEN` cookie. You can use the cookie value to set the `X-XSRF-TOKEN` request header. Some JavaScript frameworks, like Angular, do this automatically for you. + +> Note: The difference between the `X-CSRF-TOKEN` and `X-XSRF-TOKEN` is that the first uses a plain text value and the latter uses an encrypted value, because cookies in Laravel are always encrypted. If you use the `csrf_token()` function to supply the token value, you probably want to use the `X-CSRF-TOKEN` header. ## Method Spoofing -HTML forms do not support `PUT` or `DELETE` actions. So, when defining `PUT` or `DELETE` routes that are called from an HTML form, you will need to add a hidden `_method` field to the form. +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. For example:
+ + ## Route Parameters @@ -99,6 +121,8 @@ Of course, you can capture segments of the request URI within your route: return 'User '.$id; }); +> **Note:** Route parameters cannot contain the `-` character. Use an underscore (`_`) instead. + #### Optional Route Parameters Route::get('user/{name?}', function($name = null) @@ -133,11 +157,11 @@ Of course, you can capture segments of the request URI within your route: { // }) - ->where(['id' => '[0-9]+', 'name' => '[a-z]+']) + ->where(['id' => '[0-9]+', 'name' => '[a-z]+']); #### Defining Global Patterns -If you would like a route parameter to always be constrained by a given regular expression, you may use the `pattern` method. You should define these patterns in the `before` method of your `RouteServiceProvider`: +If you would like a route parameter to always be constrained by a given regular expression, you may use the `pattern` method. You should define these patterns in the `boot` method of your `RouteServiceProvider`: $router->pattern('id', '[0-9]+'); @@ -182,7 +206,7 @@ Named routes allow you to conveniently generate URLs or redirects for a specific You may also specify route names for controller actions: Route::get('user/profile', [ - 'as' => 'profile', 'uses' => 'UserController@showProfile' + 'as' => 'profile', 'uses' => 'UserController@showProfile' ]); Now, you may use the route's name when generating URLs or redirects: @@ -198,29 +222,45 @@ The `currentRouteName` method returns the name of the route handling the current ## Route Groups -Sometimes you may need to apply filters to a group of routes. Instead of specifying the filter on each route, you may use a route group: +Sometimes many of your routes will share common requirements such as URL segments, middleware, namespaces, etc. Instead of specifying each of these options on every route individually, you may use a route group to apply attributes to many routes. + +Shared attributes are specified in an array format as the first parameter to the `Route::group` method. - Route::group(['middleware' => 'auth'], function() + +### Middleware + +Middleware are applied to all routes within the group by defining the list of middleware with the `middleware` parameter on the group attribute array. Middleware will be executed in the order you define this array: + + Route::group(['middleware' => ['foo', 'bar']], function() { Route::get('/', function() { - // Has Auth Filter + // Has Foo And Bar Middleware }); Route::get('user/profile', function() { - // Has Auth Filter + // Has Foo And Bar Middleware }); + }); -You may use the `namespace` parameter within your `group` array to specify the namespace for all controllers within the group: + +### Namespaces + +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' => 'User'], function() + { + // Controllers Within The "App\Http\Controllers\Admin\User" Namespace + }); }); -> **Note:** By default, the `RouteServiceProvider` includes your `routes.php` file within a namespace group, allowing you to register controller routes without specifying the full namespace. +> **Note:** 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. ### Sub-Domain Routing @@ -246,12 +286,32 @@ A group of routes may be prefixed by using the `prefix` option in the attributes Route::group(['prefix' => 'admin'], function() { + Route::get('users', function() + { + // Matches The "/admin/users" URL + }); + }); + +You can also utilize the `prefix` parameter to pass common parameters to your routes: - Route::get('user', function() +#### Registering a URL parameter in a route prefix + + Route::group(['prefix' => 'accounts/{account_id}'], function() + { + Route::get('detail', function($account_id) { // }); + }); + +You can even define parameter constraints for the named parameters in your prefix: + + Route::group([ + 'prefix' => 'accounts/{account_id}', + 'where' => ['account_id' => '[0-9]+'], + ], function() { + // Define Routes Here }); @@ -288,7 +348,7 @@ If you wish to specify your own "not found" behavior, pass a Closure as the thir throw new NotFoundHttpException; }); -If you wish to use your own resolution logic, you should use the `Router::bind` method. The Closure you pass to the `bind` method will receive the value of the URI segment, and should return an instance of the class you want to be injected into the route: +If you wish to use your own resolution logic, you should use the `Route::bind` method. The Closure you pass to the `bind` method will receive the value of the URI segment, and should return an instance of the class you want to be injected into the route: Route::bind('user', function($value) { @@ -302,8 +362,8 @@ There are two ways to manually trigger a 404 error from a route. First, you may abort(404); -The `abort` helper simply throws a `Symfony\Component\HttpFoundation\Exception\HttpException` with the specified status code. +The `abort` helper simply throws a `Symfony\Component\HttpKernel\Exception\HttpException` with the specified status code. Secondly, you may manually throw an instance of `Symfony\Component\HttpKernel\Exception\NotFoundHttpException`. -More information on handling 404 exceptions and using custom responses for these errors may be found in the [errors](/docs/5.0/errors#http-exceptions) section of the documentation. +More information on handling 404 exceptions and using custom responses for these errors may be found in the [errors](/docs/{{version}}/errors#http-exceptions) section of the documentation. diff --git a/schema.md b/schema.md index 680ea9ab21d..075a92ac3af 100644 --- a/schema.md +++ b/schema.md @@ -61,7 +61,7 @@ The table builder contains a variety of column types that you may use when build Command | Description ------------- | ------------- -`$table->bigIncrements('id');` | Incrementing ID using a "big integer" equivalent. +`$table->bigIncrements('id');` | Incrementing ID using a "big integer" equivalent `$table->bigInteger('votes');` | BIGINT equivalent to the table `$table->binary('data');` | BLOB equivalent to the table `$table->boolean('confirmed');` | BOOLEAN equivalent to the table @@ -72,9 +72,10 @@ Command | Description `$table->double('column', 15, 8);` | DOUBLE equivalent with precision, 15 digits in total and 8 after the decimal point `$table->enum('choices', ['foo', 'bar']);` | ENUM equivalent to the table `$table->float('amount');` | FLOAT equivalent to the table -`$table->increments('id');` | Incrementing ID to the table (primary key). +`$table->increments('id');` | Incrementing ID to the table (primary key) `$table->integer('votes');` | INTEGER equivalent to the table `$table->json('options');` | JSON equivalent to the table +`$table->jsonb('options');` | JSONB equivalent to the table `$table->longText('description');` | LONGTEXT equivalent to the table `$table->mediumInteger('numbers');` | MEDIUMINT equivalent to the table `$table->mediumText('description');` | MEDIUMTEXT equivalent to the table @@ -103,6 +104,8 @@ If you are using the MySQL database, you may use the `after` method to specify t ## Changing Columns +**Note:** Before changing a column, be sure to add the `doctrine/dbal` dependency to your `composer.json` file. + Sometimes you may need to modify an existing column. For example, you may wish to increase the size of a string column. The `change` method makes it easy! For example, let's increase the size of the `name` column from 25 to 50: Schema::table('users', function($table) @@ -127,7 +130,7 @@ To rename a column, you may use the `renameColumn` method on the Schema builder. $table->renameColumn('from', 'to'); }); -> **Note:** Renaming `enum` column types is not supported. +> **Note:** Renaming columns in a table with `enum` column is currently not supported. ## Dropping Columns @@ -231,9 +234,9 @@ Command | Description 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->string('email'); - }); + $table->string('email'); + }); diff --git a/session.md b/session.md index 6700e22d6e1..467aea7cbc2 100644 --- a/session.md +++ b/session.md @@ -17,6 +17,8 @@ Before using Redis sessions with Laravel, you will need to install the `predis/p > **Note:** If you need all stored session data to be encrypted, set the `encrypt` configuration option to `true`. +> **Note:** When using the `cookie` session driver, you should **never** remove the `EncryptCookie` middleware from your HTTP kernel. If you remove this middleware, your application will be vulnerable to remote code injection. + #### Reserved Keys The Laravel framework uses the `flash` session key internally, so you should not add an item to the session by that name. @@ -24,10 +26,16 @@ The Laravel framework uses the `flash` session key internally, so you should not ## Session Usage +The session may be accessed in several ways, via the HTTP request's `session` method, the `Session` facade, or the `session` helper function. When the `session` helper is called without arguments, it will return the entire session object. For example: + + session()->regenerate(); + #### Storing An Item In The Session Session::put('key', 'value'); + session(['key' => 'value']); + #### Push A Value Onto An Array Session Value Session::push('user.teams', 'developers'); @@ -36,6 +44,8 @@ The Laravel framework uses the `flash` session key internally, so you should not $value = Session::get('key'); + $value = session('key'); + #### Retrieving An Item Or Returning A Default Value $value = Session::get('key', 'default'); @@ -109,10 +119,10 @@ Of course, you may use the `session:table` Artisan command to generate this migr The session "driver" defines where session data will be stored for each request. Laravel ships with several great drivers out of the box: -- `file` - sessions will be stored in `app/storage/sessions`. +- `file` - sessions will be stored in `storage/framework/sessions`. - `cookie` - sessions will be stored in secure, encrypted cookies. - `database` - sessions will be stored in a database used by your application. - `memcached` / `redis` - sessions will be stored in one of these fast, cached based stores. - `array` - sessions will be stored in a simple PHP array and will not be persisted across requests. -> **Note:** The array driver is typically used for running [unit tests](/docs/5.0/testing), so no session data will be persisted. +> **Note:** The array driver is typically used for running [unit tests](/docs/{{version}}/testing), so no session data will be persisted. diff --git a/templates.md b/templates.md index 5821185df5e..a1e40f42451 100644 --- a/templates.md +++ b/templates.md @@ -2,7 +2,6 @@ - [Blade Templating](#blade-templating) - [Other Blade Control Structures](#other-blade-control-structures) -- [Extending Blade](#extending-blade) ## Blade Templating @@ -14,6 +13,9 @@ Blade is a simple, yet powerful templating engine provided with Laravel. Unlike + +No users
+No users
@endforelse @while (true) @@ -138,20 +142,3 @@ To overwrite a section entirely, you may use the `overwrite` statement: {{-- This comment will not be in the rendered HTML --}} - -## Extending Blade - -Blade even allows you to define your own custom control structures. When a Blade file is compiled, each custom extension is called with the view contents, allowing you to do anything from simple `str_replace` manipulations to more complex regular expressions. - -The Blade compiler comes with the helper methods `createMatcher` and `createPlainMatcher`, which generate the expression you need to build your own custom directives. - -The `createPlainMatcher` method is used for directives with no arguments like `@endif` and `@stop`, while `createMatcher` is used for directives with arguments. - -The following example creates a `@datetime($var)` directive which simply calls `->format()` on `$var`: - - Blade::extend(function($view, $compiler) - { - $pattern = $compiler->createMatcher('datetime'); - - return preg_replace($pattern, '$1format(\'m/d/Y H:i\'); ?>', $view); - }); diff --git a/testing.md b/testing.md index dfcef1dbdce..fafd6614d74 100644 --- a/testing.md +++ b/testing.md @@ -52,7 +52,7 @@ You may easily call one of your routes for a test using the `call` method: $response = $this->call('GET', 'user/profile'); - $response = $this->call($method, $uri, $parameters, $files, $server, $content); + $response = $this->call($method, $uri, $parameters, $cookies, $files, $server, $content); You may then inspect the `Illuminate\Http\Response` object: @@ -151,18 +151,18 @@ Laravel ships with several `assert` methods to make testing a little easier: #### Asserting The Session Has Errors - public function testMethod() - { - $this->call('GET', '/'); + public function testMethod() + { + $this->call('GET', '/'); - $this->assertSessionHasErrors(); + $this->assertSessionHasErrors(); - // Asserting the session has errors for a given key... - $this->assertSessionHasErrors('name'); + // Asserting the session has errors for a given key... + $this->assertSessionHasErrors('name'); - // Asserting the session has errors for several keys... - $this->assertSessionHasErrors(['name', 'age']); - } + // Asserting the session has errors for several keys... + $this->assertSessionHasErrors(['name', 'age']); + } #### Asserting Old Input Has Some Data @@ -192,17 +192,17 @@ You may set the currently authenticated user using the `be` method: $this->be($user); -You may re-seed your database from a test using the `seed` method: - #### Re-Seeding Database From Tests +You may re-seed your database from a test using the `seed` method: + $this->seed(); - $this->seed($connection); + $this->seed('DatabaseSeeder'); More information on creating seeds may be found in the [migrations and seeding](/docs/migrations#database-seeding) section of the documentation. ## Refreshing The Application -As you may already know, you can access your Laravel `Application` / IoC Container via `$this->app` from any test method. This Application instance is refreshed for each test class. If you wish to manually force the Application to be refreshed for a given method, you may use the `refreshApplication` method from your test method. This will reset any extra bindings, such as mocks, that have been placed in the IoC container since the test case started running. +As you may already know, you can access your Application ([service container](/docs/{{version}}/container)) via `$this->app` from any test method. This service container instance is refreshed for each test class. If you wish to manually force the Application to be refreshed for a given method, you may use the `refreshApplication` method from your test method. This will reset any extra bindings, such as mocks, that have been placed in the IoC container since the test case started running. diff --git a/upgrade.md b/upgrade.md index bc0df1bf546..0dce57923c2 100644 --- a/upgrade.md +++ b/upgrade.md @@ -1,11 +1,19 @@ # Upgrade Guide +- [Upgrading To 5.0.16](#upgrade-5.0.16) - [Upgrading To 5.0 From 4.2](#upgrade-5.0) - [Upgrading To 4.2 From 4.1](#upgrade-4.2) - [Upgrading To 4.1.29 From <= 4.1.x](#upgrade-4.1.29) - [Upgrading To 4.1.26 From <= 4.1.25](#upgrade-4.1.26) - [Upgrading To 4.1 From 4.0](#upgrade-4.1) + +## Upgrading To 5.0.16 + +In your `bootstrap/autoload.php` file, update the `$compiledPath` variable to: + + $compiledPath = __DIR__.'/../vendor/compiled.php'; + ## Upgrading To 5.0 From 4.2 @@ -13,7 +21,7 @@ The recommended method of upgrading is to create a new Laravel `5.0` install and then to copy your `4.2` site's unique application files into the new application. This would include controllers, routes, Eloquent models, Artisan commands, assets, and other code specific to your application. -To start, [install a new Laravel 5 application](/docs/5.0/installation) into a fresh directory in your local environment. We'll discuss each piece of the migration process in further detail below. +To start, [install a new Laravel 5 application](/docs/{{version}}/installation) into a fresh directory in your local environment. We'll discuss each piece of the migration process in further detail below. ### Composer Dependencies & Packages @@ -33,7 +41,7 @@ Copy the new `.env.example` file to `.env`, which is the `5.0` equivalent of the Additionally, copy any custom values you had in your old `.env.php` file and place them in both `.env` (the real value for your local environment) and `.env.example` (a sample instructional value for other team members). -For more information on environment configuration, view the [full documentation](/docs/5.0/configuration#environment-configuration). +For more information on environment configuration, view the [full documentation](/docs/{{version}}/configuration#environment-configuration). > **Note:** You will need to place the appropriate `.env` file and values on your production server before deploying your Laravel 5 application. @@ -65,7 +73,7 @@ Filters are not removed in Laravel 5. You can still bind and use your own custom ### Global CSRF -By default, [CSRF protection](/docs/5.0/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: +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', @@ -73,7 +81,7 @@ If you want to use it elsewhere, add this line to `$routeMiddleware`: '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/5.0/middleware). +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). ### Eloquent Models @@ -83,7 +91,7 @@ Update any models using `SoftDeletingTrait` to use `Illuminate\Database\Eloquent #### Eloquent Caching -Eloquent no longer provides the `remember` method for caching queries. You now are responsible for caching your queries manually using the `Cache::remember` function. For more information on caching, consult the [full documentation](/docs/5.0/cache). +Eloquent no longer provides the `remember` method for caching queries. You now are responsible for caching your queries manually using the `Cache::remember` function. For more information on caching, consult the [full documentation](/docs/{{version}}/cache). ### User Authentication Model @@ -123,13 +131,13 @@ use Authenticatable, CanResetPassword; ### Cashier User Changes -The name of the trait and interface used by [Laravel Cashier](/docs/5.0/billing) has changed. Instead of using `BillableTrait`, use the `Laravel\Cashier\Billable` trait. And, instead of `Laravel\Cashier\BillableInterface` implement the `Laravel\Cashier\Contracts\Billable` interface instead. No other method changes are required. +The name of the trait and interface used by [Laravel Cashier](/docs/{{version}}/billing) has changed. Instead of using `BillableTrait`, use the `Laravel\Cashier\Billable` trait. And, instead of `Laravel\Cashier\BillableInterface` implement the `Laravel\Cashier\Contracts\Billable` interface instead. No other method changes are required. ### Artisan Commands Move all of your command classes from your old `app/commands` directory to the new `app/Console/Commands` directory. Next, add the `app/Console/Commands` directory to the `classmap` directive of your `composer.json` file. -Then, copy your list of Artisan commands from `start/artisan.php` into the `command` array of the `app/Console/Kernel.php` file. +Then, copy your list of Artisan commands from `start/artisan.php` into the `commands` array of the `app/Console/Kernel.php` file. ### Database Migrations & Seeds @@ -139,7 +147,7 @@ Move all of your migration classes from the old `app/database/migrations` direct ### Global IoC Bindings -If you have any [IoC](/docs/5.0/container) bindings in `start/global.php`, move them all to the `register` method of the `app/Providers/AppServiceProvider.php` file. You may need to import the `App` facade. +If you have any [IoC](/docs/{{version}}/container) bindings in `start/global.php`, move them all to the `register` method of the `app/Providers/AppServiceProvider.php` file. You may need to import the `App` facade. Optionally, you may break these bindings up into separate service providers by category. @@ -181,16 +189,18 @@ You may move your Sass, Less, or CoffeeScript to any location you wish. The `res ### Form & HTML Helpers -If you're using Form or HTML helpers, you will see an error stating `class 'Form' not found` or `class 'Html' not found`. To fix this, add `"illuminate/html": "~5.0"` to your `composer.json` file's `require` section. +If you're using Form or HTML helpers, you will see an error stating `class 'Form' not found` or `class 'Html' not found`. The Form and HTML helpers have been deprecated in Laravel 5.0; however, there are community-driven replacements such as those maintained by the [Laravel Collective](http://laravelcollective.com/docs/{{version}}/html). -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: +For example, you may add `"laravelcollective/html": "~5.0"` to your `composer.json` file's `require` section. - 'Illuminate\Html\HtmlServiceProvider', +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', Next, add these lines to the 'aliases' array: - 'Form' => 'Illuminate\Html\FormFacade', - 'Html' => 'Illuminate\Html\HtmlFacade', + 'Form' => 'Collective\Html\FormFacade', + 'Html' => 'Collective\Html\HtmlFacade', ### CacheManager @@ -200,6 +210,10 @@ If your application code was injecting `Illuminate\Cache\CacheManager` to get a Replace any calls to `$paginator->links()` with `$paginator->render()`. +Replace any calls to `$paginator->getFrom()` and `$paginator->getTo()` with `$paginator->firstItem()` and `$paginator->lastItem()` respectively. + +Remove the "get" prefix from calls to `$paginator->getPerPage()`, `$paginator->getCurrentPage()`, `$paginator->getLastPage()` and `$paginator->getTotal()` (e.g. `$paginator->perPage()`). + ### Beanstalk Queuing Laravel 5.0 now requires `"pda/pheanstalk": "~3.0"` instead of `"pda/pheanstalk": "~2.1"`. @@ -265,7 +279,7 @@ If you are extending the `Illuminate\Pagination\Presenter` class, the abstract m 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 @@ -323,15 +337,15 @@ To upgrade your application to Laravel 4.1, change your `laravel/framework` vers ### Replacing Files -Replace your `public/index.php` file with [this fresh copy from the repository](https://github.com/laravel/laravel/blob/master/public/index.php). +Replace your `public/index.php` file with [this fresh copy from the repository](https://github.com/laravel/laravel/blob/v4.1.0/public/index.php). -Replace your `artisan` file with [this fresh copy from the repository](https://github.com/laravel/laravel/blob/master/artisan). +Replace your `artisan` file with [this fresh copy from the repository](https://github.com/laravel/laravel/blob/v4.1.0/artisan). ### Adding Configuration Files & Options -Update your `aliases` and `providers` arrays in your `app/config/app.php` configuration file. The updated values for these arrays can be found [in this file](https://github.com/laravel/laravel/blob/master/app/config/app.php). Be sure to add your custom and package service providers / aliases back to the arrays. +Update your `aliases` and `providers` arrays in your `app/config/app.php` configuration file. The updated values for these arrays can be found [in this file](https://github.com/laravel/laravel/blob/v4.1.0/app/config/app.php). Be sure to add your custom and package service providers / aliases back to the arrays. -Add the new `app/config/remote.php` file [from the repository](https://github.com/laravel/laravel/blob/master/app/config/remote.php). +Add the new `app/config/remote.php` file [from the repository](https://github.com/laravel/laravel/blob/v4.1.0/app/config/remote.php). Add the new `expire_on_close` configuration option to your `app/config/session.php` file. The default value should be `false`. @@ -349,9 +363,9 @@ If `app/controllers/BaseController.php` has a `use` statement at the top, change ### Password Reminders Updates -Password reminders have been overhauled for greater flexibility. You may examine the new stub controller by running the `php artisan auth:reminders-controller` Artisan command. You may also browse the [updated documentation](/docs/security#password-reminders-and-reset) and update your application accordingly. +Password reminders have been overhauled for greater flexibility. You may examine the new stub controller by running the `php artisan auth:reminders-controller` Artisan command. You may also browse the [updated documentation](/docs/4.1/security#password-reminders-and-reset) and update your application accordingly. -Update your `app/lang/en/reminders.php` language file to match [this updated file](https://github.com/laravel/laravel/blob/master/app/lang/en/reminders.php). +Update your `app/lang/en/reminders.php` language file to match [this updated file](https://github.com/laravel/laravel/blob/v4.1.0/app/lang/en/reminders.php). ### Environment Detection Updates @@ -365,7 +379,7 @@ Laravel now generates a single log file: `app/storage/logs/laravel.log`. However In your `bootstrap/start.php` file, remove the call to `$app->redirectIfTrailingSlash()`. This method is no longer needed as this functionality is now handled by the `.htaccess` file included with the framework. -Next, replace your Apache `.htaccess` file with [this new one](https://github.com/laravel/laravel/blob/master/public/.htaccess) that handles trailing slashes. +Next, replace your Apache `.htaccess` file with [this new one](https://github.com/laravel/laravel/blob/v4.1.0/public/.htaccess) that handles trailing slashes. ### Current Route Access diff --git a/validation.md b/validation.md index c3fcab674a6..02b940340e4 100644 --- a/validation.md +++ b/validation.md @@ -13,7 +13,7 @@ ## Basic Usage -Laravel ships with a simple, convenient facility for validating data and retrieving validation error messages via the `Validation` class. +Laravel ships with a simple, convenient facility for validating data and retrieving validation error messages via the `Validator` class. #### Basic Validation Example @@ -35,18 +35,18 @@ Multiple rules may be delimited using either a "pipe" character, or as separate #### Validating Multiple Fields - $validator = Validator::make( - [ - 'name' => 'Dayle', - 'password' => 'lamepassword', - 'email' => 'email@example.com' - ], - [ - 'name' => 'required', - 'password' => 'required|min:8', - 'email' => 'required|email|unique:users' - ] - ); + $validator = Validator::make( + [ + 'name' => 'Dayle', + 'password' => 'lamepassword', + 'email' => 'email@example.com' + ], + [ + 'name' => 'required', + 'password' => 'required|min:8', + 'email' => 'required|email|unique:users' + ] + ); Once a `Validator` instance has been created, the `fails` (or `passes`) method may be used to perform the validation. @@ -224,7 +224,7 @@ If you plan to have authorization logic in another part of your application, sim ### 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 request (`App\Http\Requests\Request`). Don't forget to import the `Illuminate\Validation\Validator` class at the top of the file: +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\Validation\Validator` class at the top of the file: /** * {@inheritdoc} @@ -366,7 +366,7 @@ Below is a list of all available validation rules and their function: #### accepted -The field under validation must be _yes_, _on_, or _1_. This is useful for validating "Terms of Service" acceptance. +The field under validation must be _yes_, _on_, _1_, or _true_. This is useful for validating "Terms of Service" acceptance. #### active_url @@ -533,7 +533,7 @@ The field under validation must be present in the input data. #### required_if:_field_,_value_,... -The field under validation must be present if the _field_ field is equal to any _value_. +The field under validation must be present if the _field_ is equal to any _value_. #### required_with:_foo_,_bar_,... @@ -566,7 +566,7 @@ The given _field_ must match the field under validation. The field under validation must have a size matching the given _value_. For string data, _value_ corresponds to the number of characters. For numeric data, _value_ corresponds to a given integer value. For files, _size_ corresponds to the file size in kilobytes. -#### string:_value_ +#### string The field under validation must be a string type. @@ -580,6 +580,20 @@ The field under validation must be a valid timezone identifier according to the The field under validation must be unique on a given database table. If the `column` option is not specified, the field name will be used. +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, do the following: + + $verifier = App::make('validation.presence'); + + $verifier->setConnection('connectionName'); + + $validator = Validator::make($input, [ + 'name' => 'required', + 'password' => 'required|min:8', + 'email' => 'required|email|unique:users', + ]); + + $validator->setPresenceVerifier($verifier); + #### Basic Usage Of Unique Rule 'email' => 'unique:users' @@ -712,7 +726,7 @@ Instead of using Closure callbacks to extend the Validator, you may also extend **Note:** 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\Composers` directory. +> **Note:** 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. + +Remember, 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: - **Note:** All view composers are resolved via the [service container](/docs/5.0/container), so you may type-hint any dependencies you need within a composer's constructor. +> **Note:** All view composers are resolved via the [service container](/docs/{{version}}/container), so you may type-hint any dependencies you need within a composer's constructor. #### Wildcard View Composers The `composer` method accepts the `*` character as a wildcard, so you may attach a composer to all views like so: - View::composer('*', function() + View::composer('*', function($view) { // });