All pastes #638322 Raw Edit

Walker Hack

public php v1 · immutable
#638322 ·published 2007-07-29 19:09 UTC
rendered paste body
<?phpfunction ideas_list_pages($args = '') {	if ( is_array($args) )		$r = &$args;	else		parse_str($args, $r);	$defaults = array('depth' => 0, 'show_date' => '', 'date_format' => get_option('date_format'),		'child_of' => 0, 'exclude' => '', 'title_li' => __('Pages'), 'echo' => 1, 'authors' => '', 'sort_column' => 'menu_order');	$r = array_merge($defaults, $r);	$output = '';	$current_page = 0;	// sanitize, mostly to keep spaces out	$r['exclude'] = preg_replace('[^0-9,]', '', $r['exclude']);	// Allow plugins to filter an array of excluded pages	$r['exclude'] = implode(',', apply_filters('wp_list_pages_excludes', explode(',', $r['exclude'])));	// Query pages.	$pages = get_pages($r);	if ( !empty($pages) ) {		if ( $r['title_li'] )			$output .= '<div class="pagenav">' . $r['title_li'] . '<ul>';		global $wp_query;		if ( is_page() )			$current_page = $wp_query->get_queried_object_id();		$output .= iwalk_page_tree($pages, $r['depth'], $current_page, $r);		if ( $r['title_li'] )			$output .= '</ul></div>';	}	$output = apply_filters('ideas_list_pages', $output);	if ( $r['echo'] )		echo $output;	else		return $output;}function iwalk_page_tree() {	$walker = new iWalker_Page;	$args = func_get_args();	return call_user_func_array(array(&$walker, 'iwalk'), $args);}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, 'istart_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, 'iend_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, 'istart_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 = call_user_func_array(array(&$this, 'iend_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 = call_user_func_array(array(&$this, 'iend_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 = call_user_func_array(array(&$this, 'iend_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, 'iend_lvl'), $cb_args);						$cb_args = array_merge( array($output, $parent, $depth - 1), $args);						$output = call_user_func_array(array(&$this, 'iend_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 = call_user_func_array(array(&$this, 'iend_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 = call_user_func_array(array(&$this, 'istart_el'), $cb_args);				}			}			$previous_element = $element;		}		return $output;	}}class iWalker_Page extends iWalker {	var $tree_type = 'page';	var $db_fields = array ('parent' => 'post_parent', 'id' => 'ID'); //TODO: decouple this	function istart_lvl($output, $depth) {		$indent = str_repeat("\t", $depth);		$output .= "\n$indent<div class='child'><ul>\n";		return $output;	}	function iend_lvl($output, $depth) {		$indent = str_repeat("\t", $depth);		$output .= "$indent</ul></div>\n";		return $output;	}	function istart_el($output, $page, $depth, $current_page, $args) {		if ( $depth )			$indent = str_repeat("\t", $depth);		extract($args, EXTR_SKIP);		$css_class = 'page_item';		$_current_page = get_page( $current_page );		if ( $page->ID == $current_page )			$css_class .= ' current_page_item';		elseif ( $_current_page && $page->ID == $_current_page->post_parent )			$css_class .= ' current_page_parent';		$output .= $indent . '<li class="' . $css_class . '" id="' . attribute_escape($page->post_name) . '"><a href="' . get_page_link($page->ID) . '" title="' . attribute_escape(apply_filters('the_title', $page->post_title)) . '">' . apply_filters('the_title', $page->post_title) . '</a>';		if ( !empty($show_date) ) {			if ( 'modified' == $show_date )				$time = $page->post_modified;			else				$time = $page->post_date;			$output .= " " . mysql2date($date_format, $time);		}		return $output;	}	function iend_el($output, $page, $depth) {		$output .= "</li>\n";		return $output;	}	function iparent_start($output, $page, $depth, $current_page, $args) {		if ( $depth )			$indent = str_repeat("\t", $depth);		extract($args, EXTR_SKIP);		$css_class = 'page_item';		$_current_page = get_page( $current_page );		if ( $page->ID == $current_page )			$css_class .= ' current_page_item';		elseif ( $_current_page && $page->ID == $_current_page->post_parent )			$css_class .= ' current_page_parent';		$output .= $indent . '<li class="' . $css_class . '"><a href="' . get_page_link($page->ID) . '" title="' . attribute_escape(apply_filters('the_title', $page->post_title)) . '">' . apply_filters('the_title', $page->post_title) . '</a>';		if ( !empty($show_date) ) {			if ( 'modified' == $show_date )				$time = $page->post_modified;			else				$time = $page->post_date;			$output .= " " . mysql2date($date_format, $time);		}		return $output;	}	function iparent_end($output, $page, $depth) {		$output .= "</li>\n";		return $output;	}}