Статьи

Основы создания связок Laravel

Инфраструктура Laravel PHP предлагает свою систему пакетов, которая позволяет разработчикам перераспределять полезные пакеты кода или организовывать приложения в несколько «пакетов» небольших приложений.

В этом уроке мы изучим все тонкости создания и распространения пакетов с нуля.

Пакет Laravel имеет доступ ко всем функциям, которые инфраструктура предлагает своему хост-приложению, включая маршрутизацию, миграции, тесты, представления и множество других полезных функций.

Вот маленький секрет между нами: папка application исходного пакета Laravel также является пакетом, который Laravel называет DEFAULT_BUNDLE .


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

Если ответ на этот вопрос положительный, то сначала я должен убедиться, что кто-то еще не создал подобный пакет или пакет. Кроме как в учебных целях, бессмысленно воссоздавать колесо. Если другой пакет имеет достаточно высокий стандарт для использования в вашем проекте, используйте его и сэкономьте время.

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

Для получения дополнительной информации о Composer, обратитесь к следующим ссылкам:

Если код может быть полезен для других и зависит от платформы Laravel, то у вас есть веская причина для создания нового пакета.

СУХОЙ это название игры.

Если код предоставляет функции, которые вы часто пишете, то имеет смысл создать пакет. СУХОЙ (не повторяйся!) — это название игры.

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

Другим примером может быть административный раздел или «бэкэнд» для вашего сайта. Этот раздел можно легко считать отдельным компонентом от основного приложения, и вместо этого он может быть организован в один или несколько пакетов.

Если это так, вы можете вместо этого написать «Библиотеку». Библиотека — это отдельный класс, который содержит повторно используемый код. Его можно легко добавить в проект Laravel, поместив класс в каталог application/libraries/ , который по умолчанию загружается автоматически.


Давайте создадим простой плагин, который взаимодействует со службой Gravatar и предлагает простой метод создания аватаров различных размеров в нашем основном приложении. Мы также добавим необходимые функции для ввода адреса электронной почты и размера аватара, а также предварительного просмотра соответствующего граватара на странице.

Давайте начнем с создания нового каталога в каталоге /bundles нашего проекта. Мы позвоним в каталог и наш комплект gravvy . Не подливка … подливка.

Давайте добавим гравию в массив bundles внутри application/bundles.php чтобы мы могли проверить его по ходу работы. Мы добавим опцию 'auto' => true в массив, чтобы пакет автоматически запускался, и все создаваемые нами отображения автозагрузчика были доступны для всего Laravel.

1
2
3
4
5
6
return array(
    ‘docs’ => array(‘handles’ => ‘docs’),
    ‘gravvy’ => array(
        ‘auto’ => true
    )
);

Во-первых, нам нужно создать небольшую библиотеку, которая будет извлекать аватар пользователя, используя адрес электронной почты. Создайте новый файл в корне пакета с именем gravvy.php . Давайте создадим класс, называемый Gravvy со статическим методом make() , для репликации схемы именования, используемой собственными библиотеками Laravel.

Метод make() принимает два параметра: адрес электронной почты и целое число, представляющее размер аватара для извлечения.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
 
/**
 * Class to create Gravatar image elements.
 *
 * @author You <[email protected]>
 */
class Gravvy
{
    /**
     * Create a new image element from an email address.
     * @param string $email The email address.
     * @param integer $size The avatar size.
     * @return string The source for an image element.
     */
    public static function make($email, $size = 32)
    {
        // convert our email into an md5 hash
        $email = md5($email);
 
        // return the image element
        return ‘<img src=»http://www.gravatar.com/avatar/’
                    .$email.’?s=’.$size;
    }
}

Корневые каталоги пакетов не загружаются автоматически, поэтому давайте напишем сопоставление, чтобы Laravel знал, где найти класс ‘Gravvy’, когда он в этом нуждается.

При запуске пакета Laravel ищет файл с именем start.php и выполняет его. Итак, давайте создадим один в каталоге нашего нового пакета для хранения наших отображений автоматической загрузки.

1
2
3
4
5
6
7
<?php
 
// /bundles/gravvy/start.php
 
Autoload::map(array(
    ‘Gravvy’ => path(‘bundles’).’/gravvy/gravvy.php’
));

Теперь Laravel узнает, где найти определение для нашего класса Gravvy , и загрузит исходный код, когда он ему понадобится. Очень эффективный!

Метод path() является вспомогательной функцией, которая возвращает абсолютный путь к полезным папкам, используемым Laravel. В этом случае мы используем его для получения абсолютного пути к каталогу пакетов.

Теперь, когда у нас есть рабочий класс Gravvy, мы можем попытаться использовать его из контроллера, чтобы увидеть, получим ли мы ожидаемый результат, но я думаю, что было бы более уместно написать модульный тест.

Как и в случае с хост-приложением, модульные тесты доступны в комплекте. Давайте создадим в tests папке tests папку и добавим новый файл с именем general.test.php .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?php
 
class TestGeneral extends PHPUnit_Framework_TestCase {
 
    /**
     * Test that an avatars output appears as expected.
     *
     * @return void
     */
    public function testAvatarImageIsGenerated()
    {
        // start the gravvy bundle
        Bundle::start(‘gravvy’);
 
        // check that the output matches the expected
        $this->assertEquals(Gravvy::make(‘[email protected]’),
            ‘<img src=»http://www.gravatar.com/avatar/fac3a58aaa455adbcb3f684ccff663b8?s=32″ />’);
    }
 
    /**
     * Test that an avatars output appears as expected when
     * specifying a custom avatar size.
     *
     * @return void
     */
    public function testAvatarImageIsGeneratedWithSize()
    {
        // start the gravvy bundle
        Bundle::start(‘gravvy’);
 
        // check that the output matches the expected
        $this->assertEquals(Gravvy::make(‘[email protected]’, 64),
            ‘<img src=»http://www.gravatar.com/avatar/fac3a58aaa455adbcb3f684ccff663b8?s=64″ />’);
    }
 
}

Выше мы написали два теста PHPUnit: один для проверки результатов генерации аватара с использованием электронной почты, а другой — для определения размера аватара в пикселях. Вы заметите, что мы вызываем Bundle::start('gravvy') чтобы вручную запустить пакет. Это связано с тем, что в настоящее время Laravel не загружает пакеты автоматически через интерфейс командной строки.

Как член основной команды, я хотел бы отметить, что мы намерены решить эту проблему в будущей версии!

Давайте использовать Artisan для запуска наших тестов PHPUnit, набрав команду test и используя имя пакета, gravvy , в качестве параметра.

PHPUnit Результат

Большой! Наши тесты прошли успешно с первой попытки, а наше эго выросло — совсем немного!

Теперь, когда наш класс Gravvy протестирован, люди могут использовать его в своих приложениях! Давайте сделаем пакет еще дальше и создадим пару простых страниц для генерации и предварительного просмотра граватаров. Мы можем использовать этот пример, чтобы узнать, как система маршрутизации обрабатывает пакеты.

Для начала давайте создадим новый контроллер предварительного просмотра для нашего пакета. Нам нужно будет создать каталог controllers внутри пакета, и в него мы добавим новый файл: preview.php .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
 
class Gravvy_Preview_Controller extends Controller
{
    /**
     * Show the preview avatar form.
     */
    public function action_form()
    {
        // load the form view
        return View::make(‘gravvy::form’);
    }
 
    /**
     * Show the resulting avatar.
     */
    public function action_preview()
    {
        // load the preview view
        return View::make(‘gravvy::preview’);
    }
}

Имя контроллера должно начинаться с имени пакета и _Controller — как с обычными контроллерами.

Мы могли бы создать несколько маршрутов для сопоставления действий нашего контроллера с разумными URI, но не лучше ли было бы, если бы мы могли позволить пользователю нашего пакета выбрать базовый URI для использования? Было бы? Давайте сделаем это тогда!

Добавив 'handles' => 'gravvy' ключ-значение 'handles' => 'gravvy' в массив конфигурации комплектов, мы можем позволить пользователю изменять ее без изменения кода самого комплекта. Вот итоговая конфигурация в application/bundles.php .

1
2
3
4
5
6
7
8
9
return array(
 
    ‘docs’ => array(‘handles’ => ‘docs’),
    ‘gravvy’ => array(
        ‘auto’ => true,
        ‘handles’ => ‘gravvy’
    )
 
);

Теперь мы можем использовать заполнитель (:bundle) в наших маршрутах, который будет заменен значением параметра handles . Давайте создадим файл routes.php в корне наших пакетов и добавим несколько маршрутов.

1
2
Route::get(‘(:bundle)/form’, ‘gravvy::preview@form’);
Route::post(‘(:bundle)/preview’, ‘gravvy::preview@preview’);

У нас есть маршрут GET gravvy/form который отображается на действие form контроллера Preview , и POST gravvy/preview который отображается на действие Preview контроллера Preview .

Давайте создадим связанные представления для наших действий контроллера; Вы можете сделать их настолько сложными и красивыми, насколько захотите, но я оставлю их простыми. Сначала создайте папку представлений внутри пакета, как в каталоге приложения.

1
2
3
4
5
6
7
8
9
<!— /bundles/gravvy/views/form.blade.php —>
 
<form action=»{{ URL::to_action(‘gravvy::preview@preview’) }}» method=»POST»>
    <p><label for=»name»>Email Address:</label></p>
    <p><input type=»text» name=»email» /></p>
    <p><label for=»name»>Avatar Size:</label></p>
    <p><input type=»text» name=»size» /></p>
    <p><input type=»submit» value=»Preview!»
</form>

Теперь, когда у нас есть форма, которая будет отправлять поле электронной почты и размера в пару preview@preview controller / action, давайте создадим страницу предварительного просмотра для созданного аватара; мы будем использовать атрибут с именем $element для хранения его источника.

1
2
3
4
<!— /bundles/gravvy/views/preview.blade.php —>
 
<p>{{ $element }}</p>
<p>{{ HTML::link\_to\_action(‘gravvy::preview@form’, ‘< Go Back!’) }}</p>

Теперь мы должны изменить действие preview чтобы использовать данные, отправленные из формы.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
/**
 * Show the resulting avatar.
 */
public function action_preview()
{
    // get data from our form
    $email = Input::get(’email’);
    $size = Input::get(‘size’);
 
    // generate the avatar
    $avatar = Gravvy::make($email, $size);
 
    // load the preview view
    return View::make(‘gravvy::preview’)
        ->with(‘element’, $avatar);
}

Мы извлекаем данные POST и используем их для создания нашего аватара. Мы также должны добавить метод with() в цепочку View::make() чтобы разрешить использование элемента в представлении.

Наконец-то мы можем протестировать нашу систему предварительного просмотра аватаров! Посмотрите на /gravvy/form URI и /gravvy/form ! Все работает как положено.

Gravvy Views

Возможно, это не лучший способ организовать ваш пакет, но он выделяет некоторые полезные вещи, которые возможны. Получайте удовольствие, создавая свои собственные пакеты, и обязательно рассмотрите возможность их публикации на веб-сайте пакетов .


Как только ваш пакет будет в рабочем состоянии, вы можете рассмотреть возможность включения его в каталог пакетов Laravel . Давайте пройдемся по процессу отправки нового пакета.

Во-первых, вам нужно будет иметь учетную запись GitHub , и ваш пакет должен иметь версию в публичном репозитории. GitHub предлагает бесплатные аккаунты с неограниченным количеством публичных репозиториев; Вы найдете их регистрационную форму здесь .

Если вы новичок в управлении версиями с помощью Git, я предлагаю прочитать большую серию статей о Git прямо здесь, на Nettuts + .

После того, как вы настроите свою учетную запись и код, убедитесь, что в ветке ‘master’ находится последняя версия вашего пакета, а корень вашего пакета (где будет start.php ) является корнем хранилище, а не подкаталог.

Затем посетите веб-сайт Laravel Bundles Directory и войдите в систему, используя свои учетные данные GitHub.

GitHub Войти

Теперь нажмите кнопку «Отправить пакет», выберите свой репозиторий пакетов в раскрывающемся меню и нажмите кнопку «Продолжить».

Форма регистрации довольно проста, но вот некоторые «ошибки», которые вы можете не заметить.

имя

Имя — это строчное ключевое слово, которое используется для установки вашего приложения. Это должно быть короткое, но точное слово для описания вашей связки.

Резюме / Описание

Эти поля могут содержать содержимое формата уценки. Поэтому не стесняйтесь копировать содержимое из файла GitHub README.md .

Зависимости / Теги

Используйте кнопку с запятой на клавиатуре для разделения тегов и зависимостей. Поле зависимостей должно содержать ключевое слово short install для пакета, который существует как зависимость для пакета, который вы отправляете.

активный

Поле Active просто определяет, будет ли пакет отображаться для других пользователей. Вы все еще можете установить неактивные пакеты по их ключевому слову install для тестирования. Установите в этом поле значение «Да», только если вы рады, что другие люди используют ваш пакет.

Как только вы нажмете кнопку «Сохранить», ваш пакет будет отправлен и, если он помечен как «Активный», появится в списках пакетов. Вы всегда можете отредактировать список ваших пакетов позже.


Пакеты, которые были предоставлены сообществу Laravel, перечислены в каталоге пакетов на http://bundles.laravel.com .

Вы можете просматривать пакеты по категориям или использовать функцию поиска, чтобы найти пакет, который вы ищете. Как только вы нашли пакет, соответствующий вашим требованиям, посмотрите на вкладку «Установка» в профиле пакета, чтобы найти ключевое слово install.


Если у вас есть ключевое слово install для пакета, вы можете установить его из базы вашего проекта с помощью интерфейса командной строки Artisan и его команды bundle:install . Например..

Artisan свяжется с API комплектов, чтобы узнать путь к репозиторию комплектов GitHub и репозиториям всех его зависимостей. Затем он загрузит исходные пакеты прямо с GitHub и извлечет их в каталог /bundles .

Вам нужно будет вручную добавить имя пакета в массив в application/bundles.php чтобы пакет стал активным.

1
2
3
4
return array(
    ‘docs’ => array(‘handles’ => ‘docs’),
    ‘bob’
);

В некоторых ситуациях вам может понадобиться добавить дополнительную информацию к этой записи array чтобы упростить автоматический запуск или направление определенных маршрутов в пакет. Автор предоставит эту дополнительную информацию в описании комплектов, если это так.


Спасибо за чтение и наслаждайтесь созданием ваших собственных пакетов с Laravel! Если вы хотите узнать больше о Laravel, не забудьте забрать мою книгу !