How to build a Tree
Tree component allows you to build hierarchical structure of objects derived from class TreeItem. You should consider Tree object as a logical structure of data and not as a HTML widget (this is up to tree renderers, see below).
You can craft your tree by hand:
$tree = new Tree('System plików');
$home = new TreeItem(array('entry' => 'home'), 'System plików');
$usr = new TreeItem(array('entry' => 'usr'), 'System plików');
$usr_bin = new TreeItem(array('entry' => 'bin'), 'System plików');
$tree->addItem($home);
$tree->addItem($usr);
$usr->addItem($usr_bin);
print($tree->toHtml());
You can add new nodes at any point of the structure. If you want to insert node before existing ones use method insertItem instead of addItem. Let’s add a couple of users and make them look more fancy.
class UserTreeItem extends TreeItem {
function getPrintData() {
return array(
'text' => $this->data['username'],
‘openedIcon’ => ‘user.png’,
‘closedIcon’ => ‘user_disabled.png’,
‘enabled’ => TRUE
);
}
} // class UserTreeItem
$home_jpaszek = new UserTreeItem(array(’entry’ => ‘jpaszek’, ‘username’ => ‘Jacek Paszek’), ‘System plików’);
$home_mkrol = new UserTreeItem(array(’entry’ => ‘mkrol’, ‘username’ => ‘Marcin Król’), ‘System plików’);
$home_mslaby = new UserTreeItem(array(’entry’ => ‘mslaby’, ‘username’ => ‘Michał Słaby’), ‘System plików’);
$home->addItem($home_jpaszek);
$home->addItem($home_mkrol);
$home->addItem($home_mslaby);

What you see above here in overriden method getPrintData is a tweak to make tree items look good. Meaning of fields in the returned array is pretty obvious.
Searching the tree
Searching along the tree items is done with classes implementing interface IMatcher such as SelectedMatcher, ClassMatcher, DataMatcher,
IndexMatcher, etc. You can search within whole tree or certain node. The result returned by matcher can be either the first matching element or a collection of all matching elements. It goes like this:
$selectedItem = $tree->find(new SelectedMatcher());
$indexItem5 = $tree->find(new IndexMatcher(5));
$usernameItem = $tree->find(new DataMatcher(array('username' => 'Michał Słaby')));
$allUsers = $tree->findAll(new ClassMatcher('UserTreeItem'));
$leaves = $tree->findAll(new LeafMatcher());
$allItems = $tree->findAll(new TrueMatcher());
$startingWith_M = $home->findAll(new DataMatcher(array('entry' => '/m.*/'), TRUE));
3 topmost examples are rather clear. In example 4, $allUsers is assigned to an array holding all nodes of class UserTreeItem. In example 5, code>$leaves is assigned to nodes not having any further nodes (so, they are leafs not branches). In example 6 there is TrueMatcher object used to fetch all nodes. The last example shows how to fetch all nodes having field entry in their internal data and matches regular expression (regexp mathcing is enabled by TRUE as second parameter to matcher). It will do so only in and below node $home.
Database integration
If you already have your structure stored in database table you can easily build the tree automatically. First, you need to use DBTree class. The class has an abstract method getDBArray which is expected to return an array of hashes such as a SQL querry result. Override this method to return desired SQL querry result. Second part of the job is to define primary key and reference key names. Set properties pkeyName and rkeyName to what they should contain. Setting pkeyName to table primary key and rkeyName to prn_id is the most often case. Now you have only one thing to do to get your tree working. Assign to $pkeyInitValue the value of primary key of the first node to be placed on the tree (so called root node). Additionaly you also needo to set $rkeyInitValue to be different from $pkeyInitialValue (for the reasons you can consider as “just because”).
class OrganizationTree extends DBTree {
var $pkeyName = 'orunid';
var $rkeyName = 'prn_id';
var $pkeyInitValue = 0;
var $rkeyInitValue = -1;
function getDBArray() {
$out = $this->db->query('SELECT * FROM orgtree_view');
if ($out != -1)
return $out;
return array();
}
} // class OrganizationTree
Powyższy przykład opisuje w jaki sposób zbudować drzewo w oparciu o tabelę.
Zasadniczo getDBArray może zwrócić tabelę pozyskaną z dowolnego źródła,
niekoniecznie z bazy danych, ale wykorzystanie DB było pierwszorzędnym celem tej klasy.
Otrzymane drzewo będzie posiadać gałęzie i liście tej samej klasy - TreeItem.
Gdy potrzeba jest zróżnicować itemy w zależności od zawartości jednego z pól tablicy
istnieje po temu gotowy mechanizm. Przede wszystkim należy zaznaczyć które z pól tablicy
determinuje klasę itemu. Nazwę tej kolumny należy podać w zmiennej składowej ckeyName.
Następnie należy stworzyć słownik odwzorowujący wartość tego pola na nazwę klasy w zmiennej składowej
treeItemClasses. Opcjonalnie można zaznaczyć domyślną nazwę klasy w zmiennej
defaultTreeItemClass. Uzupełnijmy zatem przykład OrganizationTree
o różnicowanie itemów ze względu na pole ndetpe tablicy zwróconej z DB.
class OrganizationTree extends DBTree {
var $pkeyName = 'orunid';
var $rkeyName = 'prn_id';
var $ckeyName = 'ndetpe';
var $defaultTreeItemClass = 'PostTreeItem';
var $treeItemClasses = array(
'ENTITY' => 'EntityTreeItem',
'ORGCELL' => 'OrgCellTreeItem',
'POST' => 'PostTreeItem'
);
function getDBArray() {
$out = $this->db->query('SELECT * FROM orgtree_view');
if ($out != -1)
return $out;
return array();
}
} // class OrganizationTree
Skutkiem powyższego powołane będą obiekty klas EntityTreeItem, OrgCellTreeItem,
PostTreeItem gdy wartość pola ndetpe będzie równa odpowiednio ENTITY, ORGCELL i POST.
Przy innych wartościach będzie to również klasa PostTreeItem.
ustaw składową
$doCache na FALSE. Jeśli chcesz wyczyścić cache po aktualizacjistruktury drzewa użyj metody
clearCache.
wartość 0 lub NULL. By to zmienić ustaw składową
$pkeyInitValue. Jeśli ustawiasz ją na-1 to zmień również wartość składowej
$rkeyInitValue na np. -2. Zmienne te nie mogąbyć sobie równe - wówczas drzewo podczas wywołania rekurencyjnego wykryje zapętlenie, wyrzuci
debugi z ostrzeżeniami i natychmiast wyjdzie z zagłębienia.
Backendy renderujące
Drzewo wspiera rozmaite backendy renderujące. Domyślnym rendererem jest PEARTreeRenderer,
ale można sobie napisać inny. Renderer musi jednak dziedziczyć po klasie TreeRenderer.
$innyRenderer = new InnyRenderer($drzewo); $innyRenderer->toHtml();