vorst.ru - Статьи о задачах возникающих при создании сайта и их решении
Статьи помеченные tree

Подключение расширения Nested Set

Определение данных и необходимых методов в модели

Мы получили общее представление о древовидной структуре данных называемой Nested Set. Теперь пришло время подключить к блогу соответствующее расширение.

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


Как устроена структура данных Nested Set

Как сделать рубрикатор

Рубрикатор, как средство поиска интересных статей, имеет свои недостатки - трудно придумать иерархию, названия рубрик, трудно потом решить к какой конкретно рубрике относится статья. "Но, так принято" - скажите вы и будете правы.

Поэтому, давайте делать рубрикатор.



Поиск



Подключение расширения Nested Set

Определение данных и необходимых методов в модели

Мы получили общее представление о древовидной структуре данных называемой Nested Set. Теперь пришло время подключить к блогу соответствующее расширение.

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


    Поделиться

Наши задачи проще и сводятся к следующему:

  1. Управление рубрикатором - добавление и удаление рубрик, редактирование, отображение списка рубрик для визуального контроля.
  2. Закрепление статьи за рубрикой.
  3. Вывод списка рубрик для выбора нужной рубрики.

Для их решения, как обычно, нужна модель, контроллер, представления и еще виджет.

Data

Cоздадим таблицу, которая будет хранить дерево рубрик и введем обязательную корневую рубрику.

CREATE TABLE tbl_rubric (
  id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  lft INT(11) NOT NULL,
  rgt INT(11) NOT NULL,
  level INT(11) NOT NULL,
  name VARCHAR(50) NOT NULL,
  KEY lft (lft),
  KEY rgt (rgt),
  KEY level (level)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO tbl_rubric (id, lft, rgt, level, name) values(1, 1, 2, 1, 'Без рубрики')

Установим расширение Nested Set.

Model

Создадим модель common\models\Rubric.php, подключив расширение и определив два служебных поля значение которых будет объяснено позже.

namespace common\models;
use creocoder\nestedsets\NestedSetsBehavior;
use yii\db\ActiveRecord;
class Rubric extends ActiveRecord
{
  public $parent_node; // the parent node for just added
  public $post_count; // posts count in a rubric
  ...
  public function behaviors()
  {
    return [
      'tree' => [
        'class' => NestedSetsBehavior::className(),
          'depthAttribute' => 'level',
      ],
    ];
  }
  ...

И напишем пару методов.

Первый из которых будем использовать для вывода названий рубрик. Для отражения уровня вложенности будем делать отступы. Формирование отступов зависит от вывода. Метод формирования будет разным для выпадающего списка и просто вывода в блоке.

  public function getPrettyName($dropdown = false)
  {
    return $dropdown 
      ? str_repeat('-', ($this->level - 1) * 2) . ' ' . $this->name
      : '<span style="margin-left:' . (($this->level - 2) * 20) . 'px;">' . 
        $this->name . '</span>';
  }

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

Цели добавления новой рубрики и служит одно из дополнительных полей модели - $parent_node. Добавляя новую рубрику мы должны определить ее предка. Именно за ним и будет вставлен "новичок".

Итак, метод items()

  public function items($rootTitle = null)
  {
    if(!$rootTitle) 
      $rootTitle = \Yii::t('app', 'Root');
    $a = [];
    $a[1] = $rootTitle;
    foreach(Rubric::find()->where('id>1')->orderBy('lft ASC')->all() as $node)
      $a[$node->id] = $node->getPrettyName(true);
    return $a;
}

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

Заключение

Для создания рубрикатора не обязательно вникать в детали работы программы-расширения, которая выполняет всю основную работу.

Оставить комментарий

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