Публикации - Laravel

Решение типовых задач на Laravel - Разработка пакетов

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

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

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

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

Простейший способ создать пакет для использования в Laravel - с помощью команды workbench инструмента командной строки Artisan. Сперва вам нужно установить несколько параметров в файле app/config/workbench.php. Там вы найдёте такие настройки, как name и email. Их значения будут использованы при генерации composer.json для вашего нового пакета. Когда вы заполнили эти значения, то всё готово для создания заготовки.

 Использование команды workbench. Листинг 30.1

 php artisan workbench vendor/package --resources

Где vendor - имя поставщика услуг, package - это имя создаваемого вами пакета.

К примеру, мой логин на github — mikhalkevich, а создаваемый пакет я хочу назвать obmenka, соответственно, я должен выполнить команду:

Создание пакета mikhalkevich/obmenka. Листинг 30.2

php artisan workbench --resources mikhalkevich/obmenka

Где флаг resourses говорит, что необходимо так же создать специфичные для Laravel папки: migrations, views, config и тд.

Чтобы Laravel при запуске приложения автоматически подгружал наш пакет, нам необходимо в файл app/config/app.php в массив providers добавить строчку:

Добавление пакета в массив providers конфигурационного файлаapp.php. Листинг 30.3

'Mikhalkevich\Obmenka\ObmenkaServiceProvider',

Имена классов поставщика услуг следуют схеме [Package]ServiceProvider, но перед этим указывается полный namespace класса.

Структура пакета

В папке src мы можем видеть знакомую структуру папок, названия которых говорят сами за себя.

Заметим, что в папке src/Mikhalkevich/Obmenka/ хранится класс нашего поставщика услуг, а также туда стоит класть все вспомогательные классы нашего пакета.

Посмотрим на класс ObmenkaServiceProvider. Метод register будет вызван, как только пакет был зарегистрирован, а метод boot вызывается каждый раз перед обработкой запроса.

Создадим в папке src  нашего пакета файл routes.php с двумя роутами:

 Роуты файла routes.phpсоздаваемого пакета. Листинг 30.4

Route::get('/blog/', array(
            'as' => 'posts_list',
            'uses' => 'Cherryoff\Nbblog\NbblogController@showList'
        ));

 
Route::get('/blog/{link}', array(
            'as' => 'post',
            'uses' => 'Cherryoff\Nbblog\NbblogController@showPost'
        ))->where('link', '[A-Za-z-_]+');

Где в качестве контроллера указываем полный путь до нашего еще не созданного контроллера. Далее в папке controllers создадим контроллер ObmenkaController со следующим содержимым:

Содержимое ObmenkaController. Листинг 30.5



			

 
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\URL;

 
class ObmenkaController extends Controller {

 
        public function showList()
        {
            return 'Posts list';
        }

 
        public function showPost($link)
        {
            return 'Get post:'.$link;
}

 
    }

Теперь у нас прописаны пути и контроллер должен отвечать нам простыми сообщениями. Но если мы перейдем по ссылке sandbox.local/blog/, то получим исключение о том, что страница не найдена. Все дело в том, что приложение не знает о том, что у нашего пакета есть свои пути, и, чтобы исправить это, подключим файл routes.php в конце метода boot класса ObmenkaServiceProvider:

Подключение маршрутов пакета. Листинг 30.6

 include __DIR__.'/../../routes.php';

 

 

 

Чтобы показать composer где искать необходимые файлы, добавим в composer.json (нашего пакета!!!) в секцию classmap строчку «src/controllers», после чего выполним:

Обновление классов автозагрузок. Листинг 30.7

composer dump-autoload

Теперь роуты должны работать.

Далее, создадим папку models и файл Post.php в ней. Листинг файла представлен ниже:

 Модель Post. Листинг 30.8

 Cherryoff\Obmenka;

 
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Config;

 
/**
 * Модель записи в блоге
 */

 
classPostextendsModel {

 
protected$table = 'posts';
//Добавляем в выдачу вычисляемое поле
protected$appends = array('cut');
//Делаем поля доступными для автозаполнения
protected$fillable = array('header', 'link', 'article');

 
//Некоторые правила валидиции
publicstatic$rules = array(
'header' =>'required|max:256',
'link' =>'required|between:2,32|unique',
'article' =>'required'
    );

 
publicfunctiongetCutAttribute(){
return Str::limit($this->attributes['article'], 120);
}

 
}

 

Теперь необходимо добавить папку models в секцию автозагрузки composer.json (нужно добавить выше строчки "src/controllers") нашего проекта и выполнить composer dump-autoload так же, как мы это делали в случае с контроллером.

Строкой в консоли создадим миграцию для нашего пакета:

Создаем миграцию для пакета. Листинг 30.9

php artisan migrate:make create_obmenka_posts_table 
--bench="mikhalkevich/obmenka"

В папке src/migrations/ появился класс только что созданной миграции. В его методе up пропишем:

Файл миграции. Листинг 30.10

 Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('link', 32);
            $table->string('header', 256);
            $table->text('article');
$table->timestamps();
            $table->softDeletes();
});

В методе down():

 Содержимое метода down(). Листинг 30.11

Schema::dropIfExists('posts');

Выполняем миграцию:

Выполнение миграции. Листинг 30.12

 php artisan migrate --bench="mikhalkevich/obmenka"

Теперь заполним только что созданную таблицу начальными данными. Для этого в папке src создадим папку seeds с файлом ObmenkaSeeder.php со следующим содержимым:

Seeds. Листинг 30.13



			

 
use Illuminate\Database\Seeder;

 
class NbblogSeeder extends Seeder {

 
    public function run()
    {
        $posts = [
            [
                'header'=>'Header post number one',
                'link'=>'one',
                'article'=>'Body text',
            ],
            [
                'header'=>'Very important news',
                'link'=>'news',
'article'=>'Body text',
            ],
        ];

 
        foreach ($posts as $post){
            Post::create($post);
}
    }

 
}   

Добавим папку seeds в секцию автозагрузки composer.json и снова выполним dump-autoload.

Теперь загрузим начальные данные командой:

Загрузка начальных данных. Листинг 30.14

 php artisan db:seed --class="\Mikhalkevich\Obmenka\ObmenkaSeeder"

Создадим шаблоны видов для нашего блога, разместив их в папке src/views:


 

 

 
        @yield('title')

 

 

 

 


 

 

 
 

 

My simple blog

Just blog package for Laravel

 

 

 

 

 

 

 
    @yield('content')

 

 

 

Базовый шаблон. Листинг 30.15


 

 

В контроллере будем подключать такой подшаблон:

List.blade.php. Листинг 30.16

@section('title')
    List
@stop

 
@section('content')
Number of posts in the blog: {{$count}}

 
        @forelse($posts as $post)
            @include('nbblog::preview')
        @empty

 
  • No records

@endforelse

 
@stop

Preview.blade.php

Preview.blade.php. Листинг 30.17


 
  •  
{{$post->created_at}}

 

{{$post->header}}


 

{{$post->cut}}


 

Еще один файл подшаблона, post.blade.php

Post.blade.php. Листинг 30.18

@section('title')
    {{$header}}
@stop

 
@section('content')

 
 
{{$created_at}}

 

{{$header}}


 

 

            {{$article}}

 

 


 
@stop

Итак, с шаблонами закончено, теперь можно приступить к наполнению их данными. Для этого создадим файл viewComposers.php прямо в папке src. (Мы можем создать этот файл в любом месте нашего пакета, главное, не забыть его подключить).

ViewComposers.php. Листинг 30.19



			
    /**
     * Не забываем использовать имя своего пакета перед названием вида
*/
    View::composer(array('obmenka::list', 'obmenka::post'), 
function($view){
$view->with('uri', 'blog');
    });

 
    View::composer('obmenka::list', function ($view) {
        $view->with('count', \Mikhalkevich\Obmenka\Post::count())->with('posts', \Mikhalkevich\Obmenka\Post::all());
});

Мы только что привязали переменную uri к шаблону списка постов и шаблону поста (в дальнейшем, когда мы будем получать эту переменную из настроек, нам будет удобнее передавать ее в виды в одном месте), и вместе с шаблоном списка постов мы отдаем сразу все записи.

Теперь необходимо подключить созданный файл в классе нашего поставщика услуг (src/Cherryoff/Nbblog/NbblogServiceProvider.php) так же, как мы это делали с файлом route.php.

 Подключение файла ViewComposers. Листинг 30.20

 include __DIR__.'/../../viewComposers.php';

Меняем класс нашего контроллера

 Конроллер NbblogController. Листинг 30.21

 class NbblogController extends Controller {

 
        public function __construct(){
            $this->layout = View::make('nbblog::layout');
        }

 
        public function showList()
        {
            $this->layout->content = View::make('nbblog::list');
        }

 
        public function showPost($link)
        {
            $post = Post::where('link', '=', $link)->firstOrFail();
            $this->layout->content = View::make('nbblog::post', $post);
}
}

В папке public нашего пакета создадим папку css и добавим туда файл main.css.

Опубликуем внешние ресурсы нашего пакета командой:

 Публикация внешних ресурсов пакета. Листинг 30.22

php artisan asset:publish --bench="mikhalkevich/obmenka"

В папке public нашего приложения появился файл main.css, который расположился в папке packages/cherryoff/nbblog/css/. Так laravel делает со всеми внешними ресурсами пакетов. А значит, что это соглашение об именовании внешних ресурсов поможет нам обратится к этому файлу из нашего шаблона.

 Путь к таблице стилей нашего пакета. Листинг 30.23

 /packages/mikhalkevich/obmenka/css/main.css

Количество комментариев: 0

Для того, чтобы оставить коментарий необходимо зарегистрироваться


Изображения Видео

1. Подключение CKEditor https://artisansweb.net/install-use-ckeditor-laravel/#comments
2. Регистрация и авторизация https://know-online.com/post/laravel-reg
3. Что нового в Laravel 8 https://sergeymukhin.com/blog/chto-novogo-v-laravel-80
4. Авторизация Sanctum <iframe width="560" height="315" src="https://www.youtube.com/embed/MT-GJQIY3EU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>