{{TOC}} {{DOCVER 4.0=0da300f6445bec5a70d007f503834fce957b065b 16.10.2014 5:19:26, 4.1=efd541a0b218b1c6aafb73f0051c18ed150e3c24 25.05.2014 6:21:03}} == Введение == Пакеты (//packages//) - основной способ добавления нового функционала в Laravel. Пакеты могут быть всем, чем угодно - от классов для удобной работы с датами типа ((https://github.com/briannesbitt/Carbon Carbon)) до целых библиотек ((ВП:Бинарная диаграмма решений==BDD-тестирования)) наподобие ((https://github.com/Behat/Behat Behat)). Конечно, всё это разные типы пакетов. Некоторые пакеты самостоятельны, что позволяет им работать в составе любой библиотеки, а не только Laravel. Примерами таких отдельных пакетов являются Carbon и Behat. Любая из них может быть использована в Laravel после простого их указания в файле %%(t)composer.json%%. С другой стороны, некоторые пакеты разработаны специально для использования в Laravel. В предыдущей версии Laravel такие пакеты назывались //bundles//. Они могли содержать ((docs/v4/routing маршруты)), ((docs/v4/controllers контроллеры)), ((docs/v4/templates шаблоны)), ((docs/v4/configuration настройки)) и ((docs/v4/migrations миграции)), специально рассчитанные для улучшения приложения на Laravel. Так как для разработки самостоятельных пакетов нет особенных правил, этот раздел документации в основном посвящён разработке именно пакетов для Laravel. Все пакеты Laravel распространяются через ((http://packagist.org/ Packagist)) и ((http://getcomposer.org/ Composer)), поэтому нужно изучить эти прекрасные средства распространения кода для PHP. == Создание пакета == Простейший способ создать пакет для использования в Laravel - с помощью команды %%(t)workbench%% интерфейса ((docs/v4/artisan Artisan)). Сперва вам нужно установить несколько параметров в файле %%(t)app/config/workbench.php%%. Там вы найдёте такие настройки как %%(t)name%% и %%(t)email%%. Их значения будут использованы при генерации %%(t)composer.json%% для вашего нового пакета. Когда вы заполнили эти значения, то всё готово для создания заготовки. **Использование команды %%(t)workbench%%** %%(sh) php artisan workbench vendor/package --resources %% Имя поставщика (//vendor//) - способ отличить ваши собственные пакеты от пакетов других разработчиков. К примеру, если я, Тейлор Отуелл (!!(tl_note) автор Laravel - //прим. пер.//!!), хочу создать новый пакет под названием "Zapper", то имя поставщика может быть %%(t)Taylor%%, а имя пакета - %%(t)Zapper%%. По умолчанию команда %%workbench%% сгенерирует заготовку в общепринятом стиле пакетов, однако команда %%(t)resources%% может использоваться для генерации специфичных для Laravel папок, таких как %%(t)migrations%%, %%(t)views%%, %%(t)config%% и прочих. Когда команда %%(t)workbench%% была выполнена, ваш пакет будет доступен в папке %%(t)workbench%% текущей установки Laravel. Дальше вам нужно зарегистрировать %%ServiceProvider%% - ((docs/v4/ioc#поставщики поставщика услуг)), который был создан для нового пакета. Это можно сделать, добавив его к массиву %%(t)providers%% файла %%(t)app/config/app.php%%. Это укажет Laravel, что пакет должен быть загружен при запуске приложения. Имена классов поставщики услуг следуют схеме %%[Package]ServiceProvider%%. Таким образом, в примере выше мы должны были бы добавить %%Taylor\Zapper\ZapperServiceProvider%% к массиву %%(t)providers%%. Как только поставщик зарегистрирован вы готовы к началу разработки. Однако перед этим рекомендуется ознакомиться с материалом ниже, чтобы узнать о структуре пакетов и ((#процесс+))ом их разработки. .(alert) Если ваш поставщик услуг не может быть найден, выполните ((#процесс команду)) %%(sh)php artisan dump-autoload%% из корня вашего приложения. == Структура пакетов == При использовании команды %%(t)workbench%% ваш пакет будет настроен согласно общепринятым нормам, что позволит ему успешно интегрироваться с другими частями Laravel. **Базовая структура папок внутри пакета** %%(t) /src /Vendor /Package PackageServiceProvider.php /config /lang /migrations /views /tests /public %% Давайте познакомимся с этой структурой поближе. Папка %%(t)src/Vendor/Package%% - хранилище всех классов вашего пакета, включая %%ServiceProvider%%. Папки %%(t)config%%, %%(t)lang%%, %%(t)migrations%% и %%(t)views%% содержат соответствующие ресурсы для вашего пакета (!!(tl_note)настройки, языковые строки, миграции и шаблоны - //прим. пер.//). Пакеты, как и обычные приложения, могут содержать любой из этих ресурсов. == Поставщики услуг == ((docs/v4/ioc#поставщики Поставщик услуг)) - просто начальный загрузчик для пакета. По умолчанию они могут содержать два метода: %%boot()%% и %%register()%%. Внутри этих методов вы можете выполнять любой код - подключать файл с ((docs/v4/routing маршрутами)), регистрировать связи в ((docs/v4/ioc контейнере IoC)), устанавливать обработчики ((docs/v4/events событий)) или что-то ещё. Метод %%register()%% вызывается сразу после регистрации поставщика услуг, тогда как команда %%boot()%% вызывается только перед тем, как будет обработан запрос. Таким образом, если вашему поставщику требуется другой поставщик, который уже был зарегистрирован, или вы перекрываете услуги, зарегистрированные другим поставщиком - вам нужно использовать метод %%boot()%%. При создании пакета с помощью команды %%(t)workbench%%, метод %%boot()%% уже будет содержать одно действие: %% $this->package('vendor/package'); %% Этот метод позволяет Laravel определить, как правильно загружать шаблоны, настройки и другие ресурсы вашего приложения. Обычно вам не требуется изменять эту строку, так как она настраивает пакет в соответствии с обычными нормами. По умолчанию после регистрации пакета его ресурсы будут доступны через часть **package** из пары %%(t)vendor/package%%. Однако, вы можете передать второй аргумент в метод %%package()%%, чтобы переопределить это поведение. Например: %% // Передача пользовательского пространства имён (custom namespace) в метод package $this->package('vendor/package', 'custom-namespace'); // Ресурсы пакета теперь доступны через custom-namespace $view = View::make('custom-namespace::foo'); %% Для поставщиков услуг не существует "места по умолчанию". Вы можете поместить их в любое место, возможно, сгруппировав в пространство имён %%Providers%% в папке %%(t)app%%. Этот файл может располагаться где угодно - главное, чтобы Composer мог загрузить его с помощью ((http://getcomposer.org/doc/01-basic-usage.md#autoloading auto-loading facilities)). %%(DOCNEW 4.1=efd541a0b218b1c6aafb73f0051c18ed150e3c24 25.05.2014 6:21:03) Если вы изменили расположение ресурсов вашего пакета, таких как файлы конфигурации или представления, вы должны передать третий аргумент в метод %%package()%%, который указывает на местоположение ваших ресурсов: ~%% $this->package('vendor/package', null, '/path/to/resources'); ~%% == Отложенные поставщики == Если вы создаёте поставщик услуг, который не регистрирует какие-либо ресурсы, такие как настройки или представления, вы можете сделать его "отложенным". Отложенный поставщик услуг загружается и регистрируется только тогда, когда одна из услуг, которые он предоставляет, на самом деле необходима IoC-контейнеру приложения. Если ни одна из услуг провайдера не требуется для прохождения данного запроса, поставщик вообще не загружается. Чтобы отложить выполнение вашего поставщика услуг, установите его свойство **defer** в значение **true**: ~%% protected $defer = true; ~%% Затем вам надо переопределить метод %%provides()%% из базового класса %%(t)Illuminate\Support\ServiceProvider%% и возвратить массив всех привязок, которые ваш провайдер добавляет в IoC-контейнер. Например, если ваш провайдер регистрирует %%(t)package.service%% и %%(t)package.another-service%% в IoC-контейнере, то ваш метод %%provides()%% должен выглядеть следующим образом: ~%% public function provides() { return array('package.service', 'package.another-service'); } ~%% %% == Соглашения == При использовании ресурсов из пакета, таких как настройки или шаблоны, то для отделения имени пакета обычно используют двойное двоеточие (%%(t)::%%). **Загрузка шаблона из пакета** %% return View::make('package::view.name'); %% **Чтение параметров настройки в пакете** %% return Config::get('package::group.option'); %% .(alert) **Внимание:** если ваш пакет содержит ((docs/v4/migrations миграции)), подумайте о том, чтобы её имя начиналось с имени пакета для предотвращения возможных конфликтов с именами классов в других пакетах. == Процесс разработки == При разработке пакета бывает удобно работать в контексте вашего приложения, просматривая и экспериментируя с шаблонами и пр. Для начала сделайте чистую установку Laravel, затем используйте команду %%(t)workbench%% для создания структуры пакета. После того, как пакет создан вы можете сделать %%(sh)git init%% изнутри папки %%(t)workbench/[vendor]/[package]%%, а затем - %%(sh)git push%% для отправки пакета напрямую в хранилище. Это позволит вам удобно работать в среде приложения без необходимости постоянно выполнять команду %%(sh)composer update%%. Теперь, когда ваши пакеты расположены в папке %%(t)workbench%%, у вас может возникнуть вопрос: как Composer узнает, каким образом загружать эти пакеты? Laravel автоматически сканирует папку %%(t)workbench%% на наличие пакетов, загружая их файлы при запуске приложения. Если вам нужно зарегистрировать файлы автозагрузки вашего пакета, можно использовать команду %%(sh)php artisan dump-autoload%%. Эта команда пересоздаст файлы автозагрузки для корневого приложения, а также всех пакетов в %%(t)workbench%%, которые вы успели создать. **Выполнение команды автозагрузки** %%(sh) php artisan dump-autoload %% == Маршрутизация в пакетах == В предыдущей версии Laravel для указания URL, принадлежащих пакету, использовался параметр %%(t)handles%%. Начиная с Laravel 4 пакеты могут обрабатывать любой URI. Для загрузки файлов с маршрутами просто подключите его через %%include%% из метода %%boot()%% вашего поставщика услуг. **Подключение файла с маршрутами из поставщика услуг** %% public function boot() { $this->package('vendor/package'); include __DIR__.'/../../routes.php'; } %% .(alert) Если ваш поставщик использует ((docs/v4/controllers контроллеры)), вам нужно убедиться, что они верно настроены в секции автозагрузки вашего файла %%(t)composer.json%%. == Настройки пакетов == **Чтение настроек пакета** Некоторые пакеты могут требовать файлов настройки. Эти файлы должны быть определены аналогично файлам настроек обычного приложения. И затем, при использовании стандартной команды для регистрации ресурсов пакета %%$this->package()%%, они будут доступны через обычный синтаксис с двойным равно (%%(t)::%%) : %% Config::get('package::file.option'); %% **Чтение параметров из единственного файла настроек** Однако если ваш пакет содержит всего один файл с настройками, вы можете назвать его %%(t)config.php%%. Когда это сделано, то его параметры становятся доступными напрямую, без указания имени файла: %% Config::get('package::option'); %% **Ручная регистрация пространства имён ресурсов** Иногда вам может быть нужно зарегистрировать ресурсы пакета вне обычного вызова %%$this->package()%%. Обычно это требуется, если ресурс расположен не в стандартном месте. Для регистрации ресурса вручную вы можете использовать методы %%addNamespace()%% классов %%View%%, %%Lang%% и %%Config%%: %% View::addNamespace('package', __DIR__.'/path/to/views'); %% Как только пространство имён было зарегистрировано, вы можете использовать его имя и двойное двоеточие для получения доступа к ресурсам: %% return View::make('package::view.name'); %% Параметры методов %%addNamespace()%% одинаковы для классов %%View%%, %%Lang%% и %%Config%%. == Перекрытие файлов настроек == Когда другие разработчики устанавливают ваш пакет им может потребоваться перекрыть некоторые из настроек. Однако если они сделают это напрямую в коде вашего пакета, изменения будут потеряны при следующем обновлении пакета через Composer. Вместо этого нужно использовать команду %%(t)config:publish%% интерфейса ((docs/v4/artisan Artisan)): %%(t) php artisan config:publish vendor/package %% Эта команда скопирует файлы настроек вашего приложения в папку %%(t)app/config/packages/vendor/package%%, где разработчик может их безопасно изменять. .(alert) Разработчик также может создать настройки, специфичные для каждой ((docs/v4/configuration#сред+а))ы, поместив их в %%(t)app/config/packages/vendor/package/environment%%. %%(DOCNEW 4.1=efd541a0b218b1c6aafb73f0051c18ed150e3c24 25.05.2014 6:21:03) == Представления пакетов == Когда вы используете пакет в вашем приложении, вам может захотеться настроить его представления. Вы легко можете экспортировать представления пакета в вашу папку %%(t)app/views%% с помощью Artisan-команды %%(sh)view:publish%%: ~%% php artisan view:publish vendor/package ~%% Эта команда переместит представления пакета в папку %%(t)app/views/packages%%. Если эта папка не существует, она будет создана при запуске команды. После того, как представления будут опубликованы, вы можете настроить их на свой вкус! Экспортированные представления автоматически получат приоритет над собственными файлами представлений пакета. %% == Миграции пакетов == **Создание миграций для пакета в %%(t)workbench%%** Вы можете легко создавать и выполнять миграции для любого из ваших пакетов. Для создания миграции в %%(t)workbench%% используется команда %%(t)--bench%%: %%(sh) php artisan migrate:make create_users_table --bench="vendor/package" %% **Выполнение миграций пакета в %%(t)workbench%%** %%(sh) php artisan migrate --bench="vendor/package" %% **Выполнение миграций установленного пакета** Для выполнения миграции для законченного пакета, который был установлен через Composer в папку %%(t)vendor%%, вы можете использовать ключ %%(t)--package%%: %%(sh) php artisan migrate --package="vendor/package" %% == Внешние ресурсы пакетов == **Перемещение ресурсов пакета в папку %%(t)public%%** Некоторые пакеты могут содержать внешние ресурсы, такие как JavaScript-код, CSS и изображения. Однако мы не можем обращаться к ним напрямую через папки %%(t)vendor%% и %%(t)workbench%%, поэтому нам нужно перенести их в папку %%(t)public%% нашего приложения. Команда %%(t)asset:publish%% выполнит это за вас: %%(sh) php artisan asset:publish php artisan asset:publish vendor/package %% Если пакет находится в %%(t)workbench%%, используйте ключ %%(t)--bench%%: %%(sh) php artisan asset:publish --bench="vendor/package" %% Эта команда переместит ресурсы в %%(t)public/packages%% в соответствии с именем поставщика и пакета. Таким образом, внешние ресурсы пакета %%(t)userscape/kudos%% будут помещены в папку %%(t)public/packages/userscape/kudos%%. Соблюдение этого соглашения о путях позволит вам использовать их в коде шаблонов вашего пакета. == Публикация пакетов == Когда ваш пакет готов к опубликованию, вам нужно отправить его в хранилище ((http://packagist.org/ Packagist)). Если пакет предназначен для Laravel рекомендуется добавить тег **laravel** в файл %%(t)composer.json%% вашего пакета. Также обратите внимание, что полезно присваивать вашим выпускам номера (//tags//), позволяя другим разработчикам использовать стабильные версии в их файлах %%(t)composer.json%%. Если стабильный выпуск ещё не готов, можно добавить директиву Composer %%(t)branch-alias%%. Когда ваш пакет опубликован вы можете свободно продолжать его разработку в среде вашего приложения, созданной командой %%(t)workbench%%. Это отличный способ, позволяющий удобно продолжать над ним работу даже после публикации. Некоторые организации создают собственные частные хранилища пакетов для своих сотрудников. Если вам это требуется, изучите документацию проекта ((http://github.com/composer/satis Satis)), созданного командой разработчиков Composer.