rendered paste body<?php// A class for displaying various tree-like structures. Extend the Walker class to use it, see examples at the bottomclass Walker { var $tree_type; var $db_fields; //abstract callbacks function start_lvl($output) { return $output; } function end_lvl($output) { return $output; } function start_el($output) { return $output; } function end_el($output) { return $output; } function start_top_el($output) { return $output; } function end_top_el($output) { return $output; } function walk($elements, $to_depth) { $args = array_slice(func_get_args(), 2); $parents = array(); $depth = 1; $previous_element = ''; $output = ''; //padding at the end $last_element->post_parent = 0; $last_element->post_id = 0; $elements[] = $last_element; $id_field = $this->db_fields['id']; $parent_field = $this->db_fields['parent']; $flat = ($to_depth == -1) ? true : false; foreach ( $elements as $element ) { // If flat, start and end the element and skip the level checks. //// well if it's flat everything is atop level element. if ( $flat) { // Start the element. if ( isset($element->$id_field) && $element->$id_field != 0 ) { $cb_args = array_merge( array($output, $element, $depth - 1), $args); $output = call_user_func_array(array(&$this, 'start_top_el'), $cb_args); } // End the element. if ( isset($element->$id_field) && $element->$id_field != 0 ) { $cb_args = array_merge( array($output, $element, $depth - 1), $args); $output = call_user_func_array(array(&$this, 'end_top_el'), $cb_args); } continue; } // Walk the tree. if ( !empty($previous_element) && ($element->$parent_field == $previous_element->$id_field) ) { // Previous element is my parent. Descend a level. array_unshift($parents, $previous_element); if ( !$to_depth || ($depth < $to_depth) ) { //only descend if we're below $to_depth $cb_args = array_merge( array($output, $depth), $args); $output = call_user_func_array(array(&$this, 'start_lvl'), $cb_args); } else if ( $to_depth && $depth == $to_depth ) { // If we've reached depth, end the previous element. $cb_args = array_merge( array($output, $previous_element, $depth), $args); $output = ($depth ==1) ? call_user_func_array(array(&$this, 'end_top_el'), $cb_args) : call_user_func_array(array(&$this, 'end_el'), $cb_args); } $depth++; //always do this so when we start the element further down, we know where we are } else if ( $element->$parent_field == $previous_element->$parent_field) { // On the same level as previous element. if ( !$to_depth || ($depth <= $to_depth) ) { $cb_args = array_merge( array($output, $previous_element, $depth - 1), $args); $output = ($depth ==1) ? call_user_func_array(array(&$this, 'end_top_el'), $cb_args) : call_user_func_array(array(&$this, 'end_el'), $cb_args); } } else if ( $depth > 1 ) { // Ascend one or more levels. if ( !$to_depth || ($depth <= $to_depth) ) { $cb_args = array_merge( array($output, $previous_element, $depth - 1), $args); $output = ($depth ==1) ? call_user_func_array(array(&$this, 'end__top_el'), $cb_args) : call_user_func_array(array(&$this, 'end_el'), $cb_args); } while ( $parent = array_shift($parents) ) { $depth--; if ( !$to_depth || ($depth < $to_depth) ) { $cb_args = array_merge( array($output, $depth), $args); $output = call_user_func_array(array(&$this, 'end_lvl'), $cb_args); $cb_args = array_merge( array($output, $parent, $depth - 1), $args); $output = ($depth ==1 ) ? call_user_func_array(array(&$this, 'end_top_el'), $cb_args) : call_user_func_array(array(&$this, 'end_el'), $cb_args); } if ( $element->$parent_field == $parents[0]->$id_field ) { break; } } } else if ( !empty($previous_element) ) { // Close off previous element. if ( !$to_depth || ($depth <= $to_depth) ) { $cb_args = array_merge( array($output, $previous_element, $depth - 1), $args); $output = ($depth == 1) ? call_user_func_array(array(&$this, 'end__top_el'), $cb_args) : call_user_func_array(array(&$this, 'end_el'), $cb_args); } } // Start the element. if ( !$to_depth || ($depth <= $to_depth) ) { if ( $element->$id_field != 0 ) { $cb_args = array_merge( array($output, $element, $depth - 1), $args); $output = ($depth == 1 ) ? call_user_func_array(array(&$this, 'start_top_el'), $cb_args) : call_user_func_array(array(&$this, 'start_el'), $cb_args) ; } } $previous_element = $element; } return $output; }}?>