Subscribe
@@ -1006,7 +1026,7 @@ Cashier also emit events dedicated to the type of the received webhook. In addit
You can also override the default, built-in webhook route by defining the `CASHIER_WEBHOOK` environment variable in your application's `.env` file. This value should be the full URL to your webhook route and needs to match the URL set in your Paddle control panel:
-```bash
+```ini
CASHIER_WEBHOOK=https://example.com/my-paddle-webhook-url
```
@@ -1035,7 +1055,7 @@ If you would like to make a one-time charge against a customer, you may use the
After generating the pay link, you may use Cashier's provided `paddle-button` Blade component to allow the user to initiate the Paddle widget and complete the charge:
-```html
+```blade
Buy
@@ -1049,7 +1069,7 @@ The `charge` method accepts an array as its third argument, allowing you to pass
Charges happen in the currency specified in the `cashier.currency` configuration option. By default, this is set to USD. You may override the default currency by defining the `CASHIER_CURRENCY` environment variable in your application's `.env` file:
-```bash
+```ini
CASHIER_CURRENCY=EUR
```
@@ -1075,7 +1095,7 @@ If you would like to make a one-time charge against a specific product configure
Then, you may provide the pay link to the `paddle-button` component to allow the user to initialize the Paddle widget:
-```html
+```blade
Buy
@@ -1151,7 +1171,9 @@ You may use the `lastPayment` and `nextPayment` methods to retrieve and display
Both of these methods will return an instance of `Laravel\Paddle\Payment`; however, `nextPayment` will return `null` when the billing cycle has ended (such as when a subscription has been cancelled):
- Next payment: {{ $nextPayment->amount() }} due on {{ $nextPayment->date()->format('d/m/Y') }}
+```blade
+Next payment: {{ $nextPayment->amount() }} due on {{ $nextPayment->date()->format('d/m/Y') }}
+```
## Handling Failed Payments
diff --git a/docs/collections.md b/docs/collections.md
index ca5b98b..6cca782 100644
--- a/docs/collections.md
+++ b/docs/collections.md
@@ -166,6 +166,7 @@
- [random](#method-random)
- [range](#method-range)
- [reduce](#method-reduce)
+- [reduceMany](#method-reduce-many)
- [reduceSpread](#method-reduce-spread)
- [reject](#method-reject)
- [replace](#method-replace)
@@ -288,13 +289,15 @@
Этот метод особенно полезен в [шаблонах](views.md) при работе с сеткой, такой как [Bootstrap](https://getbootstrap.com/docs/4.1/layout/grid/). Например, представьте, что у вас есть коллекция моделей [Eloquent](eloquent.md), которые вы хотите отобразить в сетке:
- @foreach ($products->chunk(3) as $chunk)
-
- @foreach ($chunk as $product)
-
{{ $product->name }}
- @endforeach
-
- @endforeach
+```blade
+@foreach ($products->chunk(3) as $chunk)
+
+ @foreach ($chunk as $product)
+
{{ $product->name }}
+ @endforeach
+
+@endforeach
+```
#### `chunkWhile()`
@@ -1817,13 +1820,29 @@
// 4264
+
+#### `reduceMany()`
+
+Метод `reduceMany` сокращает коллекцию до массива значений, передавая результаты каждой итерации следующей итерации. Этот метод подобен методу `reduce`; однако он может принимать несколько начальных значений:
+
+ [$creditsRemaining, $batch] = Image::where('status', 'unprocessed')
+ ->get()
+ ->reduceMany(function ($creditsRemaining, $batch, $image) {
+ if ($creditsRemaining >= $image->creditsRequired()) {
+ $batch->push($image);
+
+ $creditsRemaining -= $image->creditsRequired();
+ }
+
+ return [$creditsRemaining, $batch];
+ }, $creditsAvailable, collect());
+
#### `reduceSpread()`
Метод `reduceSpread` сокращает коллекцию до массива значений, передавая результаты каждой итерации в следующую итерацию. Этот метод похож на метод `reduce`; однако он может принимать несколько начальных значений:
-```php
-[$creditsRemaining, $batch] = Image::where('status', 'unprocessed')
+ [$creditsRemaining, $batch] = Image::where('status', 'unprocessed')
->get()
->reduceSpread(function ($creditsRemaining, $batch, $image) {
if ($creditsRemaining >= $image->creditsRequired()) {
@@ -1834,7 +1853,6 @@
return [$creditsRemaining, $batch];
}, $creditsAvailable, collect());
-```
#### `reject()`
diff --git a/docs/configuration.md b/docs/configuration.md
index c266239..2160419 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -58,7 +58,9 @@ null | (null) null
Если вам нужно определить переменную окружения со значением, содержащим пробелы, то вы можете сделать это, заключив значение в двойные кавычки:
- APP_NAME="My Application"
+```ini
+APP_NAME="My Application"
+```
### Получение конфигурации окружения
@@ -127,26 +129,36 @@ null | (null) null
Чтобы включить режим обслуживания, выполните команду `down` Artisan:
- php artisan down
+```shell
+php artisan down
+```
Если вы хотите, чтобы HTTP-заголовок `Refresh` отправлялся со всеми ответами режима обслуживания, то вы можете указать параметр `refresh` при вызове команды `down`. Заголовок `Refresh` проинструктирует браузер автоматически обновлять страницу через указанное количество секунд:
- php artisan down --refresh=15
+```shell
+php artisan down --refresh=15
+```
Вы также можете передать команде `down` параметр `retry`, значение которого будет установлено в заголовке `Retry-After` HTTP, хотя браузеры обычно игнорируют этот заголовок:
- php artisan down --retry=60
+```shell
+php artisan down --retry=60
+```
#### Обход режима обслуживания
Находясь в режиме обслуживания, вы можете использовать параметр `secret`, чтобы указать токен для обхода режима обслуживания:
- php artisan down --secret="1630542a-246b-4b66-afa1-dd72a4c43515"
+```shell
+php artisan down --secret="1630542a-246b-4b66-afa1-dd72a4c43515"
+```
После перевода приложения в режим обслуживания, вы можете перейти по URL-адресу приложения, с учетом этого токена, и Laravel выдаст вашему браузеру файл куки для обхода режима обслуживания:
- https://example.com/1630542a-246b-4b66-afa1-dd72a4c43515
+```shell
+https://example.com/1630542a-246b-4b66-afa1-dd72a4c43515
+```
При доступе к этому скрытому маршруту вы будете перенаправлены на маршрут `/` приложения. Как только куки будет отправлен вашему браузеру, вы сможете просматривать приложение в обычном режиме, как если бы оно не находилось в режиме обслуживания.
@@ -159,21 +171,27 @@ null | (null) null
По этой причине Laravel позволяет в самом начале цикла запроса отобразить шаблон режима обслуживания. Этот шаблон отображается перед загрузкой любых зависимостей вашего приложения. Вы можете выполнить предварительный рендеринг шаблона по вашему выбору, используя параметр `render` команды `down`:
- php artisan down --render="errors::503"
+```shell
+php artisan down --render="errors::503"
+```
#### Перенаправление запросов режима обслуживания
В режиме обслуживания Laravel будет отображать шаблон режима обслуживания для всех URL-адресов приложения, к которым пользователь попытается получить доступ. Если хотите, то вы можете указать Laravel перенаправлять все запросы на определенный URL. Это может быть выполнено с помощью параметра `redirect`. Например, вы можете перенаправить все запросы на URI `/`:
- php artisan down --redirect=/
+```shell
+php artisan down --redirect=/
+```
#### Отключение режима обслуживания
Чтобы отключить режим обслуживания, используйте команду `up`:
- php artisan up
+```shell
+php artisan up
+```
> {tip} Вы можете определить свой шаблон режима обслуживания в `resources/views/errors/503.blade.php`.
diff --git a/docs/contracts.md b/docs/contracts.md
index 1a91cd8..e649d6a 100644
--- a/docs/contracts.md
+++ b/docs/contracts.md
@@ -11,7 +11,7 @@
«Контракты» Laravel – это набор интерфейсов, которые определяют основные службы фреймворка. Например, контракт `Illuminate\Contracts\Queue\Queue` определяет методы, необходимые для постановки заданий в очередь, а контракт `Illuminate\Contracts\Mail\Mailer` – для отправки электронной почты.
-Каждый контракт имеет соответствующую реализацию, предусмотренную структурой. Например, Laravel предлагает реализацию очереди с множеством драйверов и реализацию почтовой программы, которая работает на [SwiftMailer](https://swiftmailer.symfony.com/).
+Каждый контракт имеет соответствующую реализацию, предусмотренную структурой. Например, Laravel предлагает реализацию очереди с множеством драйверов и реализацию почтовой программы, которая работает на [Symfony Mailer](https://symfony.com/doc/6.0/mailer.html).
Все контракты Laravel находятся в [их собственном репозитории](https://github.com/illuminate/contracts) GitHub. Это обеспечивает быстрый доступ к списку всех доступных контрактов, а также единый, отдельный пакет, который используется разработчиками пакетов, взаимодействующих со службами Laravel.
diff --git a/docs/controllers.md b/docs/controllers.md
index 6c9b3cb..fb2c202 100644
--- a/docs/controllers.md
+++ b/docs/controllers.md
@@ -94,7 +94,9 @@
Вы можете сгенерировать вызываемый контроллер, используя параметр `--invokable` команды `make:controller` Artisan:
- php artisan make:controller ProvisionServer --invokable
+```shell
+php artisan make:controller ProvisionServer --invokable
+```
> {tip} Заготовки контроллера можно настроить с помощью [публикации заготовок](artisan.md#stub-customization).
@@ -135,7 +137,9 @@
Благодаря такому распространенному варианту использования, маршрутизация ресурсов Laravel присвоит типичные маршруты создания, чтения, обновления и удаления («CRUD») контроллеру с помощью одной строки кода. Для начала мы можем использовать параметр `--resource` команды `make:controller` Artisan, чтобы быстро создать контроллер для обработки этих действий:
- php artisan make:controller PhotoController --resource
+```shell
+php artisan make:controller PhotoController --resource
+```
Эта команда поместит новый класс контроллера в каталог `app/Http/Controllers` вашего приложения. Контроллер будет содержать метод для каждого из доступных действий с ресурсами. Затем, вы можете зарегистрировать маршрут ресурса, который указывает на контроллер:
@@ -184,14 +188,18 @@ DELETE | `/photos/{photo}` | destroy | photos.destroy
Если вы используете [привязку модели к маршруту](routing.md#route-model-binding) и хотите, чтобы методы контроллера ресурса содержали типизацию экземпляра модели, вы можете использовать параметр `--model` при создании контроллера:
- php artisan make:controller PhotoController --model=Photo --resource
+```shell
+php artisan make:controller PhotoController --model=Photo --resource
+```
#### Генерация запросов формы
Вы можете указать флаг `--requests` при создании ресурсного контроллера, чтобы указать Artisan о попутном создании [классов запросов](validation.md#form-request-validation) для методов `store` и `update` контроллера:
- php artisan make:controller PhotoController --model=Photo --resource --requests
+```shell
+php artisan make:controller PhotoController --model=Photo --resource --requests
+```
### Частичные ресурсные маршруты
@@ -229,7 +237,9 @@ DELETE | `/photos/{photo}` | destroy | photos.destroy
Чтобы быстро сгенерировать ресурсный API-контроллер, который не включает методы `create` или `edit`, используйте переключатель `--api` при выполнении команды `make:controller`:
- php artisan make:controller PhotoController --api
+```shell
+php artisan make:controller PhotoController --api
+```
### Вложенные ресурсы
diff --git a/docs/csrf.md b/docs/csrf.md
index fcd04da..c6c81be 100644
--- a/docs/csrf.md
+++ b/docs/csrf.md
@@ -18,13 +18,15 @@
Без защиты от CSRF вредоносный веб-сайт может создать HTML-форму, которая указывает на маршрут вашего приложения `/user/email` и отправляет собственный адрес электронной почты злоумышленника:
-
+```blade
+
-
+
+```
Если вредоносный веб-сайт автоматически отправляет форму при загрузке страницы, злоумышленнику нужно только подтолкнуть ничего не подозревающего пользователя вашего приложения посетить свой веб-сайт, и его адрес электронной почты будет изменен в вашем приложении.
@@ -49,12 +51,14 @@ Laravel автоматически генерирует «токен» CSRF дл
Каждый раз, когда вы создаете HTML-форму запросов «POST» «PUT», «PATCH» или «DELETE» в своем приложении, вы должны включать в форму скрытое поле `_token`, чтобы посредник защиты от CSRF смог выполнить проверку запроса. Для удобства вы можете использовать директиву `@csrf` Blade для создания скрытого поля ввода, содержащего этот токен:
-
+
+
+
+```
[Посредник](middleware.md) `App\Http\Middleware\VerifyCsrfToken`, который по умолчанию стоит в группе посредников `web`, автоматически проверяет соответствие токена во входном запросе и токен, хранящийся в сессии. Когда эти два токена совпадают, мы знаем, что запрос инициирует аутентифицированный пользователь.
@@ -97,15 +101,19 @@ Laravel автоматически генерирует «токен» CSRF дл
В дополнение к проверке токена CSRF в качестве параметра POST-запроса посредник `App\Http\Middleware\VerifyCsrfToken` также проверяет заголовок запроса `X-CSRF-TOKEN`. Вы можете, например, сохранить токен в HTML-теге `meta`:
-
+```blade
+
+```
Затем, вы можете указать библиотеке, такой как jQuery, автоматически добавлять токен во все заголовки запросов. Это обеспечивает простую и удобную защиту от CSRF для ваших приложений с использованием устаревшей технологии JavaScript на основе AJAX:
- $.ajaxSetup({
- headers: {
- 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
- }
- });
+```js
+$.ajaxSetup({
+ headers: {
+ 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
+ }
+});
+```
## Токен X-XSRF
diff --git a/docs/database-testing.md b/docs/database-testing.md
index 2376da6..72ea085 100644
--- a/docs/database-testing.md
+++ b/docs/database-testing.md
@@ -55,6 +55,10 @@ Laravel предлагает множество полезных инструм
}
}
+Трейт `Illuminate\Foundation\Testing\RefreshDatabase` не мигрирует вашу базу данных, если ваша схема обновлена. Вместо этого он будет выполнять тест только в транзакции базы данных. Следовательно, любые записи, добавленные в базу данных тестом, не использующими этот трейт, могут по-прежнему существовать в базе данных.
+
+Если вы хотите полностью сбросить базу данных с помощью миграции, то вы можете вместо этого использовать трейт `Illuminate\Foundation\Testing\DatabaseMigrations`. Однако использование трейта `DatabaseMigrations` значительно медленнее, чем использование трейта `RefreshDatabase`.
+
## Определение фабрик моделей
@@ -100,7 +104,9 @@ Laravel предлагает множество полезных инструм
Чтобы сгенерировать новую фабрику, используйте команду `make:factory` [Artisan](artisan.md):
- php artisan make:factory PostFactory
+```shell
+php artisan make:factory PostFactory
+```
Эта команда поместит новый класс фабрики в каталог `database/factories` вашего приложения.
diff --git a/docs/database.md b/docs/database.md
index 4354236..1e04bfe 100644
--- a/docs/database.md
+++ b/docs/database.md
@@ -16,7 +16,6 @@
-- MariaDB 10.2+ ([Политика версий](https://mariadb.org/about/#maintenance-policy))
- MySQL 5.7+ ([Политика версий](https://en.wikipedia.org/wiki/MySQL#Release_history))
- PostgreSQL 9.6+ ([Политика версий](https://www.postgresql.org/support/versioning/))
- SQLite 3.8.8+
@@ -36,12 +35,16 @@
Базы данных SQLite содержатся в одном файле вашей файловой системы. Вы можете создать новую базу данных SQLite, используя команду `touch` в консоли: `touch database/database.sqlite`. После создания базы данных вы можете легко настроить переменные окружения так, чтобы они указывали на эту базу данных, указав абсолютный путь к базе данных в переменной `DB_DATABASE` окружения:
- DB_CONNECTION=sqlite
- DB_DATABASE=/absolute/path/to/database.sqlite
+```ini
+DB_CONNECTION=sqlite
+DB_DATABASE=/absolute/path/to/database.sqlite
+```
Чтобы включить ограничения внешнего ключа для соединений SQLite, установите переменную `DB_FOREIGN_KEYS` окружения в `true`:
- DB_FOREIGN_KEYS=true
+```ini
+DB_FOREIGN_KEYS=true
+```
#### Конфигурация Microsoft SQL Server
@@ -313,8 +316,12 @@ driver://username:password@host:port/database?options
Если вы хотите подключиться к своей базе данных с помощью интерфейса командной строки, то вы можете использовать команду `db` Artisan:
- php artisan db
+```shell
+php artisan db
+```
При необходимости, вы можете указать имя соединения для подключения к базе данных, не являющееся соединением по умолчанию:
- php artisan db mysql
+```shell
+php artisan db mysql
+```
diff --git a/docs/deployment.md b/docs/deployment.md
index ae20a7a..238294d 100644
--- a/docs/deployment.md
+++ b/docs/deployment.md
@@ -24,13 +24,15 @@
-- PHP >= 7.3
+- PHP >= 8.0
- Расширение PHP BCMath
- Расширение PHP Ctype
+- Расширение PHP DOM
- Расширение PHP Fileinfo
- Расширение PHP JSON
- Расширение PHP Mbstring
- Расширение PHP OpenSSL
+- Расширение PHP PCRE
- Расширение PHP PDO
- Расширение PHP Tokenizer
- Расширение PHP XML
@@ -47,38 +49,40 @@
Убедитесь, что, как и в конфигурации ниже, ваш веб-сервер направляет все запросы в файл `public/index.php` вашего приложения. Вы никогда не должны пытаться переместить файл `index.php` в корень вашего проекта, поскольку обслуживание приложения из корня проекта откроет доступ ко многим конфиденциальным файлам конфигурации из общедоступной сети Интернет:
- server {
- listen 80;
- listen [::]:80;
- server_name example.com;
- root /srv/example.com/public;
+```nginx
+server {
+ listen 80;
+ listen [::]:80;
+ server_name example.com;
+ root /srv/example.com/public;
- add_header X-Frame-Options "SAMEORIGIN";
- add_header X-Content-Type-Options "nosniff";
+ add_header X-Frame-Options "SAMEORIGIN";
+ add_header X-Content-Type-Options "nosniff";
- index index.php;
+ index index.php;
- charset utf-8;
+ charset utf-8;
- location / {
- try_files $uri $uri/ /index.php?$query_string;
- }
+ location / {
+ try_files $uri $uri/ /index.php?$query_string;
+ }
- location = /favicon.ico { access_log off; log_not_found off; }
- location = /robots.txt { access_log off; log_not_found off; }
+ location = /favicon.ico { access_log off; log_not_found off; }
+ location = /robots.txt { access_log off; log_not_found off; }
- error_page 404 /index.php;
+ error_page 404 /index.php;
- location ~ \.php$ {
- fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
- fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
- include fastcgi_params;
- }
+ location ~ \.php$ {
+ fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
+ fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
+ include fastcgi_params;
+ }
- location ~ /\.(?!well-known).* {
- deny all;
- }
+ location ~ /\.(?!well-known).* {
+ deny all;
}
+}
+```
## Оптимизация
@@ -88,7 +92,9 @@
При развертывании в эксплуатационном окружении, убедитесь, что вы оптимизировали файл автозагрузчика классов Composer, чтобы он мог быстро найти нужный файл для загрузки конкретного класса:
- composer install --optimize-autoloader --no-dev
+```shell
+composer install --optimize-autoloader --no-dev
+```
> {tip} Помимо оптимизации автозагрузчика, вы всегда должны обязательно включать файл `composer.lock` в репозиторий системы управления версиями вашего проекта. Зависимости вашего проекта могут быть установлены намного быстрее, если присутствует файл `composer.lock`.
@@ -97,7 +103,9 @@
При развертывании вашего приложения в эксплуатационном окружении, вы должны убедиться, что вы выполнили команду `config:cache` Artisan в процессе развертывания:
- php artisan config:cache
+```shell
+php artisan config:cache
+```
Эта команда объединит все файлы конфигурации Laravel в один кешированный файл, что значительно сократит количество обращений, которые фреймворк должен совершить к файловой системе при загрузке значений вашей конфигурации.
@@ -108,7 +116,9 @@
Если вы создаете большое приложение с множеством маршрутов, вам следует убедиться, что вы выполнили команду `route:cache` Artisan в процессе развертывания:
- php artisan route:cache
+```shell
+php artisan route:cache
+```
Эта команда сокращает регистрации всех маршрутов до одного вызова метода в кешированном файле, повышая производительность при регистрации сотен маршрутов.
@@ -117,7 +127,9 @@
При развертывании вашего приложения в эксплуатационном окружении, вы должны убедиться, что вы выполнили команду `view:cache` Artisan в процессе развертывания:
- php artisan view:cache
+```shell
+php artisan view:cache
+```
Эта команда предварительно скомпилирует все ваши шаблоны Blade, чтобы они не компилировались во время запроса, повышая производительность каждого запроса, возвращающего шаблоном.
diff --git a/docs/documentation.md b/docs/documentation.md
index b580731..3d59305 100644
--- a/docs/documentation.md
+++ b/docs/documentation.md
@@ -89,4 +89,4 @@
- [Socialite](/docs/{{version}}/socialite)
- [Telescope](/docs/{{version}}/telescope)
- [Valet](/docs/{{version}}/valet)
-- [API Documentation](/api/8.x)
+- [API Documentation](/api/master)
diff --git a/docs/dusk.md b/docs/dusk.md
index 40666d6..86d19a7 100644
--- a/docs/dusk.md
+++ b/docs/dusk.md
@@ -58,13 +58,17 @@
Для начала установите [Google Chrome](https://www.google.com/chrome) и добавьте в зависимость `laravel/dusk` с помощью менеджера пакетов Composer в свой проект:
- composer require --dev laravel/dusk
+```shell
+composer require --dev laravel/dusk
+```
> {note} Если вы вручную регистрируете поставщика `DuskServiceProvider`, то вам **никогда** не следует регистрировать его в рабочем окружении, так как это может привести к тому, что случайные пользователи смогут пройти аутентификацию в вашем приложении.
После установки пакета Dusk выполните команду `dusk:install` Artisan. Команда `dusk:install` создаст каталог `tests/Browser` и пример теста Dusk:
- php artisan dusk:install
+```shell
+php artisan dusk:install
+```
Затем установите переменную окружения `APP_URL` в файле `.env` вашего приложения. Это значение должно соответствовать URL-адресу, который вы используете для доступа к вашему приложению в браузере.
@@ -75,17 +79,19 @@
Если вы хотите установить версию ChromeDriver, отличную от той, которая включена в Laravel Dusk, то вы можете использовать команду `dusk:chrome-driver`:
- # Установить последнюю версию ChromeDriver для вашей ОС ...
- php artisan dusk:chrome-driver
+```shell
+# Установить последнюю версию ChromeDriver для вашей ОС ...
+php artisan dusk:chrome-driver
- # Установить конкретную версию ChromeDriver для вашей ОС ...
- php artisan dusk:chrome-driver 86
+# Установить конкретную версию ChromeDriver для вашей ОС ...
+php artisan dusk:chrome-driver 86
- # Установить конкретную версию ChromeDriver для всех поддерживаемых ОС ...
- php artisan dusk:chrome-driver --all
+# Установить конкретную версию ChromeDriver для всех поддерживаемых ОС ...
+php artisan dusk:chrome-driver --all
- # Установить версию ChromeDriver, которая соответствует обнаруженной версии Chrome / Chromium для вашей ОС ...
- php artisan dusk:chrome-driver --detect
+# Установить версию ChromeDriver, которая соответствует обнаруженной версии Chrome / Chromium для вашей ОС ...
+php artisan dusk:chrome-driver --detect
+```
> {note} Dusk требует, чтобы файлы `chromedriver` были доступны для выполнения. Если у вас возникли проблемы с запуском Dusk, то вы должны убедиться, что файлы доступны для выполнения, используя следующую команду: `chmod -R 0755 vendor/laravel/dusk/bin/`.
@@ -129,7 +135,9 @@
Чтобы сгенерировать тест Dusk, используйте команду `dusk:make` Artisan. Сгенерированный тест будет помещен в каталог `tests/Browser`:
- php artisan dusk:make LoginTest
+```shell
+php artisan dusk:make LoginTest
+```
### Миграции базы данных
@@ -157,15 +165,21 @@
Чтобы запустить браузерные тесты, выполните команду `dusk` Artisan:
- php artisan dusk
+```shell
+php artisan dusk
+```
Если при последнем запуске команды `dusk` у вас были ошибки тестирования, то вы можете сэкономить время, повторно запустив сначала неудачные тесты с помощью команды `dusk:fails`:
- php artisan dusk:fails
+```shell
+php artisan dusk:fails
+```
Команда `dusk` принимает любой аргумент, который обычно принимается тестером PHPUnit, например, позволяет вам запускать тесты только для указанной [группы](https://phpunit.de/manual/current/en/appendixes.annotations.html#appendixes.annotations.group):
- php artisan dusk --group=foo
+```shell
+php artisan dusk --group=foo
+```
> {tip} Если вы используете [Laravel Sail](sail.md) для управления своей локальной средой разработки, обратитесь к документации Sail по [настройке и запуску тестов Dusk](sail.md#laravel-dusk).
@@ -1802,69 +1816,73 @@ Dusk даже позволяет вам делать утверждения о
Чтобы запустить тесты Dusk на [Travis CI](https://travis-ci.org), используйте следующую конфигурацию `.travis.yml`. Поскольку Travis CI не является графической средой, то нам нужно будет предпринять некоторые дополнительные шаги, чтобы запустить браузер Chrome. Кроме того, мы будем использовать `php artisan serve` для запуска встроенного веб-сервера PHP:
- language: php
+```yaml
+language: php
- php:
- - 7.3
+php:
+ - 7.3
- addons:
- chrome: stable
+addons:
+ chrome: stable
- install:
- - cp .env.testing .env
- - travis_retry composer install --no-interaction --prefer-dist
- - php artisan key:generate
- - php artisan dusk:chrome-driver
+install:
+ - cp .env.testing .env
+ - travis_retry composer install --no-interaction --prefer-dist
+ - php artisan key:generate
+ - php artisan dusk:chrome-driver
- before_script:
- - google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost &
- - php artisan serve --no-reload &
+before_script:
+ - google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost &
+ - php artisan serve --no-reload &
- script:
- - php artisan dusk
+script:
+ - php artisan dusk
+```
### GitHub Actions
Если вы используете [Github Actions](https://github.com/features/actions) для запуска тестов Dusk, то вы можете использовать следующий конфигурационный файл в качестве отправной точки. Как и в случае с TravisCI, мы будем использовать команду `php artisan serve` для запуска встроенного веб-сервера PHP:
- name: CI
- on: [push]
- jobs:
-
- dusk-php:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
- - name: Prepare The Environment
- run: cp .env.example .env
- - name: Create Database
- run: |
- sudo systemctl start mysql
- mysql --user="root" --password="root" -e "CREATE DATABASE 'my-database' character set UTF8mb4 collate utf8mb4_bin;"
- - name: Install Composer Dependencies
- run: composer install --no-progress --prefer-dist --optimize-autoloader
- - name: Generate Application Key
- run: php artisan key:generate
- - name: Upgrade Chrome Driver
- run: php artisan dusk:chrome-driver `/opt/google/chrome/chrome --version | cut -d " " -f3 | cut -d "." -f1`
- - name: Start Chrome Driver
- run: ./vendor/laravel/dusk/bin/chromedriver-linux &
- - name: Run Laravel Server
- run: php artisan serve --no-reload &
- - name: Run Dusk Tests
- env:
- APP_URL: "http://127.0.0.1:8000"
- run: php artisan dusk
- - name: Upload Screenshots
- if: failure()
- uses: actions/upload-artifact@v2
- with:
- name: screenshots
- path: tests/Browser/screenshots
- - name: Upload Console Logs
- if: failure()
- uses: actions/upload-artifact@v2
- with:
- name: console
- path: tests/Browser/console
+```yaml
+name: CI
+on: [push]
+jobs:
+
+ dusk-php:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Prepare The Environment
+ run: cp .env.example .env
+ - name: Create Database
+ run: |
+ sudo systemctl start mysql
+ mysql --user="root" --password="root" -e "CREATE DATABASE 'my-database' character set UTF8mb4 collate utf8mb4_bin;"
+ - name: Install Composer Dependencies
+ run: composer install --no-progress --prefer-dist --optimize-autoloader
+ - name: Generate Application Key
+ run: php artisan key:generate
+ - name: Upgrade Chrome Driver
+ run: php artisan dusk:chrome-driver `/opt/google/chrome/chrome --version | cut -d " " -f3 | cut -d "." -f1`
+ - name: Start Chrome Driver
+ run: ./vendor/laravel/dusk/bin/chromedriver-linux &
+ - name: Run Laravel Server
+ run: php artisan serve --no-reload &
+ - name: Run Dusk Tests
+ env:
+ APP_URL: "http://127.0.0.1:8000"
+ run: php artisan dusk
+ - name: Upload Screenshots
+ if: failure()
+ uses: actions/upload-artifact@v2
+ with:
+ name: screenshots
+ path: tests/Browser/screenshots
+ - name: Upload Console Logs
+ if: failure()
+ uses: actions/upload-artifact@v2
+ with:
+ name: console
+ path: tests/Browser/console
+```
diff --git a/docs/eloquent-mutators.md b/docs/eloquent-mutators.md
index 6e3b8c5..cf0721f 100644
--- a/docs/eloquent-mutators.md
+++ b/docs/eloquent-mutators.md
@@ -28,30 +28,34 @@
### Определение аксессора
-Аксессор преобразует значение атрибута экземпляра Eloquent при обращении к нему. Чтобы определить метод доступа, создайте метод `get{Attribute}Attribute` в вашей модели, где `{Attribute}` – это имя столбца, к которому вы хотите получить доступ, в «верхнем» регистре.
+Аксессор преобразует значение атрибута экземпляра Eloquent при обращении к нему. Чтобы определить метод доступа, создайте в модели защищенный метод для представления доступного атрибута. Это имя метода должно соответствовать атрибуту модели / столбца базы данных в «верблюжьем регистре» , когда это применимо.
-В этом примере мы определим аксессор для атрибута `first_name`. Аксессор будет автоматически вызван Eloquent при попытке получить значение атрибута `first_name`:
+В этом примере мы определим аксессор для атрибута `first_name`. Аксессор будет автоматически вызван Eloquent при попытке получить значение атрибута `first_name`. Все методы атрибутов (аксессоры / мутаторы) должны возвращать тип `Illuminate\Database\Eloquent\Casts\Attribute`:
ucfirst($value),
+ );
}
}
+Все методы доступа возвращают экземпляр `Attribute`, который определяет, как будет осуществляться доступ к атрибуту и, при необходимости, изменяться. В этом примере мы только определяем, как будет осуществляться доступ к атрибуту. Для этого мы передаем аргумент `get` конструктору класса `Attribute`.
+
Как видите, исходное значение столбца передается аксессору, что позволяет вам манипулировать и возвращать значение. Чтобы получить доступ к значению аксессора, вы можете просто получить доступ к атрибуту `first_name` экземпляра модели:
use App\Models\User;
@@ -60,48 +64,93 @@
$firstName = $user->first_name;
-Вы не ограничены взаимодействием с одним атрибутом в вашем аксессоре. Вы также можете использовать аксессор для возврата новых вычисленных значений из существующих атрибутов:
+> {tip} Если вы хотите, чтобы эти вычисленные значения были добавлены к представлениям массива / JSON вашей модели, [вам нужно будет добавить их](eloquent-serialization.md#appending-values-to-json).
- /**
- * Получить полное имя пользователя.
- *
- * @return string
- */
- public function getFullNameAttribute()
- {
- return "{$this->first_name} {$this->last_name}";
- }
+
+#### Построение объекта-значения из нескольких атрибутов
+
+Иногда аксессору может потребоваться преобразовать несколько атрибутов модели в один «объект-значение». Для этого ваше замыкание `get` может принимать второй аргумент `$attributes`, который будет автоматически передан замыканию и будет содержать массив всех текущих атрибутов модели:
+
+```php
+use App\Support\Address;
+use Illuminate\Database\Eloquent\Casts\Attribute;
+
+/**
+ * Взаимодействие с адресом пользователя.
+ *
+ * @return \Illuminate\Database\Eloquent\Casts\Attribute
+ */
+public function address(): Attribute
+{
+ return new Attribute(
+ get: fn ($value, $attributes) => new Address(
+ $attributes['address_line_one'],
+ $attributes['address_line_two'],
+ ),
+ );
+}
+```
+
+При возврате объектов-значений из аксессоров любые изменения, внесенные в объект-значение, будут автоматически синхронизированы с моделью перед ее сохранением. Это возможно, потому что Eloquent сохраняет экземпляры, возвращаемые аксессорами, поэтому он может возвращать один и тот же экземпляр каждый раз, когда вызывается аксессор:
-> {tip} Если вы хотите, чтобы эти вычисленные значения были добавлены к представлениям массива / JSON вашей модели, [вам нужно будет добавить их](eloquent-serialization.md#appending-values-to-json).
+ use App\Models\User;
+
+ $user = User::find(1);
+
+ $user->address->lineOne = 'Updated Address Line 1 Value';
+ $user->address->lineTwo = 'Updated Address Line 2 Value';
+
+ $user->save();
+
+Если вы хотите избежать кэширования объектов в атрибутах, то вы можете вызвать метод `withoutObjectCaching` при определении атрибута:
+
+```php
+/**
+ * Взаимодействие с адресом пользователя.
+ *
+ * @return \Illuminate\Database\Eloquent\Casts\Attribute
+ */
+public function address(): Attribute
+{
+ return (new Attribute(
+ get: fn ($value, $attributes) => new Address(
+ $attributes['address_line_one'],
+ $attributes['address_line_two'],
+ ),
+ ))->withoutObjectCaching();
+}
+```
### Определение мутатора
-Мутатор преобразует значение атрибута в момент их присвоения экземпляру Eloquent. Чтобы определить мутатор, определите метод `set{Attribute}Attribute` в вашей модели, где `{Attribute}` – это имя столбца, к которому вы хотите получить доступ, в «верхнем» регистре.
-
-Определим мутатор для атрибута `first_name`. Этот мутатор будет автоматически вызываться, когда мы попытаемся присвоить значение атрибута `first_name` модели:
+Мутатор преобразует значение атрибута в момент их присвоения экземпляру Eloquent. Чтобы определить мутатор, вы можете указать аргумент `set` при определении вашего атрибута. Определим мутатор для атрибута `first_name`. Этот мутатор будет автоматически вызываться, когда мы попытаемся присвоить значение атрибута `first_name` модели:
attributes['first_name'] = strtolower($value);
+ return new Attribute(
+ get: fn ($value) => ucfirst($value),
+ set: fn ($value) => strtolower($value),
+ );
}
}
-Мутатор получит значение, заданное для атрибута, что позволит вам манипулировать этим значением и устанавливать желаемое значение во внутреннем свойстве `$attributes` модели Eloquent. Чтобы использовать наш мутатор, нам нужно только установить атрибут `first_name` для модели Eloquent:
+Замыкание мутатора получит значение, которое устанавливается для атрибута, позволяя вам манипулировать значением и возвращать измененное значение. Чтобы использовать наш мутатор, нам нужно только установить атрибут `first_name` для модели Eloquent:
use App\Models\User;
@@ -109,7 +158,36 @@
$user->first_name = 'Sally';
-В этом примере метод `setFirstNameAttribute` будет вызываться со значением `Sally`. Затем, мутатор применит к имени функцию `strtolower` и установит полученное значение во внутреннем массиве `$attributes`.
+В этом примере замыкание `set` будет вызвано со значением `Sally`. Затем мутатор применит к имени функцию `strtolower` и установит полученное значение во внутреннем массиве `$attributes` модели.
+
+
+#### Преобразование нескольких атрибутов
+
+Иногда мутатору может потребоваться установить несколько атрибутов модели. Для этого вы можете вернуть массив из замыкания `set`. Каждый ключ в массиве должен соответствовать атрибуту / столбцу базы данных, связанному с моделью:
+
+```php
+use App\Support\Address;
+use Illuminate\Database\Eloquent\Casts\Attribute;
+
+/**
+ * Взаимодействие с адресом пользователя.
+ *
+ * @return \Illuminate\Database\Eloquent\Casts\Attribute
+ */
+protected function address(): Attribute
+{
+ return new Attribute(
+ get: fn ($value, $attributes) => new Address(
+ $attributes['address_line_one'],
+ $attributes['address_line_two'],
+ ),
+ set: fn (Address $value) => [
+ 'address_line_one' => $value->lineOne,
+ 'address_line_two' => $value->lineTwo,
+ ],
+ );
+}
+```
## Приведение атрибутов к типам
diff --git a/docs/eloquent-resources.md b/docs/eloquent-resources.md
index de4dbb6..e9a5c57 100644
--- a/docs/eloquent-resources.md
+++ b/docs/eloquent-resources.md
@@ -24,7 +24,9 @@
Ресурсы расширяют класс `Illuminate\Http\Resources\Json\JsonResource`. Чтобы сгенерировать новый ресурс, используйте команду `make:resource` [Artisan](artisan.md). Эта команда поместит новый класс ресурса в каталог `app/Http/Resources` вашего приложения:
- php artisan make:resource UserResource
+```shell
+php artisan make:resource UserResource
+```
#### Генерация коллекций ресурса
@@ -33,9 +35,11 @@
Чтобы сгенерировать новую коллекцию ресурса, вы должны использовать флаг `--collection` при создании ресурса. Или включение слова `Collection` в имя ресурса укажет Laravel, что он должен создать коллекцию ресурса. Коллекции ресурса расширяют класс `Illuminate\Http\Resources\Json\ResourceCollection`:
- php artisan make:resource User --collection
+```shell
+php artisan make:resource User --collection
- php artisan make:resource UserCollection
+php artisan make:resource UserCollection
+```
## Обзор концепции
@@ -95,7 +99,9 @@
Обратите внимание, что это не позволит добавить пользовательские метаданные, которые могут потребоваться при возвращении с вашей коллекцией. Если вы хотите получить больший контроль над ответом коллекции ресурса, то вы можете создать выделенный ресурс для представления коллекции:
- php artisan make:resource UserCollection
+```shell
+php artisan make:resource UserCollection
+```
После создания класса коллекции ресурса, вы можете легко определить любые метаданные, которые должны быть включены в ответ:
@@ -308,20 +314,22 @@
По умолчанию, ваш самый верхний ресурс будет заключен в ключ `data`, когда ответ ресурса преобразуется в JSON. Так, например, типичный ответ коллекции ресурса выглядит следующим образом:
- {
- "data": [
- {
- "id": 1,
- "name": "Eladio Schroeder Sr.",
- "email": "therese28@example.com",
- },
- {
- "id": 2,
- "name": "Liliana Mayert",
- "email": "evandervort@example.com",
- }
- ]
- }
+```json
+{
+ "data": [
+ {
+ "id": 1,
+ "name": "Eladio Schroeder Sr.",
+ "email": "therese28@example.com",
+ },
+ {
+ "id": 2,
+ "name": "Liliana Mayert",
+ "email": "evandervort@example.com",
+ }
+ ]
+}
+```
Если вы хотите использовать собственный ключ вместо `data`, вы можете определить свойство `$wrap` в классе ресурса:
@@ -407,35 +415,37 @@
При возврате разбитых на страницы коллекций через ответ ресурса, Laravel обернет ваши данные ресурса в ключ `data`, даже если был вызван метод `withoutWrapping`. Это потому, что разбитые на страницы ответы всегда содержат ключи `meta` и `links` с информацией о состоянии постраничной разбивки:
- {
- "data": [
- {
- "id": 1,
- "name": "Eladio Schroeder Sr.",
- "email": "therese28@example.com",
- },
- {
- "id": 2,
- "name": "Liliana Mayert",
- "email": "evandervort@example.com",
- }
- ],
- "links":{
- "first": "http://example.com/pagination?page=1",
- "last": "http://example.com/pagination?page=1",
- "prev": null,
- "next": null
+```json
+{
+ "data": [
+ {
+ "id": 1,
+ "name": "Eladio Schroeder Sr.",
+ "email": "therese28@example.com",
},
- "meta":{
- "current_page": 1,
- "from": 1,
- "last_page": 1,
- "path": "http://example.com/pagination",
- "per_page": 15,
- "to": 10,
- "total": 10
+ {
+ "id": 2,
+ "name": "Liliana Mayert",
+ "email": "evandervort@example.com",
}
+ ],
+ "links":{
+ "first": "http://example.com/pagination?page=1",
+ "last": "http://example.com/pagination?page=1",
+ "prev": null,
+ "next": null
+ },
+ "meta":{
+ "current_page": 1,
+ "from": 1,
+ "last_page": 1,
+ "path": "http://example.com/pagination",
+ "per_page": 15,
+ "to": 10,
+ "total": 10
}
+}
+```
### Постраничная разбивка
@@ -451,35 +461,37 @@
Ответы с постраничной разбивкой всегда содержат ключи `meta` и `links` с информацией о состоянии пагинатора:
- {
- "data": [
- {
- "id": 1,
- "name": "Eladio Schroeder Sr.",
- "email": "therese28@example.com",
- },
- {
- "id": 2,
- "name": "Liliana Mayert",
- "email": "evandervort@example.com",
- }
- ],
- "links":{
- "first": "http://example.com/pagination?page=1",
- "last": "http://example.com/pagination?page=1",
- "prev": null,
- "next": null
+```json
+{
+ "data": [
+ {
+ "id": 1,
+ "name": "Eladio Schroeder Sr.",
+ "email": "therese28@example.com",
},
- "meta":{
- "current_page": 1,
- "from": 1,
- "last_page": 1,
- "path": "http://example.com/pagination",
- "per_page": 15,
- "to": 10,
- "total": 10
+ {
+ "id": 2,
+ "name": "Liliana Mayert",
+ "email": "evandervort@example.com",
}
+ ],
+ "links":{
+ "first": "http://example.com/pagination?page=1",
+ "last": "http://example.com/pagination?page=1",
+ "prev": null,
+ "next": null
+ },
+ "meta":{
+ "current_page": 1,
+ "from": 1,
+ "last_page": 1,
+ "path": "http://example.com/pagination",
+ "per_page": 15,
+ "to": 10,
+ "total": 10
}
+}
+```
### Условные атрибуты
diff --git a/docs/eloquent-serialization.md b/docs/eloquent-serialization.md
index 58b0350..937e4b1 100644
--- a/docs/eloquent-serialization.md
+++ b/docs/eloquent-serialization.md
@@ -130,6 +130,7 @@
namespace App\Models;
+ use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
class User extends Model
@@ -137,11 +138,13 @@
/**
* Определить, является ли пользователь администратором.
*
- * @return bool
+ * @return \Illuminate\Database\Eloquent\Casts\Attribute
*/
- public function getIsAdminAttribute()
+ protected function isAdmin(): Attribute
{
- return $this->attributes['admin'] === 'yes';
+ return new Attribute(
+ get: fn () => 'yes';
+ );
}
}
diff --git a/docs/eloquent.md b/docs/eloquent.md
index 100895e..2d61f1c 100644
--- a/docs/eloquent.md
+++ b/docs/eloquent.md
@@ -11,7 +11,7 @@
- [Получение моделей](#retrieving-models)
- [Коллекции](#collections)
- [Разбиение результатов](#chunking-results)
- - [Отложенная потоковая передача результатов](#streaming-results-lazily)
+ - [Разбиение результатов с отложенными коллекциями](#chunking-using-lazy-collections)
- [Курсоры](#cursors)
- [Расширенные подзапросы](#advanced-subqueries)
- [Извлечение отдельных моделей](#retrieving-single-models)
@@ -48,15 +48,19 @@ Laravel содержит библиотеку Eloquent ORM (объектно-р
Модели расширяют класс `Illuminate\Database\Eloquent\Model`. Чтобы сгенерировать новую модель Eloquent, используйте команду `make:model` [Artisan](artisan.md). Эта команда поместит новый класс модели в каталог `app/Models` вашего приложения:
- php artisan make:model Flight
+```shell
+php artisan make:model Flight
+```
При создании модели вы можете сгенерировать [миграцию БД](migrations.md), используя параметр `--migration` или `-m`:
- php artisan make:model Flight --migration
+```shell
+php artisan make:model Flight --migration
+```
При создании модели вы можете попутно генерировать различные типы классов, например фабрики, наполнители, политики авторизации, контроллеры и запросы форм. Кроме того, эти параметры можно комбинировать для создания сразу нескольких классов:
-```bash
+```shell
# Создать модель и класс FlightFactory ...
php artisan make:model Flight --factory
php artisan make:model Flight -f
@@ -367,8 +371,8 @@ Flight::where('departed', true)
}, $column = 'id');
```
-
-### Отложенная потоковая передача результатов
+
+### Разбиение результатов с отложенными коллекциями
Метод `lazy` работает аналогично [методу `chunk`](#chunking-results) в том смысле, что он выполняет запрос по частям. Однако вместо передачи каждого фрагмента непосредственно в замыкание, метод `lazy()` возвращает экземпляр [`LazyCollection`](collections.md#lazy-collections) одноуровневых моделей Eloquent, что позволяет вам взаимодействовать с результатами как с единым потоком:
@@ -954,7 +958,9 @@ Eloquent содержит методы `isDirty`, `isClean` и `wasChanged` дл
Вы можете сымитировать свой запрос очистки, выполнив команду `model:prune` с флагом `--pretend`. При имитации команда `model:prune` просто сообщит, сколько записей будет удалено, если команда действительно будет запущена:
- php artisan model:prune --pretend
+```shell
+php artisan model:prune --pretend
+```
> {note} Программно удаляемые модели будут удалены (`forceDelete`) без возможности восстановления, если они соответствуют запросу сокращения.
@@ -1325,7 +1331,9 @@ Eloquent также позволяет вам определять глобал
Если прослушивается множество событий в модели, то можно использовать наблюдателей, чтобы сгруппировать пользовательских слушателей в одном классе. Классы наблюдателей имеют имена методов, созвучные событиям Eloquent, которые необходимо прослушивать. Каждый из этих методов получает затронутую модель в качестве единственного аргумента. Чтобы сгенерировать нового наблюдателя, используйте команду `make:observer` [Artisan](artisan.md):
- php artisan make:observer UserObserver --model=User
+```shell
+php artisan make:observer UserObserver --model=User
+```
Эта команда поместит новый класс наблюдателя в каталог `app/Observers` вашего приложения. Если этот каталог не существует в вашем приложении, то Laravel предварительно создаст его. Созданный наблюдатель может выглядеть следующим образом:
@@ -1397,6 +1405,20 @@ Eloquent также позволяет вам определять глобал
User::observe(UserObserver::class);
}
+Кроме того, вы можете перечислить своих наблюдателей в свойстве `$observers` класса `App\Providers\EventServiceProvider` вашего приложения:
+
+ use App\Models\User;
+ use App\Observers\UserObserver;
+
+ /**
+ * Наблюдатели моделей вашего приложения.
+ *
+ * @var array
+ */
+ protected $observers = [
+ User::class => [UserObserver::class],
+ ];
+
> {tip} Наблюдатель может прослушивать дополнительные события, такие как `saving` и `retrieved`. Эти события описаны в документации [событий](#events).
diff --git a/docs/envoy.md b/docs/envoy.md
index f7091df..f826728 100644
--- a/docs/envoy.md
+++ b/docs/envoy.md
@@ -27,11 +27,15 @@
Для начала установите Envoy с помощью менеджера пакетов Composer в свой проект:
- composer require laravel/envoy --dev
+```shell
+composer require laravel/envoy --dev
+```
После установки исполняемый файл Envoy будет доступен в каталоге вашего приложения `vendor/bin`:
- php vendor/bin/envoy
+```shell
+php vendor/bin/envoy
+```
## Написание задач
@@ -43,7 +47,7 @@
Все ваши задачи Envoy должны быть определены в файле `Envoy.blade.php` в корне вашего приложения. Например:
-```bash
+```blade
@servers(['web' => ['user@192.168.1.1'], 'workers' => ['user@192.168.1.2']])
@task('restart-queues', ['on' => 'workers'])
@@ -59,7 +63,7 @@
Вы можете принудительно запустить сценарий на вашем локальном компьютере, указав IP-адрес сервера как `127.0.0.1`:
-```bash
+```blade
@servers(['localhost' => '127.0.0.1'])
```
@@ -68,7 +72,7 @@
Используя директиву `@import`, вы можете импортировать другие файлы Envoy для добавления дополнительных историй и задач. После того, как файлы были импортированы, вы можете выполнять задачи, содержащиеся в них, как если бы они были определены в вашем собственном файле Envoy:
-```bash
+```blade
@import('vendor/package/Envoy.blade.php')
```
@@ -77,7 +81,7 @@
Envoy позволяет легко запускать задачу на нескольких серверах. Во-первых, добавьте необходимые серверы в объявление `@servers`. Каждому серверу должно быть присвоено уникальное имя. После определения дополнительных серверов, вы можете использовать каждый из них в массиве задачи `on`:
-```bash
+```blade
@servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2'])
@task('deploy', ['on' => ['web-1', 'web-2']])
@@ -92,7 +96,7 @@ Envoy позволяет легко запускать задачу на нес
По умолчанию задачи будут выполняться на каждом сервере поочередно. Другими словами, задача должна завершится на первом сервере, прежде чем будет выполнена на втором. Если вы хотите запустить задачу на нескольких серверах параллельно, то добавьте параметр `parallel` в определение задачи:
-```bash
+```blade
@servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2'])
@task('deploy', ['on' => ['web-1', 'web-2'], 'parallel' => true])
@@ -115,7 +119,7 @@ Envoy позволяет легко запускать задачу на нес
Если вам нужны другие файлы PHP перед выполнением вашей задачи, то вы можете использовать директиву `@include` в верхней части вашего файла `Envoy.blade.php`:
-```bash
+```blade
@include('vendor/autoload.php')
@task('restart-queues')
@@ -128,11 +132,13 @@ Envoy позволяет легко запускать задачу на нес
При необходимости вы можете передать аргументы задачам Envoy, указав их в командной строке при вызове Envoy:
- php vendor/bin/envoy run deploy --branch=master
+```shell
+php vendor/bin/envoy run deploy --branch=master
+```
Вы можете получить доступ к параметрам ваших задач, используя [синтаксис «вывода» Blade](blade.md#displaying-data). Вы также можете определять операторы `if` и циклы Blade в своих задачах. Например, давайте проверим наличие переменной `$branch` перед выполнением команды `git pull`:
-```bash
+```blade
@servers(['web' => ['user@192.168.1.1']])
@task('deploy', ['on' => 'web'])
@@ -151,7 +157,7 @@ Envoy позволяет легко запускать задачу на нес
Истории группируют набор задач под одним удобным названием. Например, вы можете сгруппировать запуск задач `update-code` и `install-dependencies`, перечислив их имена в определении истории `deploy`:
-```bash
+```blade
@servers(['web' => ['user@192.168.1.1']])
@story('deploy')
@@ -172,7 +178,9 @@ Envoy позволяет легко запускать задачу на нес
После написания история, вы можете запустить ее так же, как вы запускаете отдельную задачу:
- php vendor/bin/envoy run deploy
+```shell
+php vendor/bin/envoy run deploy
+```
### Хуки
@@ -186,7 +194,7 @@ Envoy позволяет легко запускать задачу на нес
Перед выполнением каждой задачи будут выполняться все хуки `@before`, зарегистрированные в вашем сценарии Envoy. Хуки `@before` получат имя задачи, которая будет выполняться:
-```php
+```blade
@before
if ($task === 'deploy') {
// ...
@@ -199,7 +207,7 @@ Envoy позволяет легко запускать задачу на нес
После выполнения каждой задачи будут выполняться все хуки `@after`, зарегистрированные в вашем сценарии Envoy. Хуки `@after` получат имя запущенной задачи:
-```php
+```blade
@after
if ($task === 'deploy') {
// ...
@@ -212,7 +220,7 @@ Envoy позволяет легко запускать задачу на нес
После каждого сбоя задачи (выход с кодом состояния больше `0`) будут выполняться все хуки `@error`, зарегистрированные в вашем сценарии Envoy. Хуки `@error` получат имя запущенной задачи:
-```php
+```blade
@error
if ($task === 'deploy') {
// ...
@@ -225,7 +233,7 @@ Envoy позволяет легко запускать задачу на нес
Если все задачи выполнены без ошибок, то все хуки `@success`, зарегистрированные в вашем сценарии Envoy, будут выполнены:
-```bash
+```blade
@success
// ...
@endsuccess
@@ -236,7 +244,7 @@ Envoy позволяет легко запускать задачу на нес
После выполнения всех задач (независимо от статуса выхода) будут выполнены все хуки `@finished`. Хуки `@finished` получат код состояния завершенной задачи, который может быть `null` или `integer`, большим или равным `0`:
-```bash
+```blade
@finished
if ($exitCode > 0) {
// В одной из задач произошли ошибки ...
@@ -249,14 +257,16 @@ Envoy позволяет легко запускать задачу на нес
Чтобы запустить задачу или историю, которая определена в файле `Envoy.blade.php` вашего приложения, выполните команду `run` Envoy, передав имя задачи или истории, которую вы хотите выполнить. Envoy выполнит задачу и отобразит вывод с ваших удаленных серверов во время выполнения задачи:
- php vendor/bin/envoy run deploy
+```shell
+php vendor/bin/envoy run deploy
+```
### Подтверждение выполнения задачи
Если вы хотите получить запрос на подтверждение перед запуском конкретной задачи на своих серверах, вам следует добавить параметр `confirm` в директиву определения задачи. Этот параметр особенно полезен для деструктивных операций:
-```bash
+```blade
@task('deploy', ['on' => 'web', 'confirm' => true])
cd /home/user/example.com
git pull origin {{ $branch }}
@@ -274,39 +284,49 @@ Envoy поддерживает отправку уведомлений в [Slack
Вы должны передать полный WebHook URL в качестве первого аргумента директивы `@slack`. Вторым аргументом, передаваемым директиве `@slack`, должно быть имя канала `#channel` или имя пользователя `@user`:
- @finished
- @slack('webhook-url', '#bots')
- @endfinished
+```blade
+@finished
+ @slack('webhook-url', '#bots')
+@endfinished
+```
По умолчанию уведомления Envoy отправляют сообщение в канал уведомлений с описанием выполненной задачи. Однако вы можете назначить свое сообщение, передав третий аргумент директиве `@slack`:
- @finished
- @slack('webhook-url', '#bots', 'Hello, Slack.')
- @endfinished
+```blade
+@finished
+ @slack('webhook-url', '#bots', 'Hello, Slack.')
+@endfinished
+```
### Discord
Envoy также поддерживает отправку уведомлений в [Discord](https://discord.com) после выполнения каждой задачи. Директива `@discord` принимает WebHook URL и сообщение. Вы можете получить WebHook URL, создав «Webhook» в настройках сервера и выбрав канал, на который WebHook должен публиковать сообщения. Вы должны передать полный WebHook URL в директиву `@discord`:
- @finished
- @discord('discord-webhook-url')
- @endfinished
+```blade
+@finished
+ @discord('discord-webhook-url')
+@endfinished
+```
### Telegram
Envoy также поддерживает отправку уведомлений в [Telegram](https://telegram.org) после выполнения каждой задачи. Директива `@telegram` принимает идентификатор бота Telegram и идентификатор чата. Вы можете получить свой идентификатор бота, создав нового бота в [BotFather](https://t.me/botfather). Вы можете получить действительный идентификатор чата, используя [`@username_to_id_bot`](https://t.me/username_to_id_bot). Вы должны передать полный идентификатор бота и идентификатор чата в директиву `@telegram`:
- @finished
- @telegram('bot-id','chat-id')
- @endfinished
+```blade
+@finished
+ @telegram('bot-id','chat-id')
+@endfinished
+```
### Microsoft Teams
Envoy также поддерживает отправку уведомлений в [Microsoft Teams](https://www.microsoft.com/en-us/microsoft-teams) после выполнения каждой задачи. Директива `@microsoftTeams` принимает веб-хук Teams (обязательно), сообщение, цвет темы (по типу сообщения: успешно, информация, предупреждение, ошибка) и массив параметров. Вы можете получить веб-хук Teams, создав новый [входящий веб-хук](https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook). В Teams API есть множество других атрибутов для настройки сообщения, например заголовок, сводка и разделы. Дополнительную информацию можно найти в [документации Microsoft Teams](https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-using?tabs=cURL#example-of-connector-message). Вы должны передать полный URL-адрес веб-хука в директиву `@microsoftTeams`:
- @finished
- @microsoftTeams('webhook-url')
- @endfinished
+```blade
+@finished
+ @microsoftTeams('webhook-url')
+@endfinished
+```
diff --git a/docs/errors.md b/docs/errors.md
index d09fdd0..0d0d32c 100644
--- a/docs/errors.md
+++ b/docs/errors.md
@@ -258,4 +258,11 @@ Laravel позволяет легко отображать пользовате
Вы можете опубликовать стандартные шаблоны страниц ошибок Laravel с помощью команды `vendor:publish` Artisan. После публикации шаблонов вы можете настроить их по своему вкусу:
- php artisan vendor:publish --tag=laravel-errors
+```shell
+php artisan vendor:publish --tag=laravel-errors
+```
+
+
+#### Резервные страницы ошибок HTTP
+
+Вы также можете определить «резервную» страницу ошибок для каждой серии кодов состояния HTTP. Эта страница будет отображаться, если нет соответствующей страницы для текущего кода состояния HTTP. Для этого определите шаблон `4xx.blade.php` и шаблон `5xx.blade.php` в каталоге `resources/views/errors` вашего приложения.
diff --git a/docs/events.md b/docs/events.md
index 926c241..03c6687 100644
--- a/docs/events.md
+++ b/docs/events.md
@@ -49,13 +49,17 @@
Конечно, вручную создавать файлы для каждого события и слушателя сложно. Вместо этого добавьте необходимые события и их слушатели в поставщике `App\Providers\EventServiceProvider`, затем, используйте команду `event:generate` [Artisan](artisan.md). Эта команда сгенерирует любые события или слушатели, перечисленные в поставщике `EventServiceProvider`, но которые еще не существуют:
- php artisan event:generate
+```shell
+php artisan event:generate
+```
В качестве альтернативы вы можете использовать команды `make:event` и `make:listener` Artisan для генерации отдельных событий и слушателей:
- php artisan make:event PodcastProcessed
+```shell
+php artisan make:event PodcastProcessed
- php artisan make:listener SendPodcastNotification --event=PodcastProcessed
+php artisan make:listener SendPodcastNotification --event=PodcastProcessed
+```
### Явная регистрация событий
@@ -137,7 +141,7 @@
Вместо того, чтобы вручную регистрировать события и слушателей в массиве `$listen` поставщика `EventServiceProvider`, вы можете включить автоматическое обнаружение событий. Когда обнаружение событий включено, Laravel автоматически найдет и зарегистрирует ваши события и слушатели, сканируя каталог `Listeners` вашего приложения. Кроме того, любые явно определенные события, перечисленные в `EventServiceProvider`, по-прежнему будут зарегистрированы.
-Laravel находит слушателей событий, сканируя классы слушателей с помощью рефлексии PHP. Когда Laravel находит какой-либо метод класса слушателя, который начинается с `handle`, Laravel зарегистрирует эти методы как слушатели событий для события, тип которого указан в сигнатуре метода:
+Laravel находит слушателей событий, сканируя классы слушателей с помощью рефлексии PHP. Когда Laravel находит какой-либо метод класса слушателя, который начинается с `handle` или `__invoke`, Laravel зарегистрирует эти методы как слушатели событий для события, тип которого указан в сигнатуре метода:
use App\Events\PodcastProcessed;
diff --git a/docs/filesystem.md b/docs/filesystem.md
index 5a9aa56..3d8977b 100644
--- a/docs/filesystem.md
+++ b/docs/filesystem.md
@@ -6,7 +6,6 @@
- [Публичный диск](#the-public-disk)
- [Предварительная подготовка драйверов](#driver-prerequisites)
- [Файловые системы, совместимые с Amazon S3](#amazon-s3-compatible-filesystems)
- - [Кеширование](#caching)
- [Доступ к экземплярам дисков](#obtaining-disk-instances)
- [Диски по запросу](#on-demand-disks)
- [Получение файлов](#retrieving-files)
@@ -52,7 +51,9 @@ Laravel обеспечивает мощную абстракцию файлов
Чтобы создать символическую ссылку, вы можете использовать команду `storage:link` Artisan:
- php artisan storage:link
+```shell
+php artisan storage:link
+```
После того, как была создана символическая ссылка, вы можете создавать URL-адреса для сохраненных файлов, используя помощник `asset`:
@@ -73,12 +74,8 @@ Laravel обеспечивает мощную абстракцию файлов
Перед использованием драйверов S3 или SFTP вам необходимо установить соответствующий пакет с помощью менеджера пакетов Composer:
-- Amazon S3: `composer require --with-all-dependencies league/flysystem-aws-s3-v3 "^1.0"`
-- SFTP: `composer require league/flysystem-sftp "~1.0"`
-
-Кроме того, вы можете установить декоратор CachedAdapter для повышения производительности:
-
-- CachedAdapter: `composer require league/flysystem-cached-adapter "~1.0"`
+- Amazon S3: `composer require --with-all-dependencies league/flysystem-aws-s3-v3 "^3.0"`
+- SFTP: `composer require league/flysystem-sftp-v3 "^3.0"`
#### Конфигурирование драйвера S3
@@ -136,23 +133,6 @@ Laravel обеспечивает мощную абстракцию файлов
'endpoint' => env('AWS_ENDPOINT', 'https://minio:9000'),
-
-### Кеширование
-
-Чтобы включить кеширование для конкретного диска, вы можете добавить директиву `cache` в параметры конфигурации этого диска. Параметр `cache` должен быть массивом параметров кеширования, содержащим имя `disk`, время `expire` в секундах и `prefix` кеша:
-
- 's3' => [
- 'driver' => 's3',
-
- // Other Disk Options...
-
- 'cache' => [
- 'store' => 'memcached',
- 'expire' => 600,
- 'prefix' => 'cache-prefix',
- ],
- ],
-
## Доступ к экземплярам дисков
@@ -550,7 +530,9 @@ $disk->put('image.jpg', $content);
Чтобы определить собственную файловую систему, вам понадобится адаптер Flysystem. Давайте добавим в наш проект адаптер Dropbox, поддерживаемый сообществом:
- composer require spatie/flysystem-dropbox
+```shell
+composer require spatie/flysystem-dropbox
+```
Затем вы можете зарегистрировать драйвер в методе `boot` одного из [поставщиков служб](providers.md) вашего приложения. Для этого вы должны использовать метод `extend` фасада `Storage`:
@@ -558,6 +540,7 @@ $disk->put('image.jpg', $content);
namespace App\Providers;
+ use Illuminate\Filesystem\FilesystemAdapter;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\ServiceProvider;
use League\Flysystem\Filesystem;
@@ -584,15 +567,19 @@ $disk->put('image.jpg', $content);
public function boot()
{
Storage::extend('dropbox', function ($app, $config) {
- $client = new DropboxClient(
+ $adapter = new DropboxAdapter(new DropboxClient(
$config['authorization_token']
- );
+ ););
- return new Filesystem(new DropboxAdapter($client));
+ return new FilesystemAdapter(
+ new Filesystem($adapter, $config),
+ $adapter,
+ $config
+ );
});
}
}
-Первый аргумент метода `extend` – это имя драйвера, а второй – замыкание, которое получает переменные `$app` и `$config`. Замыкание должно возвращать экземпляр `League\Flysystem\Filesystem`. Переменная `$config` содержит значения, определенные в `config/filesystems.php` для указанного диска.
+Первый аргумент метода `extend` – это имя драйвера, а второй – замыкание, которое получает переменные `$app` и `$config`. Замыкание должно возвращать экземпляр `Illuminate\Filesystem\FilesystemAdapter`. Переменная `$config` содержит значения, определенные в `config/filesystems.php` для указанного диска.
После того, как вы создали и зарегистрировали расширение поставщика службы, вы можете использовать драйвер `dropbox` в вашем файле конфигурации `config/filesystems.php`.
diff --git a/docs/fortify.md b/docs/fortify.md
index 35a6552..6dbb738 100644
--- a/docs/fortify.md
+++ b/docs/fortify.md
@@ -70,13 +70,13 @@ Laravel Sanctum занимается только управлением ток
Для начала установите Fortify с помощью менеджера пакетов Composer в свой проект:
-```nothing
+```shell
composer require laravel/fortify
```
Затем, опубликуйте ресурсы Fortify с помощью команды `vendor:publish`:
-```bash
+```shell
php artisan vendor:publish --provider="Laravel\Fortify\FortifyServiceProvider"
```
@@ -84,7 +84,7 @@ php artisan vendor:publish --provider="Laravel\Fortify\FortifyServiceProvider"
Затем, вы должны применить миграции вашей базу данных:
-```bash
+```shell
php artisan migrate
```
@@ -459,7 +459,7 @@ Fortify позаботится об определении маршрута `/re
Если запрос на сброс пароля был успешным, то Fortify перенаправит пользователя обратно на маршрут `/login`, чтобы пользователь мог войти со своим новым паролем. Кроме того, будет установлена переменная сессии `status`, чтобы вы могли отобразить успешный статус сброса пароля на экране входа в систему:
-```html
+```blade
@if (session('status'))
{{ session('status') }}
@@ -514,7 +514,7 @@ Fortify позаботится об определении маршрута, к
Если запрос на повторную отправку электронного письма со ссылкой для подтверждения был успешным, Fortify перенаправит пользователя обратно на конечную точку `/email/verify` с переменной сессии `status`, что позволит вам отобразить информационное сообщение для пользователя, информирующее его о том, что операция была выполнена. успешно. Если запрос был запросом XHR, будет возвращен `202` HTTP-ответ.
-```html
+```blade
@if (session('status') == 'verification-link-sent')
Вам отправлена новая ссылка для подтверждения адреса электронной почты!
diff --git a/docs/hashing.md b/docs/hashing.md
index 13790b3..0fc3c8d 100644
--- a/docs/hashing.md
+++ b/docs/hashing.md
@@ -19,8 +19,6 @@ Bcrypt – отличный выбор для хеширования парол
Драйвер хеширования по умолчанию для вашего приложения настраивается в файле конфигурации `config/hashing.php`. В настоящее время существует несколько поддерживаемых драйверов: [Bcrypt](https://en.wikipedia.org/wiki/Bcrypt) и [Argon2](https://en.wikipedia.org/wiki/Argon2) (вариации Argon2i и Argon2id).
-> {note} Для драйвера Argon2i требуется PHP 7.2.0 или выше, а для драйвера Argon2id требуется PHP 7.3.0 или выше.
-
## Основы использования
diff --git a/docs/helpers.md b/docs/helpers.md
index 6d6951d..ee3f661 100644
--- a/docs/helpers.md
+++ b/docs/helpers.md
@@ -133,6 +133,7 @@ Laravel содержит множество глобальных «вспомо
- [Str::substr](#method-str-substr)
- [Str::substrCount](#method-str-substrcount)
- [Str::substrReplace](#method-str-substrreplace)
+- [Str::swap](#method-str-swap)
- [Str::title](#method-title-case)
- [Str::toHtmlString](#method-str-to-html-string)
- [Str::ucfirst](#method-str-ucfirst)
@@ -140,6 +141,7 @@ Laravel содержит множество глобальных «вспомо
- [Str::uuid](#method-str-uuid)
- [Str::wordCount](#method-str-word-count)
- [Str::words](#method-str-words)
+- [str](#method-str)
- [trans](#method-trans)
- [trans_choice](#method-trans-choice)
@@ -203,6 +205,7 @@ Laravel содержит множество глобальных «вспомо
- [studly](#method-fluent-str-studly)
- [substr](#method-fluent-str-substr)
- [substrReplace](#method-fluent-str-substrreplace)
+- [swap](#method-fluent-str-swap)
- [tap](#method-fluent-str-tap)
- [test](#method-fluent-str-test)
- [title](#method-fluent-str-title)
@@ -236,6 +239,7 @@ Laravel содержит множество глобальных «вспомо
- [route](#method-route)
- [secure_asset](#method-secure-asset)
- [secure_url](#method-secure-url)
+- [to_route](#method-to-route)
- [url](#method-url)
@@ -1724,6 +1728,20 @@ Laravel содержит множество глобальных «вспомо
$result = Str::substrReplace('1300', ':', 2, 0);
// 13:00
+
+#### `Str::swap()`
+
+Метод `Str::swap` заменяет несколько значений в переданной строке, используя функцию `strtr` PHP:
+
+ use Illuminate\Support\Str;
+
+ $string = Str::swap([
+ 'Tacos' => 'Burritos',
+ 'great' => 'fantastic',
+ ], 'Tacos are great!');
+
+ // Burritos are fantastic!
+
#### `Str::title()`
@@ -1797,6 +1815,21 @@ Str::wordCount('Hello, world!'); // 2
// Perfectly balanced, as >>>
+
+#### `str()`
+
+Функция `str` возвращает новый экземпляр `Illuminate\Support\Stringable` переданной строки. Эта функция эквивалентна методу `Str::of`:
+
+ $string = str('Taylor')->append(' Otwell');
+
+ // 'Taylor Otwell'
+
+Если для функции `str` не указан аргумент, то функция возвращает экземпляр `Illuminate\Support\Str`:
+
+ $snake = str()->snake('FooBar');
+
+ // 'foo_bar'
+
#### `trans()`
@@ -2570,6 +2603,21 @@ If no matches are found, an empty collection will be returned.
// The Laravel Framework
+
+#### `swap`
+
+Метод `swap` заменяет несколько значений в переданной строке, используя функцию `strtr` PHP:
+
+ use Illuminate\Support\Str;
+
+ $string = Str::of('Tacos are great!')
+ ->swap([
+ 'Tacos' => 'Burritos',
+ 'great' => 'fantastic',
+ ]);
+
+ // Burritos are fantastic!
+
#### `tap`
@@ -2903,6 +2951,17 @@ Str::of('Hello, world!')->wordCount(); // 2
$url = secure_url('user/profile', [1]);
+
+#### `to_route()`
+
+Функция `to_route` генерирует [HTTP-ответ перенаправления](responses.md#redirects) на [именованный маршрут](routing.md#named-routes):
+
+ return to_route('users.show', ['user' => 1]);
+
+При необходимости вы можете передать код состояния HTTP, который должен быть назначен перенаправлению, и любые дополнительные заголовки ответа в качестве третьего и четвертого аргументов метода `to_route`, соответственно:
+
+ return to_route('users.show', ['user' => 1], 302, ['X-Framework' => 'Laravel']);
+
#### `url()`
@@ -3296,7 +3355,7 @@ Str::of('Hello, world!')->wordCount(); // 2
Функция `retry` пытается выполнить переданное замыкание, пока не будет достигнут указанный лимит попыток. Если замыкание не выбросит исключение, то будет возвращено его значение. Если замыкание выбросит исключение, то замыкание будет автоматически повторено. Если максимальное количество попыток превышено, будет выброшено исключение:
return retry(5, function () {
- // Attempt 5 times while resting 100ms in between attempts...
+ // Попытаться выполнить 5 раз с перерывом 100 мс между попытками ...
}, 100);
Если вы хотите указать количество миллисекунд между попытками, то вы можете передать замыкание в качестве третьего аргумента функции `retry`:
@@ -3307,7 +3366,12 @@ Str::of('Hello, world!')->wordCount(); // 2
return $attempt * 100;
});
-
+Для удобства вы можете предоставить массив в качестве первого аргумента функции `retry`. Этот массив будет использоваться для определения количества миллисекунд ожидания между последующими попытками:
+
+ return retry([100, 200] function () {
+ // Ждем 100 мс при первой попытке, 200 мс при второй попытке ...
+ });
+
Для задания определенных условий выполнения попытки, вы можете передать замыкание в качестве четвертого аргумента функции `retry`:
return retry(5, function () {
diff --git a/docs/homestead.md b/docs/homestead.md
index 69b3df1..7913811 100644
--- a/docs/homestead.md
+++ b/docs/homestead.md
@@ -147,23 +147,27 @@ Homestead работает в любой системе: Windows, macOS или L
Вы можете установить Homestead, клонировав репозиторий Homestead на свой хост-компьютер. Рассмотрите возможность клонирования репозитория в папку `Homestead` вашего «домашнего» каталога, поскольку виртуальная машина Homestead будет служить хостом для всех ваших приложений Laravel. В этой документации мы будем называть этот каталог вашим «каталогом Homestead»:
-```bash
+```shell
git clone https://github.com/laravel/homestead.git ~/Homestead
```
После клонирования репозитория Laravel Homestead вы должны проверить ветку `release`. Эта ветка всегда содержит последний стабильный релиз Homestead:
- cd ~/Homestead
+```shell
+cd ~/Homestead
- git checkout release
+git checkout release
+```
Затем выполните команду `bash init.sh` из каталога Homestead, чтобы создать конфигурационный файл `Homestead.yaml`. Файл `Homestead.yaml` – это то место, где вы настраиваете все параметры установки Homestead. Этот файл будет размещен в каталоге Homestead:
- // macOS / Linux...
- bash init.sh
+```shell
+# macOS / Linux...
+bash init.sh
- // Windows...
- init.bat
+# Windows...
+init.bat
+```
### Конфигурирование Homestead
@@ -204,31 +208,37 @@ folders:
Чтобы задействовать [NFS](https://www.vagrantup.com/docs/synced-folders/nfs.html), вы можете добавить параметр `type` при сопоставлении папок:
- folders:
- - map: ~/code/project1
- to: /home/vagrant/project1
- type: "nfs"
+```yaml
+folders:
+ - map: ~/code/project1
+ to: /home/vagrant/project1
+ type: "nfs"
+```
> {note} При использовании NFS в Windows вам следует рассмотреть возможность установки плагина [vagrant-winnfsd](https://github.com/winnfsd/vagrant-winnfsd). Этот плагин будет поддерживать корректные разрешения пользователя / группы для файлов и каталогов виртуальной машины Homestead.
Вы также можете передать любые параметры, поддерживаемые [синхронизируемыми папками](https://www.vagrantup.com/docs/synced-folders/basic_usage.html) Vagrant, указав их под параметром `options`:
- folders:
- - map: ~/code/project1
- to: /home/vagrant/project1
- type: "rsync"
- options:
- rsync__args: ["--verbose", "--archive", "--delete", "-zz"]
- rsync__exclude: ["node_modules"]
+```yaml
+folders:
+ - map: ~/code/project1
+ to: /home/vagrant/project1
+ type: "rsync"
+ options:
+ rsync__args: ["--verbose", "--archive", "--delete", "-zz"]
+ rsync__exclude: ["node_modules"]
+```
### Конфигурирование сайтов Nginx
Не знакомы с Nginx? Без проблем. Параметр `sites` вашего файла `Homestead.yaml` позволяет вам легко сопоставить «домен» с папкой в окружении Homestead. Пример конфигурации сайта содержится в файле `Homestead.yaml`. Опять же, вы можете добавить столько сайтов в окружение Homestead, сколько необходимо. Homestead может служить удобной виртуализированной средой для каждого приложения Laravel, над которым вы работаете:
- sites:
- - map: homestead.test
- to: /home/vagrant/project1/public
+```yaml
+sites:
+ - map: homestead.test
+ to: /home/vagrant/project1/public
+```
Если вы измените параметр `sites` после подготовки виртуальной машины Homestead, то вы должны выполнить команду `vagrant reload --provision` в своем терминале, чтобы обновить конфигурацию Nginx на виртуальной машине.
@@ -245,7 +255,7 @@ Homestead публикует имена хостов, используя `mDNS`
Убедитесь, что в списке указан IP-адрес, указанный в вашем файле `Homestead.yaml`. После того, как вы добавили домен в свой файл `hosts` и запустили окно Vagrant, вы сможете получить доступ к сайту через свой веб-браузер:
-```bash
+```shell
http://homestead.test
```
@@ -278,17 +288,19 @@ services:
Для начала установите Homestead с помощью менеджера пакетов Composer в свой проект:
-```bash
+```shell
composer require laravel/homestead --dev
```
Как только Homestead будет установлен, вызовите команду `make` Homestead, чтобы сгенерировать файлы `Vagrantfile` и `Homestead.yaml` для вашего проекта. Эти файлы будут помещены в корень вашего проекта. Команда `make` автоматически настроит параметры `sites` и `folder` в файле `Homestead.yaml`:
- // macOS / Linux...
- php vendor/bin/homestead make
+```shell
+# macOS / Linux...
+php vendor/bin/homestead make
- // Windows...
- vendor\\bin\\homestead make
+# Windows...
+vendor\\bin\\homestead make
+```
Запустите команду `vagrant up` в терминале и перейдите по адресу `http://homestead.test` в вашем браузере. Помните, что вам также нужно будет добавить запись в файле `/etc/hosts` для домена `homestead.test` или любого другого необходимого домена, если вы не используете автоматическое [разрешение имени хоста](#hostname-resolution).
@@ -297,41 +309,43 @@ composer require laravel/homestead --dev
Дополнительное программное обеспечение устанавливается с помощью параметра `features` в вашем файле `Homestead.yaml`. Большую часть ПО можно включить или отключить с помощью логического значения, но существует ПО, позволяющее использовать несколько параметров конфигурации:
- features:
- - blackfire:
- server_id: "server_id"
- server_token: "server_value"
- client_id: "client_id"
- client_token: "client_value"
- - cassandra: true
- - chronograf: true
- - couchdb: true
- - crystal: true
- - docker: true
- - elasticsearch:
- version: 7.9.0
- - eventstore: true
- version: 21.2.0
- - gearman: true
- - golang: true
- - grafana: true
- - influxdb: true
- - mariadb: true
- - meilisearch: true
- - minio: true
- - mongodb: true
- - neo4j: true
- - ohmyzsh: true
- - openresty: true
- - pm2: true
- - python: true
- - r-base: true
- - rabbitmq: true
- - rvm: true
- - solr: true
- - timescaledb: true
- - trader: true
- - webdriver: true
+```yaml
+features:
+ - blackfire:
+ server_id: "server_id"
+ server_token: "server_value"
+ client_id: "client_id"
+ client_token: "client_value"
+ - cassandra: true
+ - chronograf: true
+ - couchdb: true
+ - crystal: true
+ - docker: true
+ - elasticsearch:
+ version: 7.9.0
+ - eventstore: true
+ version: 21.2.0
+ - gearman: true
+ - golang: true
+ - grafana: true
+ - influxdb: true
+ - mariadb: true
+ - meilisearch: true
+ - minio: true
+ - mongodb: true
+ - neo4j: true
+ - ohmyzsh: true
+ - openresty: true
+ - pm2: true
+ - python: true
+ - r-base: true
+ - rabbitmq: true
+ - rvm: true
+ - solr: true
+ - timescaledb: true
+ - trader: true
+ - webdriver: true
+```
#### Elasticsearch
@@ -360,8 +374,10 @@ composer require laravel/homestead --dev
Вы можете добавить псевдонимы Bash для своей виртуальной машины Homestead, изменив файл `aliases` в каталоге Homestead:
- alias c='clear'
- alias ..='cd ..'
+```shell
+alias c='clear'
+alias ..='cd ..'
+```
После обновления файла `aliases` вы должны повторно подготовить виртуальную машину Homestead с помощью команды `vagrant reload --provision`. Это обеспечит доступность ваших новых псевдонимов на машине.
@@ -370,35 +386,47 @@ composer require laravel/homestead --dev
Перед обновлением Homestead, убедитесь, что вы уничтожили текущую виртуальную машину, выполнив следующую команду в каталоге Homestead:
- vagrant destroy
+```shell
+vagrant destroy
+```
Затем вам нужно обновить исходный код Homestead. Если вы клонировали репозиторий, то вы можете выполнить следующие команды в том месте, где вы изначально клонировали репозиторий:
- git fetch
+```shell
+git fetch
- git pull origin release
+git pull origin release
+```
С помощью этих команд будет подтянут последний код Homestead из репозитория GitHub, извлечены последние теги и будет выполнена проверка последнего релиза по тегам. Вы можете найти последнюю стабильную версию релиза Homestead на [странице GitHub](https://github.com/laravel/homestead/releases).
Если вы установили Homestead в свой проект с помощью Composer, то необходимо убедиться, что ваш файл `composer.json` содержит запись `"laravel/homestead": "^12"` с последующим обновлением ваших зависимостей:
- composer update
+```shell
+composer update
+```
Затем вы должны обновить образ Vagrant с помощью команды:
- vagrant box update
+```shell
+vagrant box update
+```
После обновления образа Vagrant вы должны запустить команду `bash init.sh` из каталога Homestead, чтобы обновить дополнительные файлы конфигурации Homestead. При этом вас спросят, хотите ли вы перезаписать существующие файлы `Homestead.yaml`, `after.sh` и `aliases`:
- // macOS / Linux...
- bash init.sh
+```shell
+# macOS / Linux...
+bash init.sh
- // Windows...
- init.bat
+# Windows...
+init.bat
+```
Наконец, вам нужно будет пересоздать вашу виртуальную машину Homestead, чтобы использовать последнюю установку Vagrant:
- vagrant up
+```shell
+vagrant up
+```
## Повседневное использование
@@ -413,11 +441,13 @@ composer require laravel/homestead --dev
После того, как ваша среда Homestead подготовлена и запущена, вы можете добавить дополнительные сайты Nginx для других ваших проектов Laravel. Вы можете запускать столько проектов Laravel, сколько хотите, в одном окружении Homestead. Чтобы добавить дополнительный сайт, добавьте его в свой файл `Homestead.yaml`.
- sites:
- - map: homestead.test
- to: /home/vagrant/project1/public
- - map: another.test
- to: /home/vagrant/project2/public
+```yaml
+sites:
+ - map: homestead.test
+ to: /home/vagrant/project1/public
+ - map: another.test
+ to: /home/vagrant/project2/public
+```
> {note} Перед добавлением сайта убедитесь, что вы настроили [сопоставление папок](#configuring-shared-folders) для каталога проекта.
@@ -447,23 +477,27 @@ sites:
Вы можете добавить дополнительные значения параметра `fastcgi_param` Nginx на свой сайт с помощью директивы сайта `params`:
- sites:
- - map: homestead.test
- to: /home/vagrant/project1/public
- params:
- - key: FOO
- value: BAR
+```yaml
+sites:
+ - map: homestead.test
+ to: /home/vagrant/project1/public
+ params:
+ - key: FOO
+ value: BAR
+```
### Переменные окружения
Вы можете определить глобальные переменные окружения, добавив их в свой файл `Homestead.yaml`:
- variables:
- - key: APP_ENV
- value: local
- - key: FOO
- value: bar
+```yaml
+variables:
+ - key: APP_ENV
+ value: local
+ - key: FOO
+ value: bar
+```
После обновления файла `Homestead.yaml` не забудьте повторно подготовить машину, выполнив команду `vagrant reload --provision`. Это обновит конфигурацию PHP-FPM для всех установленных версий PHP, а также обновит окружение для пользователя `vagrant`.
@@ -484,12 +518,14 @@ sites:
По желанию можно перенаправить дополнительные порты в образе Vagrant, указав конфигурационную запись `ports` в вашем файле `Homestead.yaml`. После обновления файла `Homestead.yaml` не забудьте повторно подготовить машину, выполнив команду `vagrant reload --provision`:
- ports:
- - send: 50000
- to: 5000
- - send: 7777
- to: 777
- protocol: udp
+```yaml
+ports:
+ - send: 50000
+ to: 5000
+ - send: 7777
+ to: 777
+ protocol: udp
+```
Ниже приведен список дополнительных портов служб Homestead в образе Vagrant, которые можно сопоставить со своей хост-машины:
@@ -510,32 +546,38 @@ sites:
В Homestead 6 появилась поддержка запуска нескольких версий PHP на одной виртуальной машине. Вы можете указать, какую версию PHP использовать для конкретного сайта в файле `Homestead.yaml`. Доступные версии PHP: «5.6», «7.0», «7.1», «7.2», «7.3», «7.4», «8.0» (по умолчанию) и «8.1»:
- sites:
- - map: homestead.test
- to: /home/vagrant/project1/public
- php: "7.1"
+```yaml
+sites:
+ - map: homestead.test
+ to: /home/vagrant/project1/public
+ php: "7.1"
+```
[На виртуальной машине Homestead](#connecting-via-ssh) вы можете использовать любую из поддерживаемых версий PHP через интерфейс командной строки:
- php5.6 artisan list
- php7.0 artisan list
- php7.1 artisan list
- php7.2 artisan list
- php7.3 artisan list
- php7.4 artisan list
- php8.0 artisan list
- php8.1 artisan list
+```shell
+php5.6 artisan list
+php7.0 artisan list
+php7.1 artisan list
+php7.2 artisan list
+php7.3 artisan list
+php7.4 artisan list
+php8.0 artisan list
+php8.1 artisan list
+```
Вы можете изменить версию PHP, используемую по умолчанию в CLI, выполнив следующие команды на своей виртуальной машине Homestead:
- php56
- php70
- php71
- php72
- php73
- php74
- php80
- php81
+```shell
+php56
+php70
+php71
+php72
+php73
+php74
+php80
+php81
+```
### Подключение к базам данных
@@ -574,12 +616,14 @@ sites:
[MailHog](https://github.com/mailhog/MailHog) позволяет вам перехватывать исходящую электронную почту без отправки ее получателям. Для начала обновите файл `.env` вашего приложения, чтобы использовать следующие настройки почты:
- MAIL_MAILER=smtp
- MAIL_HOST=localhost
- MAIL_PORT=1025
- MAIL_USERNAME=null
- MAIL_PASSWORD=null
- MAIL_ENCRYPTION=null
+```ini
+MAIL_MAILER=smtp
+MAIL_HOST=localhost
+MAIL_PORT=1025
+MAIL_USERNAME=null
+MAIL_PASSWORD=null
+MAIL_ENCRYPTION=null
+```
После этой настройки вы можете получить доступ к панели управления MailHog по адресу `http://localhost:8025`.
@@ -606,7 +650,7 @@ sites:
Наконец, убедитесь, что в вашем файле `.env` прописаны следующие параметры:
-```bash
+```ini
AWS_ACCESS_KEY_ID=homestead
AWS_SECRET_ACCESS_KEY=secretkey
AWS_DEFAULT_REGION=us-east-1
@@ -644,11 +688,15 @@ features:
Чтобы решить эту проблему, Homestead содержит собственную команду `share`. Для начала [подключитесь к вашей виртуальной машине](#connecting-via-ssh) через `vagrant ssh` и выполните команду `share homestead.test`. Эта команда предоставит общий доступ к сайту `homestead.test` из вашего конфигурационного файла `Homestead.yaml`. Вы можете заменить `homestead.test` на любой из других сконфигурированных вами сайтов:
- share homestead.test
+```shell
+share homestead.test
+```
После выполнения команды вы увидите экран Ngrok, который содержит журнал активности и общедоступные URL-адреса для вашего сайта. Если вы хотите указать регион, поддомен или другой параметр во время выполнения Ngrok, то вы можете добавить их в команду `share`:
- share homestead.test -region=eu -subdomain=laravel
+```shell
+share homestead.test -region=eu -subdomain=laravel
+```
> {note} Помните, что Vagrant по своей сути небезопасен, и вы открываете свою виртуальную машину для доступа в Интернет, выполняя команду `share`.
@@ -737,10 +785,12 @@ networks:
Настраивая Homestead, Ubuntu может спросить вас, хотите ли вы сохранить исходную конфигурацию пакета или перезаписать ее новым файлом конфигурации. Чтобы избежать этого, вы должны использовать следующую команду при установке пакетов, чтобы избежать перезаписи любой конфигурации, ранее созданной Homestead:
- sudo apt-get -y \
- -o Dpkg::Options::="--force-confdef" \
- -o Dpkg::Options::="--force-confold" \
- install package-name
+```shell
+sudo apt-get -y \
+ -o Dpkg::Options::="--force-confdef" \
+ -o Dpkg::Options::="--force-confold" \
+ install package-name
+```
### Пользовательские настройки
diff --git a/docs/horizon.md b/docs/horizon.md
index c21e8a3..3ef43be 100644
--- a/docs/horizon.md
+++ b/docs/horizon.md
@@ -32,11 +32,15 @@
Для начала установите Horizon с помощью менеджера пакетов Composer в свой проект:
- composer require laravel/horizon
+```shell
+composer require laravel/horizon
+```
После установки Horizon опубликуйте его ресурсы с помощью команды `horizon:install` Artisan:
- php artisan horizon:install
+```shell
+php artisan horizon:install
+```
### Конфигурирование
@@ -143,44 +147,58 @@
При обновлении до новой основной версии Horizon важно внимательно изучить [руководство по обновлению](https://github.com/laravel/horizon/blob/master/UPGRADE.md). Кроме того, при обновлении до любой новой версии Horizon вам следует повторно опубликовать веб-активы Horizon:
- php artisan horizon:publish
+```shell
+php artisan horizon:publish
+```
Чтобы поддерживать веб-активы в актуальном состоянии и избежать проблем при будущих обновлениях, вы можете добавить команду `horizon:publish` в блок `post-update-cmd` раздела `scripts` в файле `composer.json` вашего приложения:
- {
- "scripts": {
- "post-update-cmd": [
- "@php artisan horizon:publish --ansi"
- ]
- }
+```json
+{
+ "scripts": {
+ "post-update-cmd": [
+ "@php artisan horizon:publish --ansi"
+ ]
}
+}
+```
## Запуск Horizon
После того, как вы настроили своих диспетчеров и обработчиков процессов в конфигурационном файле `config/horizon.php` вашего приложения, то вы можете запустить Horizon, используя команду `horizon` Artisan. Эта единая команда запустит все сконфигурированные обработчики процессов для текущего окружения:
- php artisan horizon
+```shell
+php artisan horizon
+```
Вы можете приостановить процесс Horizon и дать ему указание продолжить обработку заданий, используя команды `horizon:pause` и `horizon:continue` Artisan:
- php artisan horizon:pause
+```shell
+php artisan horizon:pause
- php artisan horizon:continue
+php artisan horizon:continue
+```
Вы также можете приостановить и продолжить конкретные [диспетчеры](#supervisors) Horizon, используя команды `horizon:pause-supervisor` и `horizon:continue-supervisor` Artisan:
- php artisan horizon:pause-supervisor supervisor-1
+```shell
+php artisan horizon:pause-supervisor supervisor-1
- php artisan horizon:continue-supervisor supervisor-1
+php artisan horizon:continue-supervisor supervisor-1
+```
Вы можете проверить текущий статус процесса Horizon, используя команду `horizon:status` Artisan:
- php artisan horizon:status
+```shell
+php artisan horizon:status
+```
Вы можете корректно завершить процесс Horizon, используя команду `horizon:terminate` Artisan. Любые задания, которые в настоящее время обрабатываются, будут выполнены, а затем Horizon остановит свой процесс:
- php artisan horizon:terminate
+```shell
+php artisan horizon:terminate
+```
### Развертывание Horizon
@@ -189,14 +207,18 @@
Во время процесса развертывания вашего приложения вы должны дать команду Horizon завершить процесс, чтобы он был перезапущен вашим монитором процессов и получил изменения вашего кода:
- php artisan horizon:terminate
+```shell
+php artisan horizon:terminate
+```
#### Установка Supervisor
Supervisor – это монитор процесса для операционной системы Linux, который автоматически перезапустит ваш процесс `horizon`, если он перестанет выполняться. Чтобы установить Supervisor в Ubuntu, вы можете использовать следующую команду. Если вы не используете Ubuntu, то вы, вероятно, можете установить Supervisor с помощью диспетчера пакетов вашей операционной системы:
- sudo apt-get install supervisor
+```shell
+sudo apt-get install supervisor
+```
> {tip} Если настройка Supervisor сама по себе кажется утомительной, рассмотрите возможность использования [Laravel Forge](https://forge.laravel.com), который автоматически установит и настроит Supervisor для ваших проектов Laravel.
@@ -205,15 +227,17 @@ Supervisor – это монитор процесса для операцион
Конфигурационные файлы Supervisor обычно хранятся в каталоге `/etc/supervisor/conf.d` вашего сервера. В этом каталоге вы можете создать любое количество файлов конфигурации, которые инструктируют диспетчера процессов, как следует контролировать ваши процессы. Например, давайте создадим файл `horizon.conf`, который запускает и отслеживает процесс `horizon`:
- [program:horizon]
- process_name=%(program_name)s
- command=php /home/forge/example.com/artisan horizon
- autostart=true
- autorestart=true
- user=forge
- redirect_stderr=true
- stdout_logfile=/home/forge/example.com/horizon.log
- stopwaitsecs=3600
+```ini
+[program:horizon]
+process_name=%(program_name)s
+command=php /home/forge/example.com/artisan horizon
+autostart=true
+autorestart=true
+user=forge
+redirect_stderr=true
+stdout_logfile=/home/forge/example.com/horizon.log
+stopwaitsecs=3600
+```
> {note} Вы должны убедиться, что значение `stopwaitsecs` больше, чем количество секунд, потребляемых вашим самым продолжительным выполняемым заданием. В противном случае Supervisor может убить задание до того, как оно завершит обработку.
@@ -222,11 +246,13 @@ Supervisor – это монитор процесса для операцион
После создания файла конфигурации вы можете обновить конфигурацию Supervisor и запустить отслеживаемые процессы, используя следующие команды:
- sudo supervisorctl reread
+```shell
+sudo supervisorctl reread
- sudo supervisorctl update
+sudo supervisorctl update
- sudo supervisorctl start horizon
+sudo supervisorctl start horizon
+```
> {tip} Для получения дополнительной информации о запуске Supervisor обратитесь к [документации Supervisor](http://supervisord.org/index.html).
@@ -358,15 +384,21 @@ Horizon содержит панель показателей, которая п
Если вы хотите удалить невыполненное задание, то вы можете использовать команду `horizon:forget`. Команда `horizon:forget` принимает идентификатор (ID или UUID) неудачного задания в качестве своего единственного аргумента:
- php artisan horizon:forget 5
+```shell
+php artisan horizon:forget 5
+```
## Очистка заданий из очередей
Если вы хотите удалить все задания из очереди по умолчанию вашего приложения, то вы можете сделать это с помощью команды `horizon:clear` Artisan:
- php artisan horizon:clear
+```shell
+php artisan horizon:clear
+```
Вы можете передать параметр `queue` для удаления заданий из конкретной очереди:
- php artisan horizon:clear --queue=emails
+```shell
+php artisan horizon:clear --queue=emails
+```
diff --git a/docs/http-client.md b/docs/http-client.md
index f1a5379..4f45aa3 100644
--- a/docs/http-client.md
+++ b/docs/http-client.md
@@ -23,7 +23,9 @@ Laravel предлагает минимальный и выразительны
Вы должны убедиться, что пакет Guzzle включен в зависимости вашего приложения. По умолчанию Laravel автоматически включает эту зависимость. Однако, если вы ранее удалили пакет, то вы можете установить его снова через Composer:
- composer require guzzlehttp/guzzle
+```shell
+composer require guzzlehttp/guzzle
+```
## Выполнение запросов
@@ -166,6 +168,10 @@ Laravel предлагает минимальный и выразительны
Если указанный тайм-аут превышен, то будет выброшено исключение `Illuminate\Http\Client\ConnectionException`.
+Вы можете указать максимальное количество секунд ожидания при попытке подключения к серверу с помощью метода `connectTimeout`:
+
+ $response = Http::connectTimeout(3)->get(...);
+
### Повторные попытки
@@ -179,7 +185,9 @@ Laravel предлагает минимальный и выразительны
return $exception instanceof ConnectionException;
})->post(...);
-Если все запросы окажутся неуспешными, то будет выброшено исключение `Illuminate\Http\Client\RequestException`.
+Если все запросы окажутся неуспешными, то будет выброшено исключение `Illuminate\Http\Client\RequestException`. Если вы хотите отключить это поведение, вы можете указать аргумент `throw` со значением `false`. Если отключено, то последний ответ, полученный клиентом, будет возвращен после всех повторных попыток:
+
+ $response = Http::retry(3, 100, throw: false)->post(...);
### Обработка ошибок
@@ -315,8 +323,6 @@ $response = Http::github()->get('/');
$response = Http::post(...);
-> {note} При фальсификации запросов посредник HTTP-клиента не выполняется. Вы должны определить ожидания для фиктивных ответов, как если бы этот посредник работал правильно.
-
#### Фальсификация конкретных URL
diff --git a/docs/img/releases-1.png b/docs/img/releases-1.png
new file mode 100644
index 0000000..e25e058
Binary files /dev/null and b/docs/img/releases-1.png differ
diff --git a/docs/img/releases-2.png b/docs/img/releases-2.png
new file mode 100644
index 0000000..3ba8ec1
Binary files /dev/null and b/docs/img/releases-2.png differ
diff --git a/docs/img/releases-3.png b/docs/img/releases-3.png
new file mode 100644
index 0000000..1a2c3ef
Binary files /dev/null and b/docs/img/releases-3.png differ
diff --git a/docs/img/releases-4.png b/docs/img/releases-4.png
new file mode 100644
index 0000000..9099682
Binary files /dev/null and b/docs/img/releases-4.png differ
diff --git a/docs/img/releases-5.gif b/docs/img/releases-5.gif
new file mode 100644
index 0000000..676e102
Binary files /dev/null and b/docs/img/releases-5.gif differ
diff --git a/docs/installation.md b/docs/installation.md
index 2e3b7b8..810bf2c 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -61,7 +61,7 @@ Laravel Sail – это легкий интерфейс командной ст
Если вы разрабатываете на Mac и [Docker Desktop](https://www.docker.com/products/docker-desktop) уже установлен, то вы можете использовать простую команду терминала для создания нового проекта Laravel. Например, чтобы создать новое приложение Laravel в каталоге с именем `example-app`, вы можете запустить следующую команду в своем терминале:
-```nothing
+```shell
curl -s https://laravel.build/example-app | bash
```
@@ -69,7 +69,7 @@ curl -s https://laravel.build/example-app | bash
После создания проекта вы можете перейти в каталог приложения и запустить Laravel Sail. Laravel Sail предлагает простой интерфейс командной строки для взаимодействия с конфигурацией Docker по умолчанию в Laravel:
-```nothing
+```shell
cd example-app
./vendor/bin/sail up
@@ -90,7 +90,7 @@ cd example-app
Теперь вы готовы создать свой первый проект Laravel. Запустите [Терминал Windows](https://www.microsoft.com/ru-ru/p/windows-terminal/9n0dx20hk701?rtc=1&activetab=pivot:overviewtab) и начните новый сеанс терминала для вашей операционной системы WSL2 Linux. Затем вы можете использовать простую команду терминала для создания нового проекта Laravel. Например, чтобы создать новое приложение Laravel в каталоге с именем `example-app`, вы можете запустить следующую команду в своем терминале:
-```nothing
+```shell
curl -s https://laravel.build/example-app | bash
```
@@ -98,7 +98,7 @@ curl -s https://laravel.build/example-app | bash
После создания проекта вы можете перейти в каталог приложения и запустить Laravel Sail. Laravel Sail предлагает простой интерфейс командной строки для взаимодействия с конфигурацией Docker по умолчанию в Laravel:
-```nothing
+```shell
cd example-app
./vendor/bin/sail up
@@ -121,7 +121,7 @@ cd example-app
Если вы разрабатываете в Linux и [Docker Compose](https://docs.docker.com/compose/install/) уже установлен, то вы можете использовать простую команду терминала для создания нового проекта Laravel. Например, чтобы создать новое приложение Laravel в каталоге с именем `example-app`, вы можете запустить следующую команду в своем терминале:
-```nothing
+```shell
curl -s https://laravel.build/example-app | bash
```
@@ -129,7 +129,7 @@ curl -s https://laravel.build/example-app | bash
После создания проекта вы можете перейти в каталог приложения и запустить Laravel Sail. Laravel Sail предлагает простой интерфейс командной строки для взаимодействия с конфигурацией Docker по умолчанию в Laravel:
-```nothing
+```shell
cd example-app
./vendor/bin/sail up
@@ -146,29 +146,37 @@ cd example-app
При создании нового приложения Laravel через Sail вы можете использовать строковую переменную запроса `with`, чтобы выбрать, какие службы должны быть настроены в файле `docker-compose.yml` вашего нового приложения. Доступны следующие службы `mysql`, `pgsql`, `mariadb`, `redis`, `memcached`, `meilisearch`, `minio`,`selenium` и `mailhog`:
-```nothing
+```shell
curl -s "https://laravel.build/example-app?with=mysql,redis" | bash
```
Если вы не укажете желаемые службы, то будет сконфигурирован стек по умолчанию из `mysql`, `redis`, `meilisearch`, `mailhog` и `selenium`.
+Вы можете указать Sail установить [Devcontainer](sail.md#using-devcontainers) по умолчанию, добавив параметр `devcontainer` к URL-адресу:
+
+```shell
+curl -s "https://laravel.build/example-app?with=mysql,redis&devcontainer" | bash
+```
+
### Установка через Composer
Если на вашем компьютере уже установлены PHP и Composer, то вы можете создать новый проект Laravel напрямую с помощью Composer. После того, как приложение было создано, вы можете запустить локальный сервер разработки Laravel с помощью команды `serve` Artisan CLI:
- composer create-project laravel/laravel example-app
+```shell
+composer create-project laravel/laravel example-app
- cd example-app
+cd example-app
- php artisan serve
+php artisan serve
+```
#### Установщик Laravel
В качестве альтернативы, вы можете использовать установщик Laravel, включив его в глобальную зависимость Composer:
-```nothing
+```shell
composer global require laravel/installer
laravel new example-app
@@ -190,31 +198,31 @@ php artisan serve
Для удобства установщик Laravel также может создать репозиторий Git для вашего нового проекта. Чтобы указать, что вы хотите создать репозиторий Git, передайте флаг `--git` при создании нового проекта:
-```bash
+```shell
laravel new example-app --git
```
Эта команда инициализирует новый репозиторий Git для вашего проекта и автоматически зафиксирует базовый каркас Laravel. Флаг `--git` предполагает, что вы правильно установили и настроили Git. Можно также использовать параметр `--branch`, чтобы задать имя ответвления:
-```bash
+```shell
laravel new example-app --git --branch="main"
```
Вместо использования флага `--git` вы можете использовать параметр `--github`, чтобы создать репозиторий Git и, соответствующий ему, частный репозиторий на GitHub:
-```bash
+```shell
laravel new example-app --github
```
Созданный репозиторий будет доступен по адресу `https://github.com/
/example-app`. Параметр `--github` предполагает, что вы правильно установили [GitHub CLI](https://cli.github.com) и прошли аутентификацию с помощью интерфейса командной строки. Кроме того, у вас должен быть установлен и правильно настроен [git](https://git-scm.com/). При необходимости вы можете передать [дополнительные параметры и флаги](https://cli.github.com/manual/gh_repo_create), поддерживаемые GitHub CLI:
-```bash
+```shell
laravel new example-app --github="--public"
```
Можно использовать параметр `--organization` для создания репозитория под определенной организацией GitHub:
-```bash
+```shell
laravel new example-app --github="--public" --organization="laravel"
```
diff --git a/docs/localization.md b/docs/localization.md
index 3b67185..a0422ed 100644
--- a/docs/localization.md
+++ b/docs/localization.md
@@ -103,7 +103,7 @@ Laravel предлагает два способа управления стро
По этой причине Laravel предлагает определение строк перевода с использованием переводимой строки в качестве ключа «по умолчанию». Файлы перевода, которые используют строки перевода в качестве ключей, хранятся как файлы JSON в каталоге `resources/lang`. Например, если ваше приложение имеет испанский перевод, то вы должны создать файл `resources/lang/es.json`:
-```js
+```json
{
"I love programming.": "Me encanta programar."
}
@@ -157,7 +157,7 @@ Laravel предлагает два способа управления стро
Конечно, множественное число также поддерживается при использовании [строк перевода в качестве ключей](#using-translation-strings-as-keys):
-```js
+```json
{
"There is one apple|There are many apples": "Hay una manzana|Hay muchas manzanas"
}
diff --git a/docs/mail.md b/docs/mail.md
index 28be6eb..d74d102 100644
--- a/docs/mail.md
+++ b/docs/mail.md
@@ -11,7 +11,7 @@
- [Данные шаблона](#view-data)
- [Вложения](#attachments)
- [Встраиваемые вложения](#inline-attachments)
- - [Настройка сообщения SwiftMailer](#customizing-the-swiftmailer-message)
+ - [Настройка сообщения Symfony](#customizing-the-symfony-message)
- [Отправления с разметкой Markdown](#markdown-mailables)
- [Генерация отправлений с разметкой Markdown](#generating-markdown-mailables)
- [Написание сообщений с разметкой Markdown](#writing-markdown-messages)
@@ -24,11 +24,13 @@
- [Тестирование отправлений](#testing-mailables)
- [Почта и локальная разработка](#mail-and-local-development)
- [События](#events)
+- [Пользовательские драйвера](#custom-transports)
+ - [Дополнительные драйвера Symfony](#additional-symfony-transports)
## Введение
-Отправка электронной почты не должна быть сложной. Laravel предлагает чистый и простой почтовый API на базе популярной библиотеки [SwiftMailer](https://swiftmailer.symfony.com/). Laravel и SwiftMailer обеспечены драйверами для отправки электронной почты через SMTP, Mailgun, Postmark, Amazon SES и `sendmail`, что позволяет быстро начать отправку почты через локальный или облачный сервис по вашему выбору.
+Отправка электронной почты не должна быть сложной. Laravel предлагает чистый и простой почтовый API на базе популярного компонента [Symfony Mailer](https://symfony.com/doc/6.0/mailer.html). Laravel и Symfony Mailer обеспечены драйверами для отправки электронной почты через SMTP, Mailgun, Postmark, Amazon SES и `sendmail`, что позволяет быстро начать отправку почты через локальный или облачный сервис по вашему выбору.
### Конфигурирование
@@ -40,14 +42,18 @@
### Предварительная подготовка драйверов
-Драйверы на основе API, такие как Mailgun и Postmark, часто проще в использовании и быстрее, чем отправка почты через SMTP-серверы. По возможности мы рекомендуем использовать один из этих драйверов. Для всех драйверов на основе API требуется HTTP-библиотека Guzzle, которую можно установить через менеджер пакетов Composer:
-
- composer require guzzlehttp/guzzle
+Драйверы на основе API, такие как Mailgun и Postmark, часто проще в использовании и быстрее, чем отправка почты через SMTP-серверы. По возможности мы рекомендуем использовать один из этих драйверов.
#### Драйвер Mailgun
-Чтобы использовать драйвер Mailgun, сначала установите HTTP-библиотеку Guzzle. Затем установите параметру `default` в вашем конфигурационном файле `config/mail.php` значение `mailgun`. Затем убедитесь, что ваш конфигурационный файл `config/services.php` содержит следующие параметры:
+Чтобы использовать драйвер Mailgun, сначала установите Symfony Mailgun Mailer с помощью менеджера пакетов Composer:
+
+```shell
+composer require symfony/mailgun-mailer
+```
+
+Затем установите параметру `default` в вашем конфигурационном файле `config/mail.php` значение `mailgun`. Затем убедитесь, что ваш конфигурационный файл `config/services.php` содержит следующие параметры:
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
@@ -65,11 +71,13 @@
#### Драйвер Postmark
-Чтобы использовать драйвер Postmark, установите транспорт SwiftMailer для Postmark через Composer:
+Чтобы использовать драйвер Postmark, сначала установите Symfony Postmark Mailer с помощью менеджера пакетов Composer:
- composer require wildbit/swiftmailer-postmark
+```shell
+composer require symfony/postmark-mailer
+```
-Затем установите HTTP-библиотеку Guzzle и установите для параметра `default` в конфигурационном файле `config/mail.php` значение `postmark`. Наконец, убедитесь, что ваш конфигурационный файл `config/services.php` содержит следующие параметры:
+Затем установите параметру `default` в вашем конфигурационном файле `config/mail.php` значение `postmark`. Затем убедитесь, что ваш конфигурационный файл `config/services.php` содержит следующие параметры:
'postmark' => [
'token' => env('POSTMARK_TOKEN'),
@@ -89,7 +97,7 @@
Чтобы использовать драйвер Amazon SES, сначала необходимо установить Amazon AWS SDK для PHP. Вы можете установить эту библиотеку через менеджер пакетов Composer:
-```bash
+```shell
composer require aws/aws-sdk-php
```
@@ -110,7 +118,7 @@ composer require aws/aws-sdk-php
'token' => env('AWS_SESSION_TOKEN'),
],
-Если вы хотите определить [дополнительные параметры](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-email-2010-12-01.html#sendrawemail), которые Laravel должен передать методу `SendRawEmail` AWS SDK при отправке сообщения электронной почты, вы можете определить массив `options` в конфигурации `ses`:
+Если вы хотите определить [дополнительные параметры](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sesv2-2019-09-27.html#sendemail), которые Laravel должен передать методу `SendEmail` AWS SDK при отправке сообщения электронной почты, вы можете определить массив `options` в конфигурации `ses`:
'ses' => [
'key' => env('AWS_ACCESS_KEY_ID'),
@@ -118,7 +126,7 @@ composer require aws/aws-sdk-php
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'options' => [
'ConfigurationSetName' => 'MyConfigurationSet',
- 'Tags' => [
+ 'EmailTags' => [
['Name' => 'foo', 'Value' => 'bar'],
],
],
@@ -153,7 +161,9 @@ composer require aws/aws-sdk-php
При создании приложений Laravel каждый тип электронной почты, отправляемой вашим приложением, представляется экземпляром класса `Illuminate\Mail\Mailable`. Эти классы хранятся в каталоге `app/Mail`. Не беспокойтесь, если вы не видите этот каталог в своем приложении, поскольку он будет сгенерирован для вас, когда вы создадите свой первый почтовый класс с помощью команды `make:mail` [Artisan](artisan.md):
- php artisan make:mail OrderShipped
+```shell
+php artisan make:mail OrderShipped
+```
## Написание отправлений
@@ -437,11 +447,13 @@ composer require aws/aws-sdk-php
Встраивание изображений в ваши электронные письма, как правило, обременительно; однако Laravel предлагает удобный способ прикреплять изображения к вашим письмам. Чтобы встроить изображение, используйте метод `embed` для переменной `$message` в вашем шаблоне электронной почты. Laravel автоматически делает переменную `$message` доступной для всех ваших шаблонов электронной почты, поэтому вам не нужно беспокоиться о ее передаче вручную:
-
- Here is an image:
+```blade
+
+ Here is an image:
-
-
+
+
+```
> {note} Переменная `$message` недоступна в шаблонах текстовых сообщений, так как в текстовых сообщениях не используются встроенные вложения.
@@ -450,16 +462,20 @@ composer require aws/aws-sdk-php
Если у вас уже есть строка необработанных данных изображения, которую вы хотите встроить в шаблон электронной почты, то вы можете вызвать метод `embedData` для переменной `$message`. При вызове метода `embedData` вам необходимо указать имя файла, которое должно быть присвоено встраиваемому изображению:
-
- Here is an image from raw data:
+```blade
+
+ Here is an image from raw data:
-
-
+
+
+```
-
-### Настройка сообщения SwiftMailer
+
+### Настройка сообщения Symfony
-Метод `withSwiftMessage` базового класса `Mailable` позволяет вам зарегистрировать замыкание, которое будет вызываться с экземпляром сообщения SwiftMailer перед отправкой сообщения. Это дает вам возможность глубокой настройки сообщения перед его доставкой:
+Метод `withSymfonyMessage` базового класса `Mailable` позволяет вам зарегистрировать замыкание, которое будет вызываться с экземпляром сообщения Symfony перед отправкой сообщения. Это дает вам возможность глубокой настройки сообщения перед его доставкой:
+
+ use Symfony\Component\Mime\Email;
/**
* Создать сообщение.
@@ -470,7 +486,7 @@ composer require aws/aws-sdk-php
{
$this->view('emails.orders.shipped');
- $this->withSwiftMessage(function ($message) {
+ $this->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'Custom-Header', 'Header Value'
);
@@ -489,7 +505,9 @@ composer require aws/aws-sdk-php
Чтобы сгенерировать почтовый класс с соответствующим шаблоном Markdown, вы можете использовать параметр `--markdown` в команде `make:mail` Artisan:
- php artisan make:mail OrderShipped --markdown=emails.orders.shipped
+```shell
+php artisan make:mail OrderShipped --markdown=emails.orders.shipped
+```
Затем, в методе `build` почтового класса вызовите метод `markdown` вместо метода `view`. Метод `markdown` принимает имя шаблона Markdown и необязательный массив данных, которые должны быть доступны для шаблона:
@@ -511,18 +529,20 @@ composer require aws/aws-sdk-php
Почтовые сообщения Markdown используют комбинацию компонентов Blade и синтаксиса Markdown, которые позволяют легко создавать почтовые сообщения, используя предварительно созданные компоненты пользовательского интерфейса электронной почты Laravel:
- @component('mail::message')
- # Order Shipped
+```blade
+@component('mail::message')
+# Order Shipped
- Your order has been shipped!
+Your order has been shipped!
- @component('mail::button', ['url' => $url])
- View Order
- @endcomponent
+@component('mail::button', ['url' => $url])
+View Order
+@endcomponent
- Thanks,
- {{ config('app.name') }}
- @endcomponent
+Thanks,
+{{ config('app.name') }}
+@endcomponent
+```
> {tip} Не используйте лишние отступы при написании писем Markdown. По стандартам Markdown парсеры будут отображать контент с отступом в виде блоков кода.
@@ -531,37 +551,45 @@ composer require aws/aws-sdk-php
Компонент кнопки отображает ссылку на кнопку по центру. Компонент принимает два аргумента: `url` и необязательный `color`. Поддерживаемые цвета: `primary`, `success` и `error`. Вы можете добавить к сообщению столько компонентов кнопки, сколько захотите:
- @component('mail::button', ['url' => $url, 'color' => 'success'])
- View Order
- @endcomponent
+```blade
+@component('mail::button', ['url' => $url, 'color' => 'success'])
+View Order
+@endcomponent
+```
#### Компонент Panel
Компонент панели отображает указанный блок текста на панели, цвет фона которой немного отличается от цвета остальной части сообщения. Это позволяет привлечь внимание к указанному блоку текста:
- @component('mail::panel')
- This is the panel content.
- @endcomponent
+```blade
+@component('mail::panel')
+This is the panel content.
+@endcomponent
+```
#### Компонент Table
Компонент таблицы позволяет преобразовать таблицу Markdown в таблицу HTML. Компонент принимает в качестве содержимого таблицу Markdown. Выравнивание столбцов таблицы поддерживается с использованием синтаксиса выравнивания таблицы Markdown по умолчанию:
- @component('mail::table')
- | Laravel | Table | Example |
- | ------------- |:-------------:| --------:|
- | Col 2 is | Centered | $10 |
- | Col 3 is | Right-Aligned | $20 |
- @endcomponent
+```blade
+@component('mail::table')
+| Laravel | Table | Example |
+| ------------- |:-------------:| --------:|
+| Col 2 is | Centered | $10 |
+| Col 3 is | Right-Aligned | $20 |
+@endcomponent
+```
### Изменение компонентов
Вы можете экспортировать все почтовые компоненты Markdown в собственное приложение для их дальнейшего изменения. Чтобы экспортировать компоненты, используйте команду `vendor:publish` Artisan с параметром `--tag=laravel-mail`:
- php artisan vendor:publish --tag=laravel-mail
+```shell
+php artisan vendor:publish --tag=laravel-mail
+```
Эта команда опубликует почтовые компоненты Markdown в каталоге `resources/views/vendor/mail`. Каталог `mail` будет содержать каталог `html` и `text`, каждый из которых содержит соответствующие представления каждого доступного компонента. Вы можете настроить эти компоненты по своему усмотрению.
@@ -785,7 +813,7 @@ Laravel позволяет отправлять почтовые сообщен
## Тестирование отправлений
-Laravel предлагает несколько удобных методов для тестирования того, что ваши почтовые сообщения содержат ожидаемый контент. Это следующие методы: `assertSeeInHtml`, `assertDontSeeInHtml`, `assertSeeInText` и `assertDontSeeInText`.
+Laravel предлагает несколько удобных методов для тестирования того, что ваши почтовые сообщения содержат ожидаемый контент. Это следующие методы: `assertSeeInHtml`, `assertDontSeeInHtml`, `assertSeeInOrderInHtml`, `assertSeeInText`, `assertDontSeeInText` и `assertSeeInOrderInText`.
Как и следовало ожидать, утверждения «HTML» утверждают, что HTML-версия вашего почтового сообщения содержит переданную строку, в то время как утверждения «текст» утверждают, что текстовая версия вашего почтового сообщения содержит переданную строку:
@@ -800,9 +828,10 @@ Laravel предлагает несколько удобных методов д
$mailable->assertSeeInHtml($user->email);
$mailable->assertSeeInHtml('Invoice Paid');
+ $mailable->assertSeeInOrderInHtml(['Invoice Paid', 'Thanks']);
$mailable->assertSeeInText($user->email);
- $mailable->assertSeeInText('Invoice Paid');
+ $mailable->assertSeeInOrderInText(['Invoice Paid', 'Thanks']);
}
@@ -864,3 +893,124 @@ Laravel запускает два события в процессе отпра
'App\Listeners\LogSentMessage',
],
];
+
+
+## Пользовательские драйвера
+
+Laravel включает множество почтовых транспортов; однако вы можете написать свои собственные транспорты для доставки электронной почты через другие сервисы, которые Laravel не поддерживает по умолчанию. Для начала определите класс, который расширяет класс `Symfony\Component\Mailer\Transport\AbstractTransport`. Затем реализуйте методы `doSend` и `__toString()` в вашем классе транспорта:
+
+ use MailchimpTransactional\ApiClient;
+ use Symfony\Component\Mailer\SentMessage;
+ use Symfony\Component\Mailer\Transport\AbstractTransport;
+ use Symfony\Component\Mime\MessageConverter;
+
+ class MailchimpTransport extends AbstractTransport
+ {
+ /**
+ * Клиент Mailchimp API.
+ *
+ * @var \MailchimpTransactional\ApiClient
+ */
+ protected $client;
+
+ /**
+ * Создать новый экземпляр транспорта Mailchimp.
+ *
+ * @param \MailchimpTransactional\ApiClient $client
+ * @return void
+ */
+ public function __construct(ApiClient $client)
+ {
+ $this->client = $client
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function doSend(SentMessage $message): void
+ {
+ $email = MessageConverter::toEmail($message->getOriginalMessage());
+
+ $this->client->messages->send(['message' => [
+ 'from_email' => $email->getFrom(),
+ 'to' => collect($email->getTo())->map(function ($email) {
+ return ['email' => $email->getAddress(), 'type' => 'to'];
+ })->all(),
+ 'subject' => $email->getSubject(),
+ 'text' => $email->getTextBody(),
+ ]]);
+ }
+
+ /**
+ * Получить строковое представление транспорта.
+ *
+ * @return string
+ */
+ public function __toString(): string
+ {
+ return 'mailchimp';
+ }
+ }
+
+После того, как вы определили свой собственный транспорт, вы можете зарегистрировать его с помощью метода `extend` фасада `Mail`. Как правило, это должно быть сделано в методе `boot` поставщика `AppServiceProvider` вашего приложения. Аргумент `$config` будет передан замыканию метода `extend`. Этот аргумент будет содержать массив конфигурации, определенный для почтовой программы в конфигурационном файле `config/mail.php` приложения:
+
+ use App\Mail\MailchimpTransport;
+ use Illuminate\Support\Facades\Mail;
+
+ /**
+ * Загрузка любых служб приложения.
+ *
+ * @return void
+ */
+ public function boot()
+ {
+ Mail::extend('mailchimp', function (array $config = []) {
+ return new MailchimpTransport(...);
+ })
+ }
+
+После того, как ваш пользовательский транспорт был определен и зарегистрирован, для использования нового транспорта вы можете создать определение почтовой программы в конфигурационном файле `config/mail.php` вашего приложения:
+
+ 'mailchimp' => [
+ 'transport' => 'mailchimp',
+ // ...
+ ],
+
+
+### Дополнительные драйвера Symfony
+
+Laravel включает поддержку некоторых существующих почтовых транспортов, поддерживаемых Symfony, таких как Mailgun и Postmark. Однако вы можете захотеть расширить Laravel поддержкой дополнительных транспортов, поддерживаемых Symfony. Вы можете сделать это, потребовав необходимую почтовую программу Symfony через Composer и зарегистрировав транспорт в Laravel. Например, вы можете установить и зарегистрировать почтовую программу Symfony Sendinblue:
+
+```none
+composer require symfony/sendinblue-mailer
+```
+
+После установки пакета Sendinblue вы можете добавить запись для своих учетных данных в конфигурационном файле `services` вашего приложения:
+
+ 'sendinblue' => [
+ 'key' => 'your-api-key',
+ ],
+
+Наконец, вы можете использовать метод `extend` фасада `Mail` для регистрации транспорта в Laravel. Как правило, это должно быть сделано в методе `boot` поставщика `AppServiceProvider` вашего приложения:
+
+ use Illuminate\Support\Facades\Mail;
+ use Symfony\Component\Mailer\Bridge\Sendinblue\Transport\SendinblueTransportFactory;
+ use Symfony\Component\Mailer\Transport\Dsn;
+
+ /**
+ * Загрузка любых служб приложения.
+ *
+ * @return void
+ */
+ public function boot()
+ {
+ Mail::extend('sendinblue', function () {
+ return (new SendinblueTransportFactory)->create(
+ new Dsn(
+ 'sendinblue+api',
+ 'default',
+ config('services.sendinblue.key')
+ )
+ );
+ });
+ }
diff --git a/docs/middleware.md b/docs/middleware.md
index bc2642c..0fa27b6 100644
--- a/docs/middleware.md
+++ b/docs/middleware.md
@@ -22,7 +22,9 @@
Чтобы создать нового посредника, используйте команду `make:middleware` [Artisan](artisan.md):
- php artisan make:middleware EnsureTokenIsValid
+```shell
+php artisan make:middleware EnsureTokenIsValid
+```
Эта команда поместит новый класс посредника в каталог `app/Http/Middleware` вашего приложения. В этом посреднике мы будем разрешать доступ к маршруту только в том случае, если значение входящего `token` соответствует указанному. В противном случае мы перенаправим пользователя по маршруту `home`:
diff --git a/docs/migrations.md b/docs/migrations.md
index 9808937..c7b1823 100644
--- a/docs/migrations.md
+++ b/docs/migrations.md
@@ -35,7 +35,9 @@
Чтобы сгенерировать новую миграцию базы данных, используйте команду `make:migration` [Artisan](artisan.md). Эта команда поместит новый класс миграции в каталог `database/migrations` вашего приложения. Каждое имя файла миграции содержит временную метку, которая позволяет Laravel определять порядок применения миграций:
- php artisan make:migration create_flights_table
+```shell
+php artisan make:migration create_flights_table
+```
Laravel будет использовать имя миграции, чтобы попытаться угадать имя таблицы и будет ли миграция создавать новую таблицу. Если Laravel может определить имя таблицы по имени миграции, то сгенерированный файл миграции будет предварительно заполнен указанной таблицей. В противном случае вы можете просто вручную указать таблицу в файле миграции.
@@ -48,10 +50,12 @@ Laravel будет использовать имя миграции, чтобы
По мере создания приложения вы можете со временем накапливать все больше и больше миграций. Это может привести к тому, что ваш каталог `database/migrations` станет раздутым из-за потенциально сотен миграций. Если хотите, то можете «сжать» свои миграции в один файл SQL. Для начала выполните команду `schema:dump`:
- php artisan schema:dump
+```shell
+php artisan schema:dump
- // Выгрузить текущую схему БД и удалить все существующие миграции ...
- php artisan schema:dump --prune
+// Выгрузить текущую схему БД и удалить все существующие миграции ...
+php artisan schema:dump --prune
+```
Когда вы выполните эту команду, Laravel запишет файл «схемы» в каталог `database/schema` вашего приложения. Теперь, когда вы попытаетесь перенести свою базу данных, Laravel сначала выполнит SQL-операторы файла схемы, при условии, что никакие другие миграции не выполнялись. После выполнения команд файла схемы, Laravel выполнит все оставшиеся миграции, которые не были включены в дамп схемы БД.
@@ -72,7 +76,7 @@ Laravel будет использовать имя миграции, чтобы
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
- class CreateFlightsTable extends Migration
+ return new class extends Migration
{
/**
* Запустить миграцию.
@@ -98,7 +102,7 @@ Laravel будет использовать имя миграции, чтобы
{
Schema::drop('flights');
}
- }
+ };
#### Анонимные миграции
@@ -141,56 +145,74 @@ Laravel будет использовать имя миграции, чтобы
Чтобы запустить все незавершенные миграции, выполните команду `migrate` Artisan:
- php artisan migrate
+```shell
+php artisan migrate
+```
Если вы хотите узнать, какие миграции уже выполнены, то вы можете использовать команду `migrate:status` Artisan:
- php artisan migrate:status
+```shell
+php artisan migrate:status
+```
#### Принудительный запуск миграции в рабочем окружении
Некоторые операции миграции являются деструктивными, что означает, что они могут привести к потере данных. Чтобы защитить вас от запуска этих команд для вашей производственной базы данных, от вас потребуется подтверждение перед выполнением команд. Чтобы команды запускались без подтверждения, используйте флаг `--force`:
- php artisan migrate --force
+```shell
+php artisan migrate --force
+```
### Откат миграций
Чтобы откатить последнюю операцию миграции, вы можете использовать команду `rollback` Artisan. Эта команда откатывает последний «пакет» миграций, который может включать несколько файлов миграции:
- php artisan migrate:rollback
+```shell
+php artisan migrate:rollback
+```
Вы можете откатить ограниченное количество миграций, указав параметр `step` для команды `rollback`. Например, следующая команда откатит последние пять миграций:
- php artisan migrate:rollback --step=5
+```shell
+php artisan migrate:rollback --step=5
+```
Команда `migrate:reset` откатит все миграции вашего приложения:
- php artisan migrate:reset
+```shell
+php artisan migrate:reset
+```
#### Откат и миграция с помощью одной команды
Команда `migrate:refresh` откатит все ваши миграции, а затем выполнит команду `migrate`. Эта команда эффективно воссоздает всю вашу базу данных:
- php artisan migrate:refresh
+```shell
+php artisan migrate:refresh
- // Обновляем базу данных и запускаем все наполнители базы данных ...
- php artisan migrate:refresh --seed
+// Обновляем базу данных и запускаем все наполнители базы данных ...
+php artisan migrate:refresh --seed
+```
Вы можете откатить и повторно запустить ограниченное количество миграций, указав параметр `step` для команды `refresh`. Например, следующая команда откатит и повторно запустит последние пять миграций:
- php artisan migrate:refresh --step=5
+```shell
+php artisan migrate:refresh --step=5
+```
#### Удаление всех таблиц с последующей миграцией
Команда `migrate:fresh` удалит все таблицы из базы данных, а затем выполнит команду `migrate`:
- php artisan migrate:fresh
+```shell
+php artisan migrate:fresh
- php artisan migrate:fresh --seed
+php artisan migrate:fresh --seed
+```
> {note} Команда `migrate:fresh` удалит все таблицы базы данных независимо от их префикса. Эту команду следует использовать с осторожностью при разработке в базе данных, которая используется совместно с другими приложениями.
@@ -900,7 +922,7 @@ Laravel будет использовать имя миграции, чтобы
use Illuminate\Database\Query\Expression;
use Illuminate\Database\Migrations\Migration;
- class CreateFlightsTable extends Migration
+ return new class extends Migration
{
/**
* Запустить миграцию.
@@ -915,7 +937,7 @@ Laravel будет использовать имя миграции, чтобы
$table->timestamps();
});
}
- }
+ };
> {note} Поддержка выражений по умолчанию зависит от вашего драйвера базы данных, версии базы данных и типа поля. См. документацию к вашей базе данных.
@@ -1051,8 +1073,8 @@ Laravel содержит несколько удобных методов, св
`$table->primary(['id', 'parent_id']);` | Добавить составной ключ.
`$table->unique('email');` | Добавить уникальный индекс.
`$table->index('state');` | Добавить простой индекс.
-`$table->fulltext('body');` | Добавить полнотекстовый индекс (MySQL/PostgreSQL).
-`$table->fulltext('body')->language('english');` | Добавить полнотекстовый индекс для указанного языка (PostgreSQL).
+`$table->fullText('body');` | Добавить полнотекстовый индекс (MySQL/PostgreSQL).
+`$table->fullText('body')->language('english');` | Добавить полнотекстовый индекс для указанного языка (PostgreSQL).
`$table->spatialIndex('location');` | Добавить пространственный индекс (кроме SQLite).
diff --git a/docs/mix.md b/docs/mix.md
index daf28e5..86d5035 100644
--- a/docs/mix.md
+++ b/docs/mix.md
@@ -22,12 +22,14 @@
## Введение
-[Laravel Mix](https://github.com/JeffreyWay/laravel-mix) – это пакет, разработанный создателем [Laracasts](https://laracasts.com) Джеффри Уэй, предлагает гибкий API для определения шагов сборки [Webpack](https://webpack.js.org) для вашего приложения с использованием нескольких распространенных препроцессоров CSS и JavaScript.
+[Laravel Mix](https://github.com/laravel-mix/laravel-mix) – это пакет, разработанный создателем [Laracasts](https://laracasts.com) Джеффри Уэй, предлагает гибкий API для определения шагов сборки [Webpack](https://webpack.js.org) для вашего приложения с использованием нескольких распространенных препроцессоров CSS и JavaScript.
Другими словами, Mix упрощает компиляцию и минимизацию файлов CSS и JavaScript вашего приложения. Посредством простой цепочки методов вы можете гибко определять свой сценарий по сборки веб-актива. Например:
- mix.js('resources/js/app.js', 'public/js')
- .postCss('resources/css/app.css', 'public/css');
+```js
+mix.js('resources/js/app.js', 'public/js')
+ .postCss('resources/css/app.css', 'public/css');
+```
Если вы однажды были сбиты с толку и ошеломлены, начав работу с Webpack, то вам понравится Laravel Mix. Однако от вас не требуется использовать его при разработке приложения; вы можете использовать любой желаемый инструмент сборки, или даже не использовать его вовсе. Справедливо и обратное: вы можете использовать Laravel Mix без привязки вашего приложения к фреймворку Laravel.
@@ -41,42 +43,54 @@
Перед запуском Mix вы должны сначала убедиться, что на вашем компьютере установлены Node.js и NPM:
- node -v
- npm -v
+```shell
+node -v
+npm -v
+```
Вы можете легко установить последнюю версию Node и NPM с помощью простых графических установщиков с [официального веб-сайта Node](https://nodejs.org/en/download/). Или, если вы используете [Laravel Sail](sail.md), вы можете вызывать Node и NPM через Sail:
- ./sail node -v
- ./sail npm -v
+```shell
+./sail node -v
+./sail npm -v
+```
#### Установка Laravel Mix
Единственный оставшийся шаг – установить Laravel Mix. В свежей установке Laravel вы найдете файл `package.json` в вашем корневом каталоге. Файл `package.json` по умолчанию уже включает в себя все, что вам нужно для начала работы с Laravel Mix. Думайте об этом файле как о вашем файле `composer.json`, за исключением того, что он определяет зависимости Node вместо зависимостей PHP. Вы можете установить зависимости, на которые он ссылается, запустив:
- npm install
+```shell
+npm install
+```
## Запуск Mix
Mix – это слой конфигурации поверх [Webpack](https://webpack.js.org), поэтому для запуска задач Mix вам нужно только выполнить один из сценариев NPM, который содержится в файле `package.json` по умолчанию. Когда вы запускаете сценарии `dev` или `production`, все исходники активов CSS и JavaScript вашего приложения будут скомпилированы и помещены в каталог `public` приложения:
- // Запустить все задачи Mix ...
- npm run dev
+```shell
+// Запустить все задачи Mix ...
+npm run dev
- // Запустить все задачи Mix и минифицировать на выходе ...
- npm run prod
+// Запустить все задачи Mix и минифицировать на выходе ...
+npm run prod
+```
#### Наблюдение за изменениями исходников веб-активов
Команда `npm run watch` продолжит работу в консоли и будет следить за изменениями во всех соответствующих файлах CSS и JavaScript. Webpack автоматически перекомпилирует ваши исходники, когда обнаружит изменение в одном из этих файлов:
- npm run watch
+```shell
+npm run watch
+```
Webpack может не обнаруживать изменения ваших файлов в определенных локальных средах разработки. Если это наблюдается в вашей системе, рассмотрите возможность использования команды `watch-poll`:
- npm run watch-poll
+```shell
+npm run watch-poll
+```
## Работа с таблицами стилей
@@ -88,11 +102,13 @@ Webpack может не обнаруживать изменения ваших
[Tailwind CSS](https://tailwindcss.com) – это современный, низкоутилитарный фреймворк для создания удивительных сайтов, не покидая HTML-разметку. Давайте рассмотрим, как начать использовать его в проекте Laravel совместно с Mix. Во-первых, мы должны установить Tailwind с помощью NPM и сгенерировать наш конфигурационный файл Tailwind:
- npm install
+```shell
+npm install
- npm install -D tailwindcss
+npm install -D tailwindcss
- npx tailwindcss init
+npx tailwindcss init
+```
Команда `init` сгенерирует файл `tailwind.config.js`. Раздел `content` этого файла позволяет вам настроить пути ко всем вашим шаблонам HTML, компонентам JavaScript и любым другим исходным файлам, которые содержат имена классов Tailwind, чтобы все классы CSS, не используемые в этих файлах, были удалены из вашего конечного файла CSS:
@@ -124,7 +140,7 @@ mix.js('resources/js/app.js', 'public/js')
Наконец, вы должны указать свою таблицу стилей в основном шаблоне макета вашего приложения. Многие разработчики приложений предпочитают хранить этот шаблон в `resources/views/layouts/app.blade.php`. Кроме того, убедитесь, что вы добавили метатег `viewport`, если он еще не присутствует:
-```html
+```blade
@@ -139,79 +155,101 @@ mix.js('resources/js/app.js', 'public/js')
Сначала установите нужный плагин через NPM и включите его в свой массив плагинов при вызове метода `postCss` Mix. Метод `postCss` принимает путь к вашему файлу CSS в качестве первого аргумента, а в качестве второго аргумента – каталог, в который следует поместить скомпилированный файл:
- mix.postCss('resources/css/app.css', 'public/css', [
- require('postcss-custom-properties')
- ]);
+```js
+mix.postCss('resources/css/app.css', 'public/css', [
+ require('postcss-custom-properties')
+]);
+```
Или вы можете выполнить `postCss` без дополнительных плагинов, чтобы получить простую компиляцию и минификацию CSS:
- mix.postCss('resources/css/app.css', 'public/css');
+```js
+mix.postCss('resources/css/app.css', 'public/css');
+```
### Sass
Метод `sass` позволяет вам скомпилировать [Sass](https://sass-lang.com/) в CSS, понятный веб-браузерам. Метод `sass` принимает путь к вашему файлу Sass в качестве своего первого аргумента и каталог, в который должен быть помещен скомпилированный файл, в качестве второго аргумента:
- mix.sass('resources/sass/app.scss', 'public/css');
+```js
+mix.sass('resources/sass/app.scss', 'public/css');
+```
Вы можете скомпилировать несколько файлов Sass в отдельные файлы CSS и даже настроить каталог назначения результирующего CSS, вызывая метод `sass` несколько раз:
- mix.sass('resources/sass/app.sass', 'public/css')
- .sass('resources/sass/admin.sass', 'public/css/admin');
+```js
+mix.sass('resources/sass/app.sass', 'public/css')
+ .sass('resources/sass/admin.sass', 'public/css/admin');
+```
### Обработка URL
Поскольку Laravel Mix построен поверх Webpack, важно понимать несколько концепций Webpack. Для компиляции CSS Webpack перезапишет и оптимизирует любые вызовы `url()` в ваших таблицах стилей. Хотя поначалу это может показаться странным, это невероятно мощная функциональность. Представьте, что мы хотим скомпилировать Sass, который включает относительный URL-адрес изображения:
- .example {
- background: url('../images/example.png');
- }
+```css
+.example {
+ background: url('../images/example.png');
+}
+```
> {note} Абсолютные пути для любого заданного `url()` будут исключены из перезаписи URL. Например, `url('/images/thing.png')` или `url('http://example.com/images/thing.png')` не будут изменены.
По умолчанию Laravel Mix и Webpack найдут `example.png`, скопируют его в вашу папку `public/images`, а затем перепишут `url()` в созданной вами таблице стилей. Таким образом, ваш скомпилированный CSS будет:
- .example {
- background: url(/images/example.png?d41d8cd98f00b204e9800998ecf8427e);
- }
+```css
+.example {
+ background: url(/images/example.png?d41d8cd98f00b204e9800998ecf8427e);
+}
+```
Какой бы полезной ни была эта функция, возможно, что ваша существующая структура папок уже настроена так, как вам нравится. В этом случае вы можете отключить перезапись `url()` следующим образом:
- mix.sass('resources/sass/app.scss', 'public/css').options({
- processCssUrls: false
- });
+```js
+mix.sass('resources/sass/app.scss', 'public/css').options({
+ processCssUrls: false
+});
+```
После добавления этой записи в ваш файл `webpack.mix.js`, Mix больше не будет сопоставлять какой-либо `url()` или копировать веб-активы в ваш публичный каталог. Другими словами, скомпилированный CSS будет выглядеть так же, как вы его изначально указали:
- .example {
- background: url("../images/thing.png");
- }
+```css
+.example {
+ background: url("../images/thing.png");
+}
+```
### Карты исходников CSS
Хотя по умолчанию они отключены, карты исходников могут быть активированы путем вызова метода `mix.sourceMaps()` в вашем файле `webpack.mix.js`. Хоть это и связано с затратами на компиляцию / производительность, но, в свою очередь, предоставит дополнительную отладочную информацию в инструментах разработчика вашего браузера при использовании скомпилированных веб-активов:
- mix.js('resources/js/app.js', 'public/js')
- .sourceMaps();
+```js
+mix.js('resources/js/app.js', 'public/js')
+ .sourceMaps();
+```
#### Стиль сопоставления исходников
Webpack предлагает множество [стилей сопоставления исходников](https://webpack.js.org/configuration/devtool/#devtool). По умолчанию стиль сопоставления исходников Mix установлен как `eval-source-map`, что обеспечивает быстрое время перестроения. Если вы хотите изменить стиль сопоставления, то вы можете сделать это с помощью метода `sourceMaps`:
- let productionSourceMaps = false;
+```js
+let productionSourceMaps = false;
- mix.js('resources/js/app.js', 'public/js')
- .sourceMaps(productionSourceMaps, 'source-map');
+mix.js('resources/js/app.js', 'public/js')
+ .sourceMaps(productionSourceMaps, 'source-map');
+```
## Работа с JavaScript
Mix содержит несколько функций, которые помогут вам работать с вашими файлами JavaScript, например, компиляция современного ECMAScript, объединение модулей, минификация и объединение простых файлов JavaScript. Более того, все это работает без проблем, не требуя ни унции специального конфигурирования:
- mix.js('resources/js/app.js', 'public/js');
+```js
+mix.js('resources/js/app.js', 'public/js');
+```
Теперь, с помощью одной строчки кода вы можете воспользоваться следующими преимуществами:
@@ -228,12 +266,14 @@ Mix содержит несколько функций, которые помо
Mix автоматически установит плагины Babel, необходимые для поддержки компиляции однофайловых компонентов Vue при использовании метода `vue`. Никакой дополнительной настройки не требуется:
- mix.js('resources/js/app.js', 'public/js')
- .vue();
+```js
+mix.js('resources/js/app.js', 'public/js')
+ .vue();
+```
После того, как ваш JavaScript скомпилирован, вы можете ссылаться на него в своем приложении:
-```html
+```blade
@@ -246,12 +286,14 @@ Mix автоматически установит плагины Babel, необ
Mix автоматически установит плагины Babel, необходимые для поддержки React. Для начала добавьте вызов метода `react`:
- mix.js('resources/js/app.jsx', 'public/js')
- .react();
+```js
+mix.js('resources/js/app.jsx', 'public/js')
+ .react();
+```
За кулисами Mix загрузит и включит соответствующий плагин `babel-preset-react` Babel. После того, как ваш JavaScript скомпилирован, вы можете ссылаться на него в своем приложении:
-```html
+```blade
@@ -266,8 +308,10 @@ Mix автоматически установит плагины Babel, необ
Если вы намереваетесь часто обновлять JavaScript своего приложения, вам следует рассмотреть возможность извлечения всех сторонних библиотек в их собственный файл. Таким образом, изменение кода вашего приложения не повлияет на кеширование вашего большого файла `vendor.js`. Метод `extract` Mix делает это проще простого:
- mix.js('resources/js/app.js', 'public/js')
- .extract(['vue'])
+```js
+mix.js('resources/js/app.js', 'public/js')
+ .extract(['vue'])
+```
Метод `extract` принимает массив всех библиотек или модулей, которые вы хотите извлечь в файл `vendor.js`. Используя приведенный выше фрагмент в качестве примера, Mix сгенерирует следующие файлы:
@@ -281,9 +325,11 @@ Mix автоматически установит плагины Babel, необ
Чтобы избежать ошибок JavaScript, обязательно загружайте эти файлы в правильном порядке:
-
-
-
+```html
+
+
+
+```
### Пользовательская конфигурация Webpack
@@ -292,13 +338,15 @@ Mix автоматически установит плагины Babel, необ
Mix содержит полезный метод `webpackConfig`, который позволяет вам объединить небольшие переопределения конфигурации Webpack. Это особенно привлекательный вариант, поскольку он не требует от вас копирования и поддержки вашей собственной копии файла `webpack.config.js`. Метод `webpackConfig` принимает объект, который должен содержать любую [специфичную для Webpack конфигурацию](https://webpack.js.org/configuration/), которую вы хотите применить.
- mix.webpackConfig({
- resolve: {
- modules: [
- path.resolve(__dirname, 'vendor/laravel/spark/resources/assets/js')
- ]
- }
- });
+```js
+mix.webpackConfig({
+ resolve: {
+ modules: [
+ path.resolve(__dirname, 'vendor/laravel/spark/resources/assets/js')
+ ]
+ }
+});
+```
## Версионирование / очистка кеша
@@ -307,20 +355,26 @@ Mix содержит полезный метод `webpackConfig`, который
Метод `version` добавит уникальный хеш к именам файлов всех скомпилированных исходников, что сделает очистку кеша более удобной:
- mix.js('resources/js/app.js', 'public/js')
- .version();
+```js
+mix.js('resources/js/app.js', 'public/js')
+ .version();
+```
После создания файла версионирования вы не узнаете его точное имя. Итак, вы должны использовать глобальную функцию `mix` Laravel в вашем [шаблоне](views.md) для загрузки хешированного веб-актива. Глобальная функция `mix` фреймворка Laravel автоматически определит текущее имя хешированного файла:
-
+```blade
+
+```
Поскольку файлы с поддержкой версий обычно нужны только в эксплуатационном окружении, вы можете указать, чтобы процесс управления версиями выполнялся только во время запуска `npm run prod`:
- mix.js('resources/js/app.js', 'public/js');
+```js
+mix.js('resources/js/app.js', 'public/js');
- if (mix.inProduction()) {
- mix.version();
- }
+if (mix.inProduction()) {
+ mix.version();
+}
+```
#### Изменение базовых URL-адресов с помощью Mix
@@ -331,7 +385,7 @@ Mix содержит полезный метод `webpackConfig`, который
После указания URL-адреса, функция `mix` будет подставлять указанный префикс при создании URL-адресов для веб-активов:
-```bash
+```shell
https://cdn.example.com/js/app.js?id=1964becbdd96414518cd
```
@@ -359,15 +413,21 @@ mix.browserSync({
Вы можете использовать переменные окружения в своем `webpack.mix.js`, добавив к одной из переменных префикс `MIX_` в вашем файле `.env`:
- MIX_SENTRY_DSN_PUBLIC=http://example.com
+```ini
+MIX_SENTRY_DSN_PUBLIC=http://example.com
+```
После того, как переменная была определена в вашем файле `.env`, вы можете получить к ней доступ через объект `process.env`. Однако, вам нужно будет перезапустить задание, если значение переменной среды изменится во время ее выполнения:
- process.env.MIX_SENTRY_DSN_PUBLIC
+```js
+process.env.MIX_SENTRY_DSN_PUBLIC
+```
## Уведомления
Когда доступно, Mix будет автоматически отображать уведомления ОС при компиляции, давая вам мгновенную информацию о том, была ли компиляция успешной или нет. Однако, могут быть случаи, когда вы предпочтете отключить эти уведомления. Одним из таких примеров может быть запуск Mix на вашем рабочем сервере. Уведомления можно отключить с помощью метода `disableNotifications`:
- mix.disableNotifications();
+```js
+mix.disableNotifications();
+```
diff --git a/docs/notifications.md b/docs/notifications.md
index 7a5f238..cfc44c8 100644
--- a/docs/notifications.md
+++ b/docs/notifications.md
@@ -59,7 +59,9 @@
В Laravel каждое уведомление представлено единым классом. Чтобы сгенерировать новое уведомление, используйте команду `make:notification` [Artisan](artisan.md). Эта команда поместит новый класс уведомления в каталог `app/Notifications` вашего приложения. Если этот каталог не существует в вашем приложении, то Laravel предварительно создаст его:
- php artisan make:notification InvoicePaid
+```shell
+php artisan make:notification InvoicePaid
+```
Каждый класс уведомления содержит метод `via` и переменное количество методов формирования сообщений, таких как `toMail` или `toDatabase`, которые преобразуют уведомление в сообщение, адаптированное для этого конкретного канала.
@@ -107,7 +109,7 @@
### Определение каналов доставки
-Каждый класс уведомлений имеет метод `via`, который определяет, по каким каналам будет доставлено уведомление. Уведомления можно отправлять по каналам `mail`, `database`, `broadcast`, `nexmo` и `slack`.
+Каждый класс уведомлений имеет метод `via`, который определяет, по каким каналам будет доставлено уведомление. Уведомления можно отправлять по каналам `mail`, `database`, `broadcast`, `vonage` и `slack`.
> {tip} Если вы хотите использовать другие каналы доставки, такие как Telegram или Pusher, то посетите веб-сайт сообщества [Laravel Notification Channels](http://laravel-notification-channels.com).
@@ -121,7 +123,7 @@
*/
public function via($notifiable)
{
- return $notifiable->prefers_sms ? ['nexmo'] : ['mail', 'database'];
+ return $notifiable->prefers_sms ? ['vonage'] : ['mail', 'database'];
}
@@ -258,7 +260,7 @@
По желанию можно отправить уведомление кому-то, кто не сохранен как «пользователь» вашего приложения. Используя метод `route` фасада `Notification`, вы можете указать информацию о маршрутизации специального уведомления перед отправкой уведомления:
Notification::route('mail', 'taylor@example.com')
- ->route('nexmo', '5555555555')
+ ->route('vonage', '5555555555')
->route('slack', 'https://hooks.slack.com/services/...')
->notify(new InvoicePaid($invoice));
@@ -447,7 +449,9 @@
Вы можете изменить шаблон из HTML и обычного текста, используемый для почтовых уведомлений, опубликовав необходимые ресурсы уведомления. После выполнения этой команды шаблоны почтовых уведомлений будут расположены в каталоге `resources/views/vendor/notifications`:
- php artisan vendor:publish --tag=laravel-notifications
+```shell
+php artisan vendor:publish --tag=laravel-notifications
+```
### Почтовые вложения
@@ -590,7 +594,9 @@
Чтобы сгенерировать уведомление с соответствующим шаблоном Markdown, вы можете использовать параметр `--markdown` команды `make:notification` Artisan:
- php artisan make:notification InvoicePaid --markdown=mail.invoice.paid
+```shell
+php artisan make:notification InvoicePaid --markdown=mail.invoice.paid
+```
Как и все другие почтовые уведомления, уведомления, использующие шаблоны Markdown, должны определять метод `toMail` в своем классе уведомлений. Однако вместо использования методов `line` и `action` для создания уведомления используйте метод `markdown`, чтобы указать имя шаблона Markdown, который следует использовать. Массив данных, который вы хотите сделать доступным для шаблона, может быть передан в качестве второго аргумента метода:
@@ -614,55 +620,65 @@
Почтовые уведомления Markdown используют комбинацию компонентов Blade и синтаксиса Markdown, которые позволяют легко создавать почтовые уведомления, используя предварительно созданные компоненты уведомлений Laravel:
- @component('mail::message')
- # Invoice Paid
+```blade
+@component('mail::message')
+# Invoice Paid
- Your invoice has been paid!
+Your invoice has been paid!
- @component('mail::button', ['url' => $url])
- View Invoice
- @endcomponent
+@component('mail::button', ['url' => $url])
+View Invoice
+@endcomponent
- Thanks,
- {{ config('app.name') }}
- @endcomponent
+Thanks,
+{{ config('app.name') }}
+@endcomponent
+```
#### Компонент Button
Компонент кнопки отображает ссылку на кнопку по центру. Компонент принимает два аргумента: `url` и необязательный `color`. Поддерживаемые цвета: `primary`, `green` и `red`. Вы можете добавить к уведомлению столько компонентов кнопки, сколько захотите:
- @component('mail::button', ['url' => $url, 'color' => 'green'])
- View Invoice
- @endcomponent
+```blade
+@component('mail::button', ['url' => $url, 'color' => 'green'])
+View Invoice
+@endcomponent
+```
#### Компонент Panel
Компонент панели отображает указанный блок текста на панели, цвет фона которой немного отличается от цвета остальной части сообщения. Это позволяет привлечь внимание к указанному блоку текста:
- @component('mail::panel')
- This is the panel content.
- @endcomponent
+```blade
+@component('mail::panel')
+This is the panel content.
+@endcomponent
+```
#### Компонент Table
Компонент таблицы позволяет преобразовать таблицу Markdown в таблицу HTML. Компонент принимает в качестве содержимого таблицу Markdown. Выравнивание столбцов таблицы поддерживается с использованием синтаксиса выравнивания таблицы Markdown по умолчанию:
- @component('mail::table')
- | Laravel | Table | Example |
- | ------------- |:-------------:| --------:|
- | Col 2 is | Centered | $10 |
- | Col 3 is | Right-Aligned | $20 |
- @endcomponent
+```blade
+@component('mail::table')
+| Laravel | Table | Example |
+| ------------- |:-------------:| --------:|
+| Col 2 is | Centered | $10 |
+| Col 3 is | Right-Aligned | $20 |
+@endcomponent
+```
### Изменение компонентов
Вы можете экспортировать все почтовые компоненты Markdown в собственное приложение для их дальнейшего изменения. Чтобы экспортировать компоненты, используйте команду `vendor:publish` Artisan с параметром `--tag=laravel-mail`:
- php artisan vendor:publish --tag=laravel-mail
+```shell
+php artisan vendor:publish --tag=laravel-mail
+```
Эта команда опубликует почтовые компоненты Markdown в каталоге `resources/views/vendor/mail`. Каталог `mail` будет содержать каталог `html` и `text`, каждый из которых содержит соответствующие представления каждого доступного компонента. Вы можете настроить эти компоненты по своему усмотрению.
@@ -699,9 +715,11 @@
Вы можете запросить таблицу, чтобы отобразить уведомления в пользовательском интерфейсе вашего приложения. Но прежде чем вы сможете это сделать, вам нужно будет создать таблицу базы данных для хранения ваших уведомлений. Вы можете использовать команду `notifications:table` для создания [миграции](migrations.md) с необходимой схемой таблицы:
- php artisan notifications:table
+```shell
+php artisan notifications:table
- php artisan migrate
+php artisan migrate
+```
### Формирование уведомлений канала `database`
@@ -874,90 +892,63 @@
Отправка SMS-уведомлений в Laravel обеспечивается [Vonage](https://www.vonage.com/) (бывший Nexmo). Прежде чем вы сможете отправлять уведомления через Vonage, вам необходимо установить пакеты Composer:
- composer require laravel/nexmo-notification-channel nexmo/laravel
+ composer require laravel/vonage-notification-channel guzzlehttp/guzzle
-Пакет `nexmo/laravel` содержит [собственный конфигурационный файл](https://github.com/Nexmo/nexmo-laravel/blob/master/config/nexmo.php). Однако вам не обязательно экспортировать этот файл конфигурации в собственное приложение. Вы можете просто использовать переменные окружения `NEXMO_KEY` и `NEXMO_SECRET` для установки публичного и секретного ключей Vonage.
+Пакет содержит [конфигурационный файл](https://github.com/laravel/vonage-notification-channel/blob/3.x/config/vonage.php). Однако вам не обязательно экспортировать этот файл конфигурации в собственное приложение. Вы можете просто использовать переменные окружения `VONAGE_KEY` и `VONAGE_SECRET` для определения публичного и секретного ключей Vonage.
-Затем вам нужно будет добавить запись `nexmo` в ваш конфигурационный файл `config/services.php`. Для начала вам достаточно скопировать приведенный ниже пример конфигурации:
+После определения ключей вы можете установить переменную окружения `VONAGE_SMS_FROM`, которая определяет номер телефона, с которого по умолчанию должны отправляться ваши SMS-сообщения. Вы можете сгенерировать этот номер телефона в панели управления Vonage:
- 'nexmo' => [
- 'sms_from' => '15556666666',
- ],
-
-Параметр `sms_from` – это номер телефона, с которого будут отправляться ваши SMS-сообщения. Вы должны сгенерировать номер телефона для своего приложения в панели управления Vonage.
+ VONAGE_SMS_FROM=15556666666
### Формирование уведомлений через SMS
-Если уведомление поддерживает отправку в виде SMS, то вы должны определить метод `toNexmo` в классе уведомлений. Этот метод получит объект `$notifiable` и должен вернуть экземпляр `Illuminate\Notifications\Messages\NexmoMessage`:
+Если уведомление поддерживает отправку в виде SMS, то вы должны определить метод `toVonage` в классе уведомлений. Этот метод получит объект `$notifiable` и должен вернуть экземпляр `Illuminate\Notifications\Messages\VonageMessage`:
/**
* Получить SMS-представление уведомления.
*
* @param mixed $notifiable
- * @return \Illuminate\Notifications\Messages\NexmoMessage
+ * @return \Illuminate\Notifications\Messages\VonageMessage
*/
- public function toNexmo($notifiable)
+ public function toVonage($notifiable)
{
- return (new NexmoMessage)
+ return (new VonageMessage)
->content('Your SMS message content');
}
#### Содержимое Unicode
-Если ваше SMS-сообщение будет содержать символы Unicode, то вы должны вызвать метод `unicode` при создании экземпляра `NexmoMessage`:
+Если ваше SMS-сообщение будет содержать символы Unicode, то вы должны вызвать метод `unicode` при создании экземпляра `VonageMessage`:
/**
* Получить SMS-представление уведомления.
*
* @param mixed $notifiable
- * @return \Illuminate\Notifications\Messages\NexmoMessage
+ * @return \Illuminate\Notifications\Messages\VonageMessage
*/
- public function toNexmo($notifiable)
+ public function toVonage($notifiable)
{
- return (new NexmoMessage)
+ return (new VonageMessage)
->content('Your unicode message')
->unicode();
}
-
-### Использование шорткодов при формировании SMS-уведомлений
-
-Laravel также поддерживает отправку уведомлений с шорткодами, которые представляют собой предварительно определенные шаблоны сообщений в вашей учетной записи Vonage. Чтобы отправить такое SMS-уведомление, вы должны определить метод `toShortcode` в своем классе уведомления. Из этого метода вы можете вернуть массив, определяющий тип уведомления (`alert`, `2fa` или `marketing`) и значения, которые будут заполнять шаблон:
-
- /**
- * Получить SMS-представление уведомления.
- *
- * @param mixed $notifiable
- * @return array
- */
- public function toShortcode($notifiable)
- {
- return [
- 'type' => 'alert',
- 'custom' => [
- 'code' => 'ABC123',
- ],
- ];
- }
-
-> {tip} Как и в случае с [маршрутизацией SMS-уведомлений](#routing-sms-notifications), вам также следует реализовать метод `routeNotificationForShortcode` вашей уведомляемой модели.
-
### Изменение номера отправителя
-Если вы хотите отправить уведомление с номера телефона, который отличается от номера телефона, указанного в вашем файле `config/services.php`, то вы можете вызвать метод `from` экземпляра `NexmoMessage`:
+Если вы хотите отправить уведомление с номера телефона, который отличается от номера телефона, указанного вашей переменной окружения `VONAGE_SMS_FROM`, вы можете вызвать метод `from` экземпляра `VonageMessage`:
/**
* Получить SMS-представление уведомления.
*
* @param mixed $notifiable
- * @return NexmoMessage
+ * @return \Illuminate\Notifications\Messages\VonageMessage
*/
- public function toNexmo($notifiable)
+ public function toVonage($notifiable)
{
- return (new NexmoMessage)
+ return (new VonageMessage)
->content('Your SMS message content')
->from('15554443333');
}
@@ -971,11 +962,11 @@ Laravel также поддерживает отправку уведомлен
* Получить SMS-представление уведомления.
*
* @param mixed $notifiable
- * @return NexmoMessage
+ * @return \Illuminate\Notifications\Messages\VonageMessage
*/
- public function toNexmo($notifiable)
+ public function toVonage($notifiable)
{
- return (new NexmoMessage)
+ return (new VonageMessage)
->clientReference((string) $notifiable->id)
->content('Your SMS message content');
}
@@ -983,7 +974,7 @@ Laravel также поддерживает отправку уведомлен
### Маршрутизация SMS-уведомлений
-Для отправки уведомления с использованием Vonage на необходимый номер телефона, определите метод `routeNotificationForNexmo` вашего уведомляемого объекта:
+Для отправки уведомления с использованием Vonage на необходимый номер телефона, определите метод `routeNotificationForVonage` вашего уведомляемого объекта:
phone_number;
}
@@ -1016,7 +1007,9 @@ Laravel также поддерживает отправку уведомлен
Прежде чем вы сможете отправлять уведомления через Slack, вы должны установить канал уведомлений Slack через Composer:
- composer require laravel/slack-notification-channel
+```shell
+composer require laravel/slack-notification-channel
+```
Вам также потребуется создать [приложение Slack](https://api.slack.com/apps?new_app=1) для своей команды. После создания приложения вы должны настроить «Incoming Webhook» для рабочей области. Затем Slack предоставит вам URL-адрес веб-хука, который вы можете использовать при [маршрутизации Slack-уведомлений](#routing-slack-notifications).
diff --git a/docs/octane.md b/docs/octane.md
index 416aab5..77f6be6 100644
--- a/docs/octane.md
+++ b/docs/octane.md
@@ -33,13 +33,13 @@
Octane may be installed via the Composer package manager:
-```bash
+```shell
composer require laravel/octane
```
After installing Octane, you may execute the `octane:install` Artisan command, which will install Octane's configuration file into your application:
-```bash
+```shell
php artisan octane:install
```
@@ -58,7 +58,7 @@ php artisan octane:install
If you plan to develop your application using [Laravel Sail](/docs/{{version}}/sail), you should run the following commands to install Octane and RoadRunner:
-```bash
+```shell
./vendor/bin/sail up
./vendor/bin/sail composer require laravel/octane spiral/roadrunner
@@ -66,7 +66,7 @@ If you plan to develop your application using [Laravel Sail](/docs/{{version}}/s
Next, you should start a Sail shell and use the `rr` executable to retrieve the latest Linux based build of the RoadRunner binary:
-```bash
+```shell
./vendor/bin/sail shell
# Within the Sail shell...
@@ -75,7 +75,7 @@ Next, you should start a Sail shell and use the `rr` executable to retrieve the
After installing the RoadRunner binary, you may exit your Sail shell session. You will now need to adjust the `supervisor.conf` file used by Sail to keep your application running. To get started, execute the `sail:publish` Artisan command:
-```bash
+```shell
./vendor/bin/sail artisan sail:publish
```
@@ -87,7 +87,7 @@ command=/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start
Finally, ensure the `rr` binary is executable and build your Sail images:
-```bash
+```shell
chmod +x ./rr
./vendor/bin/sail build --no-cache
@@ -98,7 +98,7 @@ chmod +x ./rr
If you plan to use the Swoole application server to serve your Laravel Octane application, you must install the Swoole PHP extension. Typically, this can be done via PECL:
-```bash
+```shell
pecl install swoole
```
@@ -109,7 +109,7 @@ pecl install swoole
Alternatively, you may develop your Swoole based Octane application using [Laravel Sail](/docs/{{version}}/sail), the official Docker based development environment for Laravel. Laravel Sail includes the Swoole extension by default. However, you will still need to adjust the `supervisor.conf` file used by Sail to keep your application running. To get started, execute the `sail:publish` Artisan command:
-```bash
+```shell
./vendor/bin/sail artisan sail:publish
```
@@ -121,7 +121,7 @@ command=/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start
Finally, build your Sail images:
-```bash
+```shell
./vendor/bin/sail build --no-cache
```
@@ -144,7 +144,7 @@ Swoole supports a few additional configuration options that you may add to your
The Octane server can be started via the `octane:start` Artisan command. By default, this command will utilize the server specified by the `server` configuration option of your application's `octane` configuration file:
-```bash
+```shell
php artisan octane:start
```
@@ -168,7 +168,7 @@ In production environments, you should serve your Octane application behind a tr
In the Nginx configuration example below, Nginx will serve the site's static assets and proxy requests to the Octane server that is running on port 8000:
-```conf
+```nginx
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
@@ -227,13 +227,13 @@ server {
Since your application is loaded in memory once when the Octane server starts, any changes to your application's files will not be reflected when you refresh your browser. For example, route definitions added to your `routes/web.php` file will not be reflected until the server is restarted. For convenience, you may use the `--watch` flag to instruct Octane to automatically restart the server on any file changes within your application:
-```bash
+```shell
php artisan octane:start --watch
```
Before using this feature, you should ensure that [Node](https://nodejs.org) is installed within your local development environment. In addition, you should install the [Chokidar](https://github.com/paulmillr/chokidar) file-watching library within your project:library:
-```bash
+```shell
npm install --save-dev chokidar
```
@@ -244,13 +244,13 @@ You may configure the directories and files that should be watched using the `wa
By default, Octane will start an application request worker for each CPU core provided by your machine. These workers will then be used to serve incoming HTTP requests as they enter your application. You may manually specify how many workers you would like to start using the `--workers` option when invoking the `octane:start` command:
-```bash
+```shell
php artisan octane:start --workers=4
```
If you are using the Swoole application server, you may also specify how many ["task workers"](#concurrent-tasks) you wish to start:
-```bash
+```shell
php artisan octane:start --workers=4 --task-workers=6
```
@@ -259,7 +259,7 @@ php artisan octane:start --workers=4 --task-workers=6
To help prevent stray memory leaks, Octane can gracefully restart a worker once it has handled a given number of requests. To instruct Octane to do this, you may use the `--max-requests` option:
-```bash
+```shell
php artisan octane:start --max-requests=250
```
@@ -268,7 +268,7 @@ php artisan octane:start --max-requests=250
You may gracefully restart the Octane server's application workers using the `octane:reload` command. Typically, this should be done after deployment so that your newly deployed code is loaded into memory and is used to serve to subsequent requests:
-```bash
+```shell
php artisan octane:reload
```
@@ -277,7 +277,7 @@ php artisan octane:reload
You may stop the Octane server using the `octane:stop` Artisan command:
-```bash
+```shell
php artisan octane:stop
```
@@ -286,7 +286,7 @@ php artisan octane:stop
You may check the current status of the Octane server using the `octane:status` Artisan command:
-```bash
+```shell
php artisan octane:status
```
@@ -470,7 +470,7 @@ use Laravel\Octane\Facades\Octane;
Concurrent tasks processed by Octane utilize Swoole's "task workers", and execute within an entirely different process than the incoming request. The amount of workers available to process concurrent tasks is determined by the `--task-workers` directive on the `octane:start` command:
-```bash
+```shell
php artisan octane:start --workers=4 --task-workers=6
```
diff --git a/docs/packages.md b/docs/packages.md
index bf59b17..830da27 100644
--- a/docs/packages.md
+++ b/docs/packages.md
@@ -34,16 +34,18 @@
Параметр `providers` конфигурационного файла `config/app.php` определяет список поставщиков служб, загружаемых Laravel. Когда кто-то устанавливает ваш пакет, то вы обычно хотите, чтобы ваш поставщик службы был включен в этот список. Вместо того, чтобы требовать от пользователей ручного добавления вашего поставщика в этот список, вы можете определить его в разделе `extra` файла `composer.json` вашего пакета. Помимо поставщиков, вы также можете указать любые [фасады](facades.md), которые вы хотите зарегистрировать:
- "extra": {
- "laravel": {
- "providers": [
- "Barryvdh\\Debugbar\\ServiceProvider"
- ],
- "aliases": {
- "Debugbar": "Barryvdh\\Debugbar\\Facade"
- }
+```json
+"extra": {
+ "laravel": {
+ "providers": [
+ "Barryvdh\\Debugbar\\ServiceProvider"
+ ],
+ "aliases": {
+ "Debugbar": "Barryvdh\\Debugbar\\Facade"
}
- },
+ }
+},
+```
После того, как ваш пакет будет настроен для обнаружения, Laravel автоматически зарегистрирует поставщиков и фасады пакета при его установке, создав удобство установки для пользователей вашего пакета.
@@ -52,23 +54,27 @@
Если вы являетесь пользователем пакета и хотите отключить обнаружение какого-то конкретного пакета, то вы можете указать его название в разделе `extra` файла `composer.json` вашего приложения:
- "extra": {
- "laravel": {
- "dont-discover": [
- "barryvdh/laravel-debugbar"
- ]
- }
- },
+```json
+"extra": {
+ "laravel": {
+ "dont-discover": [
+ "barryvdh/laravel-debugbar"
+ ]
+ }
+},
+```
Вы можете отключить обнаружение для всех пакетов, используя метасимвол `*` внутри директивы `dont-discover` вашего приложения:
- "extra": {
- "laravel": {
- "dont-discover": [
- "*"
- ]
- }
- },
+```json
+"extra": {
+ "laravel": {
+ "dont-discover": [
+ "*"
+ ]
+ }
+},
+```
## Поставщики служб
@@ -266,16 +272,20 @@
После того, как ваши компоненты шаблонов зарегистрированы в поставщике, вы можете ссылаться на них в своих шаблонах следующим образом:
-
+```blade
+
-
+
+```
#### Анонимные компоненты
Если ваш пакет содержит анонимные компоненты, то они должны быть помещены в каталог `components` каталога «views» вашего пакета (как указано в `loadViewsFrom`). Затем вы можете отобразить их, добавив к имени компонента префикс пространства имен шаблонов пакета:
-
+```blade
+
+```
## Команды
@@ -319,7 +329,9 @@
Теперь, когда пользователи вашего пакета выполнят команду `vendor:publish`, ваши веб-активы будут скопированы в указанное место публикации. Поскольку каждый раз при обновлении пакета требуется перезаписывать веб-активы, то можно использовать флаг `--force`:
- php artisan vendor:publish --tag=public --force
+```shell
+php artisan vendor:publish --tag=public --force
+```
## Публикация групп файлов
@@ -344,4 +356,6 @@
Теперь ваши пользователи могут публиковать эти группы отдельно, ссылаясь на их теги при выполнении команды `vendor:publish`:
- php artisan vendor:publish --tag=courier-config
+```shell
+php artisan vendor:publish --tag=courier-config
+```
diff --git a/docs/pagination.md b/docs/pagination.md
index b25c586..c75ce6a 100644
--- a/docs/pagination.md
+++ b/docs/pagination.md
@@ -211,7 +211,7 @@ select * from users where id > 15 order by id asc limit 15;
Эти объекты содержат несколько методов, описывающих результирующий набор. В дополнение к этим вспомогательным методам, экземпляры пагинатора являются итераторами и могут быть перебраны как массив. Итак, как только вы получили результаты, вы можете отобразить результаты и отрисовать ссылки на страницы, используя [Blade](blade.md):
-```html
+```blade
@foreach ($users as $user)
{{ $user->name }}
@@ -228,7 +228,9 @@ select * from users where id > 15 order by id asc limit 15;
Пагинатор отображает навигационные ссылки, которые содержат номер текущей страницы, а также ссылки для трех страниц до и после текущей страницы. Используя метод `onEachSide`, вы можете контролировать количество дополнительных ссылок, отображаемых с каждой стороны от текущей страницы в среднем блоке ссылок, созданных пагинатором:
- {{ $users->onEachSide(5)->links() }}
+```blade
+{{ $users->onEachSide(5)->links() }}
+```
### Преобразование результатов в JSON
@@ -270,14 +272,18 @@ JSON из пагинатора будет включать метаинформ
По умолчанию сгенерированные шаблоны для отображения навигационных ссылок, совместимы со структурой [фреймворка Tailwind CSS](https://tailwindcss.com). Однако, если вы не используете Tailwind, вы можете определять свои собственные шаблоны для отображения этих ссылок. При вызове метода `links` в экземпляре пагинатора вы можете передать имя шаблона в качестве первого аргумента метода:
- {{ $paginator->links('view.name') }}
+```blade
+{{ $paginator->links('view.name') }}
- // Передача дополнительных данных в шаблон ...
- {{ $paginator->links('view.name', ['foo' => 'bar']) }}
+// Передача дополнительных данных в шаблон ...
+{{ $paginator->links('view.name', ['foo' => 'bar']) }}
+```
Однако, самый простой способ отредактировать шаблоны постраничной навигации – это экспортировать их в каталог `resources/views/vendor` с помощью команды `vendor:publish`:
- php artisan vendor:publish --tag=laravel-pagination
+```shell
+php artisan vendor:publish --tag=laravel-pagination
+```
Эта команда поместит шаблоны в каталог `resources/views/vendor/pagination` вашего приложения. Файл `tailwind.blade.php` в этом каталоге соответствует шаблону постраничной навигации по умолчанию. Вы можете отредактировать этот файл для изменения HTML-кода навигации.
@@ -309,7 +315,7 @@ JSON из пагинатора будет включать метаинформ
### Использование Bootstrap
-Laravel содержит шаблоны постраничной навигации, созданные с использованием [Bootstrap CSS](https://getbootstrap.com/). Чтобы использовать эти шаблоны вместо шаблонов Tailwind по умолчанию, вы можете вызвать метод пагинатора `useBootstrap` в методе `boot` поставщика `App\Providers\AppServiceProvider`:
+Laravel содержит шаблоны постраничной навигации, созданные с использованием [Bootstrap CSS](https://getbootstrap.com/). Чтобы использовать эти шаблоны вместо шаблонов Tailwind по умолчанию, вы можете вызвать метод пагинатора `useBootstrapFour` или `useBootstrapFive` в методе `boot` поставщика `App\Providers\AppServiceProvider`:
use Illuminate\Pagination\Paginator;
@@ -320,7 +326,8 @@ Laravel содержит шаблоны постраничной навигац
*/
public function boot()
{
- Paginator::useBootstrap();
+ Paginator::useBootstrapFive();
+ Paginator::useBootstrapFour();
}
diff --git a/docs/passport.md b/docs/passport.md
index d6c7c6e..aaa7c86 100644
--- a/docs/passport.md
+++ b/docs/passport.md
@@ -62,15 +62,21 @@ However, if you are attempting to authenticate a single-page application, mobile
To get started, install Passport via the Composer package manager:
- composer require laravel/passport
+```shell
+composer require laravel/passport
+```
Passport's [service provider](/docs/{{version}}/providers) registers its own database migration directory, so you should migrate your database after installing the package. The Passport migrations will create the tables your application needs to store OAuth2 clients and access tokens:
- php artisan migrate
+```shell
+php artisan migrate
+```
Next, you should execute the `passport:install` Artisan command. This command will create the encryption keys needed to generate secure access tokens. In addition, the command will create "personal access" and "password grant" clients which will be used to generate access tokens:
- php artisan passport:install
+```shell
+php artisan passport:install
+```
> {tip} If you would like to use UUIDs as the primary key value of the Passport `Client` model instead of auto-incrementing integers, please install Passport using [the `uuids` option](#client-uuids).
@@ -145,14 +151,18 @@ Finally, in your application's `config/auth.php` configuration file, you should
You may also run the `passport:install` command with the `--uuids` option present. This option will instruct Passport that you would like to use UUIDs instead of auto-incrementing integers as the Passport `Client` model's primary key values. After running the `passport:install` command with the `--uuids` option, you will be given additional instructions regarding disabling Passport's default migrations:
- php artisan passport:install --uuids
+```shell
+php artisan passport:install --uuids
+```
### Deploying Passport
When deploying Passport to your application's servers for the first time, you will likely need to run the `passport:keys` command. This command generates the encryption keys Passport needs in order to generate access tokens. The generated keys are not typically kept in source control:
- php artisan passport:keys
+```shell
+php artisan passport:keys
+```
If necessary, you may define the path where Passport's keys should be loaded from. You may use the `Passport::loadKeysFrom` method to accomplish this. Typically, this method should be called from the `boot` method of your application's `App\Providers\AuthServiceProvider` class:
@@ -175,11 +185,13 @@ If necessary, you may define the path where Passport's keys should be loaded fro
Alternatively, you may publish Passport's configuration file using the `vendor:publish` Artisan command:
- php artisan vendor:publish --tag=passport-config
+```shell
+php artisan vendor:publish --tag=passport-config
+```
After the configuration file has been published, you may load your application's encryption keys by defining them as environment variables:
-```bash
+```ini
PASSPORT_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----"
@@ -194,7 +206,9 @@ PASSPORT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----
If you are not going to use Passport's default migrations, you should call the `Passport::ignoreMigrations` method in the `register` method of your `App\Providers\AppServiceProvider` class. You may export the default migrations using the `vendor:publish` Artisan command:
- php artisan vendor:publish --tag=passport-migrations
+```shell
+php artisan vendor:publish --tag=passport-migrations
+```
### Upgrading Passport
@@ -289,13 +303,15 @@ First, developers building applications that need to interact with your applicat
The simplest way to create a client is using the `passport:client` Artisan command. This command may be used to create your own clients for testing your OAuth2 functionality. When you run the `client` command, Passport will prompt you for more information about your client and will provide you with a client ID and secret:
- php artisan passport:client
+```shell
+php artisan passport:client
+```
**Redirect URLs**
If you would like to allow multiple redirect URLs for your client, you may specify them using a comma-delimited list when prompted for the URL by the `passport:client` command. Any URLs which contain commas should be URL encoded:
-```bash
+```shell
http://example.com/callback,http://examplefoo.com/callback
```
@@ -313,10 +329,12 @@ The JSON API is guarded by the `web` and `auth` middleware; therefore, it may on
This route returns all of the clients for the authenticated user. This is primarily useful for listing all of the user's clients so that they may edit or delete them:
- axios.get('/oauth/clients')
- .then(response => {
- console.log(response.data);
- });
+```js
+axios.get('/oauth/clients')
+ .then(response => {
+ console.log(response.data);
+ });
+```
#### `POST /oauth/clients`
@@ -325,46 +343,52 @@ This route is used to create new clients. It requires two pieces of data: the cl
When a client is created, it will be issued a client ID and client secret. These values will be used when requesting access tokens from your application. The client creation route will return the new client instance:
- const data = {
- name: 'Client Name',
- redirect: 'http://example.com/callback'
- };
-
- axios.post('/oauth/clients', data)
- .then(response => {
- console.log(response.data);
- })
- .catch (response => {
- // List errors on response...
- });
+```js
+const data = {
+ name: 'Client Name',
+ redirect: 'http://example.com/callback'
+};
+
+axios.post('/oauth/clients', data)
+ .then(response => {
+ console.log(response.data);
+ })
+ .catch (response => {
+ // List errors on response...
+ });
+```
#### `PUT /oauth/clients/{client-id}`
This route is used to update clients. It requires two pieces of data: the client's `name` and a `redirect` URL. The `redirect` URL is where the user will be redirected after approving or denying a request for authorization. The route will return the updated client instance:
- const data = {
- name: 'New Client Name',
- redirect: 'http://example.com/callback'
- };
-
- axios.put('/oauth/clients/' + clientId, data)
- .then(response => {
- console.log(response.data);
- })
- .catch (response => {
- // List errors on response...
- });
+```js
+const data = {
+ name: 'New Client Name',
+ redirect: 'http://example.com/callback'
+};
+
+axios.put('/oauth/clients/' + clientId, data)
+ .then(response => {
+ console.log(response.data);
+ })
+ .catch (response => {
+ // List errors on response...
+ });
+```
#### `DELETE /oauth/clients/{client-id}`
This route is used to delete clients:
- axios.delete('/oauth/clients/' + clientId)
- .then(response => {
- //
- });
+```js
+axios.delete('/oauth/clients/' + clientId)
+ .then(response => {
+ //
+ });
+```
### Requesting Tokens
@@ -400,7 +424,9 @@ When receiving authorization requests, Passport will automatically display a tem
If you would like to customize the authorization approval screen, you may publish Passport's views using the `vendor:publish` Artisan command. The published views will be placed in the `resources/views/vendor/passport` directory:
- php artisan vendor:publish --tag=passport-views
+```shell
+php artisan vendor:publish --tag=passport-views
+```
Sometimes you may wish to skip the authorization prompt, such as when authorizing a first-party client. You may accomplish this by [extending the `Client` model](#overriding-default-models) and defining a `skipsAuthorization` method. If `skipsAuthorization` returns `true` the client will be approved and the user will be redirected back to the `redirect_uri` immediately:
@@ -464,17 +490,21 @@ Passport also includes a JSON API for managing authorized access tokens. You may
This route returns all of the authorized access tokens that the authenticated user has created. This is primarily useful for listing all of the user's tokens so that they can revoke them:
- axios.get('/oauth/tokens')
- .then(response => {
- console.log(response.data);
- });
+```js
+axios.get('/oauth/tokens')
+ .then(response => {
+ console.log(response.data);
+ });
+```
#### `DELETE /oauth/tokens/{token-id}`
This route may be used to revoke authorized access tokens and their related refresh tokens:
- axios.delete('/oauth/tokens/' + tokenId);
+```js
+axios.delete('/oauth/tokens/' + tokenId);
+```
### Refreshing Tokens
@@ -517,14 +547,16 @@ You may revoke a token by using the `revokeAccessToken` method on the `Laravel\P
When tokens have been revoked or expired, you might want to purge them from the database. Passport's included `passport:purge` Artisan command can do this for you:
- # Purge revoked and expired tokens and auth codes...
- php artisan passport:purge
+```shell
+# Purge revoked and expired tokens and auth codes...
+php artisan passport:purge
- # Only purge revoked tokens and auth codes...
- php artisan passport:purge --revoked
+# Only purge revoked tokens and auth codes...
+php artisan passport:purge --revoked
- # Only purge expired tokens and auth codes...
- php artisan passport:purge --expired
+# Only purge expired tokens and auth codes...
+php artisan passport:purge --expired
+```
You may also configure a [scheduled job](/docs/{{version}}/scheduling) in your application's `App\Console\Kernel` class to automatically prune your tokens on a schedule:
@@ -549,7 +581,9 @@ The Authorization Code grant with "Proof Key for Code Exchange" (PKCE) is a secu
Before your application can issue tokens via the authorization code grant with PKCE, you will need to create a PKCE-enabled client. You may do this using the `passport:client` Artisan command with the `--public` option:
- php artisan passport:client --public
+```shell
+php artisan passport:client --public
+```
### Requesting Tokens
@@ -642,7 +676,9 @@ The OAuth2 password grant allows your other first-party clients, such as a mobil
Before your application can issue tokens via the password grant, you will need to create a password grant client. You may do this using the `passport:client` Artisan command with the `--password` option. **If you have already run the `passport:install` command, you do not need to run this command:**
- php artisan passport:client --password
+```shell
+php artisan passport:client --password
+```
### Requesting Tokens
@@ -792,7 +828,9 @@ The client credentials grant is suitable for machine-to-machine authentication.
Before your application can issue tokens via the client credentials grant, you will need to create a client credentials grant client. You may do this using the `--client` option of the `passport:client` Artisan command:
- php artisan passport:client --client
+```shell
+php artisan passport:client --client
+```
Next, to use this grant type, you need to add the `CheckClientCredentials` middleware to the `$routeMiddleware` property of your `app/Http/Kernel.php` file:
@@ -842,11 +880,13 @@ Sometimes, your users may want to issue access tokens to themselves without goin
Before your application can issue personal access tokens, you will need to create a personal access client. You may do this by executing the `passport:client` Artisan command with the `--personal` option. If you have already run the `passport:install` command, you do not need to run this command:
- php artisan passport:client --personal
+```shell
+php artisan passport:client --personal
+```
After creating your personal access client, place the client's ID and plain-text secret value in your application's `.env` file:
-```bash
+```ini
PASSPORT_PERSONAL_ACCESS_CLIENT_ID="client-id-value"
PASSPORT_PERSONAL_ACCESS_CLIENT_SECRET="unhashed-client-secret-value"
```
@@ -878,45 +918,53 @@ The JSON API is guarded by the `web` and `auth` middleware; therefore, it may on
This route returns all of the [scopes](#token-scopes) defined for your application. You may use this route to list the scopes a user may assign to a personal access token:
- axios.get('/oauth/scopes')
- .then(response => {
- console.log(response.data);
- });
+```js
+axios.get('/oauth/scopes')
+ .then(response => {
+ console.log(response.data);
+ });
+```
#### `GET /oauth/personal-access-tokens`
This route returns all of the personal access tokens that the authenticated user has created. This is primarily useful for listing all of the user's tokens so that they may edit or revoke them:
- axios.get('/oauth/personal-access-tokens')
- .then(response => {
- console.log(response.data);
- });
+```js
+axios.get('/oauth/personal-access-tokens')
+ .then(response => {
+ console.log(response.data);
+ });
+```
#### `POST /oauth/personal-access-tokens`
This route creates new personal access tokens. It requires two pieces of data: the token's `name` and the `scopes` that should be assigned to the token:
- const data = {
- name: 'Token Name',
- scopes: []
- };
-
- axios.post('/oauth/personal-access-tokens', data)
- .then(response => {
- console.log(response.data.accessToken);
- })
- .catch (response => {
- // List errors on response...
- });
+```js
+const data = {
+ name: 'Token Name',
+ scopes: []
+};
+
+axios.post('/oauth/personal-access-tokens', data)
+ .then(response => {
+ console.log(response.data.accessToken);
+ })
+ .catch (response => {
+ // List errors on response...
+ });
+```
#### `DELETE /oauth/personal-access-tokens/{token-id}`
This route may be used to revoke personal access tokens:
- axios.delete('/oauth/personal-access-tokens/' + tokenId);
+```js
+axios.delete('/oauth/personal-access-tokens/' + tokenId);
+```
## Protecting Routes
diff --git a/docs/passwords.md b/docs/passwords.md
index 97efdab..d00926c 100644
--- a/docs/passwords.md
+++ b/docs/passwords.md
@@ -29,7 +29,9 @@
Необходимо создать таблицу для сохранения токенов сброса пароля вашего приложения. Миграция для этой таблицы содержится по умолчанию в Laravel, поэтому вам нужно только выполнить миграцию БД для создания этой таблицы:
- php artisan migrate
+```shell
+php artisan migrate
+```
### Конфигурирование доверенных хостов
@@ -150,7 +152,9 @@
Токены сброса пароля, срок действия которых истек, по-прежнему будут присутствовать в вашей базе данных. Однако вы можете легко удалить эти записи, используя команду `auth:clear-resets` Artisan:
- php artisan auth:clear-resets
+```shell
+php artisan auth:clear-resets
+```
Если вы хотите автоматизировать этот процесс, рассмотрите возможность добавления команды в [планировщик](scheduling.md) вашего приложения:
diff --git a/docs/providers.md b/docs/providers.md
index cac94c6..1648fff 100644
--- a/docs/providers.md
+++ b/docs/providers.md
@@ -27,7 +27,9 @@
Чтобы сгенерировать нового поставщика, используйте команду `make:provider` [Artisan](artisan.md):
- php artisan make:provider RiakServiceProvider
+```shell
+php artisan make:provider RiakServiceProvider
+```
### Метод `register`
diff --git a/docs/queries.md b/docs/queries.md
index 09023c3..a777131 100644
--- a/docs/queries.md
+++ b/docs/queries.md
@@ -18,6 +18,7 @@
- [Расширенные выражения Where](#advanced-where-clauses)
- [Выражения Where Exists](#where-exists-clauses)
- [Подзапросы выражений Where](#subquery-where-clauses)
+ - [Полнотекстовый поиск](#full-text-where-clauses)
- [Сортировка, группировка, ограничение и смещение](#ordering-grouping-limit-and-offset)
- [Сортировка](#ordering)
- [Группировка](#grouping)
@@ -666,6 +667,17 @@ where exists (
$query->selectRaw('avg(i.amount)')->from('incomes as i');
})->get();
+
+### Полнотекстовый поиск
+
+> {note} Полнотекстовый поиск в настоящее время поддерживаются MySQL и PostgreSQL.
+
+Методы `whereFullText` и `orWhereFullText` полнотекстового поиска можно использовать для добавления условий `where` в запрос для столбцов, которые имеют [полнотекстовые индексы](migrations.md#available-index-types). Эти методы будут преобразованы Laravel в соответствующий SQL базы данных. Например, предложение `MATCH AGAINST` будет создано для приложений, использующих MySQL:
+
+ $users = DB::table('users')
+ ->whereFullText('bio', 'web developer')
+ ->get();
+
## Сортировка, группировка, ограничение и смещение
diff --git a/docs/queues.md b/docs/queues.md
index 9a8fca7..dfac670 100644
--- a/docs/queues.md
+++ b/docs/queues.md
@@ -74,7 +74,9 @@
Некоторым приложениям может не понадобиться помещать задания в несколько очередей, вместо этого предпочитая иметь одну простую очередь. Однако отправка заданий в несколько очередей может быть особенно полезна для приложений, определяющих приоритеты или сегментацию процесса обработки заданий, поскольку обработчик очереди Laravel позволяет вам указать, какие очереди он должен обрабатывать по приоритету. Например, если вы помещаете задания в очередь `high`, то вы можете запустить обработчик, который даст им более высокий приоритет обработки:
- php artisan queue:work --queue=high,default
+```shell
+php artisan queue:work --queue=high,default
+```
### Предварительная подготовка драйверов
@@ -84,9 +86,11 @@
Чтобы использовать драйвер очереди `database`, вам понадобится таблица базы данных для хранения заданий. Чтобы сгенерировать миграцию, которая создает эту таблицу, запустите команду `queue:table` Artisan. После того, как миграция будет создана, вы можете выполнить ее миграцию с помощью команды `migrate`:
- php artisan queue:table
+```shell
+php artisan queue:table
- php artisan migrate
+php artisan migrate
+```
Наконец, не забудьте указать вашему приложению использовать драйвер `database`, обновив переменную `QUEUE_CONNECTION` в файле `.env` вашего приложения:
@@ -145,7 +149,9 @@
Чтобы сгенерировать новое задание, используйте команду `make:job` [Artisan](artisan.md). Эта команда поместит новый класс задания в каталог `app/Jobs` вашего приложения. Если этот каталог не существует в вашем приложении, то Laravel предварительно создаст его:
- php artisan make:job ProcessPodcast
+```shell
+php artisan make:job ProcessPodcast
+```
Сгенерированный класс будет реализовывать интерфейс `Illuminate\Contracts\Queue\ShouldQueue`, указывая Laravel, что задание должно быть поставлено в очередь для асинхронного выполнения.
@@ -937,7 +943,9 @@ Laravel содержит посредника `Illuminate\Queue\Middleware\Throt
Один из подходов к указанию максимального количества попыток выполнения задания – это использование переключателя `--tries` в командной строке Artisan. Это будет применяться ко всем заданиям обработчика, если только обрабатываемое задание не указывает более конкретное количество попыток его выполнения:
- php artisan queue:work --tries=3
+```shell
+php artisan queue:work --tries=3
+```
Если задание превышает максимальное количество попыток, то оно будет считаться «неудачным». Для получения дополнительной информации об обработке невыполненных заданий обратитесь к [документации по разбору неудачных заданий](#dealing-with-failed-jobs).
@@ -1028,7 +1036,9 @@ Laravel содержит посредника `Illuminate\Queue\Middleware\Throt
Максимальное количество секунд, в течение которых могут выполняться задания, можно указать с помощью переключателя `--timeout` в командной строке Artisan:
- php artisan queue:work --timeout=30
+```shell
+php artisan queue:work --timeout=30
+```
Если задание превышает максимальное количество попыток из-за постоянного тайм-аута, оно будет помечено как «неудачное».
@@ -1118,9 +1128,11 @@ public $failOnTimeout = true;
Функционал пакетной обработки заданий Laravel позволяет вам легко выполнить пакет заданий, по завершению которого дополнительно совершить определенные действия. Перед тем, как начать, вы должны создать миграцию базы данных, чтобы построить таблицу, содержащую метаинформацию о ваших пакетах заданий, такую как процент их завершения. Эта миграция может быть сгенерирована с помощью команды `queue:batches-table` Artisan:
- php artisan queue:batches-table
+```shell
+php artisan queue:batches-table
- php artisan migrate
+php artisan migrate
+```
### Определение пакета заданий
@@ -1377,7 +1389,7 @@ public $failOnTimeout = true;
Для удобства Artisan содержит команду `queue:retry-batch`, которая позволяет вам легко повторить все неудачные задания для указанного пакета. Команда `queue:retry-batch` принимает UUID пакета, чьи неудачные задания следует повторить:
-```bash
+```shell
php artisan queue:retry-batch 32dbc76c-4f82-4749-b610-a639fe0099b5
```
@@ -1425,7 +1437,9 @@ php artisan queue:retry-batch 32dbc76c-4f82-4749-b610-a639fe0099b5
Laravel включает команду Artisan, которая запускает обработчика очереди и обрабатывает новые задания по мере их помещения в очередь. Вы можете запустить обработчик с помощью команды `queue:work` Artisan. Обратите внимание, что после запуска команды `queue:work` она будет продолжать работать, пока не будет остановлена вручную или пока вы не закроете терминал (консоль):
- php artisan queue:work
+```shell
+php artisan queue:work
+```
> {tip} Чтобы процесс `queue:work` постоянно работал в фоновом режиме, вы должны использовать диспетчер процессов, такой как [Supervisor](#supervisor-configuration), чтобы гарантировать, что обработчик очереди не перестанет работать.
@@ -1433,7 +1447,9 @@ Laravel включает команду Artisan, которая запускае
Как вариант, вы можете запустить команду `queue:listen`. При использовании команды `queue:listen` вам не нужно вручную перезапускать обработчик, если вы хотите перезагрузить обновленный код или сбросить состояние приложения; однако эта команда значительно менее эффективна, чем команда `queue:work`:
- php artisan queue:listen
+```shell
+php artisan queue:listen
+```
#### Запуск нескольких обработчиков очереди
@@ -1445,44 +1461,58 @@ Laravel включает команду Artisan, которая запускае
Вы также можете указать, какое соединение очереди должен использовать обработчик. Имя соединения, переданное команде `work`, должно соответствовать одному из соединений, определенных в конфигурационном файле `config/queue.php`:
- php artisan queue:work redis
+```shell
+php artisan queue:work redis
+```
По умолчанию команда `queue:work` обрабатывает задания только для очереди по умолчанию указанного соединения. Однако вы дополнительно можете указать, какие очереди необходимо обрабатывать для указанного соединения. Например, если все ваши электронные письма обрабатываются в очереди `emails` соединения `redis`, то вы можете использовать команду, чтобы запустить обработчик только для этой очереди:
- php artisan queue:work redis --queue=emails
+```shell
+php artisan queue:work redis --queue=emails
+```
#### Обработка указанного количества заданий
Переключатель `--once` обработчика используется для указания обработать только одно задание из очереди:
- php artisan queue:work --once
+```shell
+php artisan queue:work --once
+```
Параметр `--max-jobs` обработчика укажет ему обработать заданное количество заданий, а затем выйти. Этот параметр может быть полезен в сочетании с [Supervisor](#supervisor-configuration), чтобы ваши рабочие процессы автоматически перезапускались после обработки заданного количества заданий, освобождая любую занятую ими память:
- php artisan queue:work --max-jobs=1000
+```shell
+php artisan queue:work --max-jobs=1000
+```
#### Обработка всех заданий в очереди с последующим выходом
Переключатель `--stop-when-empty` обработчика может использоваться, чтобы дать ему указание обработать все задания и затем корректно завершить работу. Этот параметр может быть полезен при обработке очередей Laravel в контейнере Docker, если вы хотите выключить контейнер после того, как очередь пуста:
- php artisan queue:work --stop-when-empty
+```shell
+php artisan queue:work --stop-when-empty
+```
#### Обработка заданий за заданное количество секунд
Параметр `--max-time` обработчика может использоваться, чтобы дать ему указание обрабатывать задания в течение заданного количества секунд, а затем выйти. Этот параметр может быть полезен в сочетании с [Supervisor](#supervisor-configuration), чтобы ваши рабочие процессы автоматически перезапускались после обработки заданий в течение заданного времени, освобождая любую занятую ими память:
- // Обрабатываем задания в течение одного часа, а затем выходим ...
- php artisan queue:work --max-time=3600
+```shell
+// Обрабатываем задания в течение одного часа, а затем выходим ...
+php artisan queue:work --max-time=3600
+```
#### Продолжительность задержки выполнения обработчика
Когда задания доступны в очереди, обработчик будет продолжать обрабатывать задания без задержки между ними. Однако опция `sleep` определяет, сколько секунд обработчик будет «спать», если нет новых доступных заданий. Во время задержки выполнения обработчик не будет обрабатывать никаких новых заданий – задания будут обработаны после того, как обработчик снова проснется.
- php artisan queue:work --sleep=3
+```shell
+php artisan queue:work --sleep=3
+```
#### Соображения относительно ресурсов
@@ -1498,14 +1528,18 @@ Laravel включает команду Artisan, которая запускае
Чтобы запустить обработчика, который проверяет, что все задания очереди `high` обработаны, прежде чем переходить к любым заданиям в очереди `low`, передайте разделенный запятыми список имен очередей команде `work`:
- php artisan queue:work --queue=high,low
+```shell
+php artisan queue:work --queue=high,low
+```
### Обработчики очереди и развертывание
Поскольку обработчики очереди – это долгоживущие процессы, они не заметят изменений в вашем коде без перезапуска. Итак, самый простой способ развернуть приложение с использованием обработчиков очереди – это перезапустить обработчиков во время процесса развертывания. Вы можете корректно перезапустить всех обработчиков, используя команду `queue:restart`:
- php artisan queue:restart
+```shell
+php artisan queue:restart
+```
Эта команда укажет всем обработчикам очереди корректно выйти после завершения обработки своего текущего задания, чтобы существующие задания не были потеряны. Поскольку обработчики очереди выйдут при выполнении команды `queue:restart`, вы должны запустить диспетчер процессов, такой как [Supervisor](#supervisor-configuration), для автоматического перезапуска обработчиков очереди.
@@ -1526,7 +1560,7 @@ Laravel включает команду Artisan, которая запускае
Команда `queue:work` Artisan также содержит параметр `--timeout`. Если задание обрабатывается дольше, чем количество секунд, указанное значением тайм-аута, Обработчик, выполняющий задание, завершится с ошибкой. Обычно обработчик перезапускается автоматически [диспетчером, настроенным на вашем сервере](#supervisor-configuration):
-```bash
+```shell
php artisan queue:work --timeout=60
```
@@ -1546,7 +1580,9 @@ php artisan queue:work --timeout=60
Supervisor – это диспетчер процессов для операционной системы Linux, который автоматически перезапускает ваши процессы `queue:work` в случае их сбоя. Чтобы установить Supervisor в Ubuntu, вы можете использовать следующую команду:
- sudo apt-get install supervisor
+```shell
+sudo apt-get install supervisor
+```
> {tip} Если настройка Supervisor и управление им самостоятельно кажется ошеломляющим, рассмотрите возможность использования [Laravel Forge](https://forge.laravel.com), который автоматически установит и настроит Supervisor для ваших проектов Laravel.
@@ -1579,7 +1615,7 @@ stopwaitsecs=3600
После создания файла конфигурации вы можете обновить конфигурацию Supervisor и запустить процессы, используя следующие команды:
-```bash
+```shell
sudo supervisorctl reread
sudo supervisorctl update
@@ -1594,17 +1630,23 @@ sudo supervisorctl start laravel-worker:*
Иногда ваши задания в очереди терпят неудачу. Не волнуйтесь, не всегда все идет по плану! Laravel включает удобный способ [указать максимальное количество попыток выполнения задания](#max-job-attempts-and-timeout). После того, как задание превысит это количество попыток, оно будет вставлено в таблицу базы данных `failed_jobs`. Конечно, нам нужно будет создать эту таблицу, если она еще не существует. Чтобы создать миграцию для таблицы `failed_jobs`, вы можете использовать команду `queue:failed-table`:
- php artisan queue:failed-table
+```shell
+php artisan queue:failed-table
- php artisan migrate
+php artisan migrate
+```
При запуске [обработчика очереди](#running-the-queue-worker) вы можете указать максимальное количество попыток выполнения задания, используя переключатель `--tries` команды `queue:work`. Если вы не укажете значение для параметра `--tries`, задания будут выполняться только один раз или столько раз, сколько указано в свойстве класса задания `$tries`:
- php artisan queue:work redis --tries=3
+```shell
+php artisan queue:work redis --tries=3
+```
Используя параметр `--backoff`, вы можете указать, сколько секунд Laravel должен ждать перед повторной попыткой выполнения задания, для которого возникло исключение. По умолчанию задание сразу же возвращается в очередь, чтобы его можно было повторить:
- php artisan queue:work redis --tries=3 --backoff=3
+```shell
+php artisan queue:work redis --tries=3 --backoff=3
+```
Если вы хотите настроить, сколько секунд Laravel должен ждать перед повторной попыткой выполнения каждого из заданий, для которого возникло исключение, вы можете сделать это, определив свойство `$backoff` в своем классе задания:
@@ -1708,33 +1750,47 @@ sudo supervisorctl start laravel-worker:*
Чтобы просмотреть все неудачные задания, которые были вставлены в вашу таблицу базы данных `failed_jobs`, вы можете использовать команду `queue:failed` Artisan:
- php artisan queue:failed
+```shell
+php artisan queue:failed
+```
Команда `queue:failed` перечислит идентификатор задания, соединение, очередь, время сбоя и другую информацию о задании. Идентификатор задания может быть использован для повторной попытки выполнить неудачное задание. Например, чтобы повторить неудачное задание с идентификатором `ce7bb17c-cdd8-41f0-a8ec-7b4fef4e5ece`, введите следующую команду:
- php artisan queue:retry ce7bb17c-cdd8-41f0-a8ec-7b4fef4e5ece
+```shell
+php artisan queue:retry ce7bb17c-cdd8-41f0-a8ec-7b4fef4e5ece
+```
При необходимости вы можете передать команде несколько идентификаторов:
- php artisan queue:retry ce7bb17c-cdd8-41f0-a8ec-7b4fef4e5ece 91401d2c-0784-4f43-824c-34f94a33c24d
+```shell
+php artisan queue:retry ce7bb17c-cdd8-41f0-a8ec-7b4fef4e5ece 91401d2c-0784-4f43-824c-34f94a33c24d
+```
Вы также можете повторить все неудачные задания только для конкретной очереди:
- php artisan queue:retry --queue=name
+```shell
+php artisan queue:retry --queue=name
+```
Чтобы повторить все неудачные задания, выполните команду `queue:retry` и передайте `all` вместо идентификаторов:
- php artisan queue:retry all
+```shell
+php artisan queue:retry all
+```
Если вы хотите удалить неудачные задание, вы можете использовать команду `queue:forget`:
- php artisan queue:forget 91401d2c-0784-4f43-824c-34f94a33c24d
+```shell
+php artisan queue:forget 91401d2c-0784-4f43-824c-34f94a33c24d
+```
> {tip} При использовании [Horizon](horizon.md) вы должны использовать команду `horizon:forget` для удаления неудачного задания вместо команды `queue:forget`.
Чтобы удалить все неудачные задания из таблицы `failed_jobs`, вы можете использовать команду `queue:flush`:
- php artisan queue:flush
+```shell
+php artisan queue:flush
+```
### Игнорирование отсутствующих моделей
@@ -1755,11 +1811,15 @@ sudo supervisorctl start laravel-worker:*
Вы можете удалить все записи в таблице `failed_jobs` вашего приложения, вызвав команду `queue:prune-failed` Artisan:
- php artisan queue:prune-failed
+```shell
+php artisan queue:prune-failed
+```
Если вы укажете для команды параметр `--hours`, то будут сохранены записи о неудачных заданиях, которые были вставлены только в течение последних `N` часов. Например, следующая команда удалит все записи неудачных заданий, которые были вставлены более 48 часов назад:
- php artisan queue:prune-failed --hours=48
+```shell
+php artisan queue:prune-failed --hours=48
+```
### Хранение неудачных заданий в DynamoDB
@@ -1770,7 +1830,7 @@ Laravel также поддерживает хранение записей о
Кроме того, убедитесь, что вы установили AWS SDK, чтобы ваше приложение Laravel могло взаимодействовать с Amazon DynamoDB:
-```nothing
+```shell
composer require aws/aws-sdk-php
```
@@ -1791,7 +1851,9 @@ composer require aws/aws-sdk-php
Вы можете указать Laravel отбрасывать неудачные задания без их сохранения, установив для конфигурационного параметра `queue.failed.driver` значение `null`. Как правило, это можно сделать с помощью переменной окружения `QUEUE_FAILED_DRIVER`:
- QUEUE_FAILED_DRIVER=null
+```ini
+QUEUE_FAILED_DRIVER=null
+```
### События неудачных заданий
@@ -1840,11 +1902,15 @@ composer require aws/aws-sdk-php
Если вы хотите удалить все задания, принадлежащие соединению и очереди по умолчанию, вы можете сделать это с помощью команды `queue:clear` Artisan:
- php artisan queue:clear
+```shell
+php artisan queue:clear
+```
Вы также можете указать аргумент `connection` и параметр `queue` для удаления заданий из конкретного соединения / очереди:
- php artisan queue:clear redis --queue=emails
+```shell
+php artisan queue:clear redis --queue=emails
+```
> {note} Удаление заданий из очередей доступно только для драйверов очереди SQS, Redis и базы данных. Кроме того, процесс удаления в SQS занимает до 60 секунд, поэтому задания, отправленные в очередь SQS в течение 60 секунд после очистки очереди, также могут быть удалены.
@@ -1855,7 +1921,7 @@ composer require aws/aws-sdk-php
Для начала вы должны запланировать команду `queue:monitor` на [запускать каждую минуту](scheduling.md). Команда принимает имена очередей, которые вы хотите отслеживать, а также желаемый порог количества заданий:
-```bash
+```shell
php artisan queue:monitor redis:default,redis:deployments --max=100
```
diff --git a/docs/redis.md b/docs/redis.md
index 8daedcd..415e305 100644
--- a/docs/redis.md
+++ b/docs/redis.md
@@ -19,7 +19,7 @@
Если вы не можете установить расширение phpredis, то установите пакет `predis/predis` через Composer. Predis – это клиент Redis, полностью написанный на PHP и не требующий дополнительных расширений:
-```bash
+```shell
composer require predis/predis
```
@@ -34,14 +34,14 @@ composer require predis/predis
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
- 'password' => env('REDIS_PASSWORD', null),
+ 'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
'cache' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
- 'password' => env('REDIS_PASSWORD', null),
+ 'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
@@ -76,7 +76,7 @@ composer require predis/predis
'default' => [
'scheme' => 'tls',
'host' => env('REDIS_HOST', '127.0.0.1'),
- 'password' => env('REDIS_PASSWORD', null),
+ 'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
@@ -96,7 +96,7 @@ composer require predis/predis
'default' => [
[
'host' => env('REDIS_HOST', 'localhost'),
- 'password' => env('REDIS_PASSWORD', null),
+ 'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
@@ -139,7 +139,7 @@ composer require predis/predis
'default' => [
'host' => env('REDIS_HOST', 'localhost'),
- 'password' => env('REDIS_PASSWORD', null),
+ 'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
'read_write_timeout' => 60,
@@ -166,7 +166,7 @@ composer require predis/predis
'default' => [
'host' => env('REDIS_HOST', 'localhost'),
- 'password' => env('REDIS_PASSWORD', null),
+ 'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
'read_timeout' => 60,
diff --git a/docs/releases.md b/docs/releases.md
index fd976ed..ccb327d 100644
--- a/docs/releases.md
+++ b/docs/releases.md
@@ -3,27 +3,24 @@
- [Схема версионирования](#versioning-scheme)
- [Исключения](#exceptions)
- [Политика поддержки](#support-policy)
-- [Laravel 8](#laravel-8)
+- [Laravel 9](#laravel-9)
## Схема версионирования
Laravel и другие его собственные пакеты следуют [Семантическому Версионированию](https://semver.org/lang/ru/). Мажорные релизы фреймворка выпускаются каждый год (предположительно февраль), тогда как минорные и патч-релизы могут выпускаться каждую неделю. Минорные и патч-релизы **никогда** не должны содержать критических изменений.
-Ссылаясь на фреймворк Laravel или его компоненты из вашего приложения или пакета, вы всегда должны использовать ограничение версии `^8.0`, поскольку мажорные релизы Laravel действительно включают критические изменения. Однако мы всегда стремимся к тому, чтобы вы могли выполнить обновление до новой мажорной версии в течение дня или менее.
-
-
-### Исключения
+Ссылаясь на фреймворк Laravel или его компоненты из вашего приложения или пакета, вы всегда должны использовать ограничение версии `^9.0`, поскольку мажорные релизы Laravel действительно включают критические изменения. Однако мы всегда стремимся к тому, чтобы вы могли выполнить обновление до новой мажорной версии в течение дня или менее.
-#### Именованные аргументы
+### Именованные аргументы
-В настоящее время функциональные возможности [именованных аргументов](https://www.php.net/manual/ru/functions.arguments.php#functions.named-arguments) PHP не подпадают под правила обратной совместимости Laravel. При необходимости мы можем переименовать аргументы функции, чтобы улучшить кодовую базу Laravel. Поэтому использовать именованные аргументы при вызове методов Laravel следует осторожно и с пониманием того, что их имена могут измениться в будущем.
+[Именованные аргументы](https://www.php.net/manual/ru/functions.arguments.php#functions.named-arguments) PHP не подпадают под правила обратной совместимости Laravel. При необходимости мы можем переименовать аргументы функции, чтобы улучшить кодовую базу Laravel. Поэтому использовать именованные аргументы при вызове методов Laravel следует осторожно и с пониманием того, что их имена могут измениться в будущем.
## Политика поддержки
-Для релизов LTS, таких как Laravel 9, исправления ошибок предоставляются в течение 2 лет, а исправления безопасности – в течение 3 лет. Эти релизы предоставляют самый продолжительный период поддержки и обслуживания. Для основных релизов, исправления ошибок предоставляются в течение 18 месяцев, а исправления безопасности – в течение 2 лет. Для всех дополнительных библиотек, включая Lumen, только последний релиз получает исправления ошибок. Помимо этого, ознакомьтесь с версиями баз данных, которые [поддерживает Laravel](/docs/database.md#introduction).
+Для релизов LTS, таких как Laravel 9, исправления ошибок предоставляются в течение 2 лет, а исправления безопасности – в течение 3 лет. Эти релизы предоставляют самый продолжительный период поддержки и обслуживания. Для основных релизов, исправления ошибок предоставляются в течение 18 месяцев, а исправления безопасности – в течение 2 лет. Для всех дополнительных библиотек, включая Lumen, только последний релиз получает исправления ошибок. Помимо этого, ознакомьтесь с версиями баз данных, которые [поддерживает Laravel](database.md#introduction).
| Версия | PHP (*) | Дата релиза | Исправление ошибок до | Исправления безопасности до |
| --- | --- | --- | --- | --- |
@@ -46,349 +43,428 @@ Laravel и другие его собственные пакеты следую
(*) Поддерживаемые версии PHP
-
-## Laravel 8
+
+## Laravel 9
-Laravel 8 продолжает улучшения, сделанные в Laravel 7.x, представляя Laravel Jetstream, классы фабрики модели, сжатие миграций, пакетную обработку заданий, улучшенное ограничение частоты запросов, улучшения очереди, динамические компоненты Blade, постраничная навигация с использованием Tailwind, помощники по временному тестированию, улучшения в `artisan serve`, улучшения слушателей событий и множество других исправлений ошибок и улучшений юзабилити.
+Как вы, возможно, знаете, Laravel перешел на ежегодные релизы с 8-ой версии Laravel. Раньше мажорные релизы выпускались каждые 6 месяцев. Этот переход предназначен для того, чтобы облегчить бремя обслуживания для сообщества и побудить нашу команду разработчиков выпускать потрясающие, мощные новые функции без внесения критических изменений. Поэтому мы добавили в Laravel 8 множество надежных функций без нарушения обратной совместимости, таких как поддержка параллельного тестирования, улучшенные стартовые комплекты Breeze, улучшения HTTP-клиента и даже новые типы отношений Eloquent, такие как «has one of many».
-
-### Laravel Jetstream
+Поэтому это обязательство по выпуску замечательных новых функций в текущем релизе, вероятно, приведет к тому, что будущие «мажорные» релизы будут в основном использоваться для задач «обслуживания», таких как обновление вышестоящих зависимостей, что можно увидеть в этих примечаниях к релизу.
-_Laravel Jetstream был написан [Taylor Otwell](https://github.com/taylorotwell)_.
+Laravel 9 продолжает улучшения, сделанные в Laravel 8.x, путем введения поддержки компонентов Symfony 6.0, Symfony Mailer, Flysystem 3.0, улучшенного вывода `route:list`, драйвера `database` Laravel Scout, нового синтаксиса аксессоров / мутаторов Eloquent, неявных привязок маршрутов с типизированными перечислениями и множество других исправлений ошибок и улучшений юзабилити.
-[Laravel Jetstream](https://jetstream.laravel.com) это красиво оформленный каркас приложений для Laravel. Jetstream обеспечивает идеальную отправную точку для вашего следующего проекта и включает в себя вход в систему, регистрацию, проверку электронной почты, двухфакторную аутентификацию, управление сессией, поддержку API через Laravel Sanctum и дополнительное командное управление. Laravel Jetstream заменяет и улучшает устаревшую структуру пользовательского интерфейса аутентификации, доступную в предыдущих версиях Laravel.
+
+### PHP 8.0
-Jetstream разработан с использованием [Tailwind CSS](https://tailwindcss.com) и предлагает на ваш выбор каркасы [Livewire](https://laravel-livewire.com) или [Inertia](https://inertiajs.com).
+Laravel 9.x теперь требует минимальную версию PHP 8.0.
-
-### Каталог моделей
+
+### Symfony Mailer
-По многочисленным просьбам сообщества каркас приложения Laravel по умолчанию теперь содержит каталог `app/Models`. Надеемся, вам понравится это решение для ваших моделей Eloquent! Все соответствующие команды генератора были обновлены, чтобы предполагать, что модели существуют в каталоге `app/Models`, если он существует. Если каталог не существует, фреймворк предполагает, что ваши модели должны быть помещены в каталог `app`.
+_Авторы: [Dries Vints](https://github.com/driesvints)_, [James Brooks](https://github.com/jbrooksuk) и [Julius Kiekbusch](https://github.com/Jubeki).
-
-### Классы фабрики модели
+Предыдущие релизы Laravel использовали библиотеку [Swift Mailer](https://swiftmailer.symfony.com/docs/introduction.html) для отправки исходящей электронной почты. Однако эта библиотека больше не поддерживается, и ее заменил Symfony Mailer.
-_Автор: [Taylor Otwell](https://github.com/taylorotwell)_.
+Ознакомьтесь с [руководством по обновлению](upgrade.md#symfony-mailer), чтобы узнать больше о том, как обеспечить совместимость вашего приложения с Symfony Mailer.
-[Фабрики модели](/docs/database-testing.md#defining-model-factories) Eloquent были полностью переписаны как фабрики на основе классов и улучшены для обеспечения "first-class" поддержки отношений. Например, `UserFactory`, включенный в Laravel, написан так:
+
+### Flysystem 3.x
- $this->faker->name(),
- 'email' => $this->faker->unique()->safeEmail(),
- 'email_verified_at' => now(),
- 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // пароль
- 'remember_token' => Str::random(10),
- ];
- }
- }
+
+### Улучшенные аксессоры / мутаторы Eloquent
-Благодаря новому трейту `HasFactory`, доступному для сгенерированных моделей, фабрика модели может использоваться следующим образом:
+_Автор: [Taylor Otwell](https://github.com/taylorotwell)_.
- use App\Models\User;
+Laravel 9.x предлагает новый способ определения [аксессоров и мутаторов](eloquent-mutators.md#accessors-and-mutators) Eloquent. В предыдущих релизах Laravel единственным способом определения аксессоров и мутаторов было определение префиксных методов в вашей модели следующим образом:
+
+```php
+public function getNameAttribute($value)
+{
+ return strtoupper($value);
+}
+
+public function setNameAttribute($value)
+{
+ $this->attributes['name'] = $value;
+}
+```
+
+Однако в Laravel 9.x вы можете определить аксессор и мутатор, используя один метод без префикса, указав возвращаемый тип `Illuminate\Database\Eloquent\Casts\Attribute`:
+
+```php
+use Illuminate\Database\Eloquent\Casts\Attribute;
+
+public function name(): Attribute
+{
+ return new Attribute(
+ get: fn ($value) => strtoupper($value),
+ set: fn ($value) => $value,
+ );
+}
+```
+
+Кроме того, этот новый подход к определению методов доступа будет кэшировать значения объектов, которые возвращаются атрибутом, точно так же, как [пользовательские классы типизации](eloquent-mutators.md#custom-casts):
+
+```php
+use App\Support\Address;
+use Illuminate\Database\Eloquent\Casts\Attribute;
+
+public function address(): Attribute
+{
+ return new Attribute(
+ get: fn ($value, $attributes) => new Address(
+ $attributes['address_line_one'],
+ $attributes['address_line_two'],
+ ),
+ set: fn (Address $value) => [
+ 'address_line_one' => $value->lineOne,
+ 'address_line_two' => $value->lineTwo,
+ ],
+ );
+}
+```
+
+
+### Типизация `Enum` атрибутов модели Eloquent
+
+> {note} Перечисляемые типы доступны только в [PHP 8.1+](https://www.php.net/manual/ru/language.enumerations.php).
- User::factory()->count(50)->create();
+_Автор: [Mohamed Said](https://github.com/themsaid)_.
-Поскольку фабрики модели теперь являются простыми классами PHP, преобразования состояний могут быть записаны как методы класса. Кроме того, при необходимости вы можете добавить любые другие вспомогательные классы в фабрику модели Eloquent.
+Eloquent также позволяет вам преобразовывать значения ваших атрибутов в перечисления PHP. Для этого вы можете указать атрибут, который вы хотите типизировать, и соответствующий класс перечисления в массиве `$casts` вашей модели:
-Например, ваша модель `User` может находиться в состоянии `suspended`, которое изменяет одно из значений ее атрибутов по умолчанию. Вы можете определить свои преобразования состояния, используя метод `state` базовой фабрики. Вы можете называть свой метод состояния как угодно. В конце концов, это просто типичный PHP-метод:
+ use App\Enums\ServerStatus;
/**
- * Указать, что аккаунт пользователя временно приостановлен.
+ * Атрибуты, которые должны быть типизированы.
*
- * @return \Illuminate\Database\Eloquent\Factories\Factory
+ * @var array
*/
- public function suspended()
- {
- return $this->state([
- 'account_status' => 'suspended',
- ]);
+ protected $casts = [
+ 'status' => ServerStatus::class,
+ ];
+
+После того, как вы определили типизацию в своей модели, указанный атрибут будет автоматически преобразован в перечисляемый тип и из него при взаимодействии с атрибутом:
+
+ if ($server->status == ServerStatus::provisioned) {
+ $server->status = ServerStatus::ready;
+
+ $server->save();
}
-После определения метода преобразования состояния мы можем использовать его так:
+
+### Неявная привязка в маршрутах с типизированными перечислениями
+
+_Автор: [Nuno Maduro](https://github.com/nunomaduro)_.
+В PHP 8.1 появилась поддержка [типизированных перечислений](https://www.php.net/manual/ru/language.enumerations.backed.php). Laravel 9.x позволяет вам указывать типизированным перечислением в определении вашего маршрута, и Laravel будет вызывать маршрут только в том случае, если этот сегмент маршрута соответствует допустимому значению перечисления. В противном случае будет автоматически возвращен 404-ый ответ HTTP. Например, учитывая следующее определение перечисления:
+
+```php
+enum Category: string
+{
+ case Fruits = 'fruits';
+ case People = 'people';
+}
+```
+
+Вы можете определить маршрут, который будет вызываться только в том случае, если сегмент маршрута `{category}` имеет значение `fruits` или `people`. В противном случае Laravel вернет 404-ый ответ HTTP:
+
+```php
+Route::get('/categories/{category}', function (Category $category) {
+ return $category->value;
+});
+```
+
+
+### Принудительные ограничения привязки маршрута
+
+_Автор: [Claudio Dekker](https://github.com/claudiodekker)_.
+
+В предыдущих релизах Laravel при желании можно было ограничить вторую модель Eloquent в определении маршрута, чтобы она была дочерней по отношению к предыдущей модели Eloquent. Например, рассмотрим это определение маршрута, которое извлекает пост в блоге по `slug` для конкретного пользователя:
+
+ use App\Models\Post;
use App\Models\User;
- User::factory()->count(5)->suspended()->create();
+ Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
+ return $post;
+ });
-Как уже упоминалось, фабрики модели Laravel 8 содержат "first-class" поддержку отношений. Итак, предполагая, что наша модель `User` имеет метод-отношение `posts`, мы можем просто запустить следующий код для создания пользователя с тремя постами:
+При использовании неявной привязки с измененным ключом в качестве параметра вложенного маршрута, Laravel автоматически задает ограничение запроса для получения вложенной модели своим родителем, используя соглашения, чтобы угадать имя отношения родительской модели. Однако такое поведение ранее поддерживалось Laravel только тогда, когда для привязки дочернего маршрута использовался пользовательский ключ.
- $users = User::factory()
- ->hasPosts(3, [
- 'published' => false,
- ])
- ->create();
+Однако в Laravel 9.x теперь вы можете указать Laravel ограничить «дочерние» привязки, даже если ключ не был предоставлен. Для этого вы можете вызвать метод `scopeBindings` при определении вашего маршрута:
-Чтобы упростить процесс обновления, был выпущен пакет [laravel/legacy-factories](https://github.com/laravel/legacy-factories), обеспечивающий поддержку предыдущей итерации фабрик модели в Laravel 8.x.
+ use App\Models\Post;
+ use App\Models\User;
-Переписанные фабрики Laravel содержат гораздо больше функций, которые, как мы думаем, вам понравятся. Чтобы узнать больше о фабриках моделей, обратитесь к [документации по тестированию баз данных](/docs/database-testing.md#defining-model-factories).
+ Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
+ return $post;
+ })->scopeBindings();
-
-### Сжатие миграций
+Или вы можете указать в определении группы маршрутов использовать ограничения привязки:
-_Автор: [Taylor Otwell](https://github.com/taylorotwell)_.
+ Route::scopeBindings()->group(function () {
+ Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
+ return $post;
+ });
+ });
-По мере создания приложения вы можете со временем накапливать все больше и больше миграций. Это может привести к тому, что каталог миграций станет раздутым из-за потенциально сотен миграций. Если вы используете MySQL или PostgreSQL, теперь вы можете «сжать» свои миграции в один файл SQL. Для начала выполните команду `schema:dump`:
+
+### Контроллер для группы маршрутов
- php artisan schema:dump
+_Автор: [Luke Downing](https://github.com/lukeraymonddowning)_.
- // Выгрузить текущую схему БД и удалить все существующие миграции ...
- php artisan schema:dump --prune
+Вы можете использовать метод `controller`, чтобы определить общий контроллер для всех маршрутов в группе. Затем при определении маршрутов вам нужно только указать метод контроллера, который они вызывают:
-Когда вы выполните эту команду, Laravel запишет файл «схемы» в каталог `database/schema` вашего приложения. Теперь, когда вы попытаетесь перенести свою базу данных, Laravel сначала выполнит SQL-операторы файла схемы, при условии, что никакие другие миграции не выполнялись. После выполнения команд файла схемы, Laravel выполнит все оставшиеся миграции, которые не были включены в дамп схемы БД.
+ use App\Http\Controllers\OrderController;
-
-### Пакетная обработка заданий
+ Route::controller(OrderController::class)->group(function () {
+ Route::get('/orders/{id}', 'show');
+ Route::post('/orders', 'store');
+ });
-_Авторы: [Taylor Otwell](https://github.com/taylorotwell) и [Mohamed Said](https://github.com/themsaid)_.
+
+### Полнотекстовые индексы и выражения `where`
-Функционал пакетной обработки заданий Laravel позволяет вам легко выполнить пакет заданий, по завершению которого дополнительно совершить определенные действия.
+_Авторы: [Taylor Otwell](https://github.com/taylorotwell) и [Dries Vints](https://github.com/driesvints)_.
-Новый метод `batch` фасада `Bus` используется для отправки пакета заданий. Конечно, это в первую очередь полезно в сочетании с замыканиями по завершению. Итак, вы можете использовать методы `then`, `catch` и `finally` для определения замыканий пакета заданий. Каждый из этих замыканий получит экземпляр `Illuminate\Bus\Batch` при вызове:
+При использовании MySQL или PostgreSQL теперь для создания полнотекстовых индексов может быть добавлен метод `fullText` к определениям столбцов:
- use App\Jobs\ProcessPodcast;
- use App\Podcast;
- use Illuminate\Bus\Batch;
- use Illuminate\Support\Facades\Bus;
- use Throwable;
+ $table->text('bio')->fullText();
- $batch = Bus::batch([
- new ProcessPodcast(Podcast::find(1)),
- new ProcessPodcast(Podcast::find(2)),
- new ProcessPodcast(Podcast::find(3)),
- new ProcessPodcast(Podcast::find(4)),
- new ProcessPodcast(Podcast::find(5)),
- ])->then(function (Batch $batch) {
- // Все задания успешно завершены ...
- })->catch(function (Batch $batch, Throwable $e) {
- // Обнаружено первое проваленное задание из пакета ...
- })->finally(function (Batch $batch) {
- // Завершено выполнение пакета ...
- })->dispatch();
+Методы `whereFullText` и `orWhereFullText` полнотекстового поиска можно использовать для добавления условий `where` в запрос для столбцов, которые имеют [полнотекстовые индексы](migrations.md#available-index-types). Эти методы будут преобразованы Laravel в соответствующий SQL базы данных. Например, предложение `MATCH AGAINST` будет создано для приложений, использующих MySQL:
- return $batch->id;
+ $users = DB::table('users')
+ ->whereFullText('bio', 'web developer')
+ ->get();
-Чтобы узнать больше о пакетной обработки заданий, обратитесь к [документации по очередям](/docs/queues.md#job-batching).
+
+### Поисковая система `database` для Laravel Scout
-
-### Улучшенное ограничение частоты запросов
+_Авторы: [Taylor Otwell](https://github.com/taylorotwell) и [Dries Vints](https://github.com/driesvints)_.
-_Автор: [Taylor Otwell](https://github.com/taylorotwell)_.
+Если ваше приложение взаимодействует с базами данных малого и среднего размера или имеет небольшую рабочую нагрузку, то вам может быть удобнее начать работу с поисковой системой `database` Scout вместо Algolia или MeiliSerach. Поисковая система базы данных будет использовать выражения `where like` и полнотекстовые индексы при фильтрации результатов из вашей существующей базы данных, чтобы определить применимые результаты поиска для вашего запроса.
-Функционал ограничения частоты запросов в Laravel был расширен за счет большей гибкости и возможностей, при этом сохранена обратная совместимость с API посредника `throttle` предыдущих релизов.
+Чтобы узнать больше о поисковой системе `database` для Scout, обратитесь к [документации Scout](scout.md).
-Ограничители определяются с помощью метода `for` фасада `RateLimiter`. Метод `for` принимает имя ограничителя и замыкание, которое возвращает конфигурацию ограничений, применяемых к назначенным маршрутам:
+
+### Отрисовка встроенных шаблонов Blade
- use Illuminate\Cache\RateLimiting\Limit;
- use Illuminate\Support\Facades\RateLimiter;
+_Авторы: [Jason Beggs](https://github.com/jasonlbeggs) и [Toby Zerner](https://github.com/tobyzerner)_.
- RateLimiter::for('global', function (Request $request) {
- return Limit::perMinute(1000);
- });
+Иногда требуется преобразовать строку шаблона Blade в HTML. Вы можете сделать это, используя метод `render` фасада `Blade`. Метод `render` принимает строку шаблона Blade и необязательный массив данных для шаблона:
-Поскольку замыкание получает экземпляр входящего HTTP-запроса, вы можете динамически создать ограничение на основе входящего запроса или статуса аутентификации пользователя:
+```php
+use Illuminate\Support\Facades\Blade;
- RateLimiter::for('uploads', function (Request $request) {
- return $request->user()->vipCustomer()
- ? Limit::none()
- : Limit::perMinute(100);
- });
+return Blade::render('Hello, {{ $name }}', ['name' => 'Julian Bashir']);
+```
-Иногда требуется сегментация ограничений по некоторым произвольным значениям. Например, вы можете разрешить пользователям получать доступ к указанному маршруту 100 раз в минуту на каждый IP-адрес. Для этого можно использовать метод `by` при построении лимита:
+Точно так же метод `renderComponent` может использоваться для отрисовки переданного класса компонента путем передачи экземпляра компонента в метод:
- RateLimiter::for('uploads', function (Request $request) {
- return $request->user()->vipCustomer()
- ? Limit::none()
- : Limit::perMinute(100)->by($request->ip());
- });
+```php
+use App\View\Components\HelloComponent;
-Ограничители могут быть закреплены за маршрутами или группами маршрутов с помощью [посредника](/docs/middleware.md) `throttle`. Посредник `throttle` принимает имя ограничителя, которое вы хотите назначить маршруту:
+return Blade::renderComponent(new HelloComponent('Julian Bashir'));
+```
- Route::middleware(['throttle:uploads'])->group(function () {
- Route::post('/audio', function () {
- //
- });
+
+### Упрощение в именовании слота
- Route::post('/video', function () {
- //
- });
- });
+_Автор: [Caleb Porzio](https://github.com/calebporzio)._
-Чтобы узнать больше об ограничителях запросов, обратитесь к [документации по маршрутизации](/docs/routing.md#rate-limiting).
+В предыдущих релизах Laravel имена слотов определялись с использованием атрибута `name` в теге `x-slot`:
-
-### Улучшенный режим обслуживания
+```blade
+
+
+ Server Error
+
-_Автор: [Taylor Otwell](https://github.com/taylorotwell), вдохновленный [Spatie](https://spatie.be)_.
+ Whoops! Something went wrong!
+
+```
-В предыдущих релизах Laravel функционал режима обслуживания `php artisan down` можно было обойти с помощью «разрешенного списка» IP-адресов, имеющим доступ к приложению. Эта функция была удалена в пользу более простого токен-решения.
+Однако, начиная с Laravel 9.x, вы можете указать имя слота, используя удобный, более короткий синтаксис:
-Находясь в режиме обслуживания, вы можете использовать параметр `secret`, чтобы указать токен обхода режима обслуживания:
+```xml
+
+ Server Error
+
+```
- php artisan down --secret="1630542a-246b-4b66-afa1-dd72a4c43515"
+
+### Отмеченные / Выделенные элементы интерфейса
-После перевода приложения в режим обслуживания вы можете перейти по URL-адресу приложения, соответствующему этому токену, и Laravel выдаст вашему браузеру файл cookie обхода режима обслуживания:
+_Авторы: [Ash Allen](https://github.com/ash-jc-allen) и [Taylor Otwell](https://github.com/taylorotwell)_.
- https://example.com/1630542a-246b-4b66-afa1-dd72a4c43515
+Для удобства вы можете использовать директиву `@checked`, чтобы указать, должен ли быть «отмечен» HTML-флажок. Эта директива выведет `checked`, если переданное условие является истинным:
-При доступе к этому скрытому маршруту вы будете перенаправлены на корневой маршрут приложения. Как только cookie будет отправлен вашему браузеру, вы сможете просматривать приложение в обычном режиме, как если бы оно не находилось в режиме обслуживания.
+```blade
+ active)) />
+```
-
-#### Предварительный рендеринг шаблона режима обслуживания
+Аналогично, директива `@selected` может использоваться для указания, следует ли «выбрать» указанный элемент выпадающего списка:
-Если вы используете команду `php artisan down` во время развертывания, ваши пользователи могут иногда сталкиваться с ошибками, если они обращаются к приложению во время обновления ваших зависимостей Composer или других компонентов фреймворка. Это происходит потому, что значительная часть фреймворка Laravel должна загружаться, чтобы определить, находится ли ваше приложение в режиме обслуживания, и отобразить шаблон режима обслуживания с помощью механизма шаблонов.
+```blade
+
+ @foreach ($product->versions as $version)
+
+ {{ $version }}
+
+ @endforeach
+
+```
-По этой причине Laravel позволяет предварительно визуализировать шаблон режима обслуживания, который будет возвращен в самом начале цикла запроса. Этот шаблон отображается перед загрузкой любых зависимостей вашего приложения. Вы можете выполнить предварительный рендеринг шаблона по вашему выбору, используя параметр `render` команды `down`:
+
+### Шаблоны Bootstrap 5 для постраничной навигации
- php artisan down --render="errors::503"
+_Автор: [Jared Lewis](https://github.com/jrd-lewis)_.
-
-### Выполнение замыканий с использованием цепочки `catch`
+Laravel теперь содержит шаблоны для постраничной навигации, созданные с помощью [Bootstrap 5](https://getbootstrap.com/). Чтобы использовать эти шаблоны вместо шаблонов Tailwind по умолчанию, вы можете вызвать метод пагинатора `useBootstrapFive` в методе `boot` поставщика `App\Providers\AppServiceProvider`:
-_Автор: [Mohamed Said](https://github.com/themsaid)_.
+ use Illuminate\Pagination\Paginator;
-Используя новый метод `catch`, теперь можно определить замыкание, которое должно быть выполнено, если замыкание, указанное в очереди не удалось успешно завершить при исчерпании попыток повтора очереди:
+ /**
+ * Загрузка любых служб приложения.
+ *
+ * @return void
+ */
+ public function boot()
+ {
+ Paginator::useBootstrapFive();
+ }
- use Throwable;
+
+### Улучшенная валидация данных вложенного массива
- dispatch(function () use ($podcast) {
- $podcast->publish();
- })->catch(function (Throwable $e) {
- // Не удалось выполнить это задание ...
- });
+_Автор: [Steve Bauman](https://github.com/stevebauman)_.
-
-### Динамические компоненты Blade
+Иногда требуется получить доступ к значению переданного вложенного элемента массива при назначении правил валидации для атрибута. Вы можете сделать это, используя метод `Rule::foreEach`. Метод `forEach` принимает замыкание, которое будет вызываться для каждой итерации проверяемого атрибута массива, и будет получать значение атрибута и явное, полностью развернутое имя атрибута. Замыкание должно возвращать массив правил предназначенных элементу массива:
-_Автор: [Taylor Otwell](https://github.com/taylorotwell)_.
+ use App\Rules\HasPermission;
+ use Illuminate\Support\Facades\Validator;
+ use Illuminate\Validation\Rule;
-Иногда требуется отрисовать компонент, но вы не знаете, какой именно компонент это будет до момента выполнения. В этой ситуации вы можете использовать встроенный в Laravel компонент `dynamic-component` для рендеринга компонента, зависящего от значения или переменной, сформированных во время выполнения приложения:
+ $validator = Validator::make($request->all(), [
+ 'companies.*.id' => Rule::forEach(function ($value, $attribute) {
+ return [
+ Rule::exists(Company::class, 'id'),
+ new HasPermission('manage-company', $value),
+ ];
+ }),
+ ]);
-
+
+### Laravel Breeze API и Next.js
-Чтобы узнать больше о компонентах Blade, обратитесь к [документации Blade](/docs/blade.md#components).
+_Авторы: [Taylor Otwell](https://github.com/taylorotwell) и [Miguel Piedrafita](https://twitter.com/m1guelpf)_.
-
-### Улучшения слушателей событий
+Стартовый комплект [Laravel Breeze](starter-kits.md#breeze-and-next) получил режим формирования «API» и [реализацию внешнего интерфейса](https://github.com/laravel/breeze-next) на [Next.js](https://nextjs.org). Этот стартовый комплект может использоваться для быстрого запуска ваших приложений Laravel, которые служат в качестве бэкэнда с аутентификацией API для внешнего интерфейса JavaScript через Laravel Sanctum.
-_Автор: [Taylor Otwell](https://github.com/taylorotwell)_.
+
+### Улучшенная страница исключения Ignition
-Слушатели событий, основанные на замыкании, теперь регистрируются только путем передачи замыкания методу `Event::listen`. Laravel проверит замыкание, чтобы определить, какой тип события обрабатывает слушатель:
+_Автор: [Spatie](https://spatie.be/)._
- use App\Events\PodcastProcessed;
- use Illuminate\Support\Facades\Event;
+Ignition – страница отладки исключений с открытым исходным кодом, созданная Spatie, была переработана с нуля. Ignition поставляется с Laravel 9.x и включает в себя светлые / темные темы, настраиваемую функцию «открыть в редакторе» и многое другое.
- Event::listen(function (PodcastProcessed $event) {
- //
- });
+
+
+
-Кроме того, анонимные слушатели событий теперь могут быть помечены как доступные для очереди с помощью функции `Illuminate\Events\queueable`:
+
+### Красивый вывод консольной команды `route:list`
- use App\Events\PodcastProcessed;
- use function Illuminate\Events\queueable;
- use Illuminate\Support\Facades\Event;
+_Автор: [Nuno Maduro](https://github.com/nunomaduro)_.
- Event::listen(queueable(function (PodcastProcessed $event) {
- //
- }));
+Вывод `route:list` был значительно улучшен в Laravel 9.x и предлагает новый вид при обзоре ваших определений маршрутов.
-Как и задания в очереди, вы можете использовать методы `onConnection`, `onQueue` и `delay` для настройки выполнения слушателя в очереди:
+
+
+
- Event::listen(queueable(function (PodcastProcessed $event) {
- //
- })->onConnection('redis')->onQueue('podcasts')->delay(now()->addSeconds(10)));
+
+### Отчет о покрытии тестами при использовании команды `test` Artisan
-Если вы хотите обработать сбои запланированного анонимного слушателя, то предоставьте замыкание методу `catch` при определении `queueable`-слушателя:
+_Автор: [Nuno Maduro](https://github.com/nunomaduro)_.
- use App\Events\PodcastProcessed;
- use function Illuminate\Events\queueable;
- use Illuminate\Support\Facades\Event;
- use Throwable;
+Команда `test` Artisan получила новую опцию `--coverage`, которую вы можете использовать для изучения объема покрытия кода, которое ваши тесты предоставляют вашему приложению:
- Event::listen(queueable(function (PodcastProcessed $event) {
- //
- })->catch(function (PodcastProcessed $event, Throwable $e) {
- // Не удалось выполнить запланированного слушателя ...
- }));
+```shell
+php artisan test --coverage
+```
-
-### Помощники по временному тестированию
+Результаты покрытия тестами будут отображаться непосредственно при выводе в CLI.
-_Автор: [Taylor Otwell](https://github.com/taylorotwell), вдохновленный Ruby on Rails_.
+
+
+
-При тестировании вам может иногда потребоваться изменить время, возвращаемое такими помощниками, как `now` или `Illuminate\Support\Carbon::now()`. Базовый класс тестирования функций Laravel теперь включает помощников, которые позволяют вам управлять текущим временем:
+Вы можете использовать параметр `--min`, чтобы определить минимальный порог покрытия тестами вашего приложения. Набор тестов завершится ошибкой, если этот порог не будет достигнут:
- public function testTimeCanBeManipulated()
- {
- // Путешествие в будущее ...
- $this->travel(5)->milliseconds();
- $this->travel(5)->seconds();
- $this->travel(5)->minutes();
- $this->travel(5)->hours();
- $this->travel(5)->days();
- $this->travel(5)->weeks();
- $this->travel(5)->years();
-
- // Путешествие в прошлое ...
- $this->travel(-5)->hours();
-
- // Путешествие в определенное время ...
- $this->travelTo(now()->subHours(6));
-
- // Вернуться в настоящее время ...
- $this->travelBack();
- }
+```shell
+php artisan test --coverage --min=80.3
+```
-
-### Улучшения Artisan `serve`
+
+
+
-_Автор: [Taylor Otwell](https://github.com/taylorotwell)_.
+
+### Сервер Soketi Echo
+
+_Автор: [Alex Renoki](https://github.com/rennokki)_.
+
+Хотя это не является эксклюзивным для Laravel 9.x, Laravel недавно помог с документацией Soketi, совместимого с [Laravel Echo](broadcasting.md) сервера Web Socket, написанного для Node.js. Soketi предоставляет отличную альтернативу Pusher и Ably с открытым исходным кодом для тех приложений, которые предпочитают управлять собственным сервером Web Socket.
+
+Для получения дополнительной информации об использовании Soketi обратитесь к [документации по трансляции событий](broadcasting.md) и [документации по Soketi](https://docs.soketi.app/).
+
+
+### Улучшенная поддержка IDE для коллекций
+
+_Автор: [Nuno Maduro](https://github.com/nunomaduro)_.
+
+Laravel 9.x добавляет улучшенные определения типов в компонент коллекций, улучшая поддержку IDE и статического анализа. IDE, такие как [PHPStorm](https://blog.jetbrains.com/phpstorm/2021/12/phpstorm-2021-3-release/#support_for_future_laravel_collections) или инструменты статического анализа, такие как [PHPStan](https://phpstan.org) теперь будет лучше понимать коллекции Laravel изначально.
+
+
+
+
+
+
+### Новые глобальные помощники
+
+Laravel 9.x представляет две новые удобные вспомогательные функции, которые вы можете использовать в своем приложении.
-Команда `serve` консоли Artisan была улучшена за счет автоматической перезагрузки при обнаружении изменений переменных окружения в вашем локальном файле `.env`. Раньше команду приходилось останавливать и перезапускать вручную.
+
+#### `str`
-
-### Постраничная навигация с использованием Tailwind
+Функция `str` возвращает новый экземпляр `Illuminate\Support\Stringable` переданной строки. Эта функция эквивалентна методу `Str::of`:
-Пагинатор Laravel был обновлен для использования фреймворка [Tailwind CSS](https://tailwindcss.com) по умолчанию. Tailwind CSS – это настраиваемая низкоуровневая структура CSS, которая дает вам все строительные блоки, необходимые для создания нестандартных дизайнов без каких-либо раздражающих самоуверенных стилей, за которые вам придется бороться. Конечно, также остаются доступными шаблоны Bootstrap 3 и 4.
+ $string = str('Taylor')->append(' Otwell');
-
-### Обновления пространства имен маршрутизации
+ // 'Taylor Otwell'
-В предыдущих релизах Laravel `RouteServiceProvider` содержал свойство `$namespace`. Значение этого свойства будет автоматически добавлено к определениям маршрута контроллера и вызовам помощника `action` / метода `URL::action`. В Laravel 8.x это свойство по умолчанию имеет значение `null`. Это означает, что Laravel не будет автоматически подставлять префиксы пространства имен. Поэтому в новых приложениях Laravel 8.x определения маршрутов контроллера должны быть определены с использованием стандартного синтаксиса объявлений зависимостей PHP:
+Если для функции `str` не указан аргумент, то функция возвращает экземпляр `Illuminate\Support\Str`:
- use App\Http\Controllers\UserController;
+ $snake = str()->snake('LaravelFramework');
- Route::get('/users', [UserController::class, 'index']);
+ // 'laravel_framework'
-Вызов методов, связанных с `action`, должен использовать тот же синтаксис объявлений:
+
+#### `to_route`
- action([UserController::class, 'index']);
+Функция `to_route` генерирует [HTTP-ответ перенаправления](responses.md#redirects) на [именованный маршрут](routing.md#named-routes):
- return Redirect::action([UserController::class, 'index']);
+ return to_route('users.show', ['user' => 1]);
-Если вы предпочитаете префиксирование маршрута контроллера в стиле Laravel версии 7.x, то вы можете просто добавить свойство `$namespace` в поставщик `RouteServiceProvider` вашего приложения.
+При необходимости вы можете передать код состояния HTTP, который должен быть назначен перенаправлению, и любые дополнительные заголовки ответа в качестве третьего и четвертого аргументов метода `to_route`, соответственно:
-> {note} Это изменение касается только новых приложений Laravel 8.x. Приложения, обновляющиеся с Laravel 7.x, по-прежнему будут иметь свойство `$namespace` в своем `RouteServiceProvider`.
+ return to_route('users.show', ['user' => 1], 302, ['X-Framework' => 'Laravel']);
diff --git a/docs/requests.md b/docs/requests.md
index 95fef94..69ae8ee 100644
--- a/docs/requests.md
+++ b/docs/requests.md
@@ -201,8 +201,10 @@ Laravel содержит несколько методов для проверк
[Стандарт PSR-7](https://www.php-fig.org/psr/psr-7/) определяет интерфейсы для сообщений HTTP, включая запросы и ответы. Если вы хотите получить экземпляр запроса PSR-7 вместо запроса Laravel, вам сначала необходимо установить несколько библиотек. Laravel использует компонент *Symfony HTTP Message Bridge* для преобразования типичных запросов и ответов Laravel в реализации, совместимой с PSR-7:
- composer require symfony/psr-http-message-bridge
- composer require nyholm/psr7
+```shell
+composer require symfony/psr-http-message-bridge
+composer require nyholm/psr7
+```
После того, как вы установили эти библиотеки, вы можете получить запрос PSR-7, объявив тип интерфейса запроса для замыкания вашего маршрута или контроллера:
diff --git a/docs/routing.md b/docs/routing.md
index 2601068..a15ae7b 100644
--- a/docs/routing.md
+++ b/docs/routing.md
@@ -16,6 +16,7 @@
- [Префиксы имен сгруппированных маршрутов](#route-group-name-prefixes)
- [Привязка модели к маршруту](#route-model-binding)
- [Неявная привязка](#implicit-binding)
+ - [Неявная привязка с типизированными перечислениями](#implicit-enum-binding)
- [Явная привязка](#explicit-binding)
- [Резервные маршруты](#fallback-routes)
- [Ограничение частоты запросов](#rate-limiting)
@@ -484,6 +485,34 @@ Laravel автоматически извлечет модели Eloquent, оп
return Redirect::route('locations.index');
});
+
+### Неявная привязка с типизированными перечислениями
+
+В PHP 8.1 появилась поддержка [типизированных перечислений](https://www.php.net/manual/ru/language.enumerations.backed.php). Laravel позволяет вам указывать типизированным перечислением в определении вашего маршрута, и Laravel будет вызывать маршрут только в том случае, если этот сегмент маршрута соответствует допустимому значению перечисления. В противном случае будет автоматически возвращен 404-ый ответ HTTP. Например, учитывая следующее определение перечисления:
+
+```php
+value;
+});
+```
+
### Явная привязка
diff --git a/docs/sail.md b/docs/sail.md
index d32f99e..489185e 100644
--- a/docs/sail.md
+++ b/docs/sail.md
@@ -46,41 +46,49 @@ Laravel Sail автоматически устанавливается со вс
Если вы заинтересованы в использовании Sail в существующем приложением Laravel, то вы можете просто установить Sail с помощью менеджера пакетов Composer. Конечно, эти шаги предполагают, что ваша существующая локальная среда разработки позволяет вам устанавливать зависимости Composer:
- composer require laravel/sail --dev
+```shell
+composer require laravel/sail --dev
+```
После установки Sail вы можете запустить команду `sail:install` Artisan. Эта команда опубликует файл `docker-compose.yml` Sail в корне вашего приложения:
- php artisan sail:install
+```shell
+php artisan sail:install
+```
Наконец, вы можете запустить Sail. Чтобы продолжить изучение использования Sail, продолжайте читать оставшуюся часть этой документации:
- ./vendor/bin/sail up
+```shell
+./vendor/bin/sail up
+```
#### Использование Devcontainer
Если вы хотите разработать в [Devcontainer](https://code.visualstudio.com/docs/remote/containers), то вы можете указать флаг `--devcontainer` для команды `sail:install`. Флаг `--devcontainer` проинструктирует команду `sail:install` опубликовать файл `.devcontainer/devcontainer.json` в корне вашего приложения:
- php artisan sail:install --devcontainer
+```shell
+php artisan sail:install --devcontainer
+```
### Настройка псевдонима Bash
По умолчанию команды Sail вызываются с помощью скрипта `vendor/bin/sail`, который включен во все новые приложения Laravel:
-```bash
+```shell
./vendor/bin/sail up
```
Но вместо многократно повторяющегося набора `vendor/bin/sail` для выполнения команд Sail, вы можете задать псевдоним Bash, который позволит вам легче выполнять команды Sail:
-```bash
+```shell
alias sail='[ -f sail ] && bash sail || bash vendor/bin/sail'
```
После задания псевдонима Bash вы можете выполнять команды Sail, просто набрав `sail`. В остальных примерах документации предполагается, что вы настроили этот псевдоним:
-```bash
+```shell
sail up
```
@@ -91,13 +99,13 @@ sail up
Перед запуском Sail вы должны убедиться, что на вашем локальном компьютере не работают другие веб-серверы или базы данных. Чтобы запустить все контейнеры Docker, определенные в файле `docker-compose.yml` вашего приложения, вы должны выполнить команду `up`:
-```bash
+```shell
sail up
```
Чтобы запустить все контейнеры Docker в фоновом режиме, вы можете запустить Sail в режиме `detached`:
-```bash
+```shell
sail up -d
```
@@ -105,7 +113,7 @@ sail up -d
Чтобы остановить все контейнеры, вы можете просто нажать Control + C , чтобы остановить их выполнение. Или, если контейнеры работают в фоновом режиме, вы можете использовать команду `down`:
-```bash
+```shell
sail stop
```
@@ -116,7 +124,7 @@ sail stop
**При чтении документации Laravel вы часто увидите ссылки на команды Composer, Artisan и Node / NPM, которые не ссылаются на Sail**. В этих примерах предполагается, что эти инструменты установлены на вашем локальном компьютере. Если вы используете Sail для своей локальной среды разработки Laravel, то вам следует выполнить эти команды с помощью Sail:
-```bash
+```shell
# Локальный запуск команд Artisan ...
php artisan queue:work
@@ -129,7 +137,7 @@ sail artisan queue:work
Команды PHP могут быть выполнены с помощью команды `php`. Конечно, эти команды будут выполняться с использованием версии PHP вашего приложения. Чтобы узнать больше о версиях PHP, доступных для Laravel Sail, обратитесь к разделу [Выбор версии PHP](#sail-php-versions):
-```bash
+```shell
sail php --version
sail php script.php
@@ -140,7 +148,7 @@ sail php script.php
Команды Composer могут быть выполнены с помощью команды `composer`. Контейнер приложения Laravel Sail содержит Composer 2.x:
-```nothing
+```shell
sail composer require laravel/sanctum
```
@@ -151,7 +159,7 @@ sail composer require laravel/sanctum
Вы можете установить зависимости приложения, перейдя в каталог приложения и выполнив следующую команду. Эта команда использует небольшой контейнер Docker, содержащий PHP и Composer, для установки зависимостей приложения:
-```nothing
+```shell
docker run --rm \
-u "$(id -u):$(id -g)" \
-v $(pwd):/var/www/html \
@@ -167,7 +175,7 @@ docker run --rm \
Команды Artisan могут быть выполнены с помощью команды `artisan`:
-```bash
+```shell
sail artisan queue:work
```
@@ -176,7 +184,7 @@ sail artisan queue:work
Команды Node могут быть выполнены с помощью команды `node`, в то время как команды NPM могут быть выполнены с помощью команды `npm`:
-```nothing
+```shell
sail node --version
sail npm run prod
@@ -184,7 +192,7 @@ sail npm run prod
Если вы хотите, то можете использовать Yarn вместо NPM:
-```nothing
+```shell
sail yarn
```
@@ -236,13 +244,17 @@ AWS_USE_PATH_STYLE_ENDPOINT=true
Laravel provides amazing testing support out of the box, and you may use Sail's `test` command to run your applications [feature and unit tests](testing.md). Any CLI options that are accepted by PHPUnit may also be passed to the `test` command:
- sail test
+```shell
+sail test
- sail test --group orders
+sail test --group orders
+```
The Sail `test` command is equivalent to running the `test` Artisan command:
- sail artisan test
+```shell
+sail artisan test
+```
### Использование Laravel Dusk в Sail
@@ -269,7 +281,9 @@ depends_on:
Наконец, вы можете запустить свой набор тестов Dusk, запустив Sail с командой `dusk`:
- sail dusk
+```shell
+sail dusk
+```
#### Selenium на Apple Silicon
@@ -290,7 +304,7 @@ selenium:
По умолчанию файл `docker-compose.yml` Laravel Sail содержит служебную запись для [MailHog](https://github.com/mailhog/MailHog). MailHog перехватывает электронные письма, отправляемые вашим приложением во время локальной разработки, и предоставляет удобный веб-интерфейс, чтобы вы могли просматривать свои электронные письма в браузере. При использовании Sail хостом по умолчанию для MailHog является `mailhog` и он доступен через порт `1025`:
-```bash
+```ini
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_ENCRYPTION=null
@@ -303,7 +317,7 @@ MAIL_ENCRYPTION=null
По желанию можно запустить сеанс Bash в контейнере вашего приложения. Вы можете использовать команду `shell` для подключения к контейнеру вашего приложения, что позволяет проверять файлы и установленные службы, а также выполнять произвольные команды оболочки внутри контейнера:
-```nothing
+```shell
sail shell
sail root-shell
@@ -311,7 +325,7 @@ sail root-shell
Чтобы начать новый сеанс [Laravel Tinker](https://github.com/laravel/tinker), вы можете выполнить команду `tinker`:
-```bash
+```shell
sail tinker
```
@@ -339,9 +353,11 @@ image: sail-8.1/app
После обновления файла `docker-compose.yml` вашего приложения вы должны перестроить образы контейнеров:
- sail build --no-cache
+```shell
+sail build --no-cache
- sail up
+sail up
+```
## Выбор версии Node
@@ -357,16 +373,20 @@ build:
После обновления файла `docker-compose.yml` вашего приложения вы должны перестроить образы контейнеров:
- sail build --no-cache
+```shell
+sail build --no-cache
- sail up
+sail up
+```
## Совместный доступ к вашему сайту
Иногда требуется предоставить общий доступ к своему сайту для его предварительного просмотра коллеге или для проверки интеграции веб-перехватчиков с вашим приложением. Чтобы поделиться своим сайтом, вы можете использовать команду `share`. После выполнения этой команды вам будет выдан случайный URL-адрес `laravel-sail.site`, который вы можете использовать для доступа к своему приложению:
- sail share
+```shell
+sail share
+```
При совместном доступе к вашему сайту с помощью команды `share` вы должны настроить доверенные прокси вашего приложения в посреднике `TrustProxies`. В противном случае глобальные помощники генерации URL, такие как `url` и `route`, не смогут определить правильный хост HTTP, который следует использовать во время генерации URL:
@@ -379,7 +399,9 @@ build:
Если вы хотите выбрать поддомен для вашего сайта, то вы можете указать опцию `subdomain` при выполнении команды `share`:
- sail share --subdomain=my-sail-site
+```shell
+sail share --subdomain=my-sail-site
+```
> {tip} Команда `share` поддерживается [Expose](https://github.com/beyondcode/expose), службой туннелирования с открытым исходным кодом от [BeyondCode](https://beyondco.de).
@@ -398,7 +420,7 @@ SAIL_XDEBUG_MODE=develop,debug
Во-первых, вы должны определить правильный IP-адрес хоста для добавления в переменную окружения, выполнив следующую команду. Как правило, `` должно быть именем контейнера, который обслуживает ваше приложение, и чаще всего заканчиваться на `_laravel.test_1`:
-```bash
+```shell
docker inspect -f {{range.NetworkSettings.Networks}}{{.Gateway}}{{end}}
```
@@ -413,7 +435,7 @@ SAIL_XDEBUG_CONFIG="client_host="
Команда `sail debug` может быть использована для запуска сеанса отладки при запуске команды Artisan:
-```bash
+```shell
# Запустить команды Artisan без Xdebug ...
sail artisan migrate
@@ -435,12 +457,12 @@ sail debug migrate
Поскольку Sail – это просто Docker, то вы можете настроить почти все в нем. Чтобы опубликовать Docker-файлы Sail, вы можете выполнить команду `sail:publish`:
-```bash
+```shell
sail artisan sail:publish
```
После запуска этой команды файлы Docker и другие конфигурационные файлы, используемые Laravel Sail, будут помещены в каталог `docker` корневого каталога вашего приложения. После настройки Sail вы можете изменить имя образа для контейнера приложения в файле `docker-compose.yml` вашего приложения. После этого пересоберите контейнеры вашего приложения с помощью команды `build`. Присвоение уникального имени образу приложения особенно важно, если вы используете Sail для разработки нескольких приложений Laravel на одном компьютере:
-```bash
+```shell
sail build --no-cache
```
diff --git a/docs/sanctum.md b/docs/sanctum.md
index 964e6e3..15ca5aa 100644
--- a/docs/sanctum.md
+++ b/docs/sanctum.md
@@ -56,15 +56,21 @@ Sanctum будет пытаться аутентифицироваться с п
Для начала установите Sanctum с помощью менеджера пакетов Composer в свой проект:
- composer require laravel/sanctum
+```shell
+composer require laravel/sanctum
+```
Затем, вы должны опубликовать файлы конфигурации и миграции Sanctum с помощью команды `vendor:publish` Artisan. Файл конфигурации `sanctum` будет помещен в каталог `config` вашего приложения:
- php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
+```shell
+php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
+```
Наконец, вы должны запустить миграцию базы данных. Sanctum создаст одну таблицу базы данных, в которой будут храниться токены API:
- php artisan migrate
+```shell
+php artisan migrate
+```
Затем, если вы планируете использовать Sanctum для аутентификации SPA, то вам следует добавить посредника Sanctum в вашу группу посредников `api` в файле `app/Http/Kernel.php`:
@@ -260,7 +266,9 @@ Sanctum также обеспечивает простой метод аутен
Кроме того, вы должны задействовать параметр `withCredentials` в глобальном экземпляре `axios` вашего приложения. Обычно это нужно делать в вашем файле `resources/js/bootstrap.js`. Если вы на клиентской стороне не используете Axios для выполнения HTTP-запросов, то вам следует выполнить аналогичную настройку своего HTTP-клиента:
- axios.defaults.withCredentials = true;
+```js
+axios.defaults.withCredentials = true;
+```
Наконец, вы должны убедиться, что конфигурация домена cookie сессии вашего приложения поддерживает любой поддомен вашего корневого домена. Вы можете сделать это, добавив к домену префикс `.` в конфигурационном файле `config/session.php` вашего приложения:
@@ -274,9 +282,11 @@ Sanctum также обеспечивает простой метод аутен
Для аутентификации вашего SPA страница «входа» вашего SPA должна сначала сделать запрос к конечной точке `/sanctum/csrf-cookie` для инициализации защиты от CSRF для приложения:
- axios.get('/sanctum/csrf-cookie').then(response => {
- // Login...
- });
+```js
+axios.get('/sanctum/csrf-cookie').then(response => {
+ // Login...
+});
+```
Во время этого запроса Laravel установит cookie `XSRF-TOKEN`, содержащий текущий токен CSRF. Этот токен следует передавать в заголовке `X-XSRF-TOKEN` при последующих запросах, что некоторые клиентские библиотеки HTTP, такие как Axios и Angular HttpClient, будут делать автоматически за вас. Если ваша HTTP-библиотека JavaScript не задает автоматически значение, то вам нужно будет вручную установить заголовок `X-XSRF-TOKEN`, чтобы он соответствовал значению `XSRF-TOKEN` cookie, установленному этим маршрутом.
@@ -311,28 +321,30 @@ Sanctum также обеспечивает простой метод аутен
Затем, чтобы запросы авторизации Pusher были успешными, вам нужно будет предоставить определение `authorizer` Pusher при инициализации [Laravel Echo](broadcasting.md#client-side-installation). Это позволит вашему приложению настроить Pusher для использования экземпляра `axios`, [ориентированного на междоменные запросы](#cors-and-cookies):
- window.Echo = new Echo({
- broadcaster: "pusher",
- cluster: process.env.MIX_PUSHER_APP_CLUSTER,
- encrypted: true,
- key: process.env.MIX_PUSHER_APP_KEY,
- authorizer: (channel, options) => {
- return {
- authorize: (socketId, callback) => {
- axios.post('/api/broadcasting/auth', {
- socket_id: socketId,
- channel_name: channel.name
- })
- .then(response => {
- callback(false, response.data);
- })
- .catch(error => {
- callback(true, error);
- });
- }
- };
- },
- })
+```js
+window.Echo = new Echo({
+ broadcaster: "pusher",
+ cluster: process.env.MIX_PUSHER_APP_CLUSTER,
+ encrypted: true,
+ key: process.env.MIX_PUSHER_APP_KEY,
+ authorizer: (channel, options) => {
+ return {
+ authorize: (socketId, callback) => {
+ axios.post('/api/broadcasting/auth', {
+ socket_id: socketId,
+ channel_name: channel.name
+ })
+ .then(response => {
+ callback(false, response.data);
+ })
+ .catch(error => {
+ callback(true, error);
+ });
+ }
+ };
+ },
+})
+```
## Аутентификация мобильного приложения
diff --git a/docs/scheduling.md b/docs/scheduling.md
index d5ed4e2..e1833d4 100644
--- a/docs/scheduling.md
+++ b/docs/scheduling.md
@@ -59,7 +59,7 @@
Если вы хотите просмотреть список ваших запланированных задач и их последующего запуска, то вы можете использовать команду `schedule:list` Artisan:
-```nothing
+```bash
php artisan schedule:list
```
@@ -301,14 +301,18 @@ php artisan schedule:list
Итак, при использовании планировщика Laravel нам нужно добавить только одну конфигурационную запись Cron на наш сервер, которая запускает команду `schedule:run` каждую минуту. Если вы не знаете, как добавить записи Cron на свой сервер, то рассмотрите возможность использования такой службы, как [Laravel Forge](https://forge.laravel.com), которая может управлять записями Cron за вас:
- * * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
+```shell
+* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
+```
## Локальный запуск планировщика
Как правило, на локальной машине нет необходимости в добавлении записи Cron планировщика. Вместо этого вы можете использовать команду `schedule:work` Artisan. Эта команда будет работать на переднем плане и вызывать планировщик каждую минуту, пока вы не завершите команду:
- php artisan schedule:work
+```shell
+php artisan schedule:work
+```
## Результат выполнения задачи
@@ -404,7 +408,9 @@ php artisan schedule:list
Для всех методов пингования требуется библиотека Guzzle HTTP. Guzzle обычно устанавливается во всех новых проектах Laravel по умолчанию, но вы можете вручную установить Guzzle в свой проект с помощью менеджера пакетов Composer, если он был удален:
- composer require guzzlehttp/guzzle
+```shell
+composer require guzzlehttp/guzzle
+```
## События
diff --git a/docs/scout.md b/docs/scout.md
index 70aa877..05bea3a 100644
--- a/docs/scout.md
+++ b/docs/scout.md
@@ -9,7 +9,9 @@
- [Настройка индексируемых сведений](#configuring-searchable-data)
- [Настройка идентификатора модели](#configuring-the-model-id)
- [Идентификация пользователей](#identifying-users)
-- [Локальная разработка](#local-development)
+- [Поисковые системы `database` / `collection`](#database-and-collection-engines)
+ - [Поисковая система `database`](#database-engine)
+ - [Поисковая система `collection`](#collection-engine)
- [Индексирование](#indexing)
- [Пакетный импорт записей](#batch-import)
- [Добавление записей](#adding-records)
@@ -30,18 +32,22 @@
[Laravel Scout](https://github.com/laravel/scout) предлагает простое решение на основе драйверов для добавления полнотекстового поиска вашим [моделям Eloquent](eloquent.md). Используя наблюдателей моделей, Scout будет автоматически синхронизировать ваши поисковые индексы с вашими записями Eloquent.
-В настоящее время Scout поставляется с драйверами [Algolia](https://www.algolia.com/) и [MeiliSearch](https://www.meilisearch.com). Кроме того, Scout включает в себя драйвер `collection`, предназначенный для использования при локальной разработке и не требующий каких-либо внешних зависимостей или сторонних сервисов. Более того, написать свой собственный драйвер просто, и вы можете расширить Scout собственной реализацией поиска.
+В настоящее время Scout поставляется с драйверами [Algolia](https://www.algolia.com/), [MeiliSearch](https://www.meilisearch.com) и MySQL / PostgreSQL (`database`). Кроме того, Scout включает в себя драйвер `collection`, предназначенный для использования при локальной разработке и не требующий каких-либо внешних зависимостей или сторонних сервисов. Более того, написать свой собственный драйвер просто, и вы можете расширить Scout собственной реализацией поиска.
## Установка
Для начала установите Scout с помощью менеджера пакетов Composer в свой проект:
- composer require laravel/scout
+```shell
+composer require laravel/scout
+```
После установки Scout вы должны опубликовать конфигурационный файл Scout с помощью команды `vendor:publish` Artisan. Эта команда опубликует конфигурационный файл `scout.php` в каталоге `config` вашего приложения:
- php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
+```shell
+php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
+```
Наконец, добавьте трейт `Laravel\Scout\Searchable` модели, которую вы хотите сделать доступной для поиска. Этот трейт зарегистрирует наблюдателя модели, который будет автоматически синхронизировать модель с вашим драйвером поиска:
@@ -65,7 +71,9 @@
При использовании драйвера Algolia вы должны указать свои учетные данные Algolia `id` и `secret` в конфигурационном файле `config/scout.php`. После того, как ваши учетные данные будут указаны, вам также необходимо будет установить Algolia PHP SDK с помощью менеджера пакетов Composer:
- composer require algolia/algoliasearch-client-php
+```shell
+composer require algolia/algoliasearch-client-php
+```
#### MeiliSearch
@@ -74,13 +82,17 @@
При использовании драйвера MeiliSearch вам необходимо установить PHP SDK MeiliSearch с помощью менеджера пакетов Composer:
- composer require meilisearch/meilisearch-php http-interop/http-factory-guzzle
+```shell
+composer require meilisearch/meilisearch-php http-interop/http-factory-guzzle
+```
Затем укажите переменную окружения `SCOUT_DRIVER`, а также ваши учетные данные `host` и `key` MeiliSearch в файле `.env` вашего приложения:
- SCOUT_DRIVER=meilisearch
- MEILISEARCH_HOST=http://127.0.0.1:7700
- MEILISEARCH_KEY=masterKey
+```ini
+SCOUT_DRIVER=meilisearch
+MEILISEARCH_HOST=http://127.0.0.1:7700
+MEILISEARCH_KEY=masterKey
+```
Для получения дополнительной информации о MeiliSearch, пожалуйста, обратитесь к [документации MeiliSearch](https://docs.meilisearch.com/learn/getting_started/quick_start.html).
@@ -200,12 +212,62 @@
Scout также позволяет автоматически идентифицировать пользователей при использовании [Algolia](https://algolia.com). Связывание аутентифицированного пользователя с операциями поиска может быть полезно при просмотре аналитики поиска в панели управления Algolia. Вы можете задействовать идентификацию пользователя, определив значение `true` для переменной окружения `SCOUT_IDENTIFY` в файле `.env` вашего приложения:
- SCOUT_IDENTIFY=true
+```ini
+SCOUT_IDENTIFY=true
+```
С помощью данного функционала, дополнительно будет переданы IP-адрес запроса и основной идентификатор вашего аутентифицированного пользователя в Algolia, таким образом, эти данные будут связаны с любым поисковым запросом, сделанным пользователем.
-
-## Локальная разработка
+
+## Поисковые системы `database` / `collection`
+
+
+### Поисковая система `database`
+
+> {note} Поисковая система `database` в настоящее время поддерживает MySQL и PostgreSQL.
+
+Если ваше приложение взаимодействует с базами данных малого и среднего размера или имеет небольшую рабочую нагрузку, то вам может быть удобнее начать работу с поисковой системой `database` Scout. Поисковая система базы данных будет использовать выражения `where like` и полнотекстовые индексы при фильтрации результатов из вашей существующей базы данных, чтобы определить применимые результаты поиска для вашего запроса.
+
+Чтобы использовать поисковую систему базы данных, вы можете просто установить значение переменной окружения `SCOUT_DRIVER` в значение `database` или указать драйвер `database` непосредственно в конфигурационном файле `scout` вашего приложения:
+
+```ini
+SCOUT_DRIVER=database
+```
+
+После того как вы указали поисковую систему базы данных в качестве предпочитаемого драйвера, вы должны [настроить доступные для поиска данные](#configuring-searchable-data). Затем вы можете начать [выполнение поисковых запросов](#searching) по вашим моделям. Индексация поисковой системы, которая необходима для заполнения индексов Algolia или MeiliSearch, не требуется при использовании поисковой системы базы данных.
+
+#### Изменение техники поиска с использованием драйвера `database`
+
+По умолчанию поисковая система базы данных будет выполнять запрос `where like` для каждого атрибута модели, который вы [настроили как доступный для поиска](#configuring-searchable-data). Однако в некоторых ситуациях это может привести к снижению производительности. Таким образом, стратегия поиска поисковой системы базы данных может быть настроена таким образом, чтобы некоторые указанные столбцы использовали запросы полнотекстового поиска или использовали только ограничения `where like` для поиска префиксов строк (`example%`) вместо поиска по всей строке (`%example%`).
+
+Чтобы определить это поведение, вы можете назначить атрибуты PHP методу `toSearchableArray` вашей модели. Любые столбцы, которым не назначено дополнительное поведение стратегии поиска, будут по-прежнему использовать стратегию `where like` по умолчанию:
+
+```php
+use Laravel\Scout\Attributes\SearchUsingFullText;
+use Laravel\Scout\Attributes\SearchUsingPrefix;
+
+/**
+ * Получить индексируемый массив данных модели.
+ *
+ * @return array
+ */
+#[SearchUsingPrefix(['id', 'email'])]
+#[SearchUsingFullText(['bio'])]
+public function toSearchableArray()
+{
+ return [
+ 'id' => $this->id,
+ 'name' => $this->name,
+ 'email' => $this->email,
+ 'bio' => $this->bio,
+ ];
+}
+```
+
+> {note} Прежде чем указать, что столбец должен использовать ограничения полнотекстового запроса, убедитесь, что столбцу назначен [полнотекстовый индекс](migrations.ms#available-index-types).
+
+
+### Поисковая система `collection`
Хотя вы можете использовать поисковые системы Algolia или MeiliSearch во время локальной разработки, вам может быть удобнее начать работу с поисковой системой `collection`. Поисковая система будет использовать выражения `where` и фильтрацию набора результатов из вашей существующей базы данных, чтобы определить подходящие результаты поиска по вашему запросу. При использовании этого системы нет необходимости «индексировать» ваши доступные для поиска модели, поскольку они будут просто извлечены из вашей локальной базы данных.
@@ -217,6 +279,12 @@ SCOUT_DRIVER=collection
После того, как вы указали драйвер `collection` в качестве предпочтительного драйвера, вы можете начать [выполнение поисковых запросов](#searching) по вашим моделям. Индексирование поисковой системы, которое необходимо для заполнения Algolia или MeiliSearch, не требуется при использовании поисковой системы `collection`.
+#### Различия поисковых систем `database` и `collection`
+
+На первый взгляд, поисковые системы `database` и `collection` очень похожи. Оба они взаимодействуют непосредственно с вашей базой данных для получения результатов поиска. Однако механизм `collection` не использует полнотекстовые индексы или выражения `LIKE` для поиска записей. Вместо этого он извлекает все возможные записи и использует помощник `Str::is` Laravel, чтобы определить, существует ли строка поиска в значениях атрибута модели.
+
+Поисковая система `collection` является наиболее портативной поисковой системой, поскольку она работает со всеми реляционными базами данных, поддерживаемыми Laravel (включая SQLite и SQL Server); однако она менее эффективна, чем поисковая система `database` Scout.
+
## Индексирование
@@ -225,11 +293,15 @@ SCOUT_DRIVER=collection
Если вы устанавливаете Scout в существующий проект, то возможно, у вас уже есть записи базы данных, которые необходимо импортировать в соответствующие индексы. Scout содержит команду `scout:import` Artisan, которую вы можете использовать для импорта всех ваших существующих записей в соответствующие поисковые индексы:
- php artisan scout:import "App\Models\Post"
+```shell
+php artisan scout:import "App\Models\Post"
+```
Команду `flush` можно использовать для удаления всех записей модели из поисковых индексов:
- php artisan scout:flush "App\Models\Post"
+```shell
+php artisan scout:flush "App\Models\Post"
+```
#### Изменение запроса при импорте записей
@@ -355,6 +427,8 @@ SCOUT_DRIVER=collection
Метод `shouldBeSearchable` учитывается при манипулировании моделями через запросы, отношения или методы `save` и `create`. Непосредственное указание доступности моделей или коллекций для поиска с помощью метода `searchable` переопределит результат метода `shouldBeSearchable`.
+> {note} Метод `shouldBeSearchable` неприменим при использовании поисковой системы `database` Scout, поскольку все доступные для поиска данные всегда хранятся в базе данных. Чтобы добиться аналогичного поведения при использовании поисковой системы `database`, вместо этого следует использовать [выражения `where`](#where-clauses).
+
## Поиск
diff --git a/docs/seeding.md b/docs/seeding.md
index 64fc455..37723ca 100644
--- a/docs/seeding.md
+++ b/docs/seeding.md
@@ -4,6 +4,7 @@
- [Написание наполнителей](#writing-seeders)
- [Использование фабрик моделей](#using-model-factories)
- [Вызов дополнительных наполнителей](#calling-additional-seeders)
+ - [Подавление событий моделей](#muting-model-events)
- [Запуск наполнителей](#running-seeders)
@@ -18,7 +19,9 @@ Laravel предлагает возможность наполнения баз
Чтобы сгенерировать новый наполнитель, используйте команду `make:seeder` [Artisan](artisan.md). Эта команда поместит новый класс наполнителя в каталог `database/seeders` вашего приложения:
- php artisan make:seeder UserSeeder
+```shell
+php artisan make:seeder UserSeeder
+```
Класс наполнителя по умолчанию содержит только один метод: `run`. Этот метод вызывается при выполнении команды `db:seed` Artisan. В методе `run` вы можете вставлять данные в свою базу данных, как хотите. Вы можете использовать [построитель запросов](queries.md) для самостоятельной вставки данных или использовать [фабрики моделей Eloquent](database-testing.md#defining-model-factories).
@@ -93,22 +96,57 @@ Laravel предлагает возможность наполнения баз
]);
}
+
+### Подавление событий моделей
+
+Во время наполнения вы можете запретить моделям отправлять события. Вы можете добиться этого, используя трейт `WithoutModelEvents`. При использовании трейта `WithoutModelEvents` гарантирует, что события модели не инициируются, даже если дополнительные классы наполнителей выполняются с помощью метода `call`:
+
+ call([
+ UserSeeder::class,
+ ]);
+ }
+ }
+
## Запуск наполнителей
Вы можете выполнить команду `db:seed` Artisan для наполнения вашей базы данных. По умолчанию команда `db:seed` запускает класс `Database\Seeders\DatabaseSeeder`, который, в свою очередь, может вызывать другие классы. Однако вы можете использовать параметр `--class`, чтобы указать конкретный класс наполнителя для его индивидуального запуска:
- php artisan db:seed
+```shell
+php artisan db:seed
- php artisan db:seed --class=UserSeeder
+php artisan db:seed --class=UserSeeder
+```
Вы также можете заполнить свою базу данных с помощью команды `migrate:fresh` в сочетании с параметром `--seed`, которая удалит все таблицы и повторно запустит все ваши миграции. Эта команда полезна для полного перестроения вашей базы данных:
- php artisan migrate:fresh --seed
+```shell
+php artisan migrate:fresh --seed
+```
#### Принудительное наполнение при эксплуатации приложения
Некоторые операции наполнения могут привести к изменению или потере данных. В окружении `production`, чтобы защитить вас от запуска команд наполнения эксплуатируемой базы данных, вам будет предложено подтвердить их запуск. Чтобы заставить наполнители запускаться без подтверждений, используйте флаг `--force`:
- php artisan db:seed --force
+```shell
+php artisan db:seed --force
+```
diff --git a/docs/session.md b/docs/session.md
index e6afbf4..6e87620 100644
--- a/docs/session.md
+++ b/docs/session.md
@@ -60,9 +60,11 @@ Laravel предлагает множество различных типов х
Вы можете использовать команду `session:table` Artisan для генерации этой миграции. Чтобы узнать больше о миграции баз данных, вы можете ознакомиться с полной [документацией по миграции](migrations.md):
- php artisan session:table
+```shell
+php artisan session:table
- php artisan migrate
+php artisan migrate
+```
#### Redis
diff --git a/docs/socialite.md b/docs/socialite.md
index 9973262..136771e 100644
--- a/docs/socialite.md
+++ b/docs/socialite.md
@@ -23,7 +23,9 @@
Для начала установите Socialite с помощью менеджера пакетов Composer в свой проект:
- composer require laravel/socialite
+```shell
+composer require laravel/socialite
+```
## Обновление пакета Socialite
diff --git a/docs/starter-kits.md b/docs/starter-kits.md
index 2922367..7c9c9d9 100644
--- a/docs/starter-kits.md
+++ b/docs/starter-kits.md
@@ -26,7 +26,7 @@ Breeze является прекрасной отправной точкой д
Сначала вы должны [создать новое приложение Laravel](installation.md), настроить свою базу данных и запустить [миграции базы данных](migrations.md):
-```bash
+```shell
curl -s https://laravel.build/example-app | bash
cd example-app
@@ -36,13 +36,13 @@ php artisan migrate
Создав новое приложение Laravel, вы можете установить Laravel Breeze с помощью Composer:
-```bash
+```shell
composer require laravel/breeze --dev
```
После того, как Composer установит пакет Laravel Breeze, вы можете запустить команду `breeze:install` Artisan. Эта команда опубликует для вашего приложения шаблоны, маршруты, контроллеры и другие ресурсы аутентификации. Laravel Breeze опубликует весь свой код в вашем приложении, чтобы у вас был полный контроль, а также обзор всего функционала и его реализации. После установки Breeze вы также должны скомпилировать свои исходники, чтобы был доступен файл стилей вашего приложения:
-```nothing
+```shell
php artisan breeze:install
npm install
@@ -59,7 +59,7 @@ php artisan migrate
Laravel Breeze также предлагает реализацию внешнего интерфейса [Inertia.js](https://inertiajs.com) на базе Vue или React. Чтобы использовать стек Inertia, укажите `vue` или `react` в качестве желаемого стека при выполнении команды `breeze:install` Artisan:
-```nothing
+```shell
php artisan breeze:install vue
// Или ...
@@ -76,7 +76,7 @@ php artisan migrate
Laravel Breeze также может создать API-интерфейс аутентификации, готовый для аутентификации современных приложений JavaScript, например, на базе [Next](https://nextjs.org), [Nuxt](https://nuxtjs.org) и других. Для начала укажите стек `api` в качестве желаемого при выполнении команды `breeze:install` Artisan:
-```nothing
+```shell
php artisan breeze:install api
php artisan migrate
```
diff --git a/docs/telescope.md b/docs/telescope.md
index 033beb2..3b0b8ef 100644
--- a/docs/telescope.md
+++ b/docs/telescope.md
@@ -44,13 +44,17 @@
Для начала установите Telescope с помощью менеджера пакетов Composer в свой проект:
- composer require laravel/telescope
+```shell
+composer require laravel/telescope
+```
После установки Telescope опубликуйте его ресурсы с помощью команды `telescope:install` Artisan. После установки Telescope вы также должны запустить команду `migrate`, чтобы создать таблицы, необходимые для хранения данных Telescope:
- php artisan telescope:install
+```shell
+php artisan telescope:install
- php artisan migrate
+php artisan migrate
+```
#### Настройка миграции
@@ -62,11 +66,13 @@
Если вы планируете использовать Telescope только для локальной разработки, то вы можете установить Telescope с параметром `--dev`:
- composer require laravel/telescope --dev
+```shell
+composer require laravel/telescope --dev
- php artisan telescope:install
+php artisan telescope:install
- php artisan migrate
+php artisan migrate
+```
После запуска `telescope:install` вы должны удалить регистрацию поставщика `TelescopeServiceProvider` из конфигурационного файла `config/app.php` вашего приложения. Вместо этого самостоятельно зарегистрируйте поставщика службы Telescope в методе `register` поставщика `App\Providers\AppServiceProvider`. Прежде чем зарегистрировать поставщика, убедитесь, что текущее окружение является локальным:
@@ -85,13 +91,15 @@
Наконец, вы также должны предотвратить [авто-обнаружение](packages.md#package-discovery) пакета Telescope, добавив в файл `composer.json` следующее:
- "extra": {
- "laravel": {
- "dont-discover": [
- "laravel/telescope"
- ]
- }
- },
+```json
+"extra": {
+ "laravel": {
+ "dont-discover": [
+ "laravel/telescope"
+ ]
+ }
+},
+```
### Конфигурирование
@@ -143,17 +151,21 @@
Кроме того, при обновлении до любой новой версии Telescope вы должны повторно опубликовать ресурсы Telescope:
- php artisan telescope:publish
+```shell
+php artisan telescope:publish
+```
Чтобы поддерживать актуальность ресурсов и избежать проблем в будущих обновлениях, вы можете добавить команду `telescope:publish` в сценарий `post-update-cmd` файла `composer.json` вашего приложения:
- {
- "scripts": {
- "post-update-cmd": [
- "@php artisan telescope:publish --ansi"
- ]
- }
+```json
+{
+ "scripts": {
+ "post-update-cmd": [
+ "@php artisan telescope:publish --ansi"
+ ]
}
+}
+```
## Фильтрация
diff --git a/docs/testing.md b/docs/testing.md
index 792a7bc..6b3a81d 100644
--- a/docs/testing.md
+++ b/docs/testing.md
@@ -5,6 +5,7 @@
- [Создание тестов](#creating-tests)
- [Запуск тестов](#running-tests)
- [Параллельное выполнение тестов](#running-tests-in-parallel)
+ - [Отчет о покрытии тестами](#reporting-test-coverage)
## Введение
@@ -39,16 +40,22 @@ Laravel содержит трейт `CreatesApplication`, который при
Чтобы сгенерировать новый тест, используйте команду `make:test` [Artisan](artisan.md). Эта команда поместит новый класс теста в каталог `tests/Feature` вашего приложения:
- php artisan make:test UserTest
+```shell
+php artisan make:test UserTest
+```
Если вы хотите создать тест в каталоге `tests/Unit`, то используйте параметр `--unit` при выполнении команды `make:test`:
- php artisan make:test UserTest --unit
+```shell
+php artisan make:test UserTest --unit
+```
Если вы хотите создать тест [Pest PHP](https://pestphp.com), то вы можете указать флаг `--pest` для команды `make:test`:
- php artisan make:test UserTest --pest
- php artisan make:test UserTest --unit --pest
+```shell
+php artisan make:test UserTest --pest
+php artisan make:test UserTest --unit --pest
+```
> {tip} Заготовки тестов можно настроить с помощью [публикации заготовок](artisan.md#stub-customization).
@@ -80,27 +87,36 @@ Laravel содержит трейт `CreatesApplication`, который при
Как упоминалось ранее, после того, как вы написали тесты, вы можете запускать их с помощью `phpunit`:
- ./vendor/bin/phpunit
+```shell
+./vendor/bin/phpunit
+```
В дополнение к команде `phpunit`, вы можете использовать команду `test` Artisan для запуска ваших тестов. Тестер Artisan отображает подробные отчеты о тестах для упрощения разработки и отладки:
- php artisan test
+```shell
+php artisan test
+```
Любые аргументы, которые могут быть переданы команде `phpunit`, также могут быть переданы команде Artisan `test`:
- php artisan test --testsuite=Feature --stop-on-failure
+```shell
+php artisan test --testsuite=Feature --stop-on-failure
+```
-
### Параллельное выполнение тестов
По умолчанию Laravel и PHPUnit выполняют ваши тесты последовательно в рамках одного процесса. Однако вы можете значительно сократить время, необходимое для запуска тестов, за счет одновременного выполнения тестов в нескольких процессах. Для начала убедитесь, что в зависимостях вашего приложения имеется пакет `nunomaduro/collision` версии `^5.3` или выше. При выполнении команды `test` Artisan используйте параметр `--parallel`:
- php artisan test --parallel
+```shell
+php artisan test --parallel
+```
По умолчанию Laravel создает столько процессов, сколько ядер ЦП доступно на вашем компьютере. Однако вы можете настроить количество процессов, используя параметр `--processes`:
- php artisan test --parallel --processes=4
+```shell
+php artisan test --parallel --processes=4
+```
> {note} При параллельном запуске тестов некоторые параметры PHPUnit (такие как `--do-not-cache-result`) могут быть недоступны.
@@ -111,7 +127,9 @@ Laravel автоматически обрабатывает создание и
По умолчанию тестовые базы данных сохраняются между вызовами команды `test` Artisan, чтобы их можно было использовать снова при последующих вызовах `test`. Однако вы можете пересоздать их, используя параметр `--recreate-databases`:
- php artisan test --parallel --recreate-databases
+```shell
+php artisan test --parallel --recreate-databases
+```
#### Хуки параллельного тестирования
@@ -166,3 +184,23 @@ Laravel автоматически обрабатывает создание и
Если вы хотите получить доступ к «токену» текущего процесса из любого другого места в коде теста вашего приложения, то вы можете использовать метод `token`. Этот токен представляет собой уникальный строковый идентификатор для каждого из процессов тестирования и может использоваться для разделения [подготавливаемых ресурсов](#parallel-testing-hooks) процессов параллельного тестирования. Например, Laravel автоматически добавляет этот токен в конец тестовых баз данных, создаваемых каждым процессом параллельного тестирования:
$token = ParallelTesting::token();
+
+
+### Отчет о покрытии тестами
+
+> {note} Данный функционал требует [Xdebug](https://xdebug.org) или [PCOV](https://pecl.php.net/package/pcov).
+
+При выполнении тестов приложения вы можете определить, действительно ли ваши тесты охватывают код приложения и сколько кода приложения используется при выполнении ваших тестов. Для этого вы можете указать флаг `--coverage` при вызове команды `test`:
+
+```shell
+php artisan test --coverage
+```
+
+
+#### Обеспечение минимального порога покрытия
+
+Вы можете использовать параметр `--min`, чтобы определить минимальный порог покрытия тестами вашего приложения. Набор тестов завершится ошибкой, если этот порог не будет достигнут:
+
+```shell
+php artisan test --coverage --min=80.3
+```
diff --git a/docs/upgrade.md b/docs/upgrade.md
index 97e7a98..0e3b07c 100644
--- a/docs/upgrade.md
+++ b/docs/upgrade.md
@@ -1,18 +1,15 @@
# Laravel 9 · Руководство по обновлению
-- [Обновление с 7.x версии до 8.0](#upgrade-8.0)
+- [Обновление с 8.x версии до 9.0](#upgrade-9.0)
## Изменения, оказывающие большое влияние
-- [Фабрики модели](#model-factories)
-- [Метод очереди `retryAfter`](#queue-retry-after-method)
-- [Свойство очереди `timeoutAt`](#queue-timeout-at-property)
-- [Методы очереди `allOnQueue` и `allOnConnection`](#queue-allOnQueue-allOnConnection)
-- [Пагинация по умолчанию](#pagination-defaults)
-- [Пространства имен наполнителей и фабрик](#seeder-factory-namespaces)
+- [Обновление зависимостей](#updating-dependencies)
+- [Flysystem 3.x](#flysystem-3)
+- [Symfony Mailer](#symfony-mailer)
@@ -21,425 +18,669 @@
-- [Требование PHP 7.3.0](#php-7.3.0-required)
-- [Поддержка пакетной обработки и таблица невыполненных заданий](#failed-jobs-table-batch-support)
-- [Обновления режима обслуживания](#maintenance-mode-updates)
-- [Параметр `php artisan down --message`](#artisan-down-message)
-- [Метод `assertExactJson`](#assert-exact-json-method)
+- [Методы `firstOrNew`, `firstOrCreate` и `updateOrCreate` отношений «Belongs To Many»](#belongs-to-many-first-or-new)
+- [Пользовательская типизация и `null`](#custom-casts-and-null)
+- [Время ожидания HTTP-клиента по умолчанию](#http-client-default-timeout)
+- [Возвращаемые типы PHP](#php-return-types)
+- [Изменение параметра `schema` для Postgres](#postgres-schema-configuration)
+- [Метод `assertDeleted`](#the-assert-deleted-method)
+- [Каталог `lang`](#the-lang-directory)
+- [Правило `password`](#the-password-rule)
+- [Методы `when` / `unless`](#when-and-unless-methods)
+- [Непровалидированные ключи массива](#unvalidated-array-keys)
-
-## Обновление с 7.x версии до 8.0
+
+## Обновление с 8.x версии до 9.0
-
-#### Приблизительное время обновления: 15 минут
+
+#### Приблизительное время обновления: 30 минут
-> {note} Мы стараемся задокументировать все возможные критические изменения. Поскольку некоторые из этих критических изменений находятся в малоизвестных частях фреймворка, только часть этих изменений может повлиять на ваше приложение.
+> {tip} Мы стараемся задокументировать все возможные критические изменения. Поскольку некоторые из этих критических изменений находятся в малоизвестных частях фреймворка, только часть этих изменений может повлиять на ваше приложение. Хотите сэкономить время? Вы можете использовать [Laravel Shift](https://laravelshift.com/), чтобы автоматизировать обновления приложений.
-
-### Требование PHP 7.3.0
+
+### Обновление зависимостей
-**Вероятность воздействия: средняя**
+**Вероятность воздействия: высокая**
-Новая минимальная версия PHP теперь 7.3.0.
+#### Требование PHP 8.0.2
-
-### Обновление зависимостей
+Laravel теперь требует PHP 8.0.2 или выше.
+
+#### Зависимости Composer
+
+Вы должны обновить следующие зависимости в файле `composer.json` вашего приложения:
+
+
-Обновите следующие зависимости в вашем файле `composer.json`:
+- `laravel/framework` до `^9.0`
+- `nunomaduro/collision` до `^6.0`
+
+
+
+Кроме того, замените `facade/ignition` на `"spatie/laravel-ignition": "^1.0"` в файле `composer.json` вашего приложения.
+
+Кроме того, следующие пакеты получили новые релизы для поддержки Laravel 9.x. Если применимо, то вы должны прочитать их отдельные руководства перед обновлением:
-- `guzzlehttp/guzzle` до `^7.0.1`
-- `facade/ignition` до `^2.3.6`
-- `laravel/framework` до `^8.0`
-- `laravel/ui` до `^3.0`
-- `nunomaduro/collision` до `^5.0`
-- `phpunit/phpunit` до `^9.0`
+- [Vonage Notification Channel (v3.0)](https://github.com/laravel/vonage-notification-channel/blob/3.x/UPGRADE.md) (заменяет Nexmo)
-Следующие сторонние пакеты имеют новые основные выпуски для поддержки Laravel 8. Если возможно, вы должны прочитать соответствующие руководства перед обновлением:
+Наконец, проверьте любые другие сторонние пакеты, используемые вашим приложением, и убедитесь, что вы используете корректную версию для поддержки Laravel 9.
+
+
+#### Возвращаемые типы PHP
+
+PHP начинает переходить к требованию определения типа возвращаемого значения в методах PHP, таких как `offsetGet`, `offsetSet` и т. д. В свете этого Laravel 9 реализовал эти возвращаемые типы в своей кодовой базе. Как правило, это не должно влиять на написанный пользователем код; однако, если вы переопределяете один из этих методов, расширяя базовые классы Laravel, то вам нужно будет добавить эти возвращаемые типы в код вашего собственного приложения или пакета:
-- [Horizon v5.0](https://github.com/laravel/horizon/blob/master/UPGRADE.md)
-- [Passport v10.0](https://github.com/laravel/passport/blob/master/UPGRADE.md)
-- [Socialite v5.0](https://github.com/laravel/socialite/blob/master/UPGRADE.md)
-- [Telescope v4.0](https://github.com/laravel/telescope/blob/master/UPGRADE.md)
+- `count(): int`
+- `getIterator(): Traversable`
+- `getSize(): int`
+- `jsonSerialize(): array`
+- `offsetExists($key): bool`
+- `offsetGet($key): mixed`
+- `offsetSet($key, $value): void`
+- `offsetUnset($key): void`
-Кроме того, установщик Laravel был обновлен для поддержки `composer create-project` и Laravel Jetstream. Любой установщик старше 4.0 перестанет работать после октября 2020 года. Вам следует как можно скорее обновить глобальный установщик до `^4.0`.
+Кроме того, в методы, реализующие `SessionHandlerInterface` PHP, были добавлены возвращаемые типы. Опять же, маловероятно, что это изменение повлияет на ваше собственное приложение или код пакета:
+
+
-Наконец, изучите любые другие сторонние пакеты, используемые вашим приложением, и убедитесь, что вы используете корректную версию с поддержкой Laravel 8.
+- `open($savePath, $sessionName): bool`
+- `close(): bool`
+- `read($sessionId): string|false`
+- `write($sessionId, $data): bool`
+- `destroy($sessionId): bool`
+- `gc($lifetime): int`
+
+
+
+
+### Приложение
+
+
+#### Контракт `Application`
+
+**Вероятность воздействия: низкая**
+
+Метод `storagePath` интерфейса `Illuminate\Contracts\Foundation\Application` был обновлен, чтобы принимать аргумент `$path`. Если вы реализуете этот интерфейс, то вы должны соответствующим образом обновить свою реализацию:
+
+ public function storagePath($path = '');
+
+#### Метод `ignore` обработчика исключений
+
+**Вероятность воздействия: низкая**
+
+Метод `ignore` обработчика исключений теперь является `public`, а не `protected`. Этот метод не включен в приложение по умолчанию; однако, если вы определили этот метод самостоятельно, то вы должны обновить его до `public`:
+
+```php
+public function ignore(string $class);
+```
+
+### Шаблонизатор Blade
+
+#### Отложенные коллекции и переменная `$loop`
+
+**Вероятность воздействия: низкая**
+
+При итерации экземпляра `LazyCollection` в шаблоне Blade переменная `$loop` больше недоступна, так как доступ к этой переменной приводит к загрузке всего `LazyCollection` в память, что делает использование отложенных коллекций бессмысленным в этом сценарий.
-
### Коллекции
-
-#### Метод `isset`
+#### Контракт `Enumerable`
**Вероятность воздействия: низкая**
-Чтобы соответствовать типичному поведению PHP, метод `offsetExists` в `Illuminate\Support\Collection` был обновлен и теперь использует `isset` вместо `array_key_exists`. Это может привести к изменению поведения при работе с элементами коллекции, имеющими значение `null`:
+Контракт `Illuminate\Support\Enumerable` теперь определяет метод `sole`. Если вы реализуете этот контракт самостоятельно, то вам следует обновить свою реализацию, чтобы отразить этот новый метод:
+
+```php
+public function sole($key = null, $operator = null, $value = null);
+```
+
+#### Метод `reduceWithKeys`
+
+Метод `reduceWithKeys` был удален, так как метод `reduce` обеспечивает ту же функциональность. Вы можете просто обновить свой код, чтобы он вызывал `reduce` вместо `reduceWithKeys`.
- $collection = collect([null]);
+#### Метод `reduceMany`
- // Laravel 7.x - true
- isset($collection[0]);
+Метод `reduceMany` был переименован в `reduceSpread` для согласованности именования с другими подобными методами.
- // Laravel 8.x - false
- isset($collection[0]);
+### Контейнер служб
+
+#### Контракт `Container`
+
+**Вероятность воздействия: очень низкая**
+
+Контракт `Illuminate\Contracts\Container\Container` теперь определяет два метода: `scoped` и `scopedIf`. Если вы реализуете этот контракт самостоятельно, то вам следует обновить свою реализацию, чтобы отразить эти новые методы.
+
+#### Контракт `ContextualBindingBuilder`
+
+**Вероятность воздействия: очень низкая**
+
+Контракт `Illuminate\Contracts\Container\ContextualBindingBuilder` теперь определяет метод `giveConfig`. Если вы реализуете этот контракт самостоятельно, то вам следует обновить свою реализацию, чтобы отразить этот новый метод:
+
+```php
+public function giveConfig($key, $default = null);
+```
-
### База данных
-
-#### Пространства имен наполнителей и фабрик
+
+#### Изменение параметра `schema` для Postgres
-**Вероятность воздействия: высокая**
+**Вероятность воздействия: средняя**
-Наполнители и фабрики теперь имеют пространство имен. Чтобы учесть эти изменения, добавьте пространство имен `Database\Seeders` в ваши классы наполнителей. Кроме того, имеющийся каталог `database/seeds` должен быть переименован в `database/seeders`:
+Параметр конфигурации `schema`, используемый для настройки путей поиска соединений Postgres в конфигурационном файле `config/database.php` вашего приложения, должен быть переименован в `search_path`.
-
+#### Метод `registerCustomDoctrineType` построителя схемы
- namespace Database\Seeders;
+**Вероятность воздействия: низкая**
- use App\Models\User;
- use Illuminate\Database\Seeder;
+Метод `registerCustomDoctrineType` был удален из класса `Illuminate\Database\Schema\Builder`. Вместо этого вы можете использовать метод `registerDoctrineType` фасада `DB` или зарегистрировать пользовательские типы Doctrine в конфигурационном файле `config/database.php`.
- class DatabaseSeeder extends Seeder
- {
- /**
- * Заполнить базу данных приложения.
- *
- * @return void
- */
- public function run()
- {
- ...
- }
+### Модели Eloquent
+
+
+#### Пользовательская типизация и `null`
+
+**Вероятность воздействия: средняя**
+
+В предыдущих релизах Laravel метод `set` классов пользовательской типизации не вызывался, если для типизируемого атрибута было установлено значение `null`. Однако такое поведение не соответствовало документации Laravel. В Laravel 9.x метод `set` класса типизации будет вызываться с `null` в качестве предоставленного аргумента `$value`. Поэтому вы должны убедиться, что ваши пользовательские типизации способны в достаточной степени справиться с этим сценарием:
+
+```php
+/**
+ * Подготовить переданное значение к сохранению.
+ *
+ * @param \Illuminate\Database\Eloquent\Model $model
+ * @param string $key
+ * @param AddressModel $value
+ * @param array $attributes
+ * @return array
+ */
+public function set($model, $key, $value, $attributes)
+{
+ if (! $value instanceof AddressModel) {
+ throw new InvalidArgumentException('The given value is not an Address instance.');
}
-Если вы решите использовать пакет `laravel/legacy-factories`, то никаких изменений в классах ваших фабрик не требуется. Однако, если вы обновляете свои фабрики, вы должны добавить к этим классам пространство имен `Database\Factories`.
+ return [
+ 'address_line_one' => $value->lineOne,
+ 'address_line_two' => $value->lineTwo,
+ ];
+}
+```
-Затем в вашем файле `composer.json` удалите блок `classmap` из раздела `autoload` и добавьте новые сопоставления каталогов классов с пространством имен:
+
+#### Методы `firstOrNew`, `firstOrCreate` и `updateOrCreate` отношений «Belongs To Many»
- "autoload": {
- "psr-4": {
- "App\\": "app/",
- "Database\\Factories\\": "database/factories/",
- "Database\\Seeders\\": "database/seeders/"
- }
- },
+**Вероятность воздействия: средняя**
-
-### Eloquent
+Методы `firstOrNew`, `firstOrCreate` и `updateOrCreate` отношений «Belongs To Many» принимают массив атрибутов в качестве первого аргумента. В предыдущих релизах Laravel этот массив атрибутов сравнивался со «сводной» / промежуточной таблицей для существующих записей.
-
-#### Фабрики модели
+Однако такое поведение было неожиданным и, как правило, нежелательным. Вместо этого эти методы теперь сравнивают массив атрибутов с таблицей связанной модели:
-**Вероятность воздействия: высокая**
+```php
+$user->roles()->updateOrCreate([
+ 'name' => 'Administrator',
+]);
+```
+
+Кроме того, метод `firstOrCreate` теперь принимает массив `$values` в качестве второго аргумента. Этот массив будет объединен с первым аргументом метода (`$attributes`) при создании связанной модели, если он еще не существует. Эти изменения делают этот метод совместимым с методами `firstOrCreate`, предлагаемыми другими типами отношений:
+
+```php
+$user->roles()->firstOrCreate([
+ 'name' => 'Administrator',
+], [
+ 'created_by' => $user->id,
+]);
+```
+
+#### Метод `touch`
-Функция Laravel [фабрики модели](/docs/database-testing.md#defining-model-factories) была полностью переписана для поддержки классов и несовместима с фабриками стиля Laravel 7.x. Однако, чтобы упростить процесс обновления, был создан новый пакет `laravel/legacy-factories`, чтобы продолжать использовать ваши существующие фабрики с Laravel 8.x. Вы можете установить этот пакет через Composer:
+**Вероятность воздействия: низкая**
+
+Метод `touch` теперь принимает затрагиваемый атрибут. Если вы ранее перезаписывали этот метод, то вам следует обновить сигнатуру метода, чтобы отразить этот новый аргумент:
+
+```php
+public function touch($attribute = null);
+```
- composer require laravel/legacy-factories
+### Шифрование
-
-#### Интерфейс `Castable`
+#### Контракт `Encrypter`
**Вероятность воздействия: низкая**
-Метод `castUsing` интерфейса `Castable` обновлен и теперь принимает массив аргументов. Если вы реализуете этот интерфейс, вам, соответственно, следует обновить реализацию:
+Контракт `Illuminate\Contracts\Encryption\Encrypter` теперь определяет метод `getKey`. Если вы реализуете этот интерфейс самостоятельно, то вам следует соответствующим образом обновить свою реализацию:
- public static function castUsing(array $arguments);
+```php
+public function getKey();
+```
-
-#### События Increment / Decrement
+### Фасады
+
+#### Метод `getFacadeAccessor`
**Вероятность воздействия: низкая**
-События модели, связанные с «обновлением» и «сохранением», теперь будут вызываться при выполнении методов `increment` или `decrement` экземпляров модели Eloquent.
+Метод `getFacadeAccessor` всегда должен возвращать ключ привязки контейнера. В предыдущих релизах Laravel этот метод мог возвращать экземпляр объекта; однако это поведение больше не поддерживается. Если вы написали свои собственные фасады, то вы должны убедиться, что этот метод возвращает строку привязки контейнера:
+
+```php
+/**
+ * Получить зарегистрированное имя компонента.
+ *
+ * @return string
+ */
+protected static function getFacadeAccessor()
+{
+ return Example::class;
+}
+```
-
-### События
+### Файловое хранилище
-
-#### Класс `EventServiceProvider`
+#### Переменная окружения `FILESYSTEM_DRIVER`
**Вероятность воздействия: низкая**
-Если ваш класс `App\Providers\EventServiceProvider` содержит метод `register`, то вы должны убедиться, что вы вызываете `parent::register` в начале этого метода. В противном случае события вашего приложения не будут зарегистрированы.
+Переменная окружения `FILESYSTEM_DRIVER` была переименована в `FILESYSTEM_DISK` для более точного отражения ее использования. Это изменение затрагивает только скелет приложения; однако вы можете обновить переменные окружения своего собственного приложения, чтобы отразить это изменение, если хотите.
-
-#### Контракт `Dispatcher`
+#### Диск `cloud`
**Вероятность воздействия: низкая**
-Метод `listen` контракта `Illuminate\Contracts\Events\Dispatcher` был обновлен, чтобы сделать свойство `$listener` необязательным. Это изменение было внесено для поддержки автоматического определения обрабатываемых типов событий через рефлексию. Если вы реализуете этот интерфейс, вам, соответственно, следует обновить реализацию:
+Параметр конфигурации `cloud` диска был удален из скелета приложения по умолчанию в ноябре 2020 года. Это изменение влияет только на скелет приложения. Если вы используете диск `cloud` в своем приложении, то вы должны оставить это значение конфигурации в скелете вашего собственного приложения.
- public function listen($events, $listener = null);
+
+### Flysystem 3.x
-
-### Фреймворк
+**Вероятность воздействия: высокая**
-
-#### Обновления режима обслуживания
+Laravel 9.x мигрировал с [Flysystem](https://flysystem.thephpleague.com/v2/docs/) версии 1.x на версию 3.x. Под капотом Flysystem используются все методы манипулирования файлами, предоставляемые фасадом `Storage`. В связи с этим в вашем приложении могут потребоваться некоторые изменения; однако мы постарались сделать этот переход максимально плавным.
-**Вероятность воздействия: необязательно**
+#### Требования к драйверу
-[Режим обслуживания](/docs/configuration.md#maintenance-mode) был улучшен в Laravel 8.x. Теперь поддерживается предварительный рендеринг шаблона режима обслуживания, что исключает вероятность того, что конечные пользователи столкнутся с ошибками в режиме обслуживания. Однако для поддержки этого в ваш файл `public/index.php` необходимо добавить следующие строки. Эти строки следует разместить непосредственно под существующим определением константы `LARAVEL_START`:
+Перед использованием драйверов S3 или SFTP вам необходимо установить соответствующий пакет с помощью менеджера пакетов Composer:
- define('LARAVEL_START', microtime(true));
+- Amazon S3: `composer require --with-all-dependencies league/flysystem-aws-s3-v3 "^3.0"`
+- SFTP: `composer require league/flysystem-sftp-v3 "^3.0"`
- if (file_exists(__DIR__.'/../storage/framework/maintenance.php')) {
- require __DIR__.'/../storage/framework/maintenance.php';
- }
+#### Перезапись существующих файлов
+
+Операции записи, такие как `put`, `write`, `writeStream`, теперь по умолчанию перезаписывают существующие файлы. Если вы не хотите перезаписывать существующие файлы, то вам следует предварительно проверить существование файла перед выполнением операции записи.
+
+#### Чтение отсутствующих файлов
+
+Попытка чтения из несуществующего файла теперь возвращает `null`. В предыдущих релизах Laravel возникало исключение `Illuminate\Contracts\Filesystem\FileNotFoundException`.
+
+#### Удаление отсутствующих файлов
+
+Попытка «удалить» несуществующий файл с помощью метода `delete` теперь возвращает `true`.
+
+#### Адаптеры с кешем
+
+Flysystem больше не поддерживает адаптеры с кешем. Таким образом, они были удалены из Laravel, и любая соответствующая конфигурация (например, ключ `cache` в конфигурациях диска) может быть удалена.
+
+#### Пользовательские файловые системы
+
+Небольшие изменения были внесены в шаги, необходимые для регистрации пользовательских драйверов файловой системы. Поэтому, если вы определяли свои собственные пользовательские драйверы файловой системы или использовали пакеты, определяющие пользовательские драйверы, то вам следует обновить свой код и зависимости.
+
+Например, в Laravel 8.x пользовательский драйвер файловой системы может быть зарегистрирован следующим образом:
+
+```php
+use Illuminate\Support\Facades\Storage;
+use League\Flysystem\Filesystem;
+use Spatie\Dropbox\Client as DropboxClient;
+use Spatie\FlysystemDropbox\DropboxAdapter;
+
+Storage::extend('dropbox', function ($app, $config) {
+ $client = new DropboxClient(
+ $config['authorization_token']
+ );
-
-#### Параметр `php artisan down --message`
+ return new Filesystem(new DropboxAdapter($client));
+});
+```
+
+Однако в Laravel 9.x замыкание метода `Storage::extend` должно возвращать экземпляр `Illuminate\Filesystem\FilesystemAdapter` напрямую:
+
+```php
+use Illuminate\Filesystem\FilesystemAdapter;
+use Illuminate\Support\Facades\Storage;
+use League\Flysystem\Filesystem;
+use Spatie\Dropbox\Client as DropboxClient;
+use Spatie\FlysystemDropbox\DropboxAdapter;
+
+Storage::extend('dropbox', function ($app, $config) {
+ $adapter = new DropboxAdapter(new DropboxClient(
+ $config['authorization_token']
+ ););
+
+ return new FilesystemAdapter(
+ new Filesystem($adapter, $config),
+ $adapter,
+ $config
+ );
+});
+```
+
+### Глобальные помощники
+
+
+#### Функция `data_get` и итерируемые объекты
+
+**Вероятность воздействия: очень низкая**
+
+Раньше помощник `data_get` можно было использовать для извлечения вложенных данных в массивах и экземплярах `Collection`; однако теперь этот помощник может извлекать вложенные данные во всех итерируемых объектах.
+
+
+#### Функция `str`
+
+**Вероятность воздействия: очень низкая**
+
+Laravel 9.x теперь включает [глобальный помощник `str`](helpers.md#method-str). Если вы самостоятельно определили глобальный помощник `str` в своем приложении, то вы должны переименовать или удалить его, чтобы он не конфликтовал с помощником `str` Laravel.
+
+
+#### Методы `when` / `unless`
**Вероятность воздействия: средняя**
-Параметр `--message` команды `php artisan down` была удалена. В качестве альтернативы рассмотрите возможность [предварительного рендеринга шаблонов в режиме обслуживания](/docs/configuration.md#maintenance-mode) с желаемым сообщением.
+Как вы, возможно, знаете, методы `when` и `unless` предлагаются различными классами фреймворка. Эти методы можно использовать для условного выполнения действия, если логическое значение первого аргумента метода оценивается как «истина» или «ложь», соответственно:
-
-#### Параметр `php artisan serve --no-reload`
+```php
+$collection->when(true, function ($collection) {
+ $collection->merge([1, 2, 3]);
+});
+```
-**Вероятность воздействия: низкая**
+Поэтому в предыдущих релизах Laravel передача замыкания методам `when` или `unless` означала, что условная операция всегда будет выполняться, поскольку гибкое сравнение с объектом замыкания (или любым другим объектом) всегда оценивается как `true`. Это часто приводило к неожиданным результатам, поскольку разработчики ожидали, что **результат** замыкания будет использоваться как логическое значение, определяющее, выполняется ли условное действие.
-В команде `php artisan serve` добавлен параметр `--no-reload`. Это даст указание встроенному серверу не перезагружаться при обнаружении изменений файла окружения. Эта опция в первую очередь полезна при запуске тестов Laravel Dusk в среде CI (непрерывной интеграции).
+Таким образом, в Laravel 9.x любые замыкания, переданные методам `when` или `unless`, будут выполнены, а значение, возвращаемое замыканием, будет считаться логическим значением, используемым методами `when` и `unless`:
-
-#### Свойство `$app` Менеджера
+```php
+$collection->when(function ($collection) {
+ // Это замыкание будет выполнено ...
+ return false;
+}, function ($collection) {
+ // Не будет выполнено, так как первое замыкание вернуло `false` ...
+ $collection->merge([1, 2, 3]);
+});
+```
-**Вероятность воздействия: низкая**
+### HTTP-клиент
-Ранее устаревшее свойство `$app` класса `Illuminate\Support\Manager` было удалено. Если вы полагались на это свойство, вам следует использовать вместо него свойство `$container`.
+
+#### Время ожидания HTTP-клиента по умолчанию
-
-#### Помощник `elixir`
+**Вероятность воздействия: средняя**
-**Вероятность воздействия: низкая**
+[HTTP-клиент](http-client.md) теперь имеет время ожидания по умолчанию, равное 30 секундам. Другими словами, если сервер не отвечает в течение 30 секунд, то будет выброшено исключение. Раньше для HTTP-клиента не настраивалось время ожидания по умолчанию, из-за чего запросы иногда «зависали» на неопределенный срок.
-Ранее устаревший помощник `elixir` был удален. Приложениям, все еще использующим данный метод сборки, рекомендуется перейти на [Laravel Mix](https://github.com/JeffreyWay/laravel-mix).
+Если вы хотите указать более длительный тайм-аут для конкретного запроса, то вы можете сделать это с помощью метода `timeout`:
-
-### Почта
+ $response = Http::timeout(120)->get(...);
-
-#### Метод `sendNow`
+#### Имитация HTTP и посредник
**Вероятность воздействия: низкая**
-Ранее устаревший метод `sendNow` был удален. Вместо этого используйте метод `send`.
+Ранее Laravel не запускал посредников Guzzle HTTP, если [HTTP-клиент](http-client.md) являлся имитацией. Однако в Laravel 9.x посредник Guzzle HTTP будет выполняться даже при имитации HTTP-клиента.
+
+#### Имитация HTTP Fake и внедрение зависимостей
+
+**Вероятность воздействия: низкая**
-
-### Постраничная навигация
+В предыдущих релизах Laravel вызов метода `Http::fake()` не влиял на экземпляры `Illuminate\Http\Client\Factory`, которые были внедрены в конструкторы классов. Однако в Laravel 9.x `Http::fake()` гарантирует, что фейковые ответы будут возвращены HTTP-клиентами, внедряемыми в другие службы посредством внедрения зависимостей. Такое поведение больше соответствует поведению других фасадов и их имитаций.
-
-#### Пагинация по умолчанию
+
+### Symfony Mailer
**Вероятность воздействия: высокая**
-Пагинатор теперь использует [CSS-фреймворк Tailwind](https://tailwindcss.com) для стилизации по умолчанию. Чтобы продолжить использование Bootstrap, вы должны добавить следующий вызов метода в методе `boot` поставщика `App\Providers\AppServiceProvider`:
+Одним из самых больших изменений в Laravel 9.x является переход от SwiftMailer, который больше не поддерживается с декабря 2021 года, к Symfony Mailer. Однако мы постарались сделать этот переход как можно более плавным для ваших приложений. При этом внимательно ознакомьтесь со списком изменений ниже, чтобы убедиться, что ваше приложение полностью совместимо.
- use Illuminate\Pagination\Paginator;
+#### Предварительная подготовка драйверов
- Paginator::useBootstrap();
+Чтобы продолжить использование драйвера Mailgun, вашему приложению требуется пакет `symfony/mailgun-mailer` Composer:
-
-### Очереди
+```shell
+composer require symfony/mailgun-mailer
+```
-
-#### Метод `retryAfter`
+Пакет `wildbit/swiftmailer-postmark` Composer должен быть удален из вашего приложения. Вместо этого вашему приложению должен потребоваться пакет `symfony/postmark-mailer` Composer:
-**Вероятность воздействия: высокая**
+```shell
+composer require symfony/postmark-mailer
+```
-Для согласованности с другой функциональностью Laravel, метод `retryAfter` и свойство `retryAfter` заданий в очереди, почтовых программ, уведомлений и слушателей были переименованы в `backoff`. Вам следует обновить имя этого метода / свойства в соответствующих классах вашего приложения.
+#### Обновлены возвращаемые типы
-
-#### Свойство `timeoutAt`
+Методы `send`, `html`, `text` и `plain` больше не возвращают количество получателей, получивших сообщение. Вместо этого возвращается экземпляр `Illuminate\Mail\SentMessage`. Этот объект содержит экземпляр `Symfony\Component\Mailer\SentMessage`, доступный через метод `getSymfonySentMessage` или путем динамического вызова методов объекта.
-**Вероятность воздействия: высокая**
+#### Переименованы методы Swift
-Свойство `timeoutAt` заданий в очереди, уведомлений и слушателей переименовано в `retryUntil`. Вам следует обновить имя этого свойства в соответствующих классах вашего приложения.
+Различные методы, связанные со SwiftMailer, некоторые из которых не были задокументированы, были переименованы в их аналоги Symfony Mailer. Например, метод `withSwiftMessage` был переименован в `withSymfonyMessage`:
-
-#### Методы `allOnQueue()` / `allOnConnection()`
+ // Laravel 8.x...
+ $this->withSwiftMessage(function ($message) {
+ $message->getHeaders()->addTextHeader(
+ 'Custom-Header', 'Header Value'
+ );
+ });
-**Вероятность воздействия: высокая**
+ // Laravel 9.x...
+ use Symfony\Component\Mime\Email;
-Для согласованности с другими методами диспетчеризации были удалены методы `allOnQueue()` и `allOnConnection()`, используемые с цепочкой заданий. Вместо этого вы можете использовать методы `onQueue()` и `onConnection()`. Эти методы следует вызывать перед вызовом метода `dispatch`:
+ $this->withSymfonyMessage(function (Email $message) {
+ $message->getHeaders()->addTextHeader(
+ 'Custom-Header', 'Header Value'
+ );
+ });
- ProcessPodcast::withChain([
- new OptimizePodcast,
- new ReleasePodcast
- ])->onConnection('redis')->onQueue('podcasts')->dispatch();
+> {note} Пожалуйста, внимательно изучите [документацию Symfony Mailer](https://symfony.com/doc/6.0/mailer.html#creating-sending-messages) для взаимодействий с объектом `Symfony\Component\Mime\Email`.
-Обратите внимание, что это изменение влияет только на код, использующий метод `withChain`. В то время как методы `allOnQueue()` и `allOnConnection()` по-прежнему доступны при использовании глобального помощника `dispatch()`.
+Список ниже содержит более подробный обзор переименованных методов. Многие из этих методов являются низкоуровневыми методами, используемыми для прямого взаимодействия со SwiftMailer / Symfony Mailer, поэтому могут не использоваться в большинстве приложений Laravel:
-
-#### Поддержка пакетной обработки и таблица невыполненных заданий
+ Message::getSwiftMessage();
+ Message::getSymfonyMessage();
-**Вероятность воздействия: необязательно**
+ Mailable::withSwiftMessage($callback);
+ Mailable::withSymfonyMessage($callback);
-Если вы планируете использовать функционал [пакетной обработки заданий](/docs/queues.md#job-batching) Laravel 8.x, то таблица `failed_jobs` БД должна быть обновлена. Во-первых, в эту таблицу должен быть добавлен новый столбец `uuid`:
+ MailMessage::withSwiftMessage($callback);
+ MailMessage::withSymfonyMessage($callback);
- use Illuminate\Database\Schema\Blueprint;
- use Illuminate\Support\Facades\Schema;
+ Mailer::getSwiftMailer();
+ Mailer::getSymfonyTransport();
- Schema::table('failed_jobs', function (Blueprint $table) {
- $table->string('uuid')->after('id')->nullable()->unique();
- });
+ Mailer::setSwiftMailer($swift);
+ Mailer::setSymfonyTransport(TransportInterface $transport);
-Затем, параметр конфигурации `failed.driver` в конфигурационном файле `config/queue.php` должен быть изменен на `database-uuids`.
+ MailManager::createTransport($config);
+ MailManager::createSymfonyTransport($config);
-Кроме того, вы можете сгенерировать UUID для существующих невыполненных заданий:
+#### Прокси-методы `Illuminate\Mail\Message`
- DB::table('failed_jobs')->whereNull('uuid')->cursor()->each(function ($job) {
- DB::table('failed_jobs')
- ->where('id', $job->id)
- ->update(['uuid' => (string) Illuminate\Support\Str::uuid()]);
- });
+`Illuminate\Mail\Message` обычно проксирует отсутствующие методы базовому экземпляру `Swift_Message`. Однако отсутствующие методы теперь вместо этого проксируются экземпляру `Symfony\Component\Mime\Email`. Таким образом, любой код, который ранее полагался на отсутствующие методы для проксирования SwiftMailer, должен быть обновлен до соответствующих аналогов Symfony Mailer.
-
-### Маршрутизация
-
-
-#### Автоматическое префикс пространства имен контроллера
-
-**Вероятность воздействия: необязательно**
-
-В предыдущих выпусках Laravel класс `RouteServiceProvider` содержал свойство `$namespace` со значением `App\Http\Controllers`. Значение этого свойства использовалось для объявлений автоматического префикса маршрута контроллера и генерации URL маршрута контроллера, например, при вызове помощника `action`.
-
-В Laravel 8 для этого свойства по умолчанию установлено значение `null`. Это позволяет объявлениям маршрута вашего контроллера использовать стандартный вызываемый синтаксис PHP, который обеспечивает лучшую поддержку перехода к классу контроллера во многих IDE:
-
- use App\Http\Controllers\UserController;
-
- // Использование вызываемого синтаксиса PHP ...
- Route::get('/users', [UserController::class, 'index']);
-
- // Использование строкового синтаксиса ...
- Route::get('/users', 'App\Http\Controllers\UserController@index');
-
-В большинстве случаев это не повлияет на обновляемые приложения, потому что ваш `RouteServiceProvider` по-прежнему будет содержать свойство `$namespace` с его предыдущим значением. Однако, если вы обновите свое приложение, создав новый проект Laravel, то это изменение может стать критическим.
-
-Если вы хотите по-прежнему использовать исходную маршрутизацию контроллера с автоматическим префиксом, вы можете просто установить значение свойства `$namespace` в `RouteServiceProvider` и обновить регистрации маршрута в методе `boot`, чтобы использовать свойство `$namespace`:
-
- class RouteServiceProvider extends ServiceProvider
- {
- /**
- * Путь к «домашнему» маршруту вашего приложения.
- *
- * Используется аутентификацией Laravel для перенаправления пользователей после входа в систему.
- *
- * @var string
- */
- public const HOME = '/home';
-
- /**
- * Если указано, это пространство имен автоматически применяется к маршрутам вашего контроллера.
- *
- * Кроме того, оно устанавливается как корневое пространство имен генератора URL.
- *
- * @var string
- */
- protected $namespace = 'App\Http\Controllers';
-
- /**
- * Определить связывание модели и маршрута, фильтры шаблонов и т.д.
- *
- * @return void
- */
- public function boot()
- {
- $this->configureRateLimiting();
-
- $this->routes(function () {
- Route::middleware('web')
- ->namespace($this->namespace)
- ->group(base_path('routes/web.php'));
-
- Route::prefix('api')
- ->middleware('api')
- ->namespace($this->namespace)
- ->group(base_path('routes/api.php'));
- });
- }
-
- /**
- * Настроить ограничения запросов для приложения.
- *
- * @return void
- */
- protected function configureRateLimiting()
- {
- RateLimiter::for('api', function (Request $request) {
- return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
- });
- }
- }
+Опять же, многие приложения могут не взаимодействовать с этими методами, поскольку они не описаны в документации Laravel:
+
+ // Laravel 8.x...
+ $message
+ ->setFrom('taylor@laravel.com')
+ ->setTo('example@example.org')
+ ->setSubject('Order Shipped')
+ ->setBody('HTML ', 'text/html')
+ ->addPart('Plain Text', 'text/plain');
+
+ // Laravel 9.x...
+ $message
+ ->from('taylor@laravel.com')
+ ->to('example@example.org')
+ ->subject('Order Shipped')
+ ->html('HTML ')
+ ->text('Plain Text');
+
+#### Генерация идентификаторов сообщений
+
+SwiftMailer предлагал возможность определить собственный домен для включения в сгенерированные идентификаторы сообщений с помощью параметра конфигурации `mime.idgenerator.idright`. Это не поддерживается в Symfony Mailer. Вместо этого Symfony Mailer автоматически сгенерирует идентификатор сообщения на основе отправителя.
+
+#### Принудительное переподключение
+
+Больше невозможно принудительно переподключиться к транспорту (например, когда почтовая программа работает через процесс-демон). Вместо этого Symfony Mailer попытается автоматически переподключиться к транспорту и выдаст исключение, если переподключение не удастся.
+
+#### Параметры потока SMTP
+
+Определение параметров потока для транспорта SMTP больше не поддерживается. Вместо этого вы должны определить соответствующие параметры непосредственно в конфигурации, если они поддерживаются. Например, чтобы отключить одноранговую проверку TLS:
+
+ 'smtp' => [
+ // Laravel 8.x...
+ 'stream' => [
+ 'ssl' => [
+ 'verify_peer' => false,
+ ],
+ ],
-
-### Планирование задач
+ // Laravel 9.x...
+ 'verify_peer' => false,
+ ],
-
-#### Библиотека `cron-expression`
+Чтобы узнать больше о доступных параметрах конфигурации, ознакомьтесь с [документацией Symfony Mailer](https://symfony.com/doc/6.0/mailer.html#transport-setup).
+
+> {note} Несмотря на приведенный выше пример, обычно не рекомендуется отключать проверку SSL, поскольку это создает возможность атак типа [«man-in-the-middle»](https://ru.wikipedia.org/wiki/Атака_посредника).
+
+#### Режим аутентификации SMTP
+
+Определение параметра `auth_mode` SMTP в конфигурационном файле `mail` больше не требуется. Режим аутентификации будет автоматически согласован между Symfony Mailer и SMTP-сервером.
+
+#### Несостоявшиеся получатели
+
+Больше невозможно получить список неуспешных получателей после отправки сообщения. Вместо этого будет выброшено исключение `Symfony\Component\Mailer\Exception\TransportExceptionInterface`, если сообщение не будет отправлено. Вместо того, чтобы полагаться на получение недействительных адресов электронной почты после отправки сообщения, мы рекомендуем вам проверять адреса электронной почты перед отправкой сообщения.
+
+### Пакеты
+
+
+#### Каталог `lang`
+
+**Вероятность воздействия: средняя**
+
+В новых приложениях Laravel каталог `resources/lang` теперь находится в корневом каталоге проекта (`lang`). Если ваш пакет публикует языковые файлы в этом каталоге, то вы должны убедиться, что ваш пакет вместо жестко заданного пути публикует файлы в `app()->langPath()`.
+
+
+### Очереди
+
+
+#### Библиотека `opis/closure`
**Вероятность воздействия: низкая**
-Зависимость Laravel от `dragonmantank/cron-expression` была обновлена с `2.x` до `3.x`. Это не должно вызывать каких-либо критических изменений в вашем приложении, если вы не взаимодействуете напрямую с библиотекой `cron-expression`. Если вы напрямую взаимодействуете с этой библиотекой, просмотрите ее [журнал изменений](https://github.com/dragonmantank/cron-expression/blob/master/CHANGELOG.md).
+Зависимость Laravel от `opis/closure` была заменена на `laravel/serializable-closure`. Это не должно привести к каким-либо критическим изменениям в вашем приложении, если только вы не взаимодействуете с библиотекой `opis/closure` напрямую. Кроме того, были удалены ранее объявленные устаревшими классы `Illuminate\Queue\SerializableClosureFactory` и `Illuminate\Queue\SerializableClosure`. Если вы взаимодействуете с библиотекой `opis/closure` напрямую или используете какой-либо из удаленных классов, вместо этого вы можете использовать [Laravel Serializable Closure](https://github.com/laravel/serializable-closure).
+
+#### Метод `flush` поставщика неудачных заданий
+
+**Вероятность воздействия: низкая**
+
+Метод `flush`, определенный интерфейсом `Illuminate\Queue\Failed\FailedJobProviderInterface`, теперь принимает аргумент `$hours`, который определяет, насколько старым должно быть неудачное задание (в часах), прежде чем оно будет удалено командой `queue:flush`. Если вы самостоятельно реализуете `FailedJobProviderInterface`, то вы должны убедиться, что ваша реализация обновлена, чтобы отразить этот новый аргумент:
+
+```php
+public function flush($hours = null);
+```
-
### Сессия
-
-#### Контракт `Session`
+#### Метод `getSession`
**Вероятность воздействия: низкая**
-Контракт `Illuminate\Contracts\Session\Session` получил новый метод `pull`. Если вы реализуете этот контракт самостоятельно, то вам следует соответствующим образом обновить его реализацию:
+Класс `Symfony\Component\HttpFoundaton\Request`, расширенный собственным классом `Illuminate\Http\Request` Laravel, предлагает метод `getSession` для получения текущего обработчика хранилища сессии. Этот метод не задокументирован Laravel, так как большинство приложений Laravel взаимодействуют с сессией через метод `session` Laravel.
- /**
- * Получите значение переданного ключа и удалить его.
- *
- * @param string $key
- * @param mixed $default
- * @return mixed
- */
- public function pull($key, $default = null);
+Метод `getSession` ранее возвращал экземпляр `Illuminate\Session\Store` или `null`; однако из-за того, что в версии Symfony 6.x принудительно используется тип возвращаемого значения `Symfony\Component\HttpFoundation\Session\SessionInterface`, то `getSession` теперь корректно возвращает реализацию `SessionInterface` или выбрасывает `Symfony\Component\HttpFoundation\Exception\SessionNotFoundException`, когда сессия недоступна.
-
### Тестирование
-
-#### Метод `decodeResponseJson`
+
+#### Метод `assertDeleted`
+
+**Вероятность воздействия: средняя**
+
+Все вызовы метода `assertDeleted` должны быть заменена на `assertModelMissing`.
+
+### Доверенные прокси
**Вероятность воздействия: низкая**
-Метод `decodeResponseJson`, принадлежащий классу `Illuminate\Testing\TestResponse`, больше не принимает никаких аргументов. Пожалуйста, подумайте об использовании вместо этого метода `json`.
+Если вы обновляете свой проект Laravel 8 до Laravel 9, импортируя существующий код приложения в совершенно новый скелет приложения Laravel 9, вам может потребоваться обновить посредник «доверенного прокси» вашего приложения.
-
-#### Метод `assertExactJson`
+В вашем файле `app/Http/Middleware/TrustProxies.php` измените `use Fideloper\Proxy\TrustProxies as Middleware` на `use Illuminate\Http\Middleware\TrustProxies as Middleware`.
-**Вероятность воздействия: средняя**
+Там же вы должны обновить определение свойства `$headers`:
-Метод `assertExactJson` теперь требует, чтобы числовые ключи сравниваемых массивов совпадали и располагались в том же порядке. Если вы хотите сравнить JSON с массивом, не требуя, чтобы массивы с числовыми ключами имели одинаковый порядок, вы можете вместо этого использовать метод `assertSimilarJson`.
+```php
+// До ...
+protected $headers = Request::HEADER_X_FORWARDED_ALL;
+
+// После ...
+protected $headers =
+ Request::HEADER_X_FORWARDED_FOR |
+ Request::HEADER_X_FORWARDED_HOST |
+ Request::HEADER_X_FORWARDED_PORT |
+ Request::HEADER_X_FORWARDED_PROTO |
+ Request::HEADER_X_FORWARDED_AWS_ELB;
+```
-
### Валидация
-
-### Соединения для правил, использующих БД
+#### Метод `validated` запроса формы
**Вероятность воздействия: низкая**
-Правила `unique` и `exists` теперь будут учитывать указанное имя соединения моделей Eloquent при выполнении запросов. Это имя соединения доступно через метод `getConnectionName` модели.
+Метод `validated`, предлагаемый запросами формы, теперь принимает аргументы `$key` и `$default`. Если вы самостоятельно определяете этот метод, то вам следует обновить сигнатуру вашего метода, чтобы отразить эти новые аргументы:
+
+```php
+public function validated($key = null, $default = null)
+```
+
+
+#### Правило `password`
+
+**Вероятность воздействия: средняя**
+
+Правило `password`, которое проверяет, соответствует ли заданное входное значение текущему паролю аутентифицированного пользователя, было переименовано в `current_password`.
+
+
+#### Непровалидированные ключи массива
+
+**Вероятность воздействия: средняя**
+
+В предыдущих релизах Laravel вам приходилось вручную указывать валидатору Laravel исключать непроверенные ключи массива из «провалидированных» данных, которые он возвращает, особенно в сочетании с правилом `array`, которое не указывает список разрешенных ключей.
+
+Однако в Laravel 9.x непроверенные ключи массива всегда исключаются из «провалидированных» данных, даже если в правиле `array` не указаны разрешенные ключи. Как правило, такое поведение является наиболее ожидаемым поведением, и предыдущий метод `excludeUnvalidatedArrayKeys` был добавлен в Laravel 8.x только как временная мера для сохранения обратной совместимости.
+
+Хотя это не рекомендуется, но вы можете отказаться от предыдущего поведения Laravel 8.x, вызвав новый метод `includeUnvalidatedArrayKeys` в методе `boot` одного из поставщика служб вашего приложения:
+
+```php
+use Illuminate\Support\Facades\Validator;
+
+/**
+ * Загрузка любых служб приложения.
+ *
+ * @return void
+ */
+public function boot()
+{
+ Validator::includeUnvalidatedArrayKeys();
+}
+```
### Разное
-Мы также рекомендуем вам просматривать изменения в GitHub-репозитории [`laravel/laravel`](https://github.com/laravel/laravel). Хотя многие из этих изменений могут быть неважны, но вы можете синхронизировать эти файлы с вашим приложением. Некоторые из этих изменений будут рассмотрены в данном руководстве по обновлению, но другие, такие как изменения файлов конфигурации или комментарии, не будут. Вы можете легко просмотреть изменения с помощью [инструмента сравнения GitHub](https://github.com/laravel/laravel/compare/7.x...8.x) и выбрать, какие обновления важны для вас.
+Мы также рекомендуем вам просматривать изменения в GitHub-репозитории [`laravel/laravel`](https://github.com/laravel/laravel). Хотя многие из этих изменений могут быть неважны, но вы можете синхронизировать эти файлы с вашим приложением. Некоторые из этих изменений будут рассмотрены в данном руководстве по обновлению, но другие, такие как изменения файлов конфигурации или комментарии, не будут. Вы можете легко просмотреть изменения с помощью [инструмента сравнения GitHub](https://github.com/laravel/laravel/compare/8.x...9.x) и выбрать, какие обновления важны для вас.
diff --git a/docs/urls.md b/docs/urls.md
index fb76cef..058e27a 100644
--- a/docs/urls.md
+++ b/docs/urls.md
@@ -108,7 +108,7 @@ Laravel позволяет вам легко создавать «подписа
#### Проверка запросов подписанного маршрута
-Чтобы убедиться, что входящий запрос имеет действительную подпись, вы должны вызвать метод `hasValidSignature` для входящего запроса `Request`:
+Чтобы убедиться, что входящий запрос имеет действительную подпись, вы должны вызвать метод `hasValidSignature` для экземпляра `Illuminate\Http\Request` входящего запроса:
use Illuminate\Http\Request;
@@ -120,7 +120,13 @@ Laravel позволяет вам легко создавать «подписа
// ...
})->name('unsubscribe');
-В качестве альтернативы, вы можете назначить маршруту [посредник](middleware.md) `Illuminate\Routing\Middleware\ValidateSignature`. Если его еще нет, вы должны назначить этому посреднику ключ в массиве `routeMiddleware` в HTTP-ядре:
+Иногда требуется разрешить внешнему интерфейсу вашего приложения добавлять данные к подписанному URL-адресу, например, при выполнении разбивки на страницы на стороне клиента. Таким образом, вы можете указать параметры запроса, которые следует игнорировать при проверке подписанного URL-адреса, используя метод `hasValidSignatureWhileIgnoring`. Помните, что игнорирование параметров позволяет любому изменять эти параметры:
+
+ if (! $request->hasValidSignatureWhileIgnoring(['page', 'order'])) {
+ abort(401);
+ }
+
+Вместо проверки подписанных URL-адресов с использованием экземпляра входящего запроса, вы можете назначить маршруту [посредник](middleware.md) `Illuminate\Routing\Middleware\ValidateSignature`. Если его еще нет, то вы должны назначить этому посреднику ключ в массиве `routeMiddleware` в HTTP-ядре:
/**
* Посредники маршрутов приложения.
diff --git a/docs/valet.md b/docs/valet.md
index 37f2b4f..603fb77 100644
--- a/docs/valet.md
+++ b/docs/valet.md
@@ -71,19 +71,27 @@ However, you may extend Valet with your own [custom drivers](#custom-valet-drive
To get started, you first need to ensure that Homebrew is up to date using the `update` command:
- brew update
+```shell
+brew update
+```
Next, you should use Homebrew to install PHP:
- brew install php
+```shell
+brew install php
+```
After installing PHP, you are ready to install the [Composer package manager](https://getcomposer.org). In addition, you should make sure the `~/.composer/vendor/bin` directory is in your system's "PATH". After Composer has been installed, you may install Laravel Valet as a global Composer package:
- composer global require laravel/valet
+```shell
+composer global require laravel/valet
+```
Finally, you may execute Valet's `install` command. This will configure and install Valet and DnsMasq. In addition, the daemons Valet depends on will be configured to launch when your system starts:
- valet install
+```shell
+valet install
+```
Once Valet is installed, try pinging any `*.test` domain on your terminal using a command such as `ping foobar.test`. If Valet is installed correctly you should see this domain responding on `127.0.0.1`.
@@ -94,13 +102,17 @@ Valet will automatically start its required services each time your machine boot
Valet allows you to switch PHP versions using the `valet use php@version` command. Valet will install the specified PHP version via Homebrew if it is not already installed:
- valet use php@7.2
+```shell
+valet use php@7.2
- valet use php
+valet use php
+```
You may also create a `.valetphprc` file in the root of your project. The `.valetphprc` file should contain the PHP version the site should use:
- php@7.2
+```shell
+php@7.2
+```
Once this file has been created, you may simply execute the `valet use` command and the command will determine the site's preferred PHP version by reading the file.
@@ -131,9 +143,11 @@ Once Valet is installed, you're ready to start serving your Laravel applications
The `park` command registers a directory on your machine that contains your applications. Once the directory has been "parked" with Valet, all of the directories within that directory will be accessible in your web browser at `http://.test`:
- cd ~/Sites
+```shell
+cd ~/Sites
- valet park
+valet park
+```
That's all there is to it. Now, any application you create within your "parked" directory will automatically be served using the `http://.test` convention. So, if your parked directory contains a directory named "laravel", the application within that directory will be accessible at `http://laravel.test`. In addition, Valet automatically allows you to access the site using wildcard subdomains (`http://foo.laravel.test`).
@@ -142,38 +156,50 @@ That's all there is to it. Now, any application you create within your "parked"
The `link` command can also be used to serve your Laravel applications. This command is useful if you want to serve a single site in a directory and not the entire directory:
- cd ~/Sites/laravel
+```shell
+cd ~/Sites/laravel
- valet link
+valet link
+```
Once an application has been linked to Valet using the `link` command, you may access the application using its directory name. So, the site that was linked in the example above may be accessed at `http://laravel.test`. In addition, Valet automatically allows you to access the site using wildcard sub-domains (`http://foo.laravel.test`).
If you would like to serve the application at a different hostname, you may pass the hostname to the `link` command. For example, you may run the following command to make an application available at `http://application.test`:
- cd ~/Sites/laravel
+```shell
+cd ~/Sites/laravel
- valet link application
+valet link application
+```
You may execute the `links` command to display a list of all of your linked directories:
- valet links
+```shell
+valet links
+```
The `unlink` command may be used to destroy the symbolic link for a site:
- cd ~/Sites/laravel
+```shell
+cd ~/Sites/laravel
- valet unlink
+valet unlink
+```
### Securing Sites With TLS
By default, Valet serves sites over HTTP. However, if you would like to serve a site over encrypted TLS using HTTP/2, you may use the `secure` command. For example, if your site is being served by Valet on the `laravel.test` domain, you should run the following command to secure it:
- valet secure laravel
+```shell
+valet secure laravel
+```
To "unsecure" a site and revert back to serving its traffic over plain HTTP, use the `unsecure` command. Like the `secure` command, this command accepts the hostname that you wish to unsecure:
- valet unsecure laravel
+```shell
+valet unsecure laravel
+```
### Serving A Default Site
@@ -192,9 +218,11 @@ Valet even includes a command to share your local sites with the world, providin
To share a site, navigate to the site's directory in your terminal and run Valet's `share` command. A publicly accessible URL will be inserted into your clipboard and is ready to paste directly into your browser or share with your team:
- cd ~/Sites/laravel
+```shell
+cd ~/Sites/laravel
- valet share
+valet share
+```
To stop sharing your site, you may press `Control + C`. Sharing your site using Ngrok requires you to [create an Ngrok account](https://dashboard.ngrok.com/signup) and [setup an authentication token](https://dashboard.ngrok.com/get-started/your-authtoken).
@@ -205,9 +233,11 @@ To stop sharing your site, you may press `Control + C`. Sharing your site using
If you have [Expose](https://expose.dev) installed, you can share your site by navigating to the site's directory in your terminal and running the `expose` command. Consult the [Expose documentation](https://expose.dev/docs) for information regarding the additional command-line parameters it supports. After sharing the site, Expose will display the sharable URL that you may use on your other devices or amongst team members:
- cd ~/Sites/laravel
+```shell
+cd ~/Sites/laravel
- expose
+expose
+```
To stop sharing your site, you may press `Control + C`.
@@ -248,21 +278,25 @@ Sometimes you may wish to proxy a Valet domain to another service on your local
To solve this, you may use the `proxy` command to generate a proxy. For example, you may proxy all traffic from `http://elasticsearch.test` to `http://127.0.0.1:9200`:
-```bash
-// Proxy over HTTP...
+```shell
+# Proxy over HTTP...
valet proxy elasticsearch http://127.0.0.1:9200
-// Proxy over TLS + HTTP/2...
+# Proxy over TLS + HTTP/2...
valet proxy elasticsearch http://127.0.0.1:9200 --secure
```
You may remove a proxy using the `unproxy` command:
- valet unproxy elasticsearch
+```shell
+valet unproxy elasticsearch
+```
You may use the `proxies` command to list all site configurations that are proxied:
- valet proxies
+```shell
+valet proxies
+```
## Custom Valet Drivers
diff --git a/docs/validation.md b/docs/validation.md
index c66130f..67b616e 100644
--- a/docs/validation.md
+++ b/docs/validation.md
@@ -26,7 +26,6 @@
- [Доступные правила валидации](#available-validation-rules)
- [Условное добавление правил](#conditionally-adding-rules)
- [Валидация массивов](#validating-arrays)
- - [Исключение непровалидированных ключей массива](#excluding-unvalidated-array-keys)
- [Валидация вложенных массивов](#validating-nested-array-input)
- [Валидация паролей](#validating-passwords)
- [Пользовательские правила валидации](#custom-validation-rules)
@@ -174,7 +173,7 @@ Laravel содержит удобные правила валидации, пр
Итак, в нашем примере пользователь будет перенаправлен на метод нашего контроллера `create`, в случае, если валидация завершится неудачно, что позволит нам отобразить сообщения об ошибках в шаблоне:
-```html
+```blade
Создание поста блога
@@ -209,12 +208,15 @@ Laravel содержит удобные правила валидации, пр
Вы можете использовать директиву [`@error` Blade](blade.md#validation-errors), чтобы быстро определить, существуют ли сообщения об ошибках валидации для конкретного атрибута, включая сообщения об ошибках в именованной коллекции ошибок. В директиве `@error` вы можете вывести содержимое переменной `$message` для отображения сообщения об ошибке:
-```html
+```blade
Post Title
-
+
@error('title')
{{ $message }}
@@ -223,7 +225,7 @@ Laravel содержит удобные правила валидации, пр
Если вы используете [именованные коллекции ошибок](#named-error-bags), то вы можете передать имя коллекции в качестве второго аргумента директивы `@error`:
-```html
+```blade
```
@@ -238,7 +240,9 @@ Laravel содержит удобные правила валидации, пр
Laravel также содержит глобального помощника `old`. Если вы показываете входные данные прошлого запроса в [шаблоне Blade](blade.md), то удобнее использовать помощник `old` для повторного заполнения формы. Если для какого-то поля не были предоставлены данные в прошлом запросе, то будет возвращен `null`:
-
+```blade
+
+```
### Примечание о необязательных полях
@@ -261,7 +265,9 @@ Laravel также содержит глобального помощника `o
Для более сложных сценариев валидации вы можете создать «запрос формы». Запрос формы – это ваш класс запроса, который инкапсулирует свою собственную логику валидации и авторизации. Чтобы сгенерировать новый запрос формы, используйте команду `make:request` [Artisan](artisan.md):
- php artisan make:request StorePostRequest
+```shell
+php artisan make:request StorePostRequest
+```
Эта команда поместит новый класс запроса формы в каталог `app/Http/Requests` вашего приложения. Если этот каталог не существует в вашем приложении, то Laravel предварительно создаст его, когда вы запустите команду `make:request`. Каждый запрос формы, созданный Laravel, имеет два метода: `authorize` и `rules`.
@@ -538,7 +544,9 @@ Laravel также содержит глобального помощника `o
Затем, вы можете получить доступ к именованному экземпляру `MessageBag` из переменной `$errors`:
- {{ $errors->login->first('email') }}
+```blade
+{{ $errors->login->first('email') }}
+```
### Корректировка сообщений об ошибках
@@ -718,7 +726,9 @@ Laravel также содержит глобального помощника `o
Если это правило валидации не будет пройдено, то будет выдано следующее сообщение об ошибке:
- The credit card number field is required when payment type is cc.
+```none
+The credit card number field is required when payment type is cc.
+```
Вместо того, чтобы отображать `cc` в качестве значения типа платежа, вы можете указать более удобное для пользователя представление значения в вашем языковом файле `resources/lang/xx/validation.php`, определив массив `values`:
@@ -730,7 +740,9 @@ Laravel также содержит глобального помощника `o
После определения этого значения правило валидации выдаст следующее сообщение об ошибке:
- The credit card number field is required when payment type is credit card.
+```none
+The credit card number field is required when payment type is credit card.
+```
## Доступные правила валидации
@@ -820,6 +832,7 @@ Laravel также содержит глобального помощника `o
- [Required With All](#rule-required-with-all)
- [Required Without](#rule-required-without)
- [Required Without All](#rule-required-without-all)
+- [Required Array Keys](#rule-required-array-keys)
- [Same](#rule-same)
- [Size](#rule-size)
- [Sometimes](#validating-when-present)
@@ -899,23 +912,7 @@ Laravel также содержит глобального помощника `o
'user' => 'array:username,locale',
]);
-
+В общем, вы всегда должны указывать ключи массива, которые могут присутствовать в вашем массиве.
#### bail
@@ -1420,6 +1417,11 @@ public function boot()
Проверяемое поле должно присутствовать и не быть пустым, _только когда_ все другие указанные поля являются пустыми или отсутствуют.
+
+#### required_array_keys:_foo_,_bar_,...
+
+Проверяемое поле должно быть массивом и содержать как минимум указанные ключи.
+
#### same:_field_
@@ -1638,25 +1640,6 @@ public function boot()
В общем, вы всегда должны указывать ключи массива, которые могут присутствовать в вашем массиве. В противном случае методы валидатора `validate` и `validated` вернут все провалидированные данные, включая массив и все его ключи, даже если эти ключи не были провалидированы другими правилами валидации вложенных массивов.
-
-### Исключение непровалидированных ключей массива
-
-Если вы хотите, то можете указать валидатору Laravel никогда не включать непроверенные ключи массива в «провалидированные» данные, которые он возвращает, даже если вы используете правило `array` без указания списка разрешенных ключей. Для этого вы можете вызвать метод `excludeUnvalidatedArrayKeys` валидатора в методе `boot` поставщика `App\Providers\AppServiceProvider`. После этого валидатор будет включать ключи массива в «провалидированные» данные, которые он возвращает, только если эти ключи были специально провалидированы [правилами вложенных массивов](#validating-arrays):
-
-```php
-use Illuminate\Support\Facades\Validator;
-
-/**
- * Загрузка любых служб приложения.
- *
- * @return void
- */
-public function boot()
-{
- Validator::excludeUnvalidatedArrayKeys();
-}
-```
-
### Валидация вложенных массивов
@@ -1683,6 +1666,24 @@ public function boot()
]
],
+
+#### Доступ к данным вложенного массива
+
+Иногда требуется получить доступ к значению переданного вложенного элемента массива при назначении правил валидации для атрибута. Вы можете сделать это, используя метод `Rule::foreEach`. Метод `forEach` принимает замыкание, которое будет вызываться для каждой итерации проверяемого атрибута массива, и будет получать значение атрибута и явное, полностью развернутое имя атрибута. Замыкание должно возвращать массив правил предназначенных элементу массива:
+
+ use App\Rules\HasPermission;
+ use Illuminate\Support\Facades\Validator;
+ use Illuminate\Validation\Rule;
+
+ $validator = Validator::make($request->all(), [
+ 'companies.*.id' => Rule::forEach(function ($value, $attribute) {
+ return [
+ Rule::exists(Company::class, 'id'),
+ new HasPermission('manage-company', $value),
+ ];
+ }),
+ ]);
+
## Валидация паролей
@@ -1779,7 +1780,9 @@ public function boot()
Laravel предлагает множество полезных правил валидации; однако вы можете указать свои собственные. Один из методов регистрации собственных правил валидации – использование объектов правил. Чтобы сгенерировать новый объект правила, вы можете использовать команду `make:rule` [Artisan](artisan.md). Давайте воспользуемся этой командой, чтобы сгенерировать правило, которое проверяет, что строка состоит из прописных букв. Laravel поместит новый класс правила в каталог `app/Rules` вашего приложения. Если этот каталог не существует в вашем приложении, то Laravel предварительно создаст его, когда вы выполните команду Artisan для создания своего правила:
- php artisan make:rule Uppercase
+```shell
+php artisan make:rule Uppercase
+```
Как только правило создано, мы готовы определить его поведение. Объект правила содержит два метода: `passes` и `message`. Метод `passes` получает значение и имя атрибута и должен возвращать `true` или `false` в зависимости от того, является ли значение атрибута допустимым или нет. Метод `message` должен возвращать сообщение об ошибке валидации, которое следует использовать, если проверка оказалась не успешной:
@@ -1940,6 +1943,8 @@ Laravel предлагает множество полезных правил в
Чтобы сгенерировать новый объект неявного правила, вы можете использовать команду `make:rule` Artisan с флагом `--implicit`:
- php artisan make:rule Uppercase --implicit
+```shell
+php artisan make:rule Uppercase --implicit
+```
> {note} «Неявное» правило только _подразумевает_, что атрибут является обязательным к валидации. В действительности, решать только вам, будет ли пустой или отсутствующий атрибут считаться невалидным.
diff --git a/docs/verification.md b/docs/verification.md
index 97739e2..1713349 100644
--- a/docs/verification.md
+++ b/docs/verification.md
@@ -51,7 +51,9 @@
Ваша таблица `users` должна содержать столбец `email_verified_at` для сохранения даты и времени подтверждения адреса электронной почты пользователем. По умолчанию миграция таблицы пользователей, содержащаяся в Laravel, уже содержит этот столбец. Просто запустите миграцию базы данных:
- php artisan migrate
+```shell
+php artisan migrate
+```
## Маршрутизация
diff --git a/docs/views.md b/docs/views.md
index bbe866c..8086f85 100644
--- a/docs/views.md
+++ b/docs/views.md
@@ -16,7 +16,7 @@
Конечно, нецелесообразно возвращать целые строки HTML-документов непосредственно из ваших маршрутов и контроллеров. К счастью, шаблоны предоставляют удобный способ разместить весь наш HTML в отдельных файлах. Шаблоны отделяют логику контроллера / приложения от логики представления и хранятся в каталоге `resources/views`. Простой шаблон может выглядеть примерно так:
-```html
+```blade
@@ -258,8 +258,12 @@
Компиляция шаблонов во время запроса отрицательно влияет на производительность, поэтому Laravel содержит команду Artisan `view:cache` для предварительной компиляции всех шаблонов, используемых вашим приложением. Для повышения производительности вы можете выполнить эту команду как часть процесса развертывания:
- php artisan view:cache
+```shell
+php artisan view:cache
+```
Вы можете использовать команду `view:clear` для очистки кеша шаблонов:
- php artisan view:clear
+```shell
+php artisan view:clear
+```