21 |
22 | The `VerifyCsrfToken` [middleware](/docs/{{version}}/middleware), which is included in the `web` middleware group, will automatically verify that the token in the request input matches the token stored in the session.
23 |
24 |
25 | ## Excluding URIs From CSRF Protection
26 |
27 | Sometimes you may wish to exclude a set of URIs from CSRF protection. For example, if you are using [Stripe](https://stripe.com) to process payments and are utilizing their webhook system, you will need to exclude your Stripe webhook handler route from CSRF protection since Stripe will not know what CSRF token to send to your routes.
28 |
29 | Typically, you should place these kinds of routes outside of the `web` middleware group that the `RouteServiceProvider` applies to all routes in the `routes/web.php` file. However, you may also exclude the routes by adding their URIs to the `$except` property of the `VerifyCsrfToken` middleware:
30 |
31 |
50 | ## X-CSRF-TOKEN
51 |
52 | In addition to checking for the CSRF token as a POST parameter, the `VerifyCsrfToken` middleware will also check for the `X-CSRF-TOKEN` request header. You could, for example, store the token in a HTML `meta` tag:
53 |
54 |
55 |
56 | Then, once you have created the `meta` tag, you can instruct a library like jQuery to automatically add the token to all request headers. This provides simple, convenient CSRF protection for your AJAX based applications:
57 |
58 | $.ajaxSetup({
59 | headers: {
60 | 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
61 | }
62 | });
63 |
64 |
65 | ## X-XSRF-TOKEN
66 |
67 | Laravel stores the current CSRF token in a `XSRF-TOKEN` cookie that is included with each response generated by the framework. You can use the cookie value to set the `X-XSRF-TOKEN` request header.
68 |
69 | This cookie is primarily sent as a convenience since some JavaScript frameworks, like Angular, automatically place its value in the `X-XSRF-TOKEN` header.
70 |
--------------------------------------------------------------------------------
/documentation.md:
--------------------------------------------------------------------------------
1 | - Вступление
2 | - [Версии фреймворка](/docs/{{version}}/releases)
3 | - [Руководство по обновлению](/docs/{{version}}/upgrade)
4 | - [Участие в разработке](/docs/{{version}}/contributions)
5 | - [Документация API](/api/{{version}})
6 | - Начало работы
7 | - [Установка](/docs/{{version}}/installation)
8 | - [Настройка](/docs/{{version}}/configuration)
9 | - [Структура директорий](/docs/{{version}}/structure)
10 | - [Жизненный цикл запроса](/docs/{{version}}/lifecycle)
11 | - Среда разработки
12 | - [Homestead](/docs/{{version}}/homestead)
13 | - [Valet](/docs/{{version}}/valet)
14 | - Ключевые концепции
15 | - [Контейнеры сервисов](/docs/{{version}}/container)
16 | - [Провайдеры сервисов](/docs/{{version}}/providers)
17 | - [Фасады](/docs/{{version}}/facades)
18 | - [Контракты](/docs/{{version}}/contracts)
19 | - Слой HTTP
20 | - [Роутинг](/docs/{{version}}/routing)
21 | - [Middleware](/docs/{{version}}/middleware)
22 | - [CSRF-защита](/docs/{{version}}/csrf)
23 | - [Контроллеры](/docs/{{version}}/controllers)
24 | - [Запросы](/docs/{{version}}/requests)
25 | - [Ответы](/docs/{{version}}/responses)
26 | - [Представления](/docs/{{version}}/views)
27 | - [Сессии](/docs/{{version}}/session)
28 | - [Валидация](/docs/{{version}}/validation)
29 | - Фронтенд
30 | - [Шаблонизатор Blade](/docs/{{version}}/blade)
31 | - [Локализация](/docs/{{version}}/localization)
32 | - [Построение фронтенда](/docs/{{version}}/frontend)
33 | - [Сборка статики](/docs/{{version}}/mix)
34 | - Безопасность
35 | - [Аутентификация](/docs/{{version}}/authentication)
36 | - [Аутентификация через API](/docs/{{version}}/passport)
37 | - [Авторизация](/docs/{{version}}/authorization)
38 | - [Шифрование](/docs/{{version}}/encryption)
39 | - [Хэширование](/docs/{{version}}/hashing)
40 | - [Сброс пароля](/docs/{{version}}/passwords)
41 | - Общие вопросы
42 | - [Консольные команды Artisan](/docs/{{version}}/artisan)
43 | - [Широковещание](/docs/{{version}}/broadcasting)
44 | - [Кэш](/docs/{{version}}/cache)
45 | - [События](/docs/{{version}}/events)
46 | - [Уведомления](/docs/{{version}}/notifications)
47 | - [Очереди](/docs/{{version}}/queues)
48 | - [Коллекции](/docs/{{version}}/collections)
49 | - [Ошибки и логирование](/docs/{{version}}/errors)
50 | - [Хранение файлов](/docs/{{version}}/filesystem)
51 | - [Хелперы](/docs/{{version}}/helpers)
52 | - [Работа с почтой](/docs/{{version}}/mail)
53 | - [Планировщик задач](/docs/{{version}}/scheduling)
54 | - [Разработка пакетов](/docs/{{version}}/packages)
55 | - База данных
56 | - [Начало работы](/docs/{{version}}/database)
57 | - [Компоновщик запросов](/docs/{{version}}/queries)
58 | - [Пагинация](/docs/{{version}}/pagination)
59 | - [Миграции](/docs/{{version}}/migrations)
60 | - [Генерация тестовых данных](/docs/{{version}}/seeding)
61 | - [Redis](/docs/{{version}}/redis)
62 | - Eloquent ORM
63 | - [Начало работы](/docs/{{version}}/eloquent)
64 | - [Отношения](/docs/{{version}}/eloquent-relationships)
65 | - [Коллекции](/docs/{{version}}/eloquent-collections)
66 | - [Мутаторы](/docs/{{version}}/eloquent-mutators)
67 | - [Сериализация](/docs/{{version}}/eloquent-serialization)
68 | - Тестирование
69 | - [Начало работы](/docs/{{version}}/testing)
70 | - [HTTP-тесты](/docs/{{version}}/http-tests)
71 | - [Браузерные тесты](/docs/{{version}}/dusk)
72 | - [Тесты взаимодействия с БД](/docs/{{version}}/database-testing)
73 | - [Мокинг](/docs/{{version}}/mocking)
74 | - Официальные пакеты
75 | - [Cashier](/docs/{{version}}/billing)
76 | - [Envoy](/docs/{{version}}/envoy)
77 | - [Passport](/docs/{{version}}/passport)
78 | - [Scout](/docs/{{version}}/scout)
79 | - [Socialite](https://github.com/laravel/socialite)
80 |
--------------------------------------------------------------------------------
/redirects.md:
--------------------------------------------------------------------------------
1 | # HTTP Redirects
2 |
3 | - [Creating Redirects](#creating-redirects)
4 | - [Redirecting To Named Routes](#redirecting-named-routes)
5 | - [Redirecting To Controller Actions](#redirecting-controller-actions)
6 | - [Redirecting With Flashed Session Data](#redirecting-with-flashed-session-data)
7 |
8 |
9 | ## Creating Redirects
10 |
11 | Redirect responses are instances of the `Illuminate\Http\RedirectResponse` class, and contain the proper headers needed to redirect the user to another URL. There are several ways to generate a `RedirectResponse` instance. The simplest method is to use the global `redirect` helper:
12 |
13 | Route::get('dashboard', function () {
14 | return redirect('home/dashboard');
15 | });
16 |
17 | Sometimes you may wish to redirect the user to their previous location, such as when a submitted form is invalid. You may do so by using the global `back` helper function. Since this feature utilizes the [session](/docs/{{version}}/session), make sure the route calling the `back` function is using the `web` middleware group or has all of the session middleware applied:
18 |
19 | Route::post('user/profile', function () {
20 | // Validate the request...
21 |
22 | return back()->withInput();
23 | });
24 |
25 |
26 | ## Redirecting To Named Routes
27 |
28 | When you call the `redirect` helper with no parameters, an instance of `Illuminate\Routing\Redirector` is returned, allowing you to call any method on the `Redirector` instance. For example, to generate a `RedirectResponse` to a named route, you may use the `route` method:
29 |
30 | return redirect()->route('login');
31 |
32 | If your route has parameters, you may pass them as the second argument to the `route` method:
33 |
34 | // For a route with the following URI: profile/{id}
35 |
36 | return redirect()->route('profile', ['id' => 1]);
37 |
38 | #### Populating Parameters Via Eloquent Models
39 |
40 | If you are redirecting to a route with an "ID" parameter that is being populated from an Eloquent model, you may simply pass the model itself. The ID will be extracted automatically:
41 |
42 | // For a route with the following URI: profile/{id}
43 |
44 | return redirect()->route('profile', [$user]);
45 |
46 | If you would like to customize the value that is placed in the route parameter, you should override the `getRouteKey` method on your Eloquent model:
47 |
48 | /**
49 | * Get the value of the model's route key.
50 | *
51 | * @return mixed
52 | */
53 | public function getRouteKey()
54 | {
55 | return $this->slug;
56 | }
57 |
58 |
59 | ## Redirecting To Controller Actions
60 |
61 | You may also generate redirects to [controller actions](/docs/{{version}}/controllers). To do so, pass the controller and action name to the `action` method. Remember, you do not need to specify the full namespace to the controller since Laravel's `RouteServiceProvider` will automatically set the base controller namespace:
62 |
63 | return redirect()->action('HomeController@index');
64 |
65 | If your controller route requires parameters, you may pass them as the second argument to the `action` method:
66 |
67 | return redirect()->action(
68 | 'UserController@profile', ['id' => 1]
69 | );
70 |
71 |
72 | ## Redirecting With Flashed Session Data
73 |
74 | Redirecting to a new URL and [flashing data to the session](/docs/{{version}}/session#flash-data) are usually done at the same time. Typically, this is done after successfully performing an action when you flash a success message to the session. For convenience, you may create a `RedirectResponse` instance and flash data to the session in a single, fluent method chain:
75 |
76 | Route::post('user/profile', function () {
77 | // Update the user's profile...
78 |
79 | return redirect('dashboard')->with('status', 'Profile updated!');
80 | });
81 |
82 | After the user is redirected, you may display the flashed message from the [session](/docs/{{version}}/session). For example, using [Blade syntax](/docs/{{version}}/blade):
83 |
84 | @if (session('status'))
85 |
86 | {{ session('status') }}
87 |
88 | @endif
89 |
--------------------------------------------------------------------------------
/seeding.md:
--------------------------------------------------------------------------------
1 | # Database: Seeding
2 |
3 | - [Introduction](#introduction)
4 | - [Writing Seeders](#writing-seeders)
5 | - [Using Model Factories](#using-model-factories)
6 | - [Calling Additional Seeders](#calling-additional-seeders)
7 | - [Running Seeders](#running-seeders)
8 |
9 |
10 | ## Introduction
11 |
12 | Laravel includes a simple method of seeding your database with test data using seed classes. All seed classes are stored in the `database/seeds` directory. Seed classes may have any name you wish, but probably should follow some sensible convention, such as `UsersTableSeeder`, etc. By default, a `DatabaseSeeder` class is defined for you. From this class, you may use the `call` method to run other seed classes, allowing you to control the seeding order.
13 |
14 |
15 | ## Writing Seeders
16 |
17 | To generate a seeder, execute the `make:seeder` [Artisan command](/docs/{{version}}/artisan). All seeders generated by the framework will be placed in the `database/seeds` directory:
18 |
19 | php artisan make:seeder UsersTableSeeder
20 |
21 | A seeder class only contains one method by default: `run`. This method is called when the `db:seed` [Artisan command](/docs/{{version}}/artisan) is executed. Within the `run` method, you may insert data into your database however you wish. You may use the [query builder](/docs/{{version}}/queries) to manually insert data or you may use [Eloquent model factories](/docs/{{version}}/database-testing#writing-factories).
22 |
23 | As an example, let's modify the default `DatabaseSeeder` class and add a database insert statement to the `run` method:
24 |
25 | insert([
40 | 'name' => str_random(10),
41 | 'email' => str_random(10).'@gmail.com',
42 | 'password' => bcrypt('secret'),
43 | ]);
44 | }
45 | }
46 |
47 |
48 | ### Using Model Factories
49 |
50 | Of course, manually specifying the attributes for each model seed is cumbersome. Instead, you can use [model factories](/docs/{{version}}/database-testing#writing-factories) to conveniently generate large amounts of database records. First, review the [model factory documentation](/docs/{{version}}/database-testing#writing-factories) to learn how to define your factories. Once you have defined your factories, you may use the `factory` helper function to insert records into your database.
51 |
52 | For example, let's create 50 users and attach a relationship to each user:
53 |
54 | /**
55 | * Run the database seeds.
56 | *
57 | * @return void
58 | */
59 | public function run()
60 | {
61 | factory(App\User::class, 50)->create()->each(function ($u) {
62 | $u->posts()->save(factory(App\Post::class)->make());
63 | });
64 | }
65 |
66 |
67 | ### Calling Additional Seeders
68 |
69 | Within the `DatabaseSeeder` class, you may use the `call` method to execute additional seed classes. Using the `call` method allows you to break up your database seeding into multiple files so that no single seeder class becomes overwhelmingly large. Simply pass the name of the seeder class you wish to run:
70 |
71 | /**
72 | * Run the database seeds.
73 | *
74 | * @return void
75 | */
76 | public function run()
77 | {
78 | $this->call(UsersTableSeeder::class);
79 | $this->call(PostsTableSeeder::class);
80 | $this->call(CommentsTableSeeder::class);
81 | }
82 |
83 |
84 | ## Running Seeders
85 |
86 | Once you have written your seeder classes, you may use the `db:seed` Artisan command to seed your database. By default, the `db:seed` command runs the `DatabaseSeeder` class, which may be used to call other seed classes. However, you may use the `--class` option to specify a specific seeder class to run individually:
87 |
88 | php artisan db:seed
89 |
90 | php artisan db:seed --class=UsersTableSeeder
91 |
92 | You may also seed your database using the `migrate:refresh` command, which will also rollback and re-run all of your migrations. This command is useful for completely re-building your database:
93 |
94 | php artisan migrate:refresh --seed
95 |
--------------------------------------------------------------------------------
/lifecycle.md:
--------------------------------------------------------------------------------
1 | # Request Lifecycle
2 |
3 | - [Introduction](#introduction)
4 | - [Lifecycle Overview](#lifecycle-overview)
5 | - [Focus On Service Providers](#focus-on-service-providers)
6 |
7 |
8 | ## Introduction
9 |
10 | When using any tool in the "real world", you feel more confident if you understand how that tool works. Application development is no different. When you understand how your development tools function, you feel more comfortable and confident using them.
11 |
12 | The goal of this document is to give you a good, high-level overview of how the Laravel framework works. By getting to know the overall framework better, everything feels less "magical" and you will be more confident building your applications. If you don't understand all of the terms right away, don't lose heart! Just try to get a basic grasp of what is going on, and your knowledge will grow as you explore other sections of the documentation.
13 |
14 |
15 | ## Lifecycle Overview
16 |
17 | ### First Things
18 |
19 | 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.
20 |
21 | 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).
22 |
23 | ### HTTP / Console Kernels
24 |
25 | Next, the incoming request is sent to either the HTTP kernel or the console kernel, depending on the type of request that is entering the application. These two kernels serve as the central location that all requests flow through. For now, let's just focus on the HTTP kernel, which is located in `app/Http/Kernel.php`.
26 |
27 | 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](/docs/{{version}}/configuration#environment-configuration), and perform other tasks that need to be done before the request is actually handled.
28 |
29 | 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](/docs/{{version}}/session), determining if the application is in maintenance mode, [verifying the CSRF token](/docs/{{version}}/csrf), and more.
30 |
31 | 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.
32 |
33 | #### Service Providers
34 |
35 | One of the most important Kernel bootstrapping actions is loading the [service providers](/docs/{{version}}/providers) for your application. All of the service providers for the application are configured in the `config/app.php` configuration file's `providers` array. First, the `register` method will be called on all providers, then, once all providers have been registered, the `boot` method will be called.
36 |
37 | Service providers are responsible for bootstrapping all of the framework's various components, such as the database, queue, validation, and routing components. Since they bootstrap and configure every feature offered by the framework, service providers are the most important aspect of the entire Laravel bootstrap process.
38 |
39 | #### Dispatch Request
40 |
41 | Once the application has been bootstrapped and all service providers have been registered, the `Request` will be handed off to the router for dispatching. The router will dispatch the request to a route or controller, as well as run any route specific middleware.
42 |
43 |
44 | ## Focus On Service Providers
45 |
46 | Service providers are truly the key to bootstrapping a Laravel application. The application instance is created, the service providers are registered, and the request is handed to the bootstrapped application. It's really that simple!
47 |
48 | Having a firm grasp of how a Laravel application is built and bootstrapped via service providers is very valuable. Of course, your application's default service providers are stored in the `app/Providers` directory.
49 |
50 | By default, the `AppServiceProvider` is fairly empty. This provider is a great place to add your application's own bootstrapping and service container bindings. Of course, for large applications, you may wish to create several service providers, each with a more granular type of bootstrapping.
51 |
--------------------------------------------------------------------------------
/contributions.md:
--------------------------------------------------------------------------------
1 | # Участие в разработке
2 |
3 | - [Баг-репорты](#bug-reports)
4 | - [Обсуждение разработки](#core-development-discussion)
5 | - [Определение ветки](#which-branch)
6 | - [Уязвимости безопасности](#security-vulnerabilities)
7 | - [Стиль написания кода](#coding-style)
8 | - [PHPDoc](#phpdoc)
9 | - [StyleCI](#styleci)
10 |
11 |
12 | ## Баг-репорты
13 |
14 | С целью активного развития фреймворка, Laravel настоятельно рекомендует создавать пулл-реквесты, а не только баг-репорты. Баг-репорты могут быть отправлены в форме пулл-реквеста, содержащего в себе ошибку прохождения юнит-тестов.
15 |
16 | Помните, что если вы отправляете баг-репорт, он должен содержать заголовок и чёткое описание проблемы. Вам также следует включить как можно больше значимой информации и примеров кода, которые отражают проблему. Цель баг-репорта состоит в упрощении локализации и исправления проблемы.
17 |
18 | Также помните, что баг-репорты создаются в надежде, что другие пользователи с такой же проблемой смогут принять участие в её решении вместе с вами. Но не ждите, что сразу появится какая-либо активность над вашим репортом или другие побегут исправлять вашу проблему. Баг-репорт призван помочь вам и другим пользователям начать совместную работу над решением проблемы.
19 |
20 | Исходный код Laravel находится на GitHub, список репозиториев каждого из проектов Laravel:
21 |
22 | - [Laravel Framework](https://github.com/laravel/framework)
23 | - [Laravel Application](https://github.com/laravel/laravel)
24 | - [Laravel Documentation](https://github.com/laravel/docs)
25 | - [Laravel Cashier](https://github.com/laravel/cashier)
26 | - [Laravel Cashier for Braintree](https://github.com/laravel/cashier-braintree)
27 | - [Laravel Envoy](https://github.com/laravel/envoy)
28 | - [Laravel Homestead](https://github.com/laravel/homestead)
29 | - [Laravel Homestead Build Scripts](https://github.com/laravel/settler)
30 | - [Laravel Passport](https://github.com/laravel/passport)
31 | - [Laravel Scout](https://github.com/laravel/scout)
32 | - [Laravel Socialite](https://github.com/laravel/socialite)
33 | - [Laravel Website](https://github.com/laravel/laravel.com)
34 | - [Laravel Art](https://github.com/laravel/art)
35 |
36 |
37 | ## Обсуждение разработки
38 |
39 | Вы можете предложить новый функционал или улучшение существующего в [обсуждениях](https://github.com/laravel/internals/issues) репозитория Laravel Internals. Если вы предлагаете новый функционал, то, пожалуйста, будьте готовы написать по крайней мере часть кода, который потребуется для завершения реализации функционала.
40 |
41 | Неформальное обсуждение ошибок, новых и существующих возможностей проходит в канале `#internals` в Slack-чате [LaraChat](https://larachat.co). Тейлор Отвелл, главный разработчик, обычно находится в канале по будням с 17:00 вечера до 02:00 ночи (время московское, UTC+03:00), и иногда появляется в другое время.
42 |
43 |
44 | ## Определение ветки
45 |
46 | **Все** баг-репорты должны отправляться в последнюю стабильную ветку или в текущую LTS-ветку (5.1). Баг-репорты **никогда** не должны отправляться в ветку `master` кроме случаев, когда они затрагивают функционал, существующий только в следующем релизе.
47 |
48 | **Мелкие** изменения, которые обладают **полной обратной совместимостью** с актуальным релизом Laravel, могут отправляться в последнюю стабильную ветку.
49 |
50 | **Крупные** изменения в функционале всегда должны отправляться в ветку `master`, в которой находится следующий релиз Laravel.
51 |
52 | Если вы не уверены в том, как квалифицировать ваше изменение, пожалуйста, спросите у Тейлора Отвелла в канале `#internals` в Slack-чате [LaraChat](https://larachat.co).
53 |
54 |
55 | ## Уязвимости безопасности
56 |
57 | Если вы обнаружили уязвимость в безопасности Laravel, пожалуйста, отправьте email-письмо Тейлору Отвеллу на taylor@laravel.com. Все подобные уязвимости будут оперативно рассмотрены.
58 |
59 |
60 | ## Стиль написания кода
61 |
62 | Laravel придерживается стандарта написания кода [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) и стандартна автозагрузки классов [PSR-4](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md).
63 |
64 |
65 | ### PHPDoc
66 |
67 | Ниже расположен пример корректного блока документации кода Laravel. Обратите внимание, что после атрибута `@param` идут два пробела, затем тип аргумента, после ещё два пробела, и всё завершается названием переменной:
68 |
69 | /**
70 | * Register a binding with the container.
71 | *
72 | * @param string|array $abstract
73 | * @param \Closure|string|null $concrete
74 | * @param bool $shared
75 | * @return void
76 | */
77 | public function bind($abstract, $concrete = null, $shared = false)
78 | {
79 | //
80 | }
81 |
82 |
83 | ### StyleCI
84 |
85 | Не беспокойтесь, если стиль вашего кода не безупречен! [StyleCI](https://styleci.io/) автоматически применит стилистические правки после вливания пулл-реквеста в репозиторий Laravel. Это позволяет нам сосредоточиться на самом коде, а не его стиле.
86 |
--------------------------------------------------------------------------------
/passwords.md:
--------------------------------------------------------------------------------
1 | # Resetting Passwords
2 |
3 | - [Introduction](#introduction)
4 | - [Database Considerations](#resetting-database)
5 | - [Routing](#resetting-routing)
6 | - [Views](#resetting-views)
7 | - [After Resetting Passwords](#after-resetting-passwords)
8 | - [Customization](#password-customization)
9 |
10 |
11 | ## Introduction
12 |
13 | > {tip} **Want to get started fast?** Just run `php artisan make:auth` in a fresh Laravel application and navigate your browser to `http://your-app.dev/register` or any other URL that is assigned to your application. This single command will take care of scaffolding your entire authentication system, including resetting passwords!
14 |
15 | Most web applications provide a way for users to reset their forgotten passwords. Rather than forcing you to re-implement this on each application, Laravel provides convenient methods for sending password reminders and performing password resets.
16 |
17 | > {note} Before using the password reset features of Laravel, your user must use the `Illuminate\Notifications\Notifiable` trait.
18 |
19 |
20 | ## Database Considerations
21 |
22 | To get started, verify that your `App\User` model implements the `Illuminate\Contracts\Auth\CanResetPassword` contract. Of course, the `App\User` model included with the framework already implements this interface, and uses the `Illuminate\Auth\Passwords\CanResetPassword` trait to include the methods needed to implement the interface.
23 |
24 | #### Generating The Reset Token Table Migration
25 |
26 | Next, a table must be created to store the password reset tokens. The migration for this table is included with Laravel out of the box, and resides in the `database/migrations` directory. So, all you need to do is run your database migrations:
27 |
28 | php artisan migrate
29 |
30 |
31 | ## Routing
32 |
33 | Laravel includes `Auth\ForgotPasswordController` and `Auth\ResetPasswordController` classes that contains the logic necessary to e-mail password reset links and reset user passwords. All of the routes needed to perform password resets may be generated using the `make:auth` Artisan command:
34 |
35 | php artisan make:auth
36 |
37 |
38 | ## Views
39 |
40 | Again, Laravel will generate all of the necessary views for password reset when the `make:auth` command is executed. These views are placed in `resources/views/auth/passwords`. You are free to customize them as needed for your application.
41 |
42 |
43 | ## After Resetting Passwords
44 |
45 | Once you have defined the routes and views to reset your user's passwords, you may simply access the route in your browser at `/password/reset`. The `ForgotPasswordController` included with the framework already includes the logic to send the password reset link e-mails, while the `ResetPasswordController` includes the logic to reset user passwords.
46 |
47 | After a password is reset, the user will automatically be logged into the application and redirected to `/home`. You can customize the post password reset redirect location by defining a `redirectTo` property on the `ResetPasswordController`:
48 |
49 | protected $redirectTo = '/dashboard';
50 |
51 | > {note} By default, password reset tokens expire after one hour. You may change this via the password reset `expire` option in your `config/auth.php` file.
52 |
53 |
54 | ## Customization
55 |
56 | #### Authentication Guard Customization
57 |
58 | In your `auth.php` configuration file, you may configure multiple "guards", which may be used to define authentication behavior for multiple user tables. You can customize the included `ResetPasswordController` to use the guard of your choice by overriding the `guard` method on the controller. This method should return a guard instance:
59 |
60 | use Illuminate\Support\Facades\Auth;
61 |
62 | protected function guard()
63 | {
64 | return Auth::guard('guard-name');
65 | }
66 |
67 | #### Password Broker Customization
68 |
69 | In your `auth.php` configuration file, you may configure multiple password "brokers", which may be used to reset passwords on multiple user tables. You can customize the included `ForgotPasswordController` and `ResetPasswordController` to use the broker of your choice by overriding the `broker` method:
70 |
71 | use Illuminate\Support\Facades\Password;
72 |
73 | /**
74 | * Get the broker to be used during password reset.
75 | *
76 | * @return PasswordBroker
77 | */
78 | protected function broker()
79 | {
80 | return Password::broker('name');
81 | }
82 |
83 | #### Reset Email Customization
84 |
85 | You may easily modify the notification class used to send the password reset link to the user. To get started, override the `sendPasswordResetNotification` method on your `User` model. Within this method, you may send the notification using any notification class you choose. The password reset `$token` is the first argument received by the method:
86 |
87 | /**
88 | * Send the password reset notification.
89 | *
90 | * @param string $token
91 | * @return void
92 | */
93 | public function sendPasswordResetNotification($token)
94 | {
95 | $this->notify(new ResetPasswordNotification($token));
96 | }
97 |
98 |
--------------------------------------------------------------------------------
/eloquent-serialization.md:
--------------------------------------------------------------------------------
1 | # Eloquent: Serialization
2 |
3 | - [Introduction](#introduction)
4 | - [Serializing Models & Collections](#serializing-models-and-collections)
5 | - [Serializing To Arrays](#serializing-to-arrays)
6 | - [Serializing To JSON](#serializing-to-json)
7 | - [Hiding Attributes From JSON](#hiding-attributes-from-json)
8 | - [Appending Values To JSON](#appending-values-to-json)
9 |
10 |
11 | ## Introduction
12 |
13 | When building JSON APIs, you will often need to convert your models and relationships to arrays or JSON. Eloquent includes convenient methods for making these conversions, as well as controlling which attributes are included in your serializations.
14 |
15 |
16 | ## Serializing Models & Collections
17 |
18 |
19 | ### Serializing To Arrays
20 |
21 | To convert a model and its loaded [relationships](/docs/{{version}}/eloquent-relationships) to an array, you should use the `toArray` method. This method is recursive, so all attributes and all relations (including the relations of relations) will be converted to arrays:
22 |
23 | $user = App\User::with('roles')->first();
24 |
25 | return $user->toArray();
26 |
27 | You may also convert entire [collections](/docs/{{version}}/eloquent-collections) of models to arrays:
28 |
29 | $users = App\User::all();
30 |
31 | return $users->toArray();
32 |
33 |
34 | ### Serializing To JSON
35 |
36 | To convert a model to JSON, you should use the `toJson` method. Like `toArray`, the `toJson` method is recursive, so all attributes and relations will be converted to JSON:
37 |
38 | $user = App\User::find(1);
39 |
40 | return $user->toJson();
41 |
42 | Alternatively, you may cast a model or collection to a string, which will automatically call the `toJson` method on the model or collection:
43 |
44 | $user = App\User::find(1);
45 |
46 | return (string) $user;
47 |
48 | Since models and collections are converted to JSON when cast to a string, you can return Eloquent objects directly from your application's routes or controllers:
49 |
50 | Route::get('users', function () {
51 | return App\User::all();
52 | });
53 |
54 |
55 | ## Hiding Attributes From JSON
56 |
57 | Sometimes you may wish to limit the attributes, such as passwords, that are included in your model's array or JSON representation. To do so, add a `$hidden` property to your model:
58 |
59 | {note} When hiding relationships, use the relationship's method name, not its dynamic property name.
76 |
77 | Alternatively, you may use the `visible` property to define a white-list of attributes that should be included in your model's array and JSON representation. All other attributes will be hidden when the model is converted to an array or JSON:
78 |
79 | makeVisible('attribute')->toArray();
100 |
101 | Likewise, if you would like to make some typically visible attributes hidden on a given model instance, you may use the `makeHidden` method.
102 |
103 | return $user->makeHidden('attribute')->toArray();
104 |
105 |
106 | ## Appending Values To JSON
107 |
108 | Occasionally, when casting models to an array or JSON, you may wish to add attributes that do not have a corresponding column in your database. To do so, first define an [accessor](/docs/{{version}}/eloquent-mutators) for the value:
109 |
110 | attributes['admin'] == 'yes';
126 | }
127 | }
128 |
129 | After creating the accessor, add the attribute name to the `appends` property on the model. Note that attribute names are typically referenced in "snake case", even though the accessor is defined using "camel case":
130 |
131 |
9 | ## Introduction
10 |
11 | While Laravel does not dictate which JavaScript or CSS pre-processors you use, it does provide a basic starting point using [Bootstrap](https://getbootstrap.com/) and [Vue](https://vuejs.org) that will be helpful for many applications. By default, Laravel uses [NPM](https://www.npmjs.org) to install both of these frontend packages.
12 |
13 | #### CSS
14 |
15 | [Laravel Mix](/docs/{{version}}/mix) provides a clean, expressive API over compiling SASS or Less, which are extensions of plain CSS that add variables, mixins, and other powerful features that make working with CSS much more enjoyable.
16 |
17 | In this document, we will briefly discuss CSS compilation in general; however, you should consult the full [Laravel Mix documentation](/docs/{{version}}/mix) for more information on compiling SASS or Less.
18 |
19 | #### JavaScript
20 |
21 | Laravel does not require you to use a specific JavaScript framework or library to build your applications. In fact, you don't have to use JavaScript at all. However, Laravel does include some basic scaffolding to make it easier to get started writing modern JavaScript using the [Vue](https://vuejs.org) library. Vue provides an expressive API for building robust JavaScript applications using components.
22 |
23 |
24 | ## Writing CSS
25 |
26 | The Laravel `package.json` file includes the `bootstrap-sass` package to help you get started prototyping your application's frontend using Bootstrap. However, feel free to add or remove packages from the `package.json` file as needed for your own application. You are not required to use the Bootstrap framework to build your Laravel application - it is simply provided as a good starting point for those who choose to use it.
27 |
28 | Before compiling your CSS, install your project's frontend dependencies using NPM:
29 |
30 | npm install
31 |
32 | Once the dependencies have been installed using `npm install`, you can compile your SASS files to plain CSS using [Laravel Mix](/docs/{{version}}/mix#working-with-stylesheets). The `npm run dev` command will process the instructions in your `webpack.mix.js` file. Typically, your compiled CSS will be placed in the `public/css` directory:
33 |
34 | npm run dev
35 |
36 | The default `webpack.mix.js` included with Laravel will compile the `resources/assets/sass/app.scss` SASS file. This `app.scss` file imports a file of SASS variables and loads Bootstrap, which provides a good starting point for most applications. Feel free to customize the `app.scss` file however you wish or even use an entirely different pre-processor by [configuring Laravel Mix](/docs/{{version}}/mix).
37 |
38 |
39 | ## Writing JavaScript
40 |
41 | All of the JavaScript dependencies required by your application can be found in the `package.json` file in the project's root directory. This file is similar to a `composer.json` file except it specifies JavaScript dependencies instead of PHP dependencies. You can install these dependencies using the [Node package manager (NPM)](https://www.npmjs.org):
42 |
43 | npm install
44 |
45 | By default, the Laravel `package.json` file includes a few packages such as `vue` and `axios` to help you get started building your JavaScript application. Feel free to add or remove from the `package.json` file as needed for your own application.
46 |
47 | Once the packages are installed, you can use the `npm run dev` command to [compile your assets](/docs/{{version}}/mix). Webpack is a module bundler for modern JavaScript applications. When you run the `npm run dev` command, Webpack will execute the instructions in your `webpack.mix.js` file:
48 |
49 | npm run dev
50 |
51 | By default, the Laravel `webpack.mix.js` file compiles your SASS and the `resources/assets/js/app.js` file. Within the `app.js` file you may register your Vue components or, if you prefer a different framework, configure your own JavaScript application. Your compiled JavaScript will typically be placed in the `public/js` directory.
52 |
53 | > {tip} The `app.js` file will load the `resources/assets/js/bootstrap.js` file which bootstraps and configures Vue, Axios, jQuery, and all other JavaScript dependencies. If you have additional JavaScript dependencies to configure, you may do so in this file.
54 |
55 |
56 | ### Writing Vue Components
57 |
58 | By default, fresh Laravel applications contain an `Example.vue` Vue component located in the `resources/assets/js/components` directory. The `Example.vue` file is an example of a [single file Vue component](https://vuejs.org/guide/single-file-components) which defines its JavaScript and HTML template in the same file. Single file components provide a very convenient approach to building JavaScript driven applications. The example component is registered in your `app.js` file:
59 |
60 | Vue.component('example', require('./components/Example.vue'));
61 |
62 | To use the component in your application, you may simply drop it into one of your HTML templates. For example, after running the `make:auth` Artisan command to scaffold your application's authentication and registration screens, you could drop the component into the `home.blade.php` Blade template:
63 |
64 | @extends('layouts.app')
65 |
66 | @section('content')
67 |
68 | @endsection
69 |
70 | > {tip} Remember, you should run the `npm run dev` command each time you change a Vue component. Or, you may run the `npm run watch` command to monitor and automatically recompile your components each time they are modified.
71 |
72 | Of course, if you are interested in learning more about writing Vue components, you should read the [Vue documentation](https://vuejs.org/guide/), which provides a thorough, easy-to-read overview of the entire Vue framework.
73 |
--------------------------------------------------------------------------------
/installation.md:
--------------------------------------------------------------------------------
1 | # Установка
2 |
3 | - [Установка](#installation)
4 | - [Требования к серверу](#server-requirements)
5 | - [Установка Laravel](#installing-laravel)
6 | - [Настройка](#configuration)
7 | - [Настройка веб-сервера](#web-server-configuration)
8 | - [Настройка ЧПУ](#pretty-urls)
9 |
10 |
11 | ## Установка
12 |
13 | > {video} Предпочитаете визуальное обучение? На Laracasts вы можете найти [бесплатное и подробное введение в Laravel](https://laracasts.com/series/laravel-from-scratch-2017) для новичков. Это отличная отправная точка вашего путешествия.
14 |
15 |
16 | ### Требования к серверу
17 |
18 | Фреймворк Laravel предъявляет некоторые системные требования. Конечно же, виртуальная машина [Laravel Homestead](/docs/{{version}}/homestead) соответствует всем этим требованиям, поэтому настоятельно рекомендуется использовать Homestead в качестве основной локальной среды разработки с Laravel.
19 |
20 | Однако, если вы не используете Homestead, вам необходимо убедиться, что ваш сервер соответствует следующим требованиям:
21 |
22 |
23 | - PHP >= 5.6.4
24 | - Расширение PHP OpenSSL
25 | - Расширение PHP PDO
26 | - Расширение PHP Mbstring
27 | - Расширение PHP Tokenizer
28 | - Расширение PHP XML
29 |
30 |
31 |
32 | ### Установка Laravel
33 |
34 | Laravel использует [Composer](https://getcomposer.org) для управления своими зависимостями, поэтому убедитесь в том, что Composer установлен на вашей машине.
35 |
36 | #### С помощью установщика Laravel
37 |
38 | Загрузите установщик Laravel с помощью Composer:
39 |
40 | composer global require "laravel/installer"
41 |
42 | Проверьте, чтобы директория `$HOME/.composer/vendor/bin` (или аналогичная в зависимости от вашей ОС) находилась в переменной `$PATH`, что позволит вашей системе найти и выполнить команду `laravel`.
43 |
44 | Команда `laravel new` создаёт свежую установку Laravel в указанной вами директории. Например, `laravel new blog` создаст директорию с названием `blog`, которая будет содержать свежую установку Laravel со всеми зависимостями:
45 |
46 | laravel new blog
47 |
48 | #### С помощью Composer Create-Project
49 |
50 | В качестве альтернативы вы можете использовать Composer для установки Laravel с помощью команды `create-project`:
51 |
52 | composer create-project --prefer-dist laravel/laravel blog
53 |
54 | #### Локальный сервер разработки
55 |
56 | Если локально у вас уже установлен PHP и вы хотели бы использовать встроенный сервер для работы вашего приложения, то вы можете использовать команду Artisan `serve`. Эта команда запустит сервер разработки по адресу `http://localhost:8000`:
57 |
58 | php artisan serve
59 |
60 | Конечно же, [Homestead](/docs/{{version}}/homestead) и [Valet](/docs/{{version}}/valet) предоставляют наиболее надежные способы локальной разработки.
61 |
62 |
63 | ### Настройка
64 |
65 | #### Публичная директория
66 |
67 | После установки Laravel вам следует указать директорию `public` в качестве корневой директории вашего веб-сервера. Файл `index.php` в этой категории выступает в роли фронт-контроллера всех HTTP-запросов, поступающих в ваше приложение.
68 |
69 | #### Конфигурационные файлы
70 |
71 | Все конфигурационные файлы фреймворка Laravel расположены в директории `config`. Параметры в каждом из них снабжены комментариями, поэтому не стесняйтесь пройтись по этим файлам и познакомиться с доступными параметрами настройки.
72 |
73 | #### Права доступа на директории
74 |
75 | Так же, после установки Laravel вам может потребоваться настройка некоторых прав доступа. Директории внутри `storage` и `bootstrap/cache` должны быть доступны для записи веб-сервером, в противном случае Laravel не запустится. Если вы используете виртуальную машину [Homestead](/docs/{{version}}/homestead), то эти права доступа уже установлены.
76 |
77 | #### Ключ приложения
78 |
79 | Следующее, что вы должны сделать после установки Laravel, это создать ключ шифрования для вашего приложения в виде случайного набора символов. Если вы установили Laravel через Composer или установщик Laravel, то этот ключ уже был создан с помощью команды `php artisan key:generate`.
80 |
81 | Как правило, это строка должна быть длиной в 32 символа. Ключ должен быть указан в параметре `APP_KEY` файла окружения `.env`. Если вы не переименовывали файл `.env.example` в `.env`, то следует сделать это сейчас. **Если ключ приложения не создан, то сессии ваших пользователей и другие шифруемые данные не будут в безопасности!**
82 |
83 | #### Дополнительная настройка
84 |
85 | Laravel практически не требует настройки из коробки. Вы сразу можете начать разработку! Однако, рекомендуем ознакомиться с файлом `config/app.php` — он содержит в себе несколько параметров, таких как часовой пояс (`timezone`) и локаль (`locale`), которые вы можете изменить согласно потребностям вашего приложения.
86 |
87 | Вы также можете настроить некоторые дополнительные компоненты Laravel, такие как:
88 |
89 |
94 |
95 |
96 | ## Настройка веб-сервера
97 |
98 |
99 | ### Настройка ЧПУ
100 |
101 | #### Apache
102 |
103 | В Laravel есть файл `public/.htaccess`, который используется для отображения ссылок без указания фронт-контроллера `index.php` в запрашиваемом адресе. Перед началом работы Laravel с сервером Apache, убедитесь, что модуль `mod_rewrite` включен, он необходим для корректной обработки файла `.htaccess`.
104 |
105 | Если поставляемый с Laravel файл `.htaccess` не работает с вашим сервером Apache, то попробуйте альтернативу:
106 |
107 | Options +FollowSymLinks
108 | RewriteEngine On
109 |
110 | RewriteCond %{REQUEST_FILENAME} !-d
111 | RewriteCond %{REQUEST_FILENAME} !-f
112 | RewriteRule ^ index.php [L]
113 |
114 | #### Nginx
115 |
116 | Если вы используете Nginx, то следующая директива в конфигурации вашего сайта направит все запросы на фронт-контроллер `index.php`:
117 |
118 | location / {
119 | try_files $uri $uri/ /index.php?$query_string;
120 | }
121 |
122 | Конечно же, при использовании [Homestead](/docs/{{version}}/homestead) или [Valet](/docs/{{version}}/valet), ЧПУ будут работать без дополнительных настроек.
123 |
--------------------------------------------------------------------------------
/http-tests.md:
--------------------------------------------------------------------------------
1 | # HTTP Tests
2 |
3 | - [Introduction](#introduction)
4 | - [Session / Authentication](#session-and-authentication)
5 | - [Testing JSON APIs](#testing-json-apis)
6 | - [Available Assertions](#available-assertions)
7 |
8 |
9 | ## Introduction
10 |
11 | Laravel provides a very fluent API for making HTTP requests to your application and examining the output. For example, take a look at the test defined below:
12 |
13 | get('/');
32 |
33 | $response->assertStatus(200);
34 | }
35 | }
36 |
37 | The `get` method makes a `GET` request into the application, while the `assertStatus` method asserts that the returned response should have the given HTTP status code. In addition to this simple assertion, Laravel also contains a variety of assertions for inspecting the response headers, content, JSON structure, and more.
38 |
39 |
40 | ### Session / Authentication
41 |
42 | Laravel provides several helpers for working with the session during HTTP testing. First, you may set the session data to a given array using the `withSession` method. This is useful for loading the session with data before issuing a request to your application:
43 |
44 | withSession(['foo' => 'bar'])
51 | ->get('/');
52 | }
53 | }
54 |
55 | Of course, one common use of the session is for maintaining state for the authenticated user. The `actingAs` helper method provides a simple way to authenticate a given user as the current user. For example, we may use a [model factory](/docs/{{version}}/database-testing#writing-factories) to generate and authenticate a user:
56 |
57 | create();
64 |
65 | $response = $this->actingAs($user)
66 | ->withSession(['foo' => 'bar'])
67 | ->get('/')
68 | }
69 | }
70 |
71 | You may also specify which guard should be used to authenticate the given user by passing the guard name as the second argument to the `actingAs` method:
72 |
73 | $this->actingAs($user, 'api')
74 |
75 |
76 | ### Testing JSON APIs
77 |
78 | Laravel also provides several helpers for testing JSON APIs and their responses. For example, the `json`, `get`, `post`, `put`, `patch`, and `delete` methods may be used to issue requests with various HTTP verbs. You may also easily pass data and headers to these methods. To get started, let's write a test to make a `POST` request to `/user` and assert that the expected data was returned:
79 |
80 | json('POST', '/user', ['name' => 'Sally']);
92 |
93 | $response
94 | ->assertStatus(200)
95 | ->assertJson([
96 | 'created' => true,
97 | ]);
98 | }
99 | }
100 |
101 | > {tip} The `assertJson` method converts the response to an array and utilizes `PHPUnit::assertArraySubset` to verify that the given array exists within the JSON response returned by the application. So, if there are other properties in the JSON response, this test will still pass as long as the given fragment is present.
102 |
103 |
104 | ### Verifying Exact Match
105 |
106 | If you would like to verify that the given array is an **exact** match for the JSON returned by the application, you should use the `assertExactJson` method:
107 |
108 | json('POST', '/user', ['name' => 'Sally']);
120 |
121 | $response
122 | ->assertStatus(200)
123 | ->assertExactJson([
124 | 'created' => true,
125 | ]);
126 | }
127 | }
128 |
129 |
130 | ### Available Assertions
131 |
132 | Laravel provides a variety of custom assertion methods for your [PHPUnit](https://phpunit.de/) tests. These assertions may be accessed on the response that is returned from the `json`, `get`, `post`, `put`, and `delete` test methods:
133 |
134 | Method | Description
135 | ------------- | -------------
136 | `$response->assertStatus($code);` | Assert that the response has a given code.
137 | `$response->assertRedirect($uri);` | Assert that the response is a redirect to a given URI.
138 | `$response->assertHeader($headerName, $value = null);` | Assert that the given header is present on the response.
139 | `$response->assertCookie($cookieName, $value = null);` | Assert that the response contains the given cookie.
140 | `$response->assertPlainCookie($cookieName, $value = null);` | Assert that the response contains the given cookie (unencrypted).
141 | `$response->assertSessionHas($key, $value = null);` | Assert that the session contains the given piece of data.
142 | `$response->assertSessionMissing($key);` | Assert that the session does not contain the given key.
143 | `$response->assertJson(array $data);` | Assert that the response contains the given JSON data.
144 | `$response->assertJsonFragment(array $data);` | Assert that the response contains the given JSON fragment.
145 | `$response->assertExactJson(array $data);` | Assert that the response contains an exact match of the given JSON data.
146 | `$response->assertJsonStructure(array $structure);` | Assert that the response has a given JSON structure.
147 | `$response->assertViewHas($key, $value = null);` | Assert that the response view was given a piece of data.
148 |
--------------------------------------------------------------------------------
/configuration.md:
--------------------------------------------------------------------------------
1 | # Настройка
2 |
3 | - [Введение](#introduction)
4 | - [Настройка окружения](#environment-configuration)
5 | - [Определение текущего окружения](#determining-the-current-environment)
6 | - [Доступ к настройкам конфигурации](#accessing-configuration-values)
7 | - [Кэширование настроек](#configuration-caching)
8 | - [Режим обслуживания](#maintenance-mode)
9 |
10 |
11 | ## Введение
12 |
13 | Все конфигурационные файлы фреймворка Laravel расположены в директории `config`. Параметры в каждом из них снабжены комментариями, поэтому не стесняйтесь пройтись по этим файлам и познакомиться с доступными параметрами настройки.
14 |
15 |
16 | ## Настройка окружения
17 |
18 | Часто полезно иметь разные параметры настройки в зависимости от окружения, в котором работает приложение. Например, на рабочем сервере вы можете использовать одну систему кэширования, а на локальном — другую.
19 |
20 | Для предоставления такой возможности, Laravel использует PHP-библиотеку [DotEnv](https://github.com/vlucas/phpdotenv) от Вэнса Лукаса. В свежей установке Laravel, в корневой директории вашего приложения находится файл `.env.example`. Если вы установили Laravel через Composer, то этот файл автоматически переименовался в `.env`. В противном случае, вам необходимо переименовать его самостоятельно.
21 |
22 | > {tip} Вы также можете создать файл `.env.testing`. Он переопределит значения из файла `.env` при запуске PHPUnit-тестов или выполнении команд Artisan с параметром `--env=testing`.
23 |
24 | #### Получение настроек окружения
25 |
26 | Все переменные, описанные в этом файле, загружаются в суперглобальную переменную `$_ENV` при получении приложением какого-либо запроса. Однако, вы можете использовать хелпер `env` для получения значений этих переменных из ваших конфигурационных файлов. Если вы ознакомитесь с конфигурационными файлами Laravel, то увидите несколько параметров, которые уже используют этот хелпер:
27 |
28 | 'debug' => env('APP_DEBUG', false),
29 |
30 | Второй параметр, принимаемый функцией `env`, является значением по умолчанию. Оно будет использоваться в тех случаях, когда переменной окружения для заданного ключа не существует.
31 |
32 | Файл `.env` не должен попадать в вашу систему контроля версий, так как каждый из разработчиков и серверов, использующих ваше приложение, может иметь свои собственные настройки окружения.
33 |
34 | Если вы занимаетесь разработкой в команде, то вы можете включить файл `.env.example` в ваше приложение. Замените в нём значения «секретных» параметров (пароли, ключи доступа) на пустые строки или поясняющие комментарии — так другие разработчики в вашей команде смогут увидеть переменные окружения, необходимые для запуска вашего приложения.
35 |
36 |
37 | ### Определение текущего окружения
38 |
39 | Текущее окружение приложения определяется переменной `APP_ENV` в вашем файле `.env`. Получить доступ к её значению с помощью метода `environment` [фасада](/docs/{{version}}/facades) `App`:
40 |
41 | $environment = App::environment();
42 |
43 | Вы также можете передать аргументы в метод `environment` для проверки совпадения окружения с каким-либо значением. Метод возвращает `true` в случае совпадения с любым из предоставленных значений:
44 |
45 | if (App::environment('local')) {
46 | // Окружение local
47 | }
48 |
49 | if (App::environment('local', 'staging')) {
50 | // Окружение local ИЛИ staging
51 | }
52 |
53 |
54 | ## Доступ к настройкам конфигурации
55 |
56 | Вы можете получить доступ к значениям ваших параметров конфигурации из любой части вашего приложения с помощью глобальной хелпер-функции `config`. Значения параметров конфигурации могут быть получены с использованием dot-синтаксиса, который включает в себя название файла и параметра, который вы хотите получить. Также вы можете указать значение по умолчанию, которое будет возвращено в том случае, если искомый параметр конфигурации не существует:
57 |
58 | $value = config('app.timezone');
59 |
60 | Для установки параметров конфигурации в процессе работы приложения, передайте массив в хелпер-функцию `config`:
61 |
62 | config(['app.timezone' => 'America/Chicago']);
63 |
64 |
65 | ## Кэширование настроек
66 |
67 | Для ускорения работы вашего приложения следует кэшировать все конфигурационные файлы в один с использование команды Artisan `config:cache`. Она объединит все конфигурационные параметры приложения в единый файл, который быстрее загружается фреймворком.
68 |
69 | Как правило, запускать команду `php artisan config:cache` следует в процессе развёртывания приложения на рабочем сервере. Команда не должна запускаться при разработке приложения, так как в процессе этого параметры конфигурации довольно часто необходимо изменять.
70 |
71 | > {note} Если вы выполняете команду `config:cache` в процессе развёртывания, то вы должны убедиться в том, что в конфигурационных файлах вы вызываете исключительно функцию `env`.
72 |
73 |
74 | ## Режим обслуживания
75 |
76 | Когда ваше приложение находится в режиме обслуживания, то на все поступающие в приложение запросы будет отображаться специальное представление. Это позволяет легко «выключить» приложение для пользователей и провести процесс обновления или техническое обслуживание. Проверка на режим облуживания включена в стандартный стек посредников (middlewares) вашего приложения. Если приложение находится в режиме обслуживания, то будет вызываться исключение `MaintenanceModeException` с кодом статуса 503.
77 |
78 | Для включения режима обслуживания выполните команду Artisan `down`:
79 |
80 | php artisan down
81 |
82 | В качестве параметров команды `down` вы можете указать `message` и `retry`. Значение `message` может быть использовано для отображения любого информационного текста, а значение `retry` будет установлено в качестве значения HTTP-заголовка `Retry-After`:
83 |
84 | php artisan down --message="Upgrading Database" --retry=60
85 |
86 | Для отключения режима обслуживания, выполните команду Artisan `up`:
87 |
88 | php artisan up
89 |
90 | #### Шаблон ответа режима обслуживания
91 |
92 | Стандартный шаблон, отображающийся при включенном режиме обслуживания, находится в `resources/views/errors/503.blade.php`. При необходимости вы можете изменить его.
93 |
94 | #### Режим обслуживания и запросы
95 |
96 | При включенном режиме обслуживание, обработка [очередей](/docs/{{version}}/queues) приостанавливается. Они продолжат обрабатываться при выходе приложения из режима обслуживания.
97 |
98 | #### Альтернативы режиму обслуживания
99 |
100 | Так как режим обслуживания приводит к недоступности приложения в течение нескольких секунд, рассмотрите [Envoyer](https://envoyer.io) в качестве альтернативы для развёртывания вашего приложения с нулевым временем простоя.
101 |
--------------------------------------------------------------------------------
/eloquent-collections.md:
--------------------------------------------------------------------------------
1 | # Eloquent: Collections
2 |
3 | - [Introduction](#introduction)
4 | - [Available Methods](#available-methods)
5 | - [Custom Collections](#custom-collections)
6 |
7 |
8 | ## Introduction
9 |
10 | All multi-result sets returned by Eloquent are instances of the `Illuminate\Database\Eloquent\Collection` object, including results retrieved via the `get` method or accessed via a relationship. The Eloquent collection object extends the Laravel [base collection](/docs/{{version}}/collections), so it naturally inherits dozens of methods used to fluently work with the underlying array of Eloquent models.
11 |
12 | Of course, all collections also serve as iterators, allowing you to loop over them as if they were simple PHP arrays:
13 |
14 | $users = App\User::where('active', 1)->get();
15 |
16 | foreach ($users as $user) {
17 | echo $user->name;
18 | }
19 |
20 | However, collections are much more powerful than arrays and expose a variety of map / reduce operations that may be chained using an intuitive interface. For example, let's remove all inactive models and gather the first name for each remaining user:
21 |
22 | $users = App\User::where('active', 1)->get();
23 |
24 | $names = $users->reject(function ($user) {
25 | return $user->active === false;
26 | })
27 | ->map(function ($user) {
28 | return $user->name;
29 | });
30 |
31 | > {note} While most Eloquent collection methods return a new instance of an Eloquent collection, the `pluck`, `keys`, `zip`, `collapse`, `flatten` and `flip` methods return a [base collection](/docs/{{version}}/collections) instance. Likewise, if a `map` operation returns a collection that does not contain any Eloquent models, it will be automatically cast to a base collection.
32 |
33 |
34 | ## Available Methods
35 |
36 | ### The Base Collection
37 |
38 | All Eloquent collections extend the base [Laravel collection](/docs/{{version}}/collections) object; therefore, they inherit all of the powerful methods provided by the base collection class:
39 |
40 |
50 |
51 |
119 |
120 |
121 | ## Custom Collections
122 |
123 | If you need to use a custom `Collection` object with your own extension methods, you may override the `newCollection` method on your model:
124 |
125 |
11 | ## Introduction
12 |
13 | Service providers are the central place of all Laravel application bootstrapping. Your own application, as well as all of Laravel's core services are bootstrapped via service providers.
14 |
15 | But, what do we mean by "bootstrapped"? In general, we mean **registering** things, including registering service container bindings, event listeners, middleware, and even routes. Service providers are the central place to configure your application.
16 |
17 | If you open the `config/app.php` file included with Laravel, you will see a `providers` array. These are all of the service provider classes that will be loaded for your application. Of course, many of these are "deferred" providers, meaning they will not be loaded on every request, but only when the services they provide are actually needed.
18 |
19 | In this overview you will learn how to write your own service providers and register them with your Laravel application.
20 |
21 |
22 | ## Writing Service Providers
23 |
24 | All service providers extend the `Illuminate\Support\ServiceProvider` class. Most service providers contain a `register` and a `boot` method. 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.
25 |
26 | The Artisan CLI can generate a new provider via the `make:provider` command:
27 |
28 | php artisan make:provider RiakServiceProvider
29 |
30 |
31 | ### The Register Method
32 |
33 | As mentioned previously, 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. Otherwise, you may accidentally use a service that is provided by a service provider which has not loaded yet.
34 |
35 | Let's take a look at a basic service provider. Within any of your service provider methods, you always have access to the `$app` property which provides access to the service container:
36 |
37 | app->singleton(Connection::class, function ($app) {
54 | return new Connection(config('riak'));
55 | });
56 | }
57 | }
58 |
59 | This service provider only defines a `register` method, and uses that method to define an implementation of `Riak\Connection` in the service container. If you don't understand how the service container works, check out [its documentation](/docs/{{version}}/container).
60 |
61 |
62 | ### The Boot Method
63 |
64 | So, what if we need to register a view composer within our service provider? This should be done within the `boot` method. **This method is called after all other service providers have been registered**, meaning you have access to all other services that have been registered by the framework:
65 |
66 | composer('view', function () {
82 | //
83 | });
84 | }
85 | }
86 |
87 | #### Boot Method Dependency Injection
88 |
89 | You may type-hint dependencies for your service provider's `boot` method. The [service container](/docs/{{version}}/container) will automatically inject any dependencies you need:
90 |
91 | use Illuminate\Contracts\Routing\ResponseFactory;
92 |
93 | public function boot(ResponseFactory $response)
94 | {
95 | $response->macro('caps', function ($value) {
96 | //
97 | });
98 | }
99 |
100 |
101 | ## Registering Providers
102 |
103 | All service providers are registered in the `config/app.php` configuration file. This file contains a `providers` array where you can list the class names of your service providers. By default, a set of Laravel core service providers are listed in this array. These providers bootstrap the core Laravel components, such as the mailer, queue, cache, and others.
104 |
105 | To register your provider, simply add it to the array:
106 |
107 | 'providers' => [
108 | // Other Service Providers
109 |
110 | App\Providers\ComposerServiceProvider::class,
111 | ],
112 |
113 |
114 | ## Deferred Providers
115 |
116 | 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.
117 |
118 | Laravel compiles and stores a list of all of the services supplied by deferred service providers, along with the name of its service provider class. Then, only when you attempt to resolve one of these services does Laravel load the service provider.
119 |
120 | To defer the loading of a provider, set the `defer` property to `true` and define a `provides` method. The `provides` method should return the service container bindings registered by the provider:
121 |
122 | app->singleton(Connection::class, function ($app) {
146 | return new Connection($app['config']['riak']);
147 | });
148 | }
149 |
150 | /**
151 | * Get the services provided by the provider.
152 | *
153 | * @return array
154 | */
155 | public function provides()
156 | {
157 | return [Connection::class];
158 | }
159 |
160 | }
161 |
--------------------------------------------------------------------------------
/localization.md:
--------------------------------------------------------------------------------
1 | # Локализация
2 |
3 | - [Введение](#introduction)
4 | - [Определение строк перевода](#defining-translation-strings)
5 | - [Использование кратких ключей](#using-short-keys)
6 | - [Использование строк перевода как ключей](#using-translation-strings-as-keys)
7 | - [Получение строк перевода](#retrieving-translation-strings)
8 | - [Подстановка параметров в строках перевода](#replacing-parameters-in-translation-strings)
9 | - [Плюрализация](#pluralization)
10 | - [Переопределение языковых файлов пакета](#overriding-package-language-files)
11 |
12 |
13 | ## Введение
14 |
15 | Возможности локализации Laravel предоставляют удобный способ получения строк на нескольких языках, что позволяет легко организовать поддержку мультиязычности вашим приложением. Языковые строки хранятся в файлах, располагающихся внутри директории `resources/lang`. В ней должны находиться подпапки для каждого языка, поддерживаемого вашим приложением:
16 |
17 | /resources
18 | /lang
19 | /en
20 | messages.php
21 | /es
22 | messages.php
23 |
24 | Все языковые файлы возвращают простой массив ключей и строк. Например:
25 |
26 | 'Welcome to our application'
30 | ];
31 |
32 | ### Настройка локали
33 |
34 | Стандартный язык вашего приложения указан в конфигурационном файле `config/app.php`. Конечно же, вы можете изменить это значение на основе потребностей вашего приложения. Вы также можете изменить активный язык в процессе работы приложения с помощью метода `setLocale` фасада `App`:
35 |
36 | Route::get('welcome/{locale}', function ($locale) {
37 | App::setLocale($locale);
38 |
39 | //
40 | });
41 |
42 | Вы можете настроить "запасной язык", который будет использоваться в случаях, когда активный язык не содержит заданной строки перевода. Как и стандартный язык, запасной язык также настраивается в конфигурационном файле `config/app.php`:
43 |
44 | 'fallback_locale' => 'en',
45 |
46 | #### Определение текущей локали
47 |
48 | Вы можете использовать методы `getLocale` и `isLocale` фасада `App` для определения текущей локали или проверки совпадения локали с заданным значением:
49 |
50 | $locale = App::getLocale();
51 |
52 | if (App::isLocale('en')) {
53 | //
54 | }
55 |
56 |
57 | ## Определение строк перевода
58 |
59 |
60 | ### Использование кратких ключей
61 |
62 | Обычно строки перевода хранятся в файлах, располагающихся внутри директории `resources/lang`. В ней должны находиться подпапки для каждого языка, поддерживаемого вашим приложением:
63 |
64 | /resources
65 | /lang
66 | /en
67 | messages.php
68 | /es
69 | messages.php
70 |
71 | Все языковые файлы возвращают простой массив ключей и строк. Например:
72 |
73 | 'Welcome to our application'
79 | ];
80 |
81 |
82 | ### Использование строк перевода как ключей
83 |
84 | Для приложений с большими требованиями к переводу, определение каждой строки с помощью "краткого ключа" может привести к путанице при обращении к ним из ваших представлений. По этой причине, Laravel также предоставляет поддержку определения строк перевода с использованием стандартного перевода в качестве ключа.
85 |
86 | Файлы переводов, которые используют строки перевода в качестве ключей, хранятся в JSON-файлах в директории `resources/lang`. Например, если приложение имеет поддержку испанского языка, то вы должны создать файл `resources/lang/es.json`:
87 |
88 | {
89 | "I love programming.": "Me encanta la programación."
90 | }
91 |
92 |
93 | ## Получение строк перевода
94 |
95 | Вы можете получать строки из языковых файлов с помощью функции `__`. Она принимает файл и ключ строки перевода в качестве первого параметра. Например, давайте получим строку перевода `welcome` из языкового файла `resources/lang/messages.php`:
96 |
97 | echo __('messages.welcome');
98 |
99 | echo __('I love programming.');
100 |
101 | Конечно, если вы используете [шаблонизатор Blade](/docs/{{version}}/blade), то вы можете использовать синтаксис `{{ }}` для отображения строки перевода, или использовать директиву `@lang`:
102 |
103 | {{ __('messages.welcome') }}
104 |
105 | @lang('messages.welcome')
106 |
107 | Если запрошенной строки перевода не существует, то функция `__` вернёт ключ строки перевода. Таким образом, при использовании примера выше, функция `__` вернула бы `messages.welcome` при отсутствии строки перевода.
108 |
109 |
110 | ### Подстановка параметров в строках перевода
111 |
112 | При желании, вы можете указывать плейсхолдеры в ваших строках перевода. Все плейсхолдеры начинаются с символа `:`. Например, вы можете создать приветственное сообщение с плейсхолдером для имени:
113 |
114 | 'welcome' => 'Welcome, :name',
115 |
116 | Для замены плейсхолдеров, при получении строки перевода, передайте массив с необходимыми заменами в качестве второго параметра функции `__`:
117 |
118 | echo __('messages.welcome', ['name' => 'dayle']);
119 |
120 | Если ваш плейсхолдер содержит только прописные буквы, или только первая его буква является прописной, то переведённое значение будет преобразовано соответствующим образом:
121 |
122 | 'welcome' => 'Welcome, :NAME', // Welcome, DAYLE
123 | 'goodbye' => 'Goodbye, :Name', // Goodbye, Dayle
124 |
125 |
126 |
127 | ### Плюрализация
128 |
129 | Плюрализация является комплексной проблемой, так как в разных языках существуют различные сложные правила плюрализации. С помощью символа "вертикальной черты" вы можете разграничить одиночную и множественную форму строки:
130 |
131 | 'apples' => 'There is one apple|There are many apples',
132 |
133 | Вы даже можете создать сложные правила плюрализации, которые определят строки перевода для нескольких диапазонов чисел:
134 |
135 | 'apples' => '{0} There are none|[1,19] There are some|[20,*] There are many',
136 |
137 | После определения строки перевода с вариантами плюрализации, вы можете использовать функцию `trans_choice` для получения строки для заданного "числа". В данном примере, так как число больше нуля и единицы, была возвращена форма множественного числа этой строки:
138 |
139 | echo trans_choice('messages.apples', 10);
140 |
141 |
142 | ## Переопределение языковых файлов пакета
143 |
144 | Некоторые пакеты могут поставляться со своими собственными языковыми файлами. Вместо изменения корневых файлов пакета для внесения изменений в языковые строки, вы можете переопределить их, поместив файлы в директорию `resources/lang/vendor/{package}/{locale}`.
145 |
146 | Таким образом, например, если вам необходимо переопределить перевод английских строк в файле `messages.php` пакета с названием `skyrim/hearthfire`, вам необходимо разместить языковой файл в: `resources/lang/vendor/hearthfire/en/messages.php`. Внутри этого файла вам следует указать только те строки, которые вы хотели бы переопределить. Все строки перевода, которые вы не переопределите, будут загружены из оригинальных языковых файлов пакета.
147 |
--------------------------------------------------------------------------------
/envoy.md:
--------------------------------------------------------------------------------
1 | # Envoy Task Runner
2 |
3 | - [Introduction](#introduction)
4 | - [Installation](#installation)
5 | - [Writing Tasks](#writing-tasks)
6 | - [Setup](#setup)
7 | - [Variables](#variables)
8 | - [Stories](#stories)
9 | - [Multiple Servers](#multiple-servers)
10 | - [Running Tasks](#running-tasks)
11 | - [Confirming Task Execution](#confirming-task-execution)
12 | - [Notifications](#notifications)
13 | - [Slack](#slack)
14 |
15 |
16 | ## Introduction
17 |
18 | [Laravel Envoy](https://github.com/laravel/envoy) provides a clean, minimal syntax for defining common tasks you run on your remote servers. Using Blade style syntax, you can easily setup tasks for deployment, Artisan commands, and more. Currently, Envoy only supports the Mac and Linux operating systems.
19 |
20 |
21 | ### Installation
22 |
23 | First, install Envoy using the Composer `global require` command:
24 |
25 | composer global require "laravel/envoy=~1.0"
26 |
27 | Since global Composer libraries can sometimes cause package version conflicts, you may wish to consider using `cgr`, which is a drop-in replacement for the `composer global require` command. The `cgr` library's installation instructions can be [found on GitHub](https://github.com/consolidation-org/cgr).
28 |
29 | > {note} Make sure to place the `~/.composer/vendor/bin` directory in your PATH so the `envoy` executable is found when running the `envoy` command in your terminal.
30 |
31 | #### Updating Envoy
32 |
33 | You may also use Composer to keep your Envoy installation up to date. Issuing the `composer global update` command will update all of your globally installed Composer packages:
34 |
35 | composer global update
36 |
37 |
38 | ## Writing Tasks
39 |
40 | All of your Envoy tasks should be defined in an `Envoy.blade.php` file in the root of your project. Here's an example to get you started:
41 |
42 | @servers(['web' => ['user@192.168.1.1']])
43 |
44 | @task('foo', ['on' => 'web'])
45 | ls -la
46 | @endtask
47 |
48 | As you can see, an array of `@servers` is defined at the top of the file, allowing you to reference these servers in the `on` option of your task declarations. Within your `@task` declarations, you should place the Bash code that should run on your server when the task is executed.
49 |
50 | You can force a script to run locally by specifying the server's IP address as `127.0.0.1`:
51 |
52 | @servers(['localhost' => '127.0.0.1'])
53 |
54 |
55 | ### Setup
56 |
57 | Sometimes, you may need to execute some PHP code before executing your Envoy tasks. You may use the ```@setup``` directive to declare variables and do other general PHP work before any of your other tasks are executed:
58 |
59 | @setup
60 | $now = new DateTime();
61 |
62 | $environment = isset($env) ? $env : "testing";
63 | @endsetup
64 |
65 | If you need to require other PHP files before your task is executed, you may use the `@include` directive at the top of your `Envoy.blade.php` file:
66 |
67 | @include('vendor/autoload.php')
68 |
69 | @task('foo')
70 | # ...
71 | @endtask
72 |
73 |
74 | ### Variables
75 |
76 | If needed, you may pass option values into Envoy tasks using the command line:
77 |
78 | envoy run deploy --branch=master
79 |
80 | You may access the options in your tasks via Blade's "echo" syntax. Of course, you may also use `if` statements and loops within your tasks. For example, let's verify the presence of the `$branch` variable before executing the `git pull` command:
81 |
82 | @servers(['web' => '192.168.1.1'])
83 |
84 | @task('deploy', ['on' => 'web'])
85 | cd site
86 |
87 | @if ($branch)
88 | git pull origin {{ $branch }}
89 | @endif
90 |
91 | php artisan migrate
92 | @endtask
93 |
94 |
95 | ### Stories
96 |
97 | Stories group a set of tasks under a single, convenient name, allowing you to group small, focused tasks into large tasks. For instance, a `deploy` story may run the `git` and `composer` tasks by listing the task names within its definition:
98 |
99 | @servers(['web' => '192.168.1.1'])
100 |
101 | @story('deploy')
102 | git
103 | composer
104 | @endstory
105 |
106 | @task('git')
107 | git pull origin master
108 | @endtask
109 |
110 | @task('composer')
111 | composer install
112 | @endtask
113 |
114 | Once the story has been written, you may run it just like a typical task:
115 |
116 | envoy run deploy
117 |
118 |
119 | ### Multiple Servers
120 |
121 | Envoy allows you to easily run a task across multiple servers. First, add additional servers to your `@servers` declaration. Each server should be assigned a unique name. Once you have defined your additional servers, list each of the servers in the task's `on` array:
122 |
123 | @servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2'])
124 |
125 | @task('deploy', ['on' => ['web-1', 'web-2']])
126 | cd site
127 | git pull origin {{ $branch }}
128 | php artisan migrate
129 | @endtask
130 |
131 | #### Parallel Execution
132 |
133 | By default, tasks will be executed on each server serially. In other words, a task will finish running on the first server before proceeding to execute on the second server. If you would like to run a task across multiple servers in parallel, add the `parallel` option to your task declaration:
134 |
135 | @servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2'])
136 |
137 | @task('deploy', ['on' => ['web-1', 'web-2'], 'parallel' => true])
138 | cd site
139 | git pull origin {{ $branch }}
140 | php artisan migrate
141 | @endtask
142 |
143 |
144 | ## Running Tasks
145 |
146 | To run a task or story that is defined in your `Envoy.blade.php` file, execute Envoy's `run` command, passing the name of the task or story you would like to execute. Envoy will run the task and display the output from the servers as the task is running:
147 |
148 | envoy run task
149 |
150 |
151 | ### Confirming Task Execution
152 |
153 | If you would like to be prompted for confirmation before running a given task on your servers, you should add the `confirm` directive to your task declaration. This option is particularly useful for destructive operations:
154 |
155 | @task('deploy', ['on' => 'web', 'confirm' => true])
156 | cd site
157 | git pull origin {{ $branch }}
158 | php artisan migrate
159 | @endtask
160 |
161 |
162 |
163 | ## Notifications
164 |
165 |
166 | ### Slack
167 |
168 | Envoy also supports sending notifications to [Slack](https://slack.com) after each task is executed. The `@slack` directive accepts a Slack hook URL and a channel name. You may retrieve your webhook URL by creating an "Incoming WebHooks" integration in your Slack control panel. You should pass the entire webhook URL into the `@slack` directive:
169 |
170 | @finished
171 | @slack('webhook-url', '#bots')
172 | @endfinished
173 |
174 | You may provide one of the following as the channel argument:
175 |
176 |
177 | - To send the notification to a channel: `#channel`
178 | - To send the notification to a user: `@user`
179 |
180 |
181 |
--------------------------------------------------------------------------------
/views.md:
--------------------------------------------------------------------------------
1 | # Представления
2 |
3 | - [Создание представлений](#creating-views)
4 | - [Передача данных в представления](#passing-data-to-views)
5 | - [Передача данных во все представления](#sharing-data-with-all-views)
6 | - [Композеры представлений](#view-composers)
7 |
8 |
9 | ## Создание представлений
10 |
11 | Представления содержат HTML-разметку вашего приложения и отделяют контроллеры/бизнес-логику от логики отображения данных. Представления расположены в директории `resources/views`. Давайте посмотрим, как выглядит простое представление:
12 |
13 |
14 |
15 |
16 |
17 |
Привет, {{ $name }}
18 |
19 |
20 |
21 | Так как представление хранится в `resources/views/greeting.blade.php`, мы можем получить его с помощью хелпера `view`:
22 |
23 | Route::get('/', function () {
24 | return view('greeting', ['name' => 'Иван']);
25 | });
26 |
27 | Как видите, первый передаваемый в хелпер `view` аргумент соответствует названию файла представления в папке `resources/views`. Вторым аргументом передается массив с данными, которые будут доступны в представлении. В данном случае мы передаем переменную `name`, которая отображается с помощью [синтаксиса Blade](/docs/{{version}}/blade).
28 |
29 | Конечно, представления могут находиться в поддиректориях внутри `resources/views`. Для обращения к ним следует использовать dot-синтаксис. Например, если представление хранится в `resources/views/admin/profile.blade.php`, то вы можете обратиться к нему таким образом:
30 |
31 | return view('admin.profile', $data);
32 |
33 | #### Проверка существования файла представления
34 |
35 | Если нужно определить существует ли файл представления, вы можете использовать фасад `View`. Метод `exists` вернёт `true`, если он существует:
36 |
37 | use Illuminate\Support\Facades\View;
38 |
39 | if (View::exists('emails.customer')) {
40 | //
41 | }
42 |
43 |
44 | ## Передача данных в представления
45 |
46 | Как было показано в предыдущих примерах, вы можете передать массив с данными в представление:
47 |
48 | return view('greetings', ['name' => 'Виктория']);
49 |
50 | Переменная `$data` должна быть массивом (индексированным или ассоциативным) с парами ключ/значение. Внутри представления вы можете получить доступ к каждому значению, используя соответствующий ключ, такой как: ``. В качестве альтернативы передачи массива данных в хелпер-функцию `view`, можно использовать метод `with` для предачи отдельных данных в представление:
51 |
52 | return view('greeting')->with('name', 'Виктория');
53 |
54 |
55 | #### Передача данных во все представления
56 |
57 | Иногда необходимо передавать часть данных во все представления, которые используются в вашем приложении. Это можно сделать с помощью метод `share` внутри метода `boot` сервис-провайдера. Его можно добавить в провайдер `AppServiceProvider` или создать отдельный провайдер для этого:
58 |
59 |
89 | ## Композеры представлений
90 |
91 | Композеры представлений — это функции обратного вызова или методы класса, которые вызываются при рендере представления. Если у вас есть данные, которые вы хотели бы отправлять в представление при каждом его отображении, то композеры могут помочь организовать такую логику в одном месте.
92 |
93 | Давайте для примера зарегистрируем композер внутри [сервис провайдера](/docs/{{version}}/providers). Мы будем использовать фасад `View` для доступа к основному контракту `Illuminate\Contracts\View\Factory`. По умолчанию в Laravel нет папки для хранения композеров представления. Вы можете создать её там, где посчитаете нужным. Например, можете создать папку `app\Http\ViewComposers`:
94 |
95 | {note} Помните, если вы создаёте новый сервис-провайдер для хранения ваших композеров, то также следует добавить его в массив `providers` внутри конфигурационного файла `config/app.php`.
134 |
135 | Теперь, когда мы зарегистрировали композер, метод `ProfileComposer@compose` будет вызываться при каждом рендере представления `profile`. Давайте создадим класс композера:
136 |
137 | users = $users;
163 | }
164 |
165 | /**
166 | * Bind data to the view.
167 | *
168 | * @param View $view
169 | * @return void
170 | */
171 | public function compose(View $view)
172 | {
173 | $view->with('count', $this->users->count());
174 | }
175 | }
176 |
177 | Перед началом рендера представления, композер вызовет метод `compose` с экземпляром `Illuminate\View\View` в качестве первого параметра. Вы можете использовать метод `with` для передачи данных в представление.
178 |
179 | > {tip} Все композеры подключаются через [сервис контейнер](/docs/{{version}}/container), поэтому можно применить любую инъекцию зависимостей внутри конструктора композера.
180 |
181 | #### Подключение композера к нескольким представлениям
182 |
183 | Вы можете подключить к композеру несколько представлений одновременно, передав их в качестве первого аргумента метода `composer`:
184 |
185 | View::composer(
186 | ['profile', 'dashboard'],
187 | 'App\Http\ViewComposers\MyViewComposer'
188 | );
189 |
190 | Метод `composer` также принимает специальный символ `*`, что позволяет подключить его ко всем представлениям:
191 |
192 | View::composer('*', function ($view) {
193 | //
194 | });
195 |
196 | #### Создатели представлений
197 | Создатели представлений очень похожи на композеры, однако они выполняются сразу после инициализации представлений, не дожидаясь их рендера. Для регистрации создателя используется метод `creator`:
198 |
199 | View::creator('profile', 'App\Http\ViewCreators\ProfileCreator');
200 |
--------------------------------------------------------------------------------
/eloquent-mutators.md:
--------------------------------------------------------------------------------
1 | # Eloquent: Mutators
2 |
3 | - [Introduction](#introduction)
4 | - [Accessors & Mutators](#accessors-and-mutators)
5 | - [Defining An Accessor](#defining-an-accessor)
6 | - [Defining A Mutator](#defining-a-mutator)
7 | - [Date Mutators](#date-mutators)
8 | - [Attribute Casting](#attribute-casting)
9 | - [Array & JSON Casting](#array-and-json-casting)
10 |
11 |
12 | ## Introduction
13 |
14 | Accessors and mutators allow you to format Eloquent attribute values when you retrieve or set them on model instances. For example, you may want to use the [Laravel encrypter](/docs/{{version}}/encryption) to encrypt a value while it is stored in the database, and then automatically decrypt the attribute when you access it on an Eloquent model.
15 |
16 | In addition to custom accessors and mutators, Eloquent can also automatically cast date fields to [Carbon](https://github.com/briannesbitt/Carbon) instances or even [cast text fields to JSON](#attribute-casting).
17 |
18 |
19 | ## Accessors & Mutators
20 |
21 |
22 | ### Defining An Accessor
23 |
24 | To define an accessor, create a `getFooAttribute` method on your model where `Foo` is the "studly" cased name of the column you wish to access. In this example, we'll define an accessor for the `first_name` attribute. The accessor will automatically be called by Eloquent when attempting to retrieve the value of the `first_name` attribute:
25 |
26 | first_name;
51 |
52 |
53 | ### Defining A Mutator
54 |
55 | To define a mutator, define a `setFooAttribute` method on your model where `Foo` is the "studly" cased name of the column you wish to access. So, again, let's define a mutator for the `first_name` attribute. This mutator will be automatically called when we attempt to set the value of the `first_name` attribute on the model:
56 |
57 | attributes['first_name'] = strtolower($value);
74 | }
75 | }
76 |
77 | The mutator will receive the value that is being set on the attribute, allowing you to manipulate the value and set the manipulated value on the Eloquent model's internal `$attributes` property. So, for example, if we attempt to set the `first_name` attribute to `Sally`:
78 |
79 | $user = App\User::find(1);
80 |
81 | $user->first_name = 'Sally';
82 |
83 | In this example, the `setFirstNameAttribute` function will be called with the value `Sally`. The mutator will then apply the `strtolower` function to the name and set its resulting value in the internal `$attributes` array.
84 |
85 |
86 | ## Date Mutators
87 |
88 | By default, Eloquent will convert the `created_at` and `updated_at` columns to instances of [Carbon](https://github.com/briannesbitt/Carbon), which extends the PHP `DateTime` class to provide an assortment of helpful methods. You may customize which dates are automatically mutated, and even completely disable this mutation, by overriding the `$dates` property of your model:
89 |
90 | deleted_at = Carbon::now();
115 |
116 | $user->save();
117 |
118 | As noted above, when retrieving attributes that are listed in your `$dates` property, they will automatically be cast to [Carbon](https://github.com/briannesbitt/Carbon) instances, allowing you to use any of Carbon's methods on your attributes:
119 |
120 | $user = App\User::find(1);
121 |
122 | return $user->deleted_at->getTimestamp();
123 |
124 | #### Date Formats
125 |
126 | By default, timestamps are formatted as `'Y-m-d H:i:s'`. If you need to customize the timestamp format, set the `$dateFormat` property on your model. This property determines how date attributes are stored in the database, as well as their format when the model is serialized to an array or JSON:
127 |
128 |
145 | ## Attribute Casting
146 |
147 | The `$casts` property on your model provides a convenient method of converting attributes to common data types. The `$casts` property should be an array where the key is the name of the attribute being cast and the value is the type you wish to cast the column to. The supported cast types are: `integer`, `real`, `float`, `double`, `string`, `boolean`, `object`, `array`, `collection`, `date`, `datetime`, and `timestamp`.
148 |
149 | For example, let's cast the `is_admin` attribute, which is stored in our database as an integer (`0` or `1`) to a boolean value:
150 |
151 | 'boolean',
166 | ];
167 | }
168 |
169 | 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:
170 |
171 | $user = App\User::find(1);
172 |
173 | if ($user->is_admin) {
174 | //
175 | }
176 |
177 |
178 | ### Array & JSON Casting
179 |
180 | The `array` cast type is particularly useful when working with columns that are stored as serialized JSON. For example, if your database has a `JSON` or `TEXT` field type that contains serialized JSON, adding the `array` cast to that attribute will automatically deserialize the attribute to a PHP array when you access it on your Eloquent model:
181 |
182 | 'array',
197 | ];
198 | }
199 |
200 | Once the cast is defined, you may access the `options` attribute and it will automatically be deserialized from JSON into a PHP array. When you set the value of the `options` attribute, the given array will automatically be serialized back into JSON for storage:
201 |
202 | $user = App\User::find(1);
203 |
204 | $options = $user->options;
205 |
206 | $options['key'] = 'value';
207 |
208 | $user->options = $options;
209 |
210 | $user->save();
211 |
--------------------------------------------------------------------------------
/pagination.md:
--------------------------------------------------------------------------------
1 | # Pagination
2 |
3 | - [Introduction](#introduction)
4 | - [Basic Usage](#basic-usage)
5 | - [Paginating Query Builder Results](#paginating-query-builder-results)
6 | - [Paginating Eloquent Results](#paginating-eloquent-results)
7 | - [Manually Creating A Paginator](#manually-creating-a-paginator)
8 | - [Displaying Pagination Results](#displaying-pagination-results)
9 | - [Converting Results To JSON](#converting-results-to-json)
10 | - [Customizing The Pagination View](#customizing-the-pagination-view)
11 | - [Paginator Instance Methods](#paginator-instance-methods)
12 |
13 |
14 | ## Introduction
15 |
16 | In other frameworks, pagination can be very painful. Laravel's paginator is integrated with the [query builder](/docs/{{version}}/queries) and [Eloquent ORM](/docs/{{version}}/eloquent) and provides convenient, easy-to-use pagination of database results out of the box. The HTML generated by the paginator is compatible with the [Bootstrap CSS framework](https://getbootstrap.com/).
17 |
18 |
19 | ## Basic Usage
20 |
21 |
22 | ### Paginating Query Builder Results
23 |
24 | There are several ways to paginate items. The simplest is by using the `paginate` method on the [query builder](/docs/{{version}}/queries) or an [Eloquent query](/docs/{{version}}/eloquent). The `paginate` method automatically takes care of setting the proper limit and offset based on the current page being viewed by the user. By default, the current page is detected by the value of the `page` query string argument on the HTTP request. Of course, this value is automatically detected by Laravel, and is also automatically inserted into links generated by the paginator.
25 |
26 | In this example, the only argument passed to the `paginate` method is the number of items you would like displayed "per page". In this case, let's specify that we would like to display `15` items per page:
27 |
28 | paginate(15);
45 |
46 | return view('user.index', ['users' => $users]);
47 | }
48 | }
49 |
50 | > {note} Currently, pagination operations that use a `groupBy` statement cannot be executed efficiently by Laravel. If you need to use a `groupBy` with a paginated result set, it is recommended that you query the database and create a paginator manually.
51 |
52 | #### "Simple Pagination"
53 |
54 | If you only need to display simple "Next" and "Previous" links in your pagination view, you may use the `simplePaginate` method to perform a more efficient query. This is very useful for large datasets when you do not need to display a link for each page number when rendering your view:
55 |
56 | $users = DB::table('users')->simplePaginate(15);
57 |
58 |
59 | ### Paginating Eloquent Results
60 |
61 | You may also paginate [Eloquent](/docs/{{version}}/eloquent) queries. In this example, we will paginate the `User` model with `15` items per page. As you can see, the syntax is nearly identical to paginating query builder results:
62 |
63 | $users = App\User::paginate(15);
64 |
65 | Of course, you may call `paginate` after setting other constraints on the query, such as `where` clauses:
66 |
67 | $users = User::where('votes', '>', 100)->paginate(15);
68 |
69 | You may also use the `simplePaginate` method when paginating Eloquent models:
70 |
71 | $users = User::where('votes', '>', 100)->simplePaginate(15);
72 |
73 |
74 | ### Manually Creating A Paginator
75 |
76 | Sometimes you may wish to create a pagination instance manually, passing it an array of items. You may do so by creating either an `Illuminate\Pagination\Paginator` or `Illuminate\Pagination\LengthAwarePaginator` instance, depending on your needs.
77 |
78 | The `Paginator` class does not need to know the total number of items in the result set; however, because of this, the class does not have methods for retrieving the index of the last page. The `LengthAwarePaginator` accepts almost the same arguments as the `Paginator`; however, it does require a count of the total number of items in the result set.
79 |
80 | In other words, the `Paginator` corresponds to the `simplePaginate` method on the query builder and Eloquent, while the `LengthAwarePaginator` corresponds to the `paginate` method.
81 |
82 | > {note} When manually creating a paginator instance, you should manually "slice" the array of results you pass to the paginator. If you're unsure how to do this, check out the [array_slice](https://secure.php.net/manual/en/function.array-slice.php) PHP function.
83 |
84 |
85 | ## Displaying Pagination Results
86 |
87 | When calling the `paginate` method, you will receive an instance of `Illuminate\Pagination\LengthAwarePaginator`. When calling the `simplePaginate` method, you will receive an instance of `Illuminate\Pagination\Paginator`. These objects provide several methods that describe the result set. In addition to these helpers methods, the paginator instances are iterators and may be looped as an array. So, once you have retrieved the results, you may display the results and render the page links using [Blade](/docs/{{version}}/blade):
88 |
89 |
94 |
95 | {{ $users->links() }}
96 |
97 | The `links` method will render the links to the rest of the pages in the result set. Each of these links will already contain the proper `page` query string variable. Remember, the HTML generated by the `links` method is compatible with the [Bootstrap CSS framework](https://getbootstrap.com).
98 |
99 | #### Customizing The Paginator URI
100 |
101 | The `withPath` method allows you to customize the URI used by the paginator when generating links. For example, if you want the paginator to generate links like `http://example.com/custom/url?page=N`, you should pass `custom/url` to the `withPath` method:
102 |
103 | Route::get('users', function () {
104 | $users = App\User::paginate(15);
105 |
106 | $users->withPath('custom/url');
107 |
108 | //
109 | });
110 |
111 | #### Appending To Pagination Links
112 |
113 | You may append to the query string of pagination links using the `appends` method. For example, to append `sort=votes` to each pagination link, you should make the following call to `appends`:
114 |
115 | {{ $users->appends(['sort' => 'votes'])->links() }}
116 |
117 | If you wish to append a "hash fragment" to the paginator's URLs, you may use the `fragment` method. For example, to append `#foo` to the end of each pagination link, make the following call to the `fragment` method:
118 |
119 | {{ $users->fragment('foo')->links() }}
120 |
121 |
122 | ### Converting Results To JSON
123 |
124 | The Laravel paginator result classes implement the `Illuminate\Contracts\Support\Jsonable` Interface contract and expose the `toJson` method, so it's very easy to convert your pagination results to JSON. You may also convert a paginator instance to JSON by simply returning it from a route or controller action:
125 |
126 | Route::get('users', function () {
127 | return App\User::paginate();
128 | });
129 |
130 | The JSON from the paginator will include meta information such as `total`, `current_page`, `last_page`, and more. The actual result objects will be available via the `data` key in the JSON array. Here is an example of the JSON created by returning a paginator instance from a route:
131 |
132 | {
133 | "total": 50,
134 | "per_page": 15,
135 | "current_page": 1,
136 | "last_page": 4,
137 | "next_page_url": "http://laravel.app?page=2",
138 | "prev_page_url": null,
139 | "from": 1,
140 | "to": 15,
141 | "data":[
142 | {
143 | // Result Object
144 | },
145 | {
146 | // Result Object
147 | }
148 | ]
149 | }
150 |
151 |
152 | ## Customizing The Pagination View
153 |
154 | By default, the views rendered to display the pagination links are compatible with the Bootstrap CSS framework. However, if you are not using Bootstrap, you are free to define your own views to render these links. When calling the `links` method on a paginator instance, pass the view name as the first argument to the method:
155 |
156 | {{ $paginator->links('view.name') }}
157 |
158 | // Passing data to the view...
159 | {{ $paginator->links('view.name', ['foo' => 'bar']) }}
160 |
161 | However, the easiest way to customize the pagination views is by exporting them to your `resources/views/vendor` directory using the `vendor:publish` command:
162 |
163 | php artisan vendor:publish --tag=laravel-pagination
164 |
165 | This command will place the views in the `resources/views/vendor/pagination` directory. The `default.blade.php` file within this directory corresponds to the default pagination view. Simply edit this file to modify the pagination HTML.
166 |
167 |
168 | ## Paginator Instance Methods
169 |
170 | Each paginator instance provides additional pagination information via the following methods:
171 |
172 | - `$results->count()`
173 | - `$results->currentPage()`
174 | - `$results->firstItem()`
175 | - `$results->hasMorePages()`
176 | - `$results->lastItem()`
177 | - `$results->lastPage() (Not available when using simplePaginate)`
178 | - `$results->nextPageUrl()`
179 | - `$results->perPage()`
180 | - `$results->previousPageUrl()`
181 | - `$results->total() (Not available when using simplePaginate)`
182 | - `$results->url($page)`
183 |
--------------------------------------------------------------------------------
/redis.md:
--------------------------------------------------------------------------------
1 | # Redis
2 |
3 | - [Introduction](#introduction)
4 | - [Configuration](#configuration)
5 | - [Predis](#predis)
6 | - [PhpRedis](#phpredis)
7 | - [Interacting With Redis](#interacting-with-redis)
8 | - [Pipelining Commands](#pipelining-commands)
9 | - [Pub / Sub](#pubsub)
10 |
11 |
12 | ## Introduction
13 |
14 | [Redis](http://redis.io) is an open source, advanced key-value store. It is often referred to as a data structure server since keys can contain [strings](http://redis.io/topics/data-types#strings), [hashes](http://redis.io/topics/data-types#hashes), [lists](http://redis.io/topics/data-types#lists), [sets](http://redis.io/topics/data-types#sets), and [sorted sets](http://redis.io/topics/data-types#sorted-sets).
15 |
16 | Before using Redis with Laravel, you will need to install the `predis/predis` package via Composer:
17 |
18 | composer require predis/predis
19 |
20 | Alternatively, you may install the [PhpRedis](https://github.com/phpredis/phpredis) PHP extension via PECL. The extension is more complex to install but may yield better performance for applications that make heavy use of Redis.
21 |
22 |
23 | ### Configuration
24 |
25 | The Redis configuration for your application is located in the `config/database.php` configuration file. Within this file, you will see a `redis` array containing the Redis servers utilized by your application:
26 |
27 | 'redis' => [
28 |
29 | 'client' => 'predis',
30 |
31 | 'default' => [
32 | 'host' => env('REDIS_HOST', 'localhost'),
33 | 'password' => env('REDIS_PASSWORD', null),
34 | 'port' => env('REDIS_PORT', 6379),
35 | 'database' => 0,
36 | ],
37 |
38 | ],
39 |
40 | The default server configuration should suffice for development. However, you are free to modify this array based on your environment. Each Redis server defined in your configuration file is required to have a name, host, and port.
41 |
42 | #### Configuring Clusters
43 |
44 | If your application is utilizing a cluster of Redis servers, you should define these clusters within a `clusters` key of your Redis configuration:
45 |
46 | 'redis' => [
47 |
48 | 'client' => 'predis',
49 |
50 | 'clusters' => [
51 | 'default' => [
52 | [
53 | 'host' => env('REDIS_HOST', 'localhost'),
54 | 'password' => env('REDIS_PASSWORD', null),
55 | 'port' => env('REDIS_PORT', 6379),
56 | 'database' => 0,
57 | ],
58 | ],
59 | ],
60 |
61 | ],
62 |
63 | By default, clusters will perform client-side sharding across your nodes, allowing you to pool nodes and create a large amount of available RAM. However, note that client-side sharding does not handle failover; therefore, is primarily suited for cached data that is available from another primary data store. If you would like to use native Redis clustering, you should specify this in the `options` key of your Redis configuration:
64 |
65 | 'redis' => [
66 |
67 | 'client' => 'predis',
68 |
69 | 'options' => [
70 | 'cluster' => 'redis',
71 | ],
72 |
73 | 'clusters' => [
74 | // ...
75 | ],
76 |
77 | ],
78 |
79 |
80 | ### Predis
81 |
82 | In addition to the default `host`, `port`, `database`, and `password` server configuration options, Predis supports additional [connection parameters](https://github.com/nrk/predis/wiki/Connection-Parameters) that may be defined for each of your Redis servers. To utilize these additional configuration options, simply add them to your Redis server configuration in the `config/database.php` configuration file:
83 |
84 | 'default' => [
85 | 'host' => env('REDIS_HOST', 'localhost'),
86 | 'password' => env('REDIS_PASSWORD', null),
87 | 'port' => env('REDIS_PORT', 6379),
88 | 'database' => 0,
89 | 'read_write_timeout' => 60,
90 | ],
91 |
92 |
93 | ### PhpRedis
94 |
95 | > {note} If you have the PhpRedis PHP extension installed via PECL, you will need to rename the `Redis` alias in your `config/app.php` configuration file.
96 |
97 | To utilize the PhpRedis extension, you should change the `client` option of your Redis configuration to `phpredis`. This option is found in your `config/database.php` configuration file:
98 |
99 | 'redis' => [
100 |
101 | 'client' => 'phpredis',
102 |
103 | // Rest of Redis configuration...
104 | ],
105 |
106 | In addition to the default `host`, `port`, `database`, and `password` server configuration options, PhpRedis supports the following additional connection parameters: `persistent`, `prefix`, `read_timeout` and `timeout`. You may add any of these options to your Redis server configuration in the `config/database.php` configuration file:
107 |
108 | 'default' => [
109 | 'host' => env('REDIS_HOST', 'localhost'),
110 | 'password' => env('REDIS_PASSWORD', null),
111 | 'port' => env('REDIS_PORT', 6379),
112 | 'database' => 0,
113 | 'read_timeout' => 60,
114 | ],
115 |
116 |
117 | ## Interacting With Redis
118 |
119 | You may interact with Redis by calling various methods on the `Redis` [facade](/docs/{{version}}/facades). The `Redis` facade supports dynamic methods, meaning you may call any [Redis command](http://redis.io/commands) on the facade and the command will be passed directly to Redis. In this example, we will call the Redis `GET` command by calling the `get` method on the `Redis` facade:
120 |
121 | $user]);
141 | }
142 | }
143 |
144 | Of course, as mentioned above, you may call any of the Redis commands on the `Redis` facade. Laravel uses magic methods to pass the commands to the Redis server, so simply pass the arguments the Redis command expects:
145 |
146 | Redis::set('name', 'Taylor');
147 |
148 | $values = Redis::lrange('names', 5, 10);
149 |
150 | Alternatively, you may also pass commands to the server using the `command` method, which accepts the name of the command as its first argument, and an array of values as its second argument:
151 |
152 | $values = Redis::command('lrange', ['name', 5, 10]);
153 |
154 | #### Using Multiple Redis Connections
155 |
156 | You may get a Redis instance by calling the `Redis::connection` method:
157 |
158 | $redis = Redis::connection();
159 |
160 | This will give you an instance of the default Redis server. You may also pass the connection or cluster name to the `connection` method to get a specific server or cluster as defined in your Redis configuration:
161 |
162 | $redis = Redis::connection('my-connection');
163 |
164 |
165 | ### Pipelining Commands
166 |
167 | Pipelining should be used when you need to send many commands to the server in one operation. The `pipeline` method accepts one argument: a `Closure` that receives a Redis instance. You may issue all of your commands to this Redis instance and they will all be executed within a single operation:
168 |
169 | Redis::pipeline(function ($pipe) {
170 | for ($i = 0; $i < 1000; $i++) {
171 | $pipe->set("key:$i", $i);
172 | }
173 | });
174 |
175 |
176 | ## Pub / Sub
177 |
178 | Laravel provides a convenient interface to the Redis `publish` and `subscribe` commands. These Redis commands allow you to listen for messages on a given "channel". You may publish messages to the channel from another application, or even using another programming language, allowing easy communication between applications and processes.
179 |
180 | First, let's setup a channel listener using the `subscribe` method. We'll place this method call within an [Artisan command](/docs/{{version}}/artisan) since calling the `subscribe` method begins a long-running process:
181 |
182 | 'bar']));
224 | });
225 |
226 | #### Wildcard Subscriptions
227 |
228 | Using the `psubscribe` method, you may subscribe to a wildcard channel, which may be useful for catching all messages on all channels. The `$channel` name will be passed as the second argument to the provided callback `Closure`:
229 |
230 | Redis::psubscribe(['*'], function ($message, $channel) {
231 | echo $message;
232 | });
233 |
234 | Redis::psubscribe(['users.*'], function ($message, $channel) {
235 | echo $message;
236 | });
237 |
--------------------------------------------------------------------------------
/database-testing.md:
--------------------------------------------------------------------------------
1 | # Database Testing
2 |
3 | - [Introduction](#introduction)
4 | - [Resetting The Database After Each Test](#resetting-the-database-after-each-test)
5 | - [Using Migrations](#using-migrations)
6 | - [Using Transactions](#using-transactions)
7 | - [Writing Factories](#writing-factories)
8 | - [Factory States](#factory-states)
9 | - [Using Factories](#using-factories)
10 | - [Creating Models](#creating-models)
11 | - [Persisting Models](#persisting-models)
12 | - [Relationships](#relationships)
13 |
14 |
15 | ## Introduction
16 |
17 | Laravel provides a variety of helpful tools to make it easier to test your database driven applications. First, you may use the `assertDatabaseHas` helper to assert that data exists in the database matching a given set of criteria. For example, if you would like to verify that there is a record in the `users` table with the `email` value of `sally@example.com`, you can do the following:
18 |
19 | public function testDatabase()
20 | {
21 | // Make call to application...
22 |
23 | $this->assertDatabaseHas('users', [
24 | 'email' => 'sally@example.com'
25 | ]);
26 | }
27 |
28 | Of course, the `assertDatabaseHas` method and other helpers like it are for convenience. You are free to use any of PHPUnit's built-in assertion methods to supplement your tests.
29 |
30 |
31 | ## Resetting The Database After Each Test
32 |
33 | It is often useful to reset your database after each test so that data from a previous test does not interfere with subsequent tests.
34 |
35 |
36 | ### Using Migrations
37 |
38 | One approach to resetting the database state is to rollback the database after each test and migrate it before the next test. Laravel provides a simple `DatabaseMigrations` trait that will automatically handle this for you. Simply use the trait on your test class and everything will be handled for you:
39 |
40 | get('/');
61 |
62 | // ...
63 | }
64 | }
65 |
66 |
67 | ### Using Transactions
68 |
69 | Another approach to resetting the database state is to wrap each test case in a database transaction. Again, Laravel provides a convenient `DatabaseTransactions` trait that will automatically handle this for you:
70 |
71 | get('/');
92 |
93 | // ...
94 | }
95 | }
96 |
97 | > {note} By default, this trait will only wrap the default database connection in a transaction. If your application is using multiple database connections, you should define a `$connectionsToTransact` property on your test class. This property should be an array of connection names to execute the transactions on.
98 |
99 |
100 | ## Writing Factories
101 |
102 | When testing, you may need to insert a few records into your database before executing your test. Instead of manually specifying the value of each column when you create this test data, Laravel allows you to define a default set of attributes for each of your [Eloquent models](/docs/{{version}}/eloquent) using model factories. To get started, take a look at the `database/factories/ModelFactory.php` file in your application. Out of the box, this file contains one factory definition:
103 |
104 | $factory->define(App\User::class, function (Faker\Generator $faker) {
105 | static $password;
106 |
107 | return [
108 | 'name' => $faker->name,
109 | 'email' => $faker->unique()->safeEmail,
110 | 'password' => $password ?: $password = bcrypt('secret'),
111 | 'remember_token' => str_random(10),
112 | ];
113 | });
114 |
115 | Within the Closure, which serves as the factory definition, you may return the default test values of all attributes on the model. The Closure will receive an instance of the [Faker](https://github.com/fzaninotto/Faker) PHP library, which allows you to conveniently generate various kinds of random data for testing.
116 |
117 | Of course, you are free to add your own additional factories to the `ModelFactory.php` file. You may also create additional factory files for each model for better organization. For example, you could create `UserFactory.php` and `CommentFactory.php` files within your `database/factories` directory. All of the files within the `factories` directory will automatically be loaded by Laravel.
118 |
119 |
120 | ### Factory States
121 |
122 | States allow you to define discrete modifications that can be applied to your model factories in any combination. For example, your `User` model might have a `delinquent` state that modifies one of its default attribute values. You may define your state transformations using the `state` method:
123 |
124 | $factory->state(App\User::class, 'delinquent', function ($faker) {
125 | return [
126 | 'account_status' => 'delinquent',
127 | ];
128 | });
129 |
130 |
131 | ## Using Factories
132 |
133 |
134 | ### Creating Models
135 |
136 | Once you have defined your factories, you may use the global `factory` function in your tests or seed files to generate model instances. So, let's take a look at a few examples of creating models. First, we'll use the `make` method to create models but not save them to the database:
137 |
138 | public function testDatabase()
139 | {
140 | $user = factory(App\User::class)->make();
141 |
142 | // Use model in tests...
143 | }
144 |
145 | You may also create a Collection of many models or create models of a given type:
146 |
147 | // Create three App\User instances...
148 | $users = factory(App\User::class, 3)->make();
149 |
150 | #### Applying States
151 |
152 | You may also apply any of your [states](#factory-states) to the models. If you would like to apply multiple state transformations to the models, you should specify the name of each state you would like to apply:
153 |
154 | $users = factory(App\User::class, 5)->states('delinquent')->make();
155 |
156 | $users = factory(App\User::class, 5)->states('premium', 'delinquent')->make();
157 |
158 | #### Overriding Attributes
159 |
160 | If you would like to override some of the default values of your models, you may pass an array of values to the `make` method. Only the specified values will be replaced while the rest of the values remain set to their default values as specified by the factory:
161 |
162 | $user = factory(App\User::class)->make([
163 | 'name' => 'Abigail',
164 | ]);
165 |
166 |
167 | ### Persisting Models
168 |
169 | The `create` method not only creates the model instances but also saves them to the database using Eloquent's `save` method:
170 |
171 | public function testDatabase()
172 | {
173 | // Create a single App\User instance...
174 | $user = factory(App\User::class)->create();
175 |
176 | // Create three App\User instances...
177 | $users = factory(App\User::class, 3)->create();
178 |
179 | // Use model in tests...
180 | }
181 |
182 | You may override attributes on the model by passing an array to the `create` method:
183 |
184 | $user = factory(App\User::class)->create([
185 | 'name' => 'Abigail',
186 | ]);
187 |
188 |
189 | ### Relationships
190 |
191 | In this example, we'll attach a relation to some created models. When using the `create` method to create multiple models, an Eloquent [collection instance](/docs/{{version}}/eloquent-collections) is returned, allowing you to use any of the convenient functions provided by the collection, such as `each`:
192 |
193 | $users = factory(App\User::class, 3)
194 | ->create()
195 | ->each(function ($u) {
196 | $u->posts()->save(factory(App\Post::class)->make());
197 | });
198 |
199 | #### Relations & Attribute Closures
200 |
201 | You may also attach relationships to models using Closure attributes in your factory definitions. For example, if you would like to create a new `User` instance when creating a `Post`, you may do the following:
202 |
203 | $factory->define(App\Post::class, function ($faker) {
204 | return [
205 | 'title' => $faker->title,
206 | 'content' => $faker->paragraph,
207 | 'user_id' => function () {
208 | return factory(App\User::class)->create()->id;
209 | }
210 | ];
211 | });
212 |
213 | These Closures also receive the evaluated attribute array of the factory that defines them:
214 |
215 | $factory->define(App\Post::class, function ($faker) {
216 | return [
217 | 'title' => $faker->title,
218 | 'content' => $faker->paragraph,
219 | 'user_id' => function () {
220 | return factory(App\User::class)->create()->id;
221 | },
222 | 'user_type' => function (array $post) {
223 | return App\User::find($post['user_id'])->type;
224 | }
225 | ];
226 | });
227 |
--------------------------------------------------------------------------------
/errors.md:
--------------------------------------------------------------------------------
1 | # Errors & Logging
2 |
3 | - [Introduction](#introduction)
4 | - [Configuration](#configuration)
5 | - [Error Detail](#error-detail)
6 | - [Log Storage](#log-storage)
7 | - [Log Severity Levels](#log-severity-levels)
8 | - [Custom Monolog Configuration](#custom-monolog-configuration)
9 | - [The Exception Handler](#the-exception-handler)
10 | - [Report Method](#report-method)
11 | - [Render Method](#render-method)
12 | - [HTTP Exceptions](#http-exceptions)
13 | - [Custom HTTP Error Pages](#custom-http-error-pages)
14 | - [Logging](#logging)
15 |
16 |
17 | ## Introduction
18 |
19 | When you start a new Laravel project, error and exception handling is already configured for you. The `App\Exceptions\Handler` class is where all exceptions triggered by your application are logged and then rendered back to the user. We'll dive deeper into this class throughout this documentation.
20 |
21 | For logging, Laravel utilizes the [Monolog](https://github.com/Seldaek/monolog) library, which provides support for a variety of powerful log handlers. Laravel configures several of these handlers for you, allowing you to choose between a single log file, rotating log files, or writing error information to the system log.
22 |
23 |
24 | ## Configuration
25 |
26 |
27 | ### Error Detail
28 |
29 | The `debug` option in your `config/app.php` configuration file determines how much information about an error is actually displayed to the user. By default, this option is set to respect the value of the `APP_DEBUG` environment variable, which is stored in your `.env` file.
30 |
31 | For local development, you should set the `APP_DEBUG` environment variable to `true`. In your production environment, this value should always be `false`. If the value is set to `true` in production, you risk exposing sensitive configuration values to your application's end users.
32 |
33 |
34 | ### Log Storage
35 |
36 | Out of the box, Laravel supports writing log information to `single` files, `daily` files, the `syslog`, and the `errorlog`. To configure which storage mechanism Laravel uses, you should modify the `log` option in your `config/app.php` configuration file. For example, if you wish to use daily log files instead of a single file, you should set the `log` value in your `app` configuration file to `daily`:
37 |
38 | 'log' => 'daily'
39 |
40 | #### Maximum Daily Log Files
41 |
42 | When using the `daily` log mode, Laravel will only retain five days of log files by default. If you want to adjust the number of retained files, you may add a `log_max_files` configuration value to your `app` configuration file:
43 |
44 | 'log_max_files' => 30
45 |
46 |
47 | ### Log Severity Levels
48 |
49 | When using Monolog, log messages may have different levels of severity. By default, Laravel writes all log levels to storage. However, in your production environment, you may wish to configure the minimum severity that should be logged by adding the `log_level` option to your `app.php` configuration file.
50 |
51 | Once this option has been configured, Laravel will log all levels greater than or equal to the specified severity. For example, a default `log_level` of `error` will log **error**, **critical**, **alert**, and **emergency** messages:
52 |
53 | 'log_level' => env('APP_LOG_LEVEL', 'error'),
54 |
55 | > {tip} Monolog recognizes the following severity levels - from least severe to most severe: `debug`, `info`, `notice`, `warning`, `error`, `critical`, `alert`, `emergency`.
56 |
57 |
58 | ### Custom Monolog Configuration
59 |
60 | If you would like to have complete control over how Monolog is configured for your application, you may use the application's `configureMonologUsing` method. You should place a call to this method in your `bootstrap/app.php` file right before the `$app` variable is returned by the file:
61 |
62 | $app->configureMonologUsing(function ($monolog) {
63 | $monolog->pushHandler(...);
64 | });
65 |
66 | return $app;
67 |
68 |
69 | ## The Exception Handler
70 |
71 |
72 | ### The Report Method
73 |
74 | All exceptions are handled by the `App\Exceptions\Handler` class. This class contains two methods: `report` and `render`. We'll examine each of these methods in detail. The `report` method is used to log exceptions or send them to an external service like [Bugsnag](https://bugsnag.com) or [Sentry](https://github.com/getsentry/sentry-laravel). By default, the `report` method simply passes the exception to the base class where the exception is logged. However, you are free to log exceptions however you wish.
75 |
76 | For example, if you need to report different types of exceptions in different ways, you may use the PHP `instanceof` comparison operator:
77 |
78 | /**
79 | * Report or log an exception.
80 | *
81 | * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
82 | *
83 | * @param \Exception $exception
84 | * @return void
85 | */
86 | public function report(Exception $exception)
87 | {
88 | if ($exception instanceof CustomException) {
89 | //
90 | }
91 |
92 | return parent::report($exception);
93 | }
94 |
95 | #### Ignoring Exceptions By Type
96 |
97 | The `$dontReport` property of the exception handler contains an array of exception types that will not be logged. For example, exceptions resulting from 404 errors, as well as several other types of errors, are not written to your log files. You may add other exception types to this array as needed:
98 |
99 | /**
100 | * A list of the exception types that should not be reported.
101 | *
102 | * @var array
103 | */
104 | protected $dontReport = [
105 | \Illuminate\Auth\AuthenticationException::class,
106 | \Illuminate\Auth\Access\AuthorizationException::class,
107 | \Symfony\Component\HttpKernel\Exception\HttpException::class,
108 | \Illuminate\Database\Eloquent\ModelNotFoundException::class,
109 | \Illuminate\Validation\ValidationException::class,
110 | ];
111 |
112 |
113 | ### The Render Method
114 |
115 | The `render` method is responsible for converting a given exception into an HTTP response that should be sent back to the browser. By default, the exception is passed to the base class which generates a response for you. However, you are free to check the exception type or return your own custom response:
116 |
117 | /**
118 | * Render an exception into an HTTP response.
119 | *
120 | * @param \Illuminate\Http\Request $request
121 | * @param \Exception $exception
122 | * @return \Illuminate\Http\Response
123 | */
124 | public function render($request, Exception $exception)
125 | {
126 | if ($exception instanceof CustomException) {
127 | return response()->view('errors.custom', [], 500);
128 | }
129 |
130 | return parent::render($request, $exception);
131 | }
132 |
133 |
134 | ## HTTP Exceptions
135 |
136 | Some exceptions describe HTTP error codes from the server. For example, this may be a "page not found" error (404), an "unauthorized error" (401) or even a developer generated 500 error. In order to generate such a response from anywhere in your application, you may use the `abort` helper:
137 |
138 | abort(404);
139 |
140 | The `abort` helper will immediately raise an exception which will be rendered by the exception handler. Optionally, you may provide the response text:
141 |
142 | abort(403, 'Unauthorized action.');
143 |
144 |
145 | ### Custom HTTP Error Pages
146 |
147 | Laravel makes it easy to display custom error pages for various HTTP status codes. For example, if you wish to customize the error page for 404 HTTP status codes, create a `resources/views/errors/404.blade.php`. This file will be served on all 404 errors generated by your application. The views within this directory should be named to match the HTTP status code they correspond to. The `HttpException` instance raised by the `abort` function will be passed to the view as an `$exception` variable.
148 |
149 |
150 | ## Logging
151 |
152 | Laravel provides a simple abstraction layer on top of the powerful [Monolog](https://github.com/seldaek/monolog) library. By default, Laravel is configured to create a log file for your application in the `storage/logs` directory. You may write information to the logs using the `Log` [facade](/docs/{{version}}/facades):
153 |
154 | User::findOrFail($id)]);
175 | }
176 | }
177 |
178 | The logger provides the eight logging levels defined in [RFC 5424](https://tools.ietf.org/html/rfc5424): **emergency**, **alert**, **critical**, **error**, **warning**, **notice**, **info** and **debug**.
179 |
180 | Log::emergency($message);
181 | Log::alert($message);
182 | Log::critical($message);
183 | Log::error($message);
184 | Log::warning($message);
185 | Log::notice($message);
186 | Log::info($message);
187 | Log::debug($message);
188 |
189 | #### Contextual Information
190 |
191 | An array of contextual data may also be passed to the log methods. This contextual data will be formatted and displayed with the log message:
192 |
193 | Log::info('User failed to login.', ['id' => $user->id]);
194 |
195 | #### Accessing The Underlying Monolog Instance
196 |
197 | Monolog has a variety of additional handlers you may use for logging. If needed, you may access the underlying Monolog instance being used by Laravel:
198 |
199 | $monolog = Log::getMonolog();
200 |
--------------------------------------------------------------------------------
/database.md:
--------------------------------------------------------------------------------
1 | # Database: Getting Started
2 |
3 | - [Introduction](#introduction)
4 | - [Configuration](#configuration)
5 | - [Read & Write Connections](#read-and-write-connections)
6 | - [Using Multiple Database Connections](#using-multiple-database-connections)
7 | - [Running Raw SQL Queries](#running-queries)
8 | - [Listening For Query Events](#listening-for-query-events)
9 | - [Database Transactions](#database-transactions)
10 |
11 |
12 | ## Introduction
13 |
14 | Laravel makes interacting with databases extremely simple across a variety of database backends using either raw SQL, the [fluent query builder](/docs/{{version}}/queries), and the [Eloquent ORM](/docs/{{version}}/eloquent). Currently, Laravel supports four databases:
15 |
16 |
17 | - MySQL
18 | - Postgres
19 | - SQLite
20 | - SQL Server
21 |
22 |
23 |
24 | ### Configuration
25 |
26 | The database configuration for your application is located at `config/database.php`. In this file you may define all of your database connections, as well as specify which connection should be used by default. Examples for most of the supported database systems are provided in this file.
27 |
28 | By default, Laravel's sample [environment configuration](/docs/{{version}}/configuration#environment-configuration) is ready to use with [Laravel Homestead](/docs/{{version}}/homestead), which is a convenient virtual machine for doing Laravel development on your local machine. Of course, you are free to modify this configuration as needed for your local database.
29 |
30 | #### SQLite Configuration
31 |
32 | After creating a new SQLite database using a command such as `touch database/database.sqlite`, you can easily configure your environment variables to point to this newly created database by using the database's absolute path:
33 |
34 | DB_CONNECTION=sqlite
35 | DB_DATABASE=/absolute/path/to/database.sqlite
36 |
37 | #### SQL Server Configuration
38 |
39 | Laravel supports SQL Server out of the box; however, you will need to add the connection configuration for the database to your `config/database.php` configuration file:
40 |
41 | 'sqlsrv' => [
42 | 'driver' => 'sqlsrv',
43 | 'host' => env('DB_HOST', 'localhost'),
44 | 'database' => env('DB_DATABASE', 'forge'),
45 | 'username' => env('DB_USERNAME', 'forge'),
46 | 'password' => env('DB_PASSWORD', ''),
47 | 'charset' => 'utf8',
48 | 'prefix' => '',
49 | ],
50 |
51 |
52 | ### Read & Write Connections
53 |
54 | Sometimes you may wish to use one database connection for SELECT statements, and another for INSERT, UPDATE, and DELETE statements. Laravel makes this a breeze, and the proper connections will always be used whether you are using raw queries, the query builder, or the Eloquent ORM.
55 |
56 | To see how read / write connections should be configured, let's look at this example:
57 |
58 | 'mysql' => [
59 | 'read' => [
60 | 'host' => '192.168.1.1',
61 | ],
62 | 'write' => [
63 | 'host' => '196.168.1.2'
64 | ],
65 | 'driver' => 'mysql',
66 | 'database' => 'database',
67 | 'username' => 'root',
68 | 'password' => '',
69 | 'charset' => 'utf8',
70 | 'collation' => 'utf8_unicode_ci',
71 | 'prefix' => '',
72 | ],
73 |
74 | Note that two keys have been added to the configuration array: `read` and `write`. Both of these keys have array values containing a single key: `host`. The rest of the database options for the `read` and `write` connections will be merged from the main `mysql` array.
75 |
76 | You only need to place items in the `read` and `write` arrays if you wish to override the values from the main array. So, in this case, `192.168.1.1` will be used as the host for the "read" connection, while `192.168.1.2` will be used for the "write" connection. The database credentials, prefix, character set, and all other options in the main `mysql` array will be shared across both connections.
77 |
78 |
79 | ### Using Multiple Database Connections
80 |
81 | When using multiple connections, you may access each connection via the `connection` method on the `DB` facade. The `name` passed to the `connection` method should correspond to one of the connections listed in your `config/database.php` configuration file:
82 |
83 | $users = DB::connection('foo')->select(...);
84 |
85 | You may also access the raw, underlying PDO instance using the `getPdo` method on a connection instance:
86 |
87 | $pdo = DB::connection()->getPdo();
88 |
89 |
90 | ## Running Raw SQL Queries
91 |
92 | Once you have configured your database connection, you may run queries using the `DB` facade. The `DB` facade provides methods for each type of query: `select`, `update`, `insert`, `delete`, and `statement`.
93 |
94 | #### Running A Select Query
95 |
96 | To run a basic query, you may use the `select` method on the `DB` facade:
97 |
98 | $users]);
117 | }
118 | }
119 |
120 | The first argument passed to the `select` method is the raw SQL query, while the second argument is any parameter bindings that need to be bound to the query. Typically, these are the values of the `where` clause constraints. Parameter binding provides protection against SQL injection.
121 |
122 | The `select` method will always return an `array` of results. Each result within the array will be a PHP `StdClass` object, allowing you to access the values of the results:
123 |
124 | foreach ($users as $user) {
125 | echo $user->name;
126 | }
127 |
128 | #### Using Named Bindings
129 |
130 | Instead of using `?` to represent your parameter bindings, you may execute a query using named bindings:
131 |
132 | $results = DB::select('select * from users where id = :id', ['id' => 1]);
133 |
134 | #### Running An Insert Statement
135 |
136 | To execute an `insert` statement, you may use the `insert` method on the `DB` facade. Like `select`, this method takes the raw SQL query as its first argument and bindings as its second argument:
137 |
138 | DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']);
139 |
140 | #### Running An Update Statement
141 |
142 | The `update` method should be used to update existing records in the database. The number of rows affected by the statement will be returned:
143 |
144 | $affected = DB::update('update users set votes = 100 where name = ?', ['John']);
145 |
146 | #### Running A Delete Statement
147 |
148 | The `delete` method should be used to delete records from the database. Like `update`, the number of rows affected will be returned:
149 |
150 | $deleted = DB::delete('delete from users');
151 |
152 | #### Running A General Statement
153 |
154 | Some database statements do not return any value. For these types of operations, you may use the `statement` method on the `DB` facade:
155 |
156 | DB::statement('drop table users');
157 |
158 |
159 | ### Listening For Query Events
160 |
161 | If you would like to receive each SQL query executed by your application, you may use the `listen` method. This method is useful for logging queries or debugging. You may register your query listener in a [service provider](/docs/{{version}}/providers):
162 |
163 | sql
181 | // $query->bindings
182 | // $query->time
183 | });
184 | }
185 |
186 | /**
187 | * Register the service provider.
188 | *
189 | * @return void
190 | */
191 | public function register()
192 | {
193 | //
194 | }
195 | }
196 |
197 |
198 | ## Database Transactions
199 |
200 | You may use the `transaction` method on the `DB` facade to run a set of operations within a database transaction. If an exception is thrown within the transaction `Closure`, the transaction will automatically be rolled back. If the `Closure` executes successfully, the transaction will automatically be committed. You don't need to worry about manually rolling back or committing while using the `transaction` method:
201 |
202 | DB::transaction(function () {
203 | DB::table('users')->update(['votes' => 1]);
204 |
205 | DB::table('posts')->delete();
206 | });
207 |
208 | #### Handling Deadlocks
209 |
210 | The `transaction` method accepts an optional second argument which defines the number of times a transaction should be reattempted when a deadlock occurs. Once these attempts have been exhausted, an exception will be thrown:
211 |
212 | DB::transaction(function () {
213 | DB::table('users')->update(['votes' => 1]);
214 |
215 | DB::table('posts')->delete();
216 | }, 5);
217 |
218 | #### Manually Using Transactions
219 |
220 | If you would like to begin a transaction manually and have complete control over rollbacks and commits, you may use the `beginTransaction` method on the `DB` facade:
221 |
222 | DB::beginTransaction();
223 |
224 | You can rollback the transaction via the `rollBack` method:
225 |
226 | DB::rollBack();
227 |
228 | Lastly, you can commit a transaction via the `commit` method:
229 |
230 | DB::commit();
231 |
232 | > {tip} Using the `DB` facade's transaction methods also controls transactions for the [query builder](/docs/{{version}}/queries) and [Eloquent ORM](/docs/{{version}}/eloquent).
233 |
--------------------------------------------------------------------------------
/mocking.md:
--------------------------------------------------------------------------------
1 | # Mocking
2 |
3 | - [Introduction](#introduction)
4 | - [Bus Fake](#bus-fake)
5 | - [Event Fake](#event-fake)
6 | - [Mail Fake](#mail-fake)
7 | - [Notification Fake](#notification-fake)
8 | - [Queue Fake](#queue-fake)
9 | - [Facades](#mocking-facades)
10 |
11 |
12 | ## Introduction
13 |
14 | When testing Laravel applications, you may wish to "mock" certain aspects of your application so they are not actually executed during a given test. For example, when testing a controller that dispatches an event, you may wish to mock the event listeners so they are not actually executed during the test. This allows you to only test the controller's HTTP response without worrying about the execution of the event listeners, since the event listeners can be tested in their own test case.
15 |
16 | Laravel provides helpers for mocking events, jobs, and facades out of the box. These helpers primarily provide a convenience layer over Mockery so you do not have to manually make complicated Mockery method calls. Of course, you are free to use [Mockery](http://docs.mockery.io/en/latest/) or PHPUnit to create your own mocks or spies.
17 |
18 |
19 | ## Bus Fake
20 |
21 | As an alternative to mocking, you may use the `Bus` facade's `fake` method to prevent jobs from being dispatched. When using fakes, assertions are made after the code under test is executed:
22 |
23 | order->id === $order->id;
44 | });
45 |
46 | // Assert a job was not dispatched...
47 | Bus::assertNotDispatched(AnotherJob::class);
48 | }
49 | }
50 |
51 |
52 | ## Event Fake
53 |
54 | As an alternative to mocking, you may use the `Event` facade's `fake` method to prevent all event listeners from executing. You may then assert that events were dispatched and even inspect the data they received. When using fakes, assertions are made after the code under test is executed:
55 |
56 | order->id === $order->id;
81 | });
82 |
83 | Event::assertNotDispatched(OrderFailedToShip::class);
84 | }
85 | }
86 |
87 |
88 | ## Mail Fake
89 |
90 | You may use the `Mail` facade's `fake` method to prevent mail from being sent. You may then assert that [mailables](/docs/{{version}}/mail) were sent to users and even inspect the data they received. When using fakes, assertions are made after the code under test is executed:
91 |
92 | order->id === $order->id;
113 | });
114 |
115 | // Assert a message was sent to the given users...
116 | Mail::assertSent(OrderShipped::class, function ($mail) use ($user) {
117 | return $mail->hasTo($user->email) &&
118 | $mail->hasCc('...') &&
119 | $mail->hasBcc('...');
120 | });
121 |
122 | // Assert a mailable was not sent...
123 | Mail::assertNotSent(AnotherMailable::class);
124 | }
125 | }
126 |
127 |
128 | ## Notification Fake
129 |
130 | You may use the `Notification` facade's `fake` method to prevent notifications from being sent. You may then assert that [notifications](/docs/{{version}}/notifications) were sent to users and even inspect the data they received. When using fakes, assertions are made after the code under test is executed:
131 |
132 | order->id === $order->id;
156 | }
157 | );
158 |
159 | // Assert a notification was sent to the given users...
160 | Notification::assertSentTo(
161 | [$user], OrderShipped::class
162 | );
163 |
164 | // Assert a notification was not sent...
165 | Notification::assertNotSentTo(
166 | [$user], AnotherNotification::class
167 | );
168 | }
169 | }
170 |
171 |
172 | ## Queue Fake
173 |
174 | As an alternative to mocking, you may use the `Queue` facade's `fake` method to prevent jobs from being queued. You may then assert that jobs were pushed to the queue and even inspect the data they received. When using fakes, assertions are made after the code under test is executed:
175 |
176 | order->id === $order->id;
197 | });
198 |
199 | // Assert a job was pushed to a given queue...
200 | Queue::assertPushedOn('queue-name', ShipOrder::class);
201 |
202 | // Assert a job was not pushed...
203 | Queue::assertNotPushed(AnotherJob::class);
204 | }
205 | }
206 |
207 |
208 | ## Facades
209 |
210 | Unlike traditional static method calls, [facades](/docs/{{version}}/facades) may be mocked. This provides a great advantage over traditional static methods and grants you the same testability you would have if you were using dependency injection. When testing, you may often want to mock a call to a Laravel facade in one of your controllers. For example, consider the following controller action:
211 |
212 | once()
251 | ->with('key')
252 | ->andReturn('value');
253 |
254 | $response = $this->get('/users');
255 |
256 | // ...
257 | }
258 | }
259 |
260 | > {note} You should not mock the `Request` facade. Instead, pass the input you desire into the HTTP helper methods such as `get` and `post` when running your test. Likewise, instead of mocking the `Config` facade, simply call the `Config::set` method in your tests.
261 |
--------------------------------------------------------------------------------
/middleware.md:
--------------------------------------------------------------------------------
1 | # Middleware
2 |
3 | - [Introduction](#introduction)
4 | - [Defining Middleware](#defining-middleware)
5 | - [Registering Middleware](#registering-middleware)
6 | - [Global Middleware](#global-middleware)
7 | - [Assigning Middleware To Routes](#assigning-middleware-to-routes)
8 | - [Middleware Groups](#middleware-groups)
9 | - [Middleware Parameters](#middleware-parameters)
10 | - [Terminable Middleware](#terminable-middleware)
11 |
12 |
13 | ## Introduction
14 |
15 | Middleware provide a convenient mechanism for filtering HTTP requests entering your application. For example, Laravel includes a middleware that verifies the user of your application is authenticated. If the user is not authenticated, the middleware will redirect the user to the login screen. However, if the user is authenticated, the middleware will allow the request to proceed further into the application.
16 |
17 | Of course, additional middleware can be written to perform a variety of tasks besides authentication. A CORS middleware might be responsible for adding the proper headers to all responses leaving your application. A logging middleware might log all incoming requests to your application.
18 |
19 | There are several middleware included in the Laravel framework, including middleware for authentication and CSRF protection. All of these middleware are located in the `app/Http/Middleware` directory.
20 |
21 |
22 | ## Defining Middleware
23 |
24 | To create a new middleware, use the `make:middleware` Artisan command:
25 |
26 | php artisan make:middleware CheckAge
27 |
28 | This command will place a new `CheckAge` 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.
29 |
30 | age <= 200) {
48 | return redirect('home');
49 | }
50 |
51 | return $next($request);
52 | }
53 |
54 | }
55 |
56 | As you can see, if the given `age` is less than or equal to `200`, the middleware will return an HTTP redirect to the client; otherwise, the request will be passed further into the application. To pass the request deeper into the application (allowing the middleware to "pass"), simply call the `$next` callback with the `$request`.
57 |
58 | It's best to envision middleware as a series of "layers" HTTP requests must pass through before they hit your application. Each layer can examine the request and even reject it entirely.
59 |
60 | ### Before & After Middleware
61 |
62 | Whether a middleware runs before or after a request depends on the middleware itself. For example, the following middleware would perform some task **before** the request is handled by the application:
63 |
64 |
101 | ## Registering Middleware
102 |
103 |
104 | ### Global Middleware
105 |
106 | If you want a middleware to run during every HTTP request to your application, simply list the middleware class in the `$middleware` property of your `app/Http/Kernel.php` class.
107 |
108 |
109 | ### Assigning Middleware To Routes
110 |
111 | If you would like to assign middleware to specific routes, you should first assign the middleware a key in your `app/Http/Kernel.php` file. By default, the `$routeMiddleware` property of this class contains entries for the middleware included with Laravel. To add your own, simply append it to this list and assign it a key of your choosing. For example:
112 |
113 | // Within App\Http\Kernel Class...
114 |
115 | protected $routeMiddleware = [
116 | 'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
117 | 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
118 | 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
119 | 'can' => \Illuminate\Auth\Middleware\Authorize::class,
120 | 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
121 | 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
122 | ];
123 |
124 | Once the middleware has been defined in the HTTP kernel, you may use the `middleware` method to assign middleware to a route:
125 |
126 | Route::get('admin/profile', function () {
127 | //
128 | })->middleware('auth');
129 |
130 | You may also assign multiple middleware to the route:
131 |
132 | Route::get('/', function () {
133 | //
134 | })->middleware('first', 'second');
135 |
136 | When assigning middleware, you may also pass the fully qualified class name:
137 |
138 | use App\Http\Middleware\CheckAge;
139 |
140 | Route::get('admin/profile', function () {
141 | //
142 | })->middleware(CheckAge::class);
143 |
144 |
145 | ### Middleware Groups
146 |
147 | Sometimes you may want to group several middleware under a single key to make them easier to assign to routes. You may do this using the `$middlewareGroups` property of your HTTP kernel.
148 |
149 | Out of the box, Laravel comes with `web` and `api` middleware groups that contains common middleware you may want to apply to your web UI and API routes:
150 |
151 | /**
152 | * The application's route middleware groups.
153 | *
154 | * @var array
155 | */
156 | protected $middlewareGroups = [
157 | 'web' => [
158 | \App\Http\Middleware\EncryptCookies::class,
159 | \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
160 | \Illuminate\Session\Middleware\StartSession::class,
161 | \Illuminate\View\Middleware\ShareErrorsFromSession::class,
162 | \App\Http\Middleware\VerifyCsrfToken::class,
163 | \Illuminate\Routing\Middleware\SubstituteBindings::class,
164 | ],
165 |
166 | 'api' => [
167 | 'throttle:60,1',
168 | 'auth:api',
169 | ],
170 | ];
171 |
172 | Middleware groups may be assigned to routes and controller actions using the same syntax as individual middleware. Again, middleware groups simply make it more convenient to assign many middleware to a route at once:
173 |
174 | Route::get('/', function () {
175 | //
176 | })->middleware('web');
177 |
178 | Route::group(['middleware' => ['web']], function () {
179 | //
180 | });
181 |
182 | > {tip} Out of the box, the `web` middleware group is automatically applied to your `routes/web.php` file by the `RouteServiceProvider`.
183 |
184 |
185 | ## Middleware Parameters
186 |
187 | Middleware can also receive additional parameters. For example, if your application needs to verify that the authenticated user has a given "role" before performing a given action, you could create a `CheckRole` middleware that receives a role name as an additional argument.
188 |
189 | Additional middleware parameters will be passed to the middleware after the `$next` argument:
190 |
191 | user()->hasRole($role)) {
210 | // Redirect...
211 | }
212 |
213 | return $next($request);
214 | }
215 |
216 | }
217 |
218 | Middleware parameters may be specified when defining the route by separating the middleware name and parameters with a `:`. Multiple parameters should be delimited by commas:
219 |
220 | Route::put('post/{id}', function ($id) {
221 | //
222 | })->middleware('role:editor');
223 |
224 |
225 | ## Terminable Middleware
226 |
227 | Sometimes a middleware may need to do some work after the HTTP response has 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. If you define a `terminate` method on your middleware, it will automatically be called after the response is sent to the browser.
228 |
229 |
12 | ## Introduction
13 |
14 | In the past, you may have generated a Cron entry for each task you needed to schedule on your server. However, this can quickly become a pain, because your task schedule is no longer in source control and you must SSH into your server to add additional Cron entries.
15 |
16 | Laravel's command scheduler allows you to fluently and expressively define your command schedule within Laravel itself. When using the scheduler, only a single Cron entry is needed on your server. Your task schedule is defined in the `app/Console/Kernel.php` file's `schedule` method. To help you get started, a simple example is defined within the method.
17 |
18 | ### Starting The Scheduler
19 |
20 | When using the scheduler, you only need to add the following Cron entry to your server. If you do not know how to add Cron entries to your server, consider using a service such as [Laravel Forge](https://forge.laravel.com) which can manage the Cron entries for you:
21 |
22 | * * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1
23 |
24 | This Cron will call the Laravel command scheduler every minute. When the `schedule:run` command is executed, Laravel will evaluate your scheduled tasks and runs the tasks that are due.
25 |
26 |
27 | ## Defining Schedules
28 |
29 | You may define all of your scheduled tasks in the `schedule` method of the `App\Console\Kernel` class. To get started, let's look at an example of scheduling a task. In this example, we will schedule a `Closure` to be called every day at midnight. Within the `Closure` we will execute a database query to clear a table:
30 |
31 | call(function () {
59 | DB::table('recent_users')->delete();
60 | })->daily();
61 | }
62 | }
63 |
64 | In addition to scheduling `Closure` calls, you may also schedule [Artisan commands](/docs/{{version}}/artisan) and operating system commands. For example, you may use the `command` method to schedule an Artisan command using either the command's name or class:
65 |
66 | $schedule->command('emails:send --force')->daily();
67 |
68 | $schedule->command(EmailsCommand::class, ['--force'])->daily();
69 |
70 | The `exec` command may be used to issue a command to the operating system:
71 |
72 | $schedule->exec('node /home/forge/script.js')->daily();
73 |
74 |
75 | ### Schedule Frequency Options
76 |
77 | Of course, there are a variety of schedules you may assign to your task:
78 |
79 | Method | Description
80 | ------------- | -------------
81 | `->cron('* * * * * *');` | Run the task on a custom Cron schedule
82 | `->everyMinute();` | Run the task every minute
83 | `->everyFiveMinutes();` | Run the task every five minutes
84 | `->everyTenMinutes();` | Run the task every ten minutes
85 | `->everyThirtyMinutes();` | Run the task every thirty minutes
86 | `->hourly();` | Run the task every hour
87 | `->hourlyAt(17);` | Run the task every hour at 17 mins past the hour
88 | `->daily();` | Run the task every day at midnight
89 | `->dailyAt('13:00');` | Run the task every day at 13:00
90 | `->twiceDaily(1, 13);` | Run the task daily at 1:00 & 13:00
91 | `->weekly();` | Run the task every week
92 | `->monthly();` | Run the task every month
93 | `->monthlyOn(4, '15:00');` | Run the task every month on the 4th at 15:00
94 | `->quarterly();` | Run the task every quarter
95 | `->yearly();` | Run the task every year
96 | `->timezone('America/New_York');` | Set the timezone
97 |
98 | These methods may be combined with additional constraints to create even more finely tuned schedules that only run on certain days of the week. For example, to schedule a command to run weekly on Monday:
99 |
100 | // Run once per week on Monday at 1 PM...
101 | $schedule->call(function () {
102 | //
103 | })->weekly()->mondays()->at('13:00');
104 |
105 | // Run hourly from 8 AM to 5 PM on weekdays...
106 | $schedule->command('foo')
107 | ->weekdays()
108 | ->hourly()
109 | ->timezone('America/Chicago')
110 | ->between('8:00', '17:00');
111 |
112 | Below is a list of the additional schedule constraints:
113 |
114 | Method | Description
115 | ------------- | -------------
116 | `->weekdays();` | Limit the task to weekdays
117 | `->sundays();` | Limit the task to Sunday
118 | `->mondays();` | Limit the task to Monday
119 | `->tuesdays();` | Limit the task to Tuesday
120 | `->wednesdays();` | Limit the task to Wednesday
121 | `->thursdays();` | Limit the task to Thursday
122 | `->fridays();` | Limit the task to Friday
123 | `->saturdays();` | Limit the task to Saturday
124 | `->between($start, $end);` | Limit the task to run between start and end times
125 | `->when(Closure);` | Limit the task based on a truth test
126 |
127 | #### Between Time Constraints
128 |
129 | The `between` method may be used to limit the execution of a task based on the time of day:
130 |
131 | $schedule->command('reminders:send')
132 | ->hourly()
133 | ->between('7:00', '22:00');
134 |
135 | Similarly, the `unlessBetween` method can be used to exclude the execution of a task for a period of time:
136 |
137 | $schedule->command('reminders:send')
138 | ->hourly()
139 | ->unlessBetween('23:00', '4:00');
140 |
141 | #### Truth Test Constraints
142 |
143 | The `when` method may be used to limit the execution of a task based on the result of a given truth test. In other words, if the given `Closure` returns `true`, the task will execute as long as no other constraining conditions prevent the task from running:
144 |
145 | $schedule->command('emails:send')->daily()->when(function () {
146 | return true;
147 | });
148 |
149 | The `skip` method may be seen as the inverse of `when`. If the `skip` method returns `true`, the scheduled task will not be executed:
150 |
151 | $schedule->command('emails:send')->daily()->skip(function () {
152 | return true;
153 | });
154 |
155 | When using chained `when` methods, the scheduled command will only execute if all `when` conditions return `true`.
156 |
157 |
158 | ### Preventing Task Overlaps
159 |
160 | By default, scheduled tasks will be run even if the previous instance of the task is still running. To prevent this, you may use the `withoutOverlapping` method:
161 |
162 | $schedule->command('emails:send')->withoutOverlapping();
163 |
164 | In this example, the `emails:send` [Artisan command](/docs/{{version}}/artisan) will be run every minute if it is not already running. The `withoutOverlapping` method is especially useful if you have tasks that vary drastically in their execution time, preventing you from predicting exactly how long a given task will take.
165 |
166 |
167 | ### Maintenance Mode
168 |
169 | Laravel's scheduled tasks will not run when Laravel is in [maintenance mode](/docs/{{version}}/configuration#maintenance-mode), since we don't want your tasks to interfere with any unfinished maintenance you may be performing on your server. However, if you would like to force a task to run even in maintenance mode, you may use the `evenInMaintenanceMode` method:
170 |
171 | $schedule->command('emails:send')->evenInMaintenanceMode();
172 |
173 |
174 | ## Task Output
175 |
176 | The Laravel scheduler provides several convenient methods for working with the output generated by scheduled tasks. First, using the `sendOutputTo` method, you may send the output to a file for later inspection:
177 |
178 | $schedule->command('emails:send')
179 | ->daily()
180 | ->sendOutputTo($filePath);
181 |
182 | If you would like to append the output to a given file, you may use the `appendOutputTo` method:
183 |
184 | $schedule->command('emails:send')
185 | ->daily()
186 | ->appendOutputTo($filePath);
187 |
188 | Using the `emailOutputTo` method, you may e-mail the output to an e-mail address of your choice. Before e-mailing the output of a task, you should configure Laravel's [e-mail services](/docs/{{version}}/mail):
189 |
190 | $schedule->command('foo')
191 | ->daily()
192 | ->sendOutputTo($filePath)
193 | ->emailOutputTo('foo@example.com');
194 |
195 | > {note} The `emailOutputTo`, `sendOutputTo` and `appendOutputTo` methods are exclusive to the `command` method and are not supported for `call`.
196 |
197 |
198 | ## Task Hooks
199 |
200 | Using the `before` and `after` methods, you may specify code to be executed before and after the scheduled task is complete:
201 |
202 | $schedule->command('emails:send')
203 | ->daily()
204 | ->before(function () {
205 | // Task is about to start...
206 | })
207 | ->after(function () {
208 | // Task is complete...
209 | });
210 |
211 | #### Pinging URLs
212 |
213 | Using the `pingBefore` and `thenPing` methods, the scheduler can automatically ping a given URL before or after a task is complete. This method is useful for notifying an external service, such as [Laravel Envoyer](https://envoyer.io), that your scheduled task is commencing or has finished execution:
214 |
215 | $schedule->command('emails:send')
216 | ->daily()
217 | ->pingBefore($url)
218 | ->thenPing($url);
219 |
220 | Using either the `pingBefore($url)` or `thenPing($url)` feature requires the Guzzle HTTP library. You can add Guzzle to your project using the Composer package manager:
221 |
222 | composer require guzzlehttp/guzzle
223 |
--------------------------------------------------------------------------------
/container.md:
--------------------------------------------------------------------------------
1 | # Service Container
2 |
3 | - [Introduction](#introduction)
4 | - [Binding](#binding)
5 | - [Binding Basics](#binding-basics)
6 | - [Binding Interfaces To Implementations](#binding-interfaces-to-implementations)
7 | - [Contextual Binding](#contextual-binding)
8 | - [Tagging](#tagging)
9 | - [Resolving](#resolving)
10 | - [The Make Method](#the-make-method)
11 | - [Automatic Injection](#automatic-injection)
12 | - [Container Events](#container-events)
13 |
14 |
15 | ## Introduction
16 |
17 | The Laravel service container is a powerful tool for managing class dependencies and performing dependency injection. Dependency injection is a fancy phrase that essentially means this: class dependencies are "injected" into the class via the constructor or, in some cases, "setter" methods.
18 |
19 | Let's look at a simple example:
20 |
21 | users = $users;
47 | }
48 |
49 | /**
50 | * Show the profile for the given user.
51 | *
52 | * @param int $id
53 | * @return Response
54 | */
55 | public function show($id)
56 | {
57 | $user = $this->users->find($id);
58 |
59 | return view('user.profile', ['user' => $user]);
60 | }
61 | }
62 |
63 | In this example, the `UserController` needs to retrieve users from a data source. So, we will **inject** a service that is able to retrieve users. In this context, our `UserRepository` most likely uses [Eloquent](/docs/{{version}}/eloquent) to retrieve user information from the database. However, since the repository is injected, we are able to easily swap it out with another implementation. We are also able to easily "mock", or create a dummy implementation of the `UserRepository` when testing our application.
64 |
65 | A deep understanding of the Laravel service container is essential to building a powerful, large application, as well as for contributing to the Laravel core itself.
66 |
67 |
68 | ## Binding
69 |
70 |
71 | ### Binding Basics
72 |
73 | Almost all of your service container bindings will be registered within [service providers](/docs/{{version}}/providers), so most of these examples will demonstrate using the container in that context.
74 |
75 | > {tip} There is no need to bind classes into the container if they do not depend on any interfaces. The container does not need to be instructed on how to build these objects, since it can automatically resolve these objects using reflection.
76 |
77 | #### Simple Bindings
78 |
79 | Within a service provider, you always have access to the container via the `$this->app` property. We can register a binding using the `bind` method, passing the class or interface name that we wish to register along with a `Closure` that returns an instance of the class:
80 |
81 | $this->app->bind('HelpSpot\API', function ($app) {
82 | return new HelpSpot\API($app->make('HttpClient'));
83 | });
84 |
85 | Note that we receive the container itself as an argument to the resolver. We can then use the container to resolve sub-dependencies of the object we are building.
86 |
87 | #### Binding A Singleton
88 |
89 | The `singleton` method binds a class or interface into the container that should only be resolved one time. Once a singleton binding is resolved, the same object instance will be returned on subsequent calls into the container:
90 |
91 | $this->app->singleton('HelpSpot\API', function ($app) {
92 | return new HelpSpot\API($app->make('HttpClient'));
93 | });
94 |
95 | #### Binding Instances
96 |
97 | You may also bind an existing object instance into the container using the `instance` method. The given instance will always be returned on subsequent calls into the container:
98 |
99 | $api = new HelpSpot\API(new HttpClient);
100 |
101 | $this->app->instance('HelpSpot\Api', $api);
102 |
103 | #### Binding Primitives
104 |
105 | Sometimes you may have a class that receives some injected classes, but also needs an injected primitive value such as an integer. You may easily use contextual binding to inject any value your class may need:
106 |
107 | $this->app->when('App\Http\Controllers\UserController')
108 | ->needs('$variableName')
109 | ->give($value);
110 |
111 |
112 | ### Binding Interfaces To Implementations
113 |
114 | A very powerful feature of the service container is its ability to bind an interface to a given implementation. For example, let's assume we have an `EventPusher` interface and a `RedisEventPusher` implementation. Once we have coded our `RedisEventPusher` implementation of this interface, we can register it with the service container like so:
115 |
116 | $this->app->bind(
117 | 'App\Contracts\EventPusher',
118 | 'App\Services\RedisEventPusher'
119 | );
120 |
121 | This statement tells the container that it should inject the `RedisEventPusher` when a class needs an implementation of `EventPusher`. Now we can type-hint the `EventPusher` interface in a constructor, or any other location where dependencies are injected by the service container:
122 |
123 | use App\Contracts\EventPusher;
124 |
125 | /**
126 | * Create a new class instance.
127 | *
128 | * @param EventPusher $pusher
129 | * @return void
130 | */
131 | public function __construct(EventPusher $pusher)
132 | {
133 | $this->pusher = $pusher;
134 | }
135 |
136 |
137 | ### Contextual Binding
138 |
139 | Sometimes you may have two classes that utilize the same interface, but you wish to inject different implementations into each class. For example, two controllers may depend on different implementations of the `Illuminate\Contracts\Filesystem\Filesystem` [contract](/docs/{{version}}/contracts). Laravel provides a simple, fluent interface for defining this behavior:
140 |
141 | use Illuminate\Support\Facades\Storage;
142 | use App\Http\Controllers\PhotoController;
143 | use App\Http\Controllers\VideoController;
144 | use Illuminate\Contracts\Filesystem\Filesystem;
145 |
146 | $this->app->when(PhotoController::class)
147 | ->needs(Filesystem::class)
148 | ->give(function () {
149 | return Storage::disk('local');
150 | });
151 |
152 | $this->app->when(VideoController::class)
153 | ->needs(Filesystem::class)
154 | ->give(function () {
155 | return Storage::disk('s3');
156 | });
157 |
158 |
159 | ### Tagging
160 |
161 | Occasionally, you may need to resolve all of a certain "category" of binding. For example, perhaps you are building a report aggregator that receives an array of many different `Report` interface implementations. After registering the `Report` implementations, you can assign them a tag using the `tag` method:
162 |
163 | $this->app->bind('SpeedReport', function () {
164 | //
165 | });
166 |
167 | $this->app->bind('MemoryReport', function () {
168 | //
169 | });
170 |
171 | $this->app->tag(['SpeedReport', 'MemoryReport'], 'reports');
172 |
173 | Once the services have been tagged, you may easily resolve them all via the `tagged` method:
174 |
175 | $this->app->bind('ReportAggregator', function ($app) {
176 | return new ReportAggregator($app->tagged('reports'));
177 | });
178 |
179 |
180 | ## Resolving
181 |
182 |
183 | #### The `make` Method
184 |
185 | You may use the `make` method to resolve a class instance out of the container. The `make` method accepts the name of the class or interface you wish to resolve:
186 |
187 | $api = $this->app->make('HelpSpot\API');
188 |
189 | If you are in a location of your code that does not have access to the `$app` variable, you may use the global `resolve` helper:
190 |
191 | $api = resolve('HelpSpot\API');
192 |
193 |
194 | #### Automatic Injection
195 |
196 | Alternatively, and importantly, you may simply "type-hint" the dependency in the constructor of a class that is resolved by the container, including [controllers](/docs/{{version}}/controllers), [event listeners](/docs/{{version}}/events), [queue jobs](/docs/{{version}}/queues), [middleware](/docs/{{version}}/middleware), and more. In practice, this is how most of your objects should be resolved by the container.
197 |
198 | For example, you may type-hint a repository defined by your application in a controller's constructor. The repository will automatically be resolved and injected into the class:
199 |
200 | users = $users;
222 | }
223 |
224 | /**
225 | * Show the user with the given ID.
226 | *
227 | * @param int $id
228 | * @return Response
229 | */
230 | public function show($id)
231 | {
232 | //
233 | }
234 | }
235 |
236 |
237 | ## Container Events
238 |
239 | The service container fires an event each time it resolves an object. You may listen to this event using the `resolving` method:
240 |
241 | $this->app->resolving(function ($object, $app) {
242 | // Called when container resolves object of any type...
243 | });
244 |
245 | $this->app->resolving(HelpSpot\API::class, function ($api, $app) {
246 | // Called when container resolves objects of type "HelpSpot\API"...
247 | });
248 |
249 | As you can see, the object being resolved will be passed to the callback, allowing you to set any additional properties on the object before it is given to its consumer.
250 |
--------------------------------------------------------------------------------
/mix.md:
--------------------------------------------------------------------------------
1 | # Compiling Assets (Laravel Mix)
2 |
3 | - [Introduction](#introduction)
4 | - [Installation & Setup](#installation)
5 | - [Running Mix](#running-mix)
6 | - [Working With Stylesheets](#working-with-stylesheets)
7 | - [Less](#less)
8 | - [Sass](#sass)
9 | - [Plain CSS](#plain-css)
10 | - [Source Maps](#css-source-maps)
11 | - [Working With JavaScript](#working-with-scripts)
12 | - [Code Splitting](#code-splitting)
13 | - [Custom Webpack Configuration](#custom-webpack-configuration)
14 | - [Copying Files & Directories](#copying-files-and-directories)
15 | - [Versioning / Cache Busting](#versioning-and-cache-busting)
16 | - [Notifications](#notifications)
17 |
18 |
19 | ## Introduction
20 |
21 | Laravel Mix provides a fluent API for defining Webpack build steps for your Laravel application using several common CSS and JavaScript pre-processors. Through simple method chaining, you can fluently define your asset pipeline. For example:
22 |
23 | mix.js('resources/assets/js/app.js', 'public/js')
24 | .sass('resources/assets/sass/app.scss', 'public/css');
25 |
26 | If you've ever been confused and overwhelmed about getting started with Webpack and asset compilation, you will love Laravel Mix. However, you are not required to use it while developing your application. Of course, you are free to use any asset pipeline tool you wish, or even none at all.
27 |
28 |
29 | ## Installation & Setup
30 |
31 | #### Installing Node
32 |
33 | Before triggering Mix, you must first ensure that Node.js and NPM are installed on your machine.
34 |
35 | node -v
36 | npm -v
37 |
38 | By default, Laravel Homestead includes everything you need; however, if you aren't using Vagrant, then you can easily install the latest version of Node and NPM using simple graphical installers from [their download page](https://nodejs.org/en/download/).
39 |
40 | #### Laravel Mix
41 |
42 | The only remaining step is to install Laravel Mix. Within a fresh installation of Laravel, you'll find a `package.json` file in the root of your directory structure. The default `package.json` file includes everything you need to get started. 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:
43 |
44 | npm install
45 |
46 | If you are developing on a Windows system or you are running your VM on a Windows host system, you may need to run the `npm install` command with the `--no-bin-links` switch enabled:
47 |
48 | npm install --no-bin-links
49 |
50 |
51 | ## Running Mix
52 |
53 | Mix is a configuration layer on top of [Webpack](https://webpack.js.org), so to run your Mix tasks you only need to execute one of the NPM scripts that is included with the default Laravel `package.json` file:
54 |
55 | // Run all Mix tasks...
56 | npm run dev
57 |
58 | // Run all Mix tasks and minify output...
59 | npm run production
60 |
61 | #### Watching Assets For Changes
62 |
63 | The `npm run watch` command will continue running in your terminal and watch all relevant files for changes. Webpack will then automatically recompile your assets when it detects a change:
64 |
65 | npm run watch
66 |
67 |
68 | ## Working With Stylesheets
69 |
70 | The `webpack.mix.js` file is your entry point for all asset compilation. Think of it as a light configuration wrapper around Webpack. Mix tasks can be chained together to define exactly how your assets should be compiled.
71 |
72 |
73 | ### Less
74 |
75 | The `less` method may be used to compile [Less](http://lesscss.org/) into CSS. Let's compile our primary `app.less` file to `public/css/app.css`.
76 |
77 | mix.less('resources/assets/less/app.less', 'public/css');
78 |
79 | Multiple calls to the `less` method may be used to compile multiple files:
80 |
81 | mix.less('resources/assets/less/app.less', 'public/css')
82 | .less('resources/assets/less/admin.less', 'public/css');
83 |
84 | If you wish to customize the file name of the compiled CSS, you may pass a full file path as the second argument to the `less` method:
85 |
86 | mix.less('resources/assets/less/app.less', 'public/stylesheets/styles.css');
87 |
88 |
89 | ### Sass
90 |
91 | The `sass` method allows you to compile [Sass](http://sass-lang.com/) into CSS. You may use the method like so:
92 |
93 | mix.sass('resources/assets/sass/app.scss', 'public/css');
94 |
95 | Again, like the `less` method, you may compile multiple Sass files into their own respective CSS files and even customize the output directory of the resulting CSS:
96 |
97 | mix.sass('resources/assets/sass/app.sass', 'public/css')
98 | .sass('resources/assets/sass/admin.sass', 'public/css/admin');
99 |
100 |
101 | ### Plain CSS
102 |
103 | If you would just like to combine some plain CSS stylesheets into a single file, you may use the `combine` method. This method also supports concatenating JavaScript files:
104 |
105 | mix.combine([
106 | 'public/css/vendor/normalize.css',
107 | 'public/css/vendor/videojs.css'
108 | ], 'public/css/all.css');
109 |
110 |
111 | ### Source Maps
112 |
113 | Though disabled by default, source maps may be activated by calling the `mix.sourceMaps()` method in your `webpack.mix.js` file. Though it comes with a compile/performance cost, this will provide extra debugging information to your browser's developer tools when using compiled assets.
114 |
115 | mix.js('resources/assets/js/app.js', 'public/js')
116 | .sourceMaps();
117 |
118 |
119 | ## Working With JavaScript
120 |
121 | Mix provides several features to help you work with your JavaScript files, such as compiling ECMAScript 2015, module bundling, minification, and simply concatenating plain JavaScript files. Even better, this all works seamlessly, without requiring an ounce of custom configuration:
122 |
123 | mix.js('resources/assets/js/app.js', 'public/js');
124 |
125 | With this single line of code, you may now take advantage of:
126 |
127 |
128 | - ES2015 syntax.
129 | - Compilation of `.vue` files.
130 | - Minification for production environments.
131 |
132 |
133 |
134 | ### Code Splitting
135 |
136 | One potential downside to bundling all application-specific JavaScript with your vendor libraries is that it makes long-term caching more difficult. For example, a single update to your application code will force the browser to re-download all of your vendor libraries even if they haven't changed.
137 |
138 | If you intend to make frequent updates to your application's JavaScript, you should consider extracting all of your vendor libraries into their file. This way, a change to your application code will not affect the caching of your large `vendor.js` file. Mix's `extract` method makes this a breeze:
139 |
140 | mix.js('resources/assets/js/app.js', 'public/js')
141 | .extract(['vue'])
142 |
143 | The `extract` method accepts an array of all libraries or modules that you wish to extract into a `vendor.js` file. Using the above snippet as an example, Mix will generate the following files:
144 |
145 |
150 |
151 | To avoid JavaScript errors, be sure to load these files in the proper order:
152 |
153 |
154 |
155 |
156 |
157 |
158 | ### Custom Webpack Configuration
159 |
160 | Behind the scenes, Laravel Mix references a pre-configured `webpack.config.js` file to get you up and running as quickly as possible. Occasionally, you may need to manually modify this file. You might have a special loader or plugin that needs to be referenced, or maybe you prefer to use Stylus instead of Sass. In such instances, you have two choices:
161 |
162 | #### Merging
163 |
164 | Mix provides a useful `webpackConfig` method that allows you to merge any short Webpack configuration overrides. This is a particularly appealing choice, as it doesn't require you to copy and maintain your own copy of the `webpack.config.js` file. The `webpackConfig` method accepts an object, which should contain any [Webpack-specific configuration](https://webpack.js.org/configuration/) that you wish to apply.
165 |
166 | mix.webpackConfig({
167 | resolve: {
168 | modules: [
169 | path.resolve(__dirname, 'vendor/laravel/spark/resources/assets/js')
170 | ]
171 | }
172 | });
173 |
174 | #### Reference Your Own Configuration
175 |
176 | A second option is to copy Mix's `webpack.config.js` into your project root.
177 |
178 | cp node_modules/laravel-mix/setup/webpack.config.js ./
179 |
180 | Next, you'll need to update the NPM scripts in your `package.json` to ensure that they no longer reference Mix's configuration file directly. Simply remove the `--config="node_modules/laravel-mix/setup/webpack.config.js"` entry from the commands. Once this has been done, you may freely modify your configuration file as needed.
181 |
182 |
183 |
184 | ## Copying Files & Directories
185 |
186 | The `copy` method may be used to copy files and directories to new locations. This can be useful when a particular asset within your `node_modules` directory needs to be relocated to your `public` folder.
187 |
188 | mix.copy('node_modules/foo/bar.css', 'public/css/bar.css');
189 |
190 |
191 | ## Versioning / Cache Busting
192 |
193 | Many developers suffix their compiled assets with a timestamp or unique token to force browsers to load the fresh assets instead of serving stale copies of the code. Mix can handle this for you using the `version` method.
194 |
195 | The `version` method will automatically append a unique hash to the filenames of all compiled files, allowing for more convenient cache busting:
196 |
197 | mix.js('resources/assets/js/app.js', 'public/js')
198 | .version();
199 |
200 | After generating the versioned file, you won't know the exact file name. So, you should use Laravel's global `mix` function within your [views](/docs/{{version}}/views) to load the appropriately hashed asset. The `mix` function will automatically determine the current name of the hashed file:
201 |
202 |
203 |
204 | Because versioned files are usually unnecessary in development, you may wish to instruct the versioning process to only run during `npm run production`:
205 |
206 | mix.js('resources/assets/js/app.js', 'public/js');
207 |
208 | if (mix.config.inProduction) {
209 | mix.version();
210 | }
211 |
212 |
213 | ## Notifications
214 |
215 | When available, Mix will automatically display OS notifications for each bundle. This will give you instant feedback, as to whether the compilation was successful or not. However, there may be instances when you'd prefer to disable these notifications. One such example might be triggering Mix on your production server. Notifications may be deactivated, via the `disableNotifications` method.
216 |
217 | mix.disableNotifications();
218 |
--------------------------------------------------------------------------------