Перейти к содержимому



ЛП: Расширение Yii2-binds

#1 fedornabilkin

fedornabilkin
  • Модератор
  • 1 089 сообщений
  • Репутация: 171
0

Отправлено 12 Март 2018 - 22:30

Немного теории и структура

Расширение подразумевает использование глобальных uid по всему проекту, что позволяет создавать аккуратные и "чистые" модели данных. При этом данный подход может накладывать некоторые ограничения и они обязательно всплывут в процессе разработки. К этому надо быть готовым или постараться спроектировать сайт с оглядкой на использование расширения. Модель - это строка со всеми данными в таблице БД. Расширение лежит на гитхабе.

 

  1. Uids - основная таблица, которая хранит идентификаторы сущностей, относящихся к контентной части проекта.
  2. Post - таблица (родительская) с записями (используем минимальный набор полей).
  3. Catalog - таблица для формирования дерева элементов (категории, тэги...), которые можно привязать к родительской таблице.
  4. Seo - таблица (дочерняя) с информацией сео.
  5. Binds - таблица для связи родительских таблиц с таблицей catalog.

Обязательным условием является наличие поля uid в "контентных" таблицах, модели которых будем связывать через промежуточную таблицу или между собой, через поле uid_content. Поле uid должно иметь внешний ключ на поле id таблицы uids (delete CASCADE), потому что при удалении любой контентной модели будет удаляться запись из таблицы uids, а внешние ключи удалят саму модель, все связанные модели и связи из таблицы binds. Структура БД будет выглядеть приблизительно так:

yii2-binds-db.png

 

Таблицы post и news являются родительскими, catalog, comment и seo - дочерними. Т.к. к родительским моделям можно привязать только одну модель (в народе hasOne) из seo и из comment, привязывать их будем через поле uid_content в дочерних таблицах. В таблице catalog хранятся модели тэгов, категорий и т.д., поэтому к родительским моделям можно привязать несколько моделей из catalog (в народе hasMany). При этом один тэг можно привязать к нескольким моделям post и их же к моделям news. Привязку hasMany осуществляем в таблице binds.

 

В таблице binds внешние ключи указывают из двух полей (uid - модель (post,news), к которой привязываем и uid_bind - модель (catalog), которую привязываем) на поле id таблицы uids. Сделано это для того, чтобы разорвать связи удаляемой (родительской) модели с моделями из catalog.

 

Принцип создания и удаления моделей

При создании контентной модели выполняется запись в таблицу uids, в которую пишем id юзера (created_by), время создания (created_at), название таблицы создаваемой модели (бонусом идут статусы состояния). После создания записи в uids, свеженький id присваиваем создаваемой модели (пишем в поле uid). 

 

При удалении модели необходимо получить uid (равен uids.id) и выполнить удаление записи из таблицы uids.

В случае удаления модели из каталога, достаточно будет удалить только запись из таблицы uids и все связи удаляться автоматически. При удалении родительской модели, также необходимо позаботиться об удалении дочерних моделей (hasOne). Дочерние модели (hasMany) удалять нельзя, потому что они могут использоваться в других родительских моделях.

 

Для надежности все обязательные таблицы в миграциях расширения названы с префиксом bind_ и возможностью добавить свой префикс.

 

Скрины для наглядности

Управление каталогом

yii2-binds-catalog-manager.png

Добавление данных модели

yii2-binds-post-widgets.png

 

Настройка файла конфигурации

В секцию components необходимо добавить следующий код для генерации seo meta-tags

    'components' => [

        ...

        'view' => [
            'as seo' => [
                'class' => \fedornabilkin\binds\behaviors\SeoBehavior::class,
            ],
        ],
    ],

В секцию modules подключить модули для управления каталогом (расширение использует treemanager от kartik)

    'modules' => [

        ...

        'binds' => [
            'class' => 'fedornabilkin\binds\Module',
        ],
        'treemanager' => [
            'class' => 'kartik\tree\Module',
            'dataStructure' => [
                'keyAttribute' => 'id',
            ],
        ],
    ],

Класс модели

Класс контентной модели должен быть унаследован от fedornabilkin\binds\models\base\BindModel и может выглядеть следующим образом

Спойлер

 

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

 

Форма заполнения данными модели имеет такой вид (подключены Status, Seo и Binds виджеты)

Спойлер

 

Основные реляции объявлены в BindModel, поэтому получение данных связанных моделей может выглядеть следующим образом:

$model = Post::findOne(123); // получаем модель с id 123

$model->uids->created_at; // время создания
$model->uids->created_by; // id пользователя

// массив тэгов (моделей из таблицы catalog),
// привязанных к модели Post
$tags = $model->getCatalogByNickname('tags')->all();
foreach ($tags as $index => $tag) {
    echo $tag->name . ' '; // название тэга
}

$posts = Post::findFiltered()->all(); // получит все модели со статусом 1 (Опубликован)

 

 

Сообщение отредактировал fedornabilkin: 12 Март 2018 - 23:14

  • 0

Надо обсудить предложение. А тут знакосчиталка считает знаки. Про Yii2 написано.



robot

robot
  • Пользователь PRO
  • 2 652 сообщений
  • Репутация: 85
Советую обратить внимание на следующее:
  1. ЛП: Установка Yii2
  2. ЛП: миграции в yii2, работа с базой данных
  3. ЛП: Генерация кода в Yii2
  4. ЛП: Установка сторонних модулей в Yii2
  5. ЛП: Расширение Yii2-redirect

Оформление форума – IPBSkins.ru