public static function term_tree($terms, $tree_name, $config = array())
{
$defaults = array('treestart' => '<ol %s>', 'treeattr' => array('class' => 'tree', 'id' => Utils::slugify('tree_' . $tree_name)), 'treeend' => '</ol>', 'liststart' => '<ol %s>', 'listattr' => array(), 'listend' => '</ol>', 'itemstart' => '<li %s>', 'itemattr' => array('class' => 'treeitem'), 'itemend' => '</li>', 'wrapper' => '<div>%s</div>', 'linkcallback' => null, 'itemcallback' => null, 'listcallback' => null);
$config = array_merge($defaults, $config);
$out = sprintf($config['treestart'], Utils::html_attr($config['treeattr']));
$stack = array();
$tree_name = Utils::slugify($tree_name);
if (!$terms instanceof Terms) {
$terms = new Terms($terms);
}
foreach ($terms as $term) {
if (count($stack)) {
if ($term->mptt_left - end($stack)->mptt_left == 1) {
if (isset($config['listcallback'])) {
$config = call_user_func($config['listcallback'], $term, $config);
}
$out .= sprintf($config['liststart'], Utils::html_attr($config['listattr']));
}
while (count($stack) && $term->mptt_left > end($stack)->mptt_right) {
$out .= $config['listend'] . $config['itemend'] . "\n";
array_pop($stack);
}
}
$config['itemattr']['id'] = $tree_name . '_' . $term->id;
if (isset($config['itemcallback'])) {
$config = call_user_func($config['itemcallback'], $term, $config);
}
$out .= sprintf($config['itemstart'], Utils::html_attr($config['itemattr']));
if (isset($config['linkcallback'])) {
$display = call_user_func($config['linkcallback'], $term, $config);
} else {
$display = $term->term_display;
}
$out .= sprintf($config['wrapper'], $display);
if ($term->mptt_right - $term->mptt_left > 1) {
$stack[] = $term;
} else {
$out .= $config['itemend'] . "\n";
}
}
while (count($stack)) {
$out .= $config['listend'] . $config['itemend'] . "\n";
array_pop($stack);
}
$out .= $config['treeend'];
return $out;
}