Введение
Пакеты (packages) — основной способ добавления нового функционала в Laravel. Пакеты могут быть всем, чем угодно — от классов для удобной работы с датами наподобие Carbon, до целых библиотек BDD-тестирования наподобие Behat.
Конечно, есть разные типы пакетов. Некоторые пакеты автономны, что позволяет им работать в составе любого PHP-фреймворка, не только Laravel. Примерами таких отдельных пакетов являются Carbon и Behat. Любой из них может быть использован в Laravel с помощью простого указания их в файле composer.json.
С другой стороны, некоторые пакеты разработаны специально для использования в Laravel. Они могут содержать маршруты, контроллеры, представления и настройки, специально рассчитанные для улучшения приложения на Laravel. Этот раздел документации в основном посвящён разработке именно пакетов для Laravel.
Все пакеты Laravel распространяются через Packagist и Composer, поэтому нужно изучить эти прекрасные средства распространения пакетов для PHP.
добавлено в 5.3 ()
Замечание о фасадах
При создании Laravel-приложения в целом неважно, что использовать — контракты или фасады, поскольку и те и другие обеспечивают практически одинаковый уровень тестируемости. Но при создании пакетов лучше использовать контракты, а не фасады. Поскольку у вашего пакета не будет доступа ко всем вспомогательным методам Laravel для тестирования, будет проще подменить или заглушить контракт, а не фасад.
Сервис-провайдеры
Сервис-провайдеры — связующие элементы между вашим пакетом и Laravel. Они содержит привязки сервис-контейнера, а также инструкции о том, где хранятся настройки пакета, его представления и языковые файлы.
Сервис-провайдер наследует класс Illuminate\Support\ServiceProvider и содержит два метода: PHPregister()
и PHPboot()
. Базовый класс ServiceProvider находится в пакете Composer illuminate/support, который вы должны добавить в зависимости своего пакета. Подробнее о структуре и задачах сервис-провайдеров читайте в документации.
Маршруты
добавлено в 5.3 ()
Чтобы определить маршруты для своего пакета, передайте файл маршрутов в метод PHPloadRoutesFrom()
из метода PHPboot()
сервис-провайдера вашего пакета. В этом файле вы можете использовать фасад Illuminate\Support\Facades\Route для регистрации маршрутов, точно так же, как в обычном приложении Laravel:
/**
* Выполнение после-регистрационной загрузки сервисов.
*
* @return void
*/
public function boot()
{
$this->loadRoutesFrom(__DIR__.'/path/to/routes.php');
}
Чтобы определить маршруты для своего пакета, просто затребуйте (PHPrequire
) файл маршрутов в методе PHPboot()
вашего сервис-провайдера. В этом файле вы можете использовать фасад Route для регистрации маршрутов, точно так же, как в обычном приложении Laravel:
/**
* Выполнение после-регистрационной загрузки сервисов.
*
* @return void
*/
public function boot()
{
if (! $this->app->routesAreCached()) {
require __DIR__.'/../../routes.php';
}
}
добавлено в 5.0 ()
Чтобы загрузить файл маршрутов для вашего пакета, просто подключите его (include) в методе PHPboot()
вашего сервис-провайдера.
public function boot()
{
include __DIR__.'/../../routes.php';
}
Если ваш пакет использует контроллеры, вам надо убедиться в том, что они правильно настроены в разделе автозагрузки файла composer.json.
Ресурсы
Настройки
В типичном случае вам потребуется опубликовать файл настроек вашего пакета в папку config самого приложения. Это позволит пользователям вашего пакета легко изменять настройки по умолчанию. Чтобы позволить вашим файлам быть опубликованными, вызовите метод PHPpublishes()
из метода PHPboot()
вашего сервис-провайдера:
/**
* Выполнение после-регистрационной загрузки сервисов.
*
* @return void
*/
public function boot()
{
$this->publishes([
__DIR__.'/path/to/config/courier.php' => config_path('courier.php'),
]);
}
Теперь, когда пользователи вашего пакета вызовут команду Laravel shvendor:publish
, ваш файл будет скопирован в указанное место публикации. Само собой, когда ваш файл настроек опубликован, к его значениям можно обращаться как к любому другому файлу настроек:
$value = config('courier.option');
Вы также можете выбрать вариант соединения файла настроек вашего пакета с его копией в приложении. Это позволит вашим пользователям включать только те параметры, которые они хотят изменить в опубликованной копии конфигурации. Для объединения конфигураций используйте метод PHPmergeConfigFrom()
в методе PHPregister()
вашего сервис-провайдера:
/**
* Регистрация привязок в контейнере.
*
* @return void
*/
public function register()
{
$this->mergeConfigFrom(
__DIR__.'/path/to/config/courier.php', 'courier'
);
}
Этот метод объединяет только первый уровень массива настроек. Если ваши пользователи определят многомерный массив настроек, отсутствующие параметры не будут объединены.
добавлено в 5.3 ()
Миграции
Если ваш пакет содержит миграции БД, вы можете использовать метод PHPloadMigrationsFrom()
, чтобы указать Laravel как их загружать. Метод PHPloadMigrationsFrom()
принимает единственный аргумент — путь к миграциям вашего пакета:
/**
* Выполнение после-регистрационной загрузки сервисов.
*
* @return void
*/
public function boot()
{
$this->loadMigrationsFrom(__DIR__.'/path/to/migrations');
}
После регистрации миграций вашего пакета они будут автоматически запущены при выполнении команды shphp artisan migrate
. Вам не надо экспортировать их в основную папку приложения database/migrations.
Переводы
Если ваш пакет содержит языковые файлы, вы можете использовать метод PHPloadTranslationsFrom()
, чтобы указать Laravel, как их загружать. Например, если ваш пакет называется courier, вы можете добавить в метод PHPboot()
своего сервис-провайдера следующее:
/**
* Выполнение после-регистрационной загрузки сервисов.
*
* @return void
*/
public function boot()
{
$this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier');
}
На файлы переводов пакета ссылаются, используя синтаксис PHPpackage::file.line
. Поэтому вы можете загрузить строку welcome пакета courier из файла messages таким образом:
echo trans('courier::messages.welcome');
Помните, что в вашей папке с переводами должны быть подпапки для каждого языка, такие как en, es, ru и т.д.
Для публикации переводов вашего пакета в папку resources/lang/vendor приложения, используйте метод сервис-провайдера PHPpublishes()
. Этот метод принимает массив путей к переводам пакета и предполагаемые места для их публикации. Например, для публикации языковых файлов пакета courier сделайте так:
/**
* Выполнение после-регистрационной загрузки сервисов.
*
* @return void
*/
public function boot()
{
$this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier');
$this->publishes([
__DIR__.'/path/to/translations' => resource_path('lang/vendor/courier'),
//для версии 5.1 и ранее:
//__DIR__.'/path/to/translations' => base_path('resources/lang/vendor/courier'),
]);
}
Теперь, когда пользователи вашего пакета вызовут Artisan-команду Laravel shvendor:publish
, переводы вашего пакета будут скопированы в указанное место публикации.
Представления
Для регистрации представлений вашего пакета в Laravel, вам надо указать Laravel, где они расположены. Вы можете сделать это методом PHPloadViewsFrom()
. Этот метод принимает два аргумента: путь к шаблонам ваших представлений и название пакета. Например, если ваш пакет называется courier, вам надо добавить в метод PHPboot()
своего сервис-провайдера следующее:
/**
* Выполнение после-регистрационной загрузки сервисов.
*
* @return void
*/
public function boot()
{
$this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
}
На представления пакета ссылаются, используя синтаксис PHPpackage::view
. Поэтому, когда путь вашего представления зарегистрирован в сервис-провайдере, вы можете загрузить представление admin из пакета courier таким образом:
Route::get('admin', function () {
return view('courier::admin');
});
Переопределение представлений пакета
Когда вы используете метод PHPloadViewsFrom()
, на самом деле Laravel регистрирует два расположения для ваших представлений: в папке приложения resources/views/vendor и в указанной вами папке. Поэтому в нашем примере с courier Laravel сначала проверит, предоставил ли разработчик свою версию представления в PHPresources/views/vendor/courier
. Затем, если представление не было изменено, Laravel будет искать в вызове PHPloadViewsFrom()
указанную вами папку представлений пакета. Это упрощает редактирование или замену представлений вашего пакета для тех, кто им будет пользоваться.
Для публикации представлений вашего пакета в папку resources/views/vendor используйте метод PHPpublishes()
в методе PHPboot()
вашего сервис-провайдера. Метод PHPpublishes()
принимает массив путей к представлениям пакета и предполагаемые места для их публикации.
/**
* Выполнение после-регистрационной загрузки сервисов.
*
* @return void
*/
public function boot()
{
$this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
$this->publishes([
__DIR__.'/path/to/views' => resource_path('views/vendor/courier'),
//для версии 5.1 и ранее:
//__DIR__.'/path/to/views' => base_path('resources/views/vendor/courier'),
]);
}
Теперь, когда пользователи вашего пакета вызовут Artisan-команду Laravel shvendor:publish
, папка ваших представлений будет скопирована в указанное место публикации.
добавлено в 5.3 ()
Команды
Для регистрации в Laravel Artisan-команд вашего пакета используйте метод PHPcommands()
. Этот метод принимает массив имён классов команд. После регистрации команд вы можете выполнять их через консоль Artisan:
/**
* Начальная загрузка сервисов приложения.
*
* @return void
*/
public function boot()
{
if ($this->app->runningInConsole()) {
$this->commands([
FooCommand::class,
BarCommand::class,
]);
}
}
Общие ресурсы
Ваш пакет может иметь ресурсы, такие как JavaScript, CSS и изображения. Для публикации этих ресурсов в папку приложения public используйте метод PHPpublishes()
в методе PHPboot()
вашего сервис-провайдера. В этом примере мы также добавим для ресурсов групповой тег «public», который можно использовать для публикации групп связанных ресурсов:
/**
* Выполнение после-регистрационной загрузки сервисов.
*
* @return void
*/
public function boot()
{
$this->publishes([
__DIR__.'/path/to/assets' => public_path('vendor/courier'),
], 'public');
}
Теперь, когда пользователи вашего пакета вызовут команду Laravel shvendor:publish
, ваши ресурсы будут скопированы в указанное место публикации. Поскольку обычно каждый раз при обновлении пакета вам необходимо перезаписать ресурсы, используйте флаг sh--force
:
shphp artisan vendor:publish --tag=public --force
Публикация файлов по группам
Вам может пригодиться возможность публиковать отдельные группы файлов. Например, если вы захотите дать вашим пользователям возможность публиковать файлы настроек вашего пакета и файлы ресурсов по отдельности. Вы можете сделать это, присвоив им теги при вызове метода PHPpublishes()
из сервис-провайдера пакета. Например, давайте используем теги для определения двух групп для публикации в методе PHPboot()
сервис-провайдера пакета:
/**
* Выполнение после-регистрационной загрузки сервисов.
*
* @return void
*/
public function boot()
{
// Публикация файла настроек
$this->publishes([
__DIR__.'/../config/package.php' => config_path('package.php')
], 'config');
// Публикация ваших миграций
$this->publishes([
__DIR__.'/../database/migrations/' => database_path('migrations')
], 'migrations');
}
Теперь ваши пользователи могут публиковать эти группы отдельно, указывая их тег при выполнении команды shvendor:publish
:
shphp artisan vendor:publish --tag=config
добавлено в 5.0 ()
Комментарии (2)
Подскажите люди добрые, а можно как то установить собственный пакет локально — не публикую его?
https://klisl.com/laravel_package.html