Разработка пакетов

Введение

Пакеты (packages) - основной способ добавления нового функционала в Laravel. Пакеты могут быть всем, чем угодно - от классов для удобной работы с датами типа Carbon до целых библиотек BDD-тестирования наподобие Behat.

Конечно, всё это разные типы пакетов. Некоторые пакеты самостоятельны, что позволяет им работать в составе любого фреймворка, а не только Laravel. Примерами таких отдельных пакетов являются Carbon и Behat. Любой из них может быть использован в Laravel после простого указания его в файле composer.json.

С другой стороны, некоторые пакеты разработаны специально для использования в Laravel. Они могли содержать роуты, контроллеры, шаблоны, настройки и миграции. Так как для разработки самостоятельных пакетов нет особенных правил, этот раздел документации в основном посвящён разработке именно пакетов для Laravel.

Все пакеты Laravel распространяются через Packagist и Composer, поэтому нужно изучить эти прекрасные средства распространения кода для PHP.

Файлы шаблонов (views)

Структура вашего пакета зависит от вас. Обычно пакет имеет в составе один или несколько сервис-провайдеров. Сервис-провайдеры содержат регистрацию классов в IoC и определяют, где находятся конфиги, шаблоны (views) и локализационные файлы пакета.

Шаблоны

К шаблонам пакета можно обращаться через так называемую неймспейс-конструкцию :::

return view('package::view.name');

Вам нужно зарегистрить неймспейс шаблонов, указав, где находится папка шаблонов пакета. Делается это в методе boot() сервис-провайдера. Например, так регистрируется неймспейс courier

public function boot()
{
    $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
}

Теперь вы можете использовать в контроллере или роуте шаблон пакета таким образом:

return view('courier::view.name');

Когда вы регистрируете папку в loadViewsFrom, Laravel на самом деле регистрирует две папки - одну, которую вы указали и другую - resources/views/vendor. В этой папке лежат шаблоны пакетов, которые пользователи могут изменять под себя. Когда запрашивается шаблон courier::view.name, Laravel сначала пытается загрузить этот шаблон из resources/views/vendor/courier, а затем из папки, заданной в loadViewsFrom.

Публикация шаблонов для изменения

Чтобы разрешить копировать шаблоны пакета в папку resources/views/vendor, где пользователи могут их изменять, вы должны использовать метод publishes в boot сервис-провайдера пакета:

public function boot()
{
    $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');

    $this->publishes([
        __DIR__.'/path/to/views' => base_path('resources/views/vendor/courier'),
    ]);
}

Теперь, когда пользователь исполнит команду vendor:publish, шаблоны пакета будут скопированы в соответствующу папку.

Чтобы перезаписать имеющися файлы используйте флаг --force:

php artisan vendor:publish --force

Примечание: Вы можете использовать publishes не только для шаблонов, но и для любых других файлов, которые хотите скопировать из пакета в основное приложение пользователя.

Файлы переводов

Файлы локализации пакета доступны при помощи неймспейс-доступа :::

return trans('package::file.line');

Чтобы зарегистрировать этот неймспейс, воспользуйтесь методом loadTranslationsFrom в boot сервис-провайдера пакета. Например, для неймспейcа courier:

public function boot()
{
    $this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier');
}

Папка translations пакета должна содержать языковые подпапки, такие как en, es, ru, etc.

Файлы конфигов

Как правило, при установке пакета необходимо, чтобы пользователь мог перенести файлы конфигов к себе в приложение, чтобы иметь возможность менять там настройки. Для организации этой возможности воспользуйтесь методом publishes в boot сервис-провайдера пакета:

$this->publishes([
    __DIR__.'/path/to/config/courier.php' => config_path('courier.php'),
]);

Теперь когда пользователь после установки вашего пакета выполнит artisan-команду vendor:publish, указанный файл будет скопирован в новое место, а именно в папку конфигов.

Доступ к конфигу осуществляется штатным образом, без неймспейс-нотации:

$value = config('courier.option');

По умолчанию Laravel будет брать конфиг из приложения пользователя. Но вы можете сделать так, что конфиг в области приложения и конфиг в области пакета будут объединены - например, если хотите разрешить пользователям указывать в скопированном конфиге не все опции, а только некоторые, которые они хотят изменить. Для этого воспользуйтесь методом mergeConfigFrom в методе register сервис-провайдера пакета:

$this->mergeConfigFrom(
    __DIR__.'/path/to/config/courier.php', 'courier'
);

Публикация групп файлов

ВЫ можете разделить файлы, которые можно публиковать в приложение, на группы, и публиковать их раздельно. Например, в пакете есть конфиг и миграции:

// Публикация конфига
$this->publishes([
    __DIR__.'/../config/package.php', config_path('package.php')
], 'config');

// Публикация миграций
$this->publishes([
    __DIR__.'/../database/migrations/' => base_path('/database/migrations')
], 'migrations');

Тепрь пользователь может опубликовать у себя, например, только конфиг:

php artisan vendor:publish --provider="Vendor\Providers\PackageServiceProvider" --tag="config"

Файлы маршрутов

Чтобы добавить в приложение маршруты пакета, подключите файл с ними в методе boot сервис-провайдера пакета:

Вставка роутов в сервис-провайдер

public function boot()
{
    include __DIR__.'/../../routes.php';
}

Note: Если ваш пакет использует контроллеры, проследите, чтобы путь до них был корректно задан в composer.json в autoload сессии.