Документация

Начало работы

Модели (models)

Шаблоны (views) и маршрутизация (routes)

Формы

SQL запросы

Сессии и безопасность

Плагины

Деревья

Простое дерево

Строится при помощи добавления в модель поля типа Родитель "parent", которое хранит id родителя текущей записи. Для корневых записей значение данного поля равно "-1".

Внимание! Поле типа "parent" может быть в модели только одно.

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

<?
class Pages extends Model
{
    protected $name = "Меню страниц";

    protected $model_elements = array(
        array("Активировать", "bool", "active", array("on_create" => true)),
        array("Отображать в меню", "bool", "in_menu", array("on_create" => true)),
        array("Название", "char", "name", array("required" => true)),
        array("Родительский раздел", "parent", "parent", array("max_depth" => 3)),
        array("Позиция", "order", "order"),
        array("Содержание", "text", "content", array("rich_text" => true))
    );
}
?>

Связанное дерево

Для создания структуры вида "каталог -> каталог -> каталог -> товар" или "альбом -> альбом -> изображение" нужно связать модель с полем "parent" с другой моделью таким образом чтобы конечный родитель первой модели являлся внешним ключом для записей другой модели.

Пример создания связанного дерева для многоуровнего каталога товаров.

class Catalogs extends Model 
{
    protected $name = "Разделы каталога";

    protected $model_elements = array(
        array("Активен", "bool", "active", array("on_create" => true)),
        array("Название", "char", "name", array("required" => true)),
        array("Каталог", "parent", "parent", array("parent_for" => "Products")),                
        array("Ссылка", "url", "url"),
        array("Позиция", "order", "order")                    
    );
}

class Products extends Model 
{
    protected $name = "Товары каталога";

    protected $model_elements = array(
        array("Активен", "bool", "active", array("on_create" => true)),                
        array("Название", "char", "name", array("required" => true)),
        array("Раздел каталога", "enum", "parent", array("foreign_key" => "Catalogs", "is_parent" => true)),
        array("Цена", "int", "price", array("required" => true)),
        array("Изображения", "multi_images","images"),
        array("Описание", "text", "desc", array("rich_text" => true)),
        array("Позиция", "order", "order")
    );
}

Специальные методы деревьев

Для быстрого доступа к родителям и потомкам в дереве предусмотрены специальные методы.

  • getParents($id) - возвращает массив родительских записей (до записи со значением родительского поля равным -1). В результирующем массиве ключи - id записей, значения - названия записей соглаcно параметру "$name_field" из раздела Настройка модели.
  • getChildren($id) - возвращает массив всех дочерних записей, рекурсивно обходя все ветви дерева. Результирующий массив строится аналогично предыдущему методу.
  • displayBreadcrumbs($id, $url_first [, $url_field]) - отображает ссылочный путь до записи с переданным id. Возвращает последовательность html тэгов в виде
    "ссылка -> ссылка -> ссылка -> span". Входящие параметры: id текущей записи, $url_first - первая часть url,
    необязательный параметр $url_field - название поля в котором хранится текстовая ссылка для данной записи (для построения url вида "catalog/toys/"). Для предустановленной модели "Pages" ссылки автоматически строятся в виде "/page/4/" и "/contacts/" (без первой части).
$catalog = $mv -> catalogs -> findRecordById(43);

//Родительские записи
$parents = $mv -> catalogs -> getParents($catalog -> id);

//Дочерние записи
$children = $mv -> catalogs -> getChildren($catalog -> id);

//Ссылочный путь для раздела каталога
echo $mv -> catalogs -> displayBreadcrumbs($catalog -> id, "category", "url"); 

//Ссылочный путь для товара каталога 
echo $mv -> products -> displayBreadcrumbs($product -> id, "category");

//Ссылочный путь будет в виде
<a href="/category/toys/">Игрушки</a>
<a href="/category/balls/">Мячи</a>
<span>Мяч красный</span>

Перечисленные методы могут также вызываться изнутри объекта модели. В примере ниже происходит определение страницы каталога на основе URL.

public function defineCatalogPage(Router $router)
{
    $url_parts = $router -> getUrlParts();        
    $content = false;

    if(count($url_parts) == 2)
        if(is_numeric($url_parts[1]))
            $content = $this -> findRecord(array("id" => $url_parts[1], "active" => 1));
        else
            $content = $this -> findRecord(array("url" => $url_parts[1], "active" => 1));

    if($content)
        $this -> parents = $this -> getParents($content -> id);

    return $content;
}

Далее рекурсивно строим меню каталога.

public function displayCatalogMenu($parent)
{
    $rows = $this -> select(array("parent" => $parent, "active" => 1, "order->asc" => "order"));
    $html = "";
    $root_path = $this -> root_path."category/";

    foreach($rows as $row)
    {
        $active = "";
        $children = false;

        if($row['id'] == $this -> id || array_key_exists($row['id'],  $this -> parents))
        {    
            $children = $this -> select(array("parent" => $row['id'], "active" => 1));
            $active = ' class="active"';
        }

        $url = $root_path.($row['url'] ? $row['url'] : $row['id'])."/";             
        $html .= '<li><a'.$active.' href="'.$url.'">'.$row['name'].'</a>';

        if($children)
            $html .= "<ul>".$this -> displayCatalogMenu($row['id'])."</ul>";

        $html .= "</li>";        
    }

    return $html;    
}

//Вызов данного метода в шаблоне
<ul id="catalog">
    <? echo $mv -> catalogs -> displayCatalogMenu(-1); ?>
</ul>

Предыдущий раздел

Внешние ключи

Следующий раздел

Многие ко многим