79 lines
2.7 KiB
PHP
79 lines
2.7 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Сортировка дерева в представлении Nested Set
|
|
* Для дерева которое хранится в базе данных используя представление Nested Set нет возможности отсортировать элементы дерева по
|
|
* произвольному полю. Поэтому после извлечения дерева из базы данных оно преобразуется в обычное представление сортируется и обратно
|
|
*
|
|
* Пример:
|
|
* $sort = new NestedSetSort();
|
|
* $data = $sort->sortBy($data, 'name');
|
|
*/
|
|
class NestedSetSort {
|
|
private $data = array();
|
|
private $result = array();
|
|
private $sortBy = '';
|
|
|
|
public function __construct() {
|
|
}
|
|
|
|
// Преобразуем Nested Set в дерево и сортируем
|
|
private function listTree(array $tree, $offset, $level) {
|
|
$result = array();
|
|
for ($i = $offset; $i < sizeof($tree); $i++) {
|
|
$leaf = $tree[$i];
|
|
$clevel = $leaf['cat_level'];
|
|
if ($clevel == $level) {
|
|
$result [] = array($i);
|
|
} else if ($clevel > $level) {
|
|
list($subtree, $i) = $this->listTree($tree, $i, $clevel);
|
|
$i--;
|
|
$result[sizeof($result) - 1][1] = $subtree;
|
|
} else {
|
|
$this->sortList($result, $tree);
|
|
return array($result, $i);
|
|
}
|
|
}
|
|
$this->sortList($result, $tree);
|
|
return array($result, $i);
|
|
}
|
|
|
|
// Сравнение двух элементов
|
|
private function compare($a, $b) {
|
|
$a1 = $this->data[$a[0]][$this->sortBy];
|
|
$b1 = $this->data[$b[0]][$this->sortBy];
|
|
return strcmp($a1, $b1);
|
|
}
|
|
|
|
// Сортировка списка
|
|
private function sortList(array &$list, $data) {
|
|
usort($list, array($this, 'compare'));
|
|
}
|
|
|
|
// Создает дерево в виде списка
|
|
private function reorder(array $tree) {
|
|
foreach($tree as $node) {
|
|
$this->result[] = $this->data[$node[0]];
|
|
if (isset($node[1])) {
|
|
$this->reorder($node[1]);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function sortBy0(array $data, $sortBy)
|
|
{
|
|
$this->data = $data;
|
|
$this->sortBy = $sortBy;
|
|
$order = $this->listTree($data, 0, 0);
|
|
return $order[0];
|
|
}
|
|
|
|
// Сортировка по заданному полю
|
|
public function sortBy(array $data, $sortBy) {
|
|
$this->data = $data;
|
|
$this->sortBy = $sortBy;
|
|
$order = $this->listTree($data, 0, 0);
|
|
$this->reorder($order[0]);
|
|
return $this->result;
|
|
}
|
|
}
|