All pastes #638386 Raw Edit

walkerhack2

public text v1 · immutable
#638386 ·published 2007-07-29 19:58 UTC
rendered paste body
class iWalker {
	var $tree_type;
	var $db_fields;

	//abstract callbacks
	function istart_lvl($output) { return $output; }
	function iend_lvl($output)   { return $output; }
	function istart_el($output)  { return $output; }
	function iend_el($output)    { return $output; }
	function iparent_start($output)    { return $output; }
	function iparent_end($output)    { return $output; }

	function iwalk($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;

                $top_level = ($depth == 1) ? true : false;

		foreach ( $elements as $element ) {
			// If flat, start and end the element and skip the level checks.
			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, 'iparent_start'), $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, 'iparent_end'), $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);

                                        ($depth ==1) ? $output = call_user_func_array(array(&$this, 'iparent_end'), $cb_args) : $output = 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);

                                        ($depth ==1) ?$output = call_user_func_array(array(&$this, 'iparent_end'), $cb_args) : $output = 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);

                                        ($depth ==1) ? $output = call_user_func_array(array(&$this, 'iparent_end'), $cb_args) : $output = 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);

                                                ($depth ==1 ) ? $output = call_user_func_array(array(&$this, 'iparent_end'), $cb_args) : $output = 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);

                                        ($depth == 1) ? $output = call_user_func_array(array(&$this, 'iparent_end'), $cb_args) : $output = call_user_func_array(array(&$this, 'end_el'), $cb_args);

                                }

                        }