phplibrary/core/tree/sort.php
2016-07-14 16:29:26 +03:00

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;
}
}