X   Сообщение сайта
(Сообщение закроется через 3 секунды)



 

Здравствуйте, гость (

| Вход | Регистрация )

Открыть тему
Тема закрыта
> ЛП: Расширение Yii2-binds
fedornabilkin
fedornabilkin
Topic Starter сообщение 12.3.2018, 23:30; Ответить: fedornabilkin
Сообщение #1


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

  1. Uids - основная таблица, которая хранит идентификаторы сущностей, относящихся к контентной части проекта.

  2. Post - таблица (родительская) с записями (используем минимальный набор полей).

  3. Catalog - таблица для формирования дерева элементов (категории, тэги...), которые можно привязать к родительской таблице.

  4. Seo - таблица (дочерняя) с информацией сео.

  5. Binds - таблица для связи родительских таблиц с таблицей catalog.

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


Таблицы 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_ и возможностью добавить свой префикс.

Скрины для наглядности
Управление каталогом
Прикрепленное изображение

Добавление данных модели
Прикрепленное изображение


Настройка файла конфигурации
В секцию 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 и может выглядеть следующим образом
Развернуть/Свернуть


<?php

namespace frontend\models;

use fedornabilkin\binds\behaviors\BindBehavior;
use fedornabilkin\binds\behaviors\SeoBehavior;
use fedornabilkin\binds\models\base\BindModel;

/**
* This is the model class for table "post".
*
* @property int $id
* @property int $uid
* @property string $title
* @property string $post
*/
class Post extends BindModel
{

public function behaviors()
{
return array_merge_recursive(parent::behaviors(), [
'SeoBehavior' => [
'class' => SeoBehavior::class,
],
'BindsBehavior' => [
'class' => BindBehavior::class,
'tree' => [
// никнэймы корневых узлов дерева каталога
'nicknames' => [
'visible' => [
'multiple' => false, // единичный или множественный выбор
],
'categories' => [
'multiple' => false,
],
'tags' => [
'multiple' => true,
'asDropdown' => false, // развернутое состояние
],
],
],
],
]);
}

/**
* @inheritdoc
*/
public static function tableName()
{
return 'post';
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['post'], 'string'],
[['title'], 'string', 'max' => 150],
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'title' => 'Title',
'post' => 'Post',
];
}

// модели hasOne
public function getChildModels()
{
return array_merge(parent::getChildModels(), [
'comment' => Comment::class,
]);
}
}




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

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


<?php

use fedornabilkin\binds\models\Catalog;
use fedornabilkin\binds\models\Uid;
use yii\helpers\Html;

use kartik\tree\TreeViewInput;
use yii\widgets\ActiveForm;

/* @var $this yii\web\View */
/* @var $model frontend\models\Post */

$this->title = 'Update Post';
$this->params['breadcrumbs'][] = ['label' => 'Posts', 'url' => ['index']];
$this->params['breadcrumbs'][] = ['label' => $model->title, 'url' => ['view', 'id' => $model->id]];
$this->params['breadcrumbs'][] = 'Update';
?>
<div class="post-update">

<h1><?= Html::encode($this->title) ?></h1>

<?php $form = ActiveForm::begin(); ?>
<div class="row">
<div class="col-xs-12 col-sm-8">

<?= \fedornabilkin\binds\widgets\status\StatusWidget::widget(['model' => $model])?>

<?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?>

<?= $form->field($model, 'post')->textarea(['rows' => 6]) ?>

<div class="form-group">
<?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
</div>

<?= \fedornabilkin\binds\widgets\seo\SeoWidget::widget(['model' => $model])?>
</div>

<div class="col-xs-12 col-sm-4">
<?= \fedornabilkin\binds\widgets\binds\BindsWidget::widget(['model' => $model])?>
</div>
</div>
<?php ActiveForm::end(); ?>

</div>
 



Основные реляции объявлены в 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 (Опубликован)



Замечание модератора:
Эта тема была закрыта автоматически ввиду отсутствия активности в ней на протяжении 100+ дней.
Если Вы считаете ее актуальной и хотите оставить сообщение, то воспользуйтесь кнопкой
или обратитесь к любому из модераторов.


Сообщение отредактировал fedornabilkin - 13.3.2018, 0:14
0
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Открыть тему
Тема закрыта
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


Свернуть

> Похожие темы

  Тема Ответов Автор Просмотров Последний ответ
Горячая тема (нет новых ответов) Профессиональная веб-разработка (Laravel, Yii2, Symfony, Wordpress, Vue.js, Nuxt.js)
Хороший код с оптимизацией по скорости. Сайты и лендинги "под клю
33 Nell 29919 5.7.2022, 21:24
автор: karambas
Открытая тема (нет новых ответов) Нужен специалист поставить расширение на phpBB 3.2.8.
Запрет индексации тем или сразу для закрытого ращздела
0 Уфолог Бова 4398 26.7.2021, 21:59
автор: Уфолог Бова
Открытая тема (нет новых ответов) Тема имеет прикрепленные файлыСделаю движок для сайта на Yii2
10 icoder 7010 2.7.2021, 19:48
автор: nekokatalog
Открытая тема (нет новых ответов) Сделать доработки - Yii2
6 prohorlaz 1514 26.9.2019, 0:46
автор: prohorlaz
Открытая тема (нет новых ответов) Нужен Программист (Php + Yii2) + Администратор
0 codyn 1352 16.7.2019, 23:22
автор: codyn


 



RSS Текстовая версия Сейчас: 29.3.2024, 15:01
Дизайн