From a8eac8ee6de01894af258edf057508b4f0c0bfe9 Mon Sep 17 00:00:00 2001 From: ryan Date: Thu, 13 Apr 2006 04:40:48 +0000 Subject: [PATCH] Move page walkers to classes. Props David House. fixes #2593 git-svn-id: http://svn.automattic.com/wordpress/trunk@3704 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/classes.php | 279 ++++++++++++++++++++ wp-includes/functions.php | 122 --------- wp-includes/template-functions-category.php | 120 ++------- wp-includes/template-functions-post.php | 69 +---- 4 files changed, 307 insertions(+), 283 deletions(-) diff --git a/wp-includes/classes.php b/wp-includes/classes.php index c596e04d6b..dc61e799d6 100644 --- a/wp-includes/classes.php +++ b/wp-includes/classes.php @@ -400,4 +400,283 @@ function is_wp_error($thing) { return false; } + +// A class for displaying various tree-like structures. Extend the Walker class to use it, see examples at the bottom + +class 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 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. + if ( $flat) { + // Start the element. + if ( $element->$id_field != 0 ) { + $cb_args = array_merge( array($output, $element, $depth - 1), $args); + $output = call_user_func_array(array(&$this, 'start_el'), $cb_args); + } + + // End the element. + if ( $element->$id_field != 0 ) { + $cb_args = array_merge( array($output, $element, $depth - 1), $args); + $output = call_user_func_array(array(&$this, 'end_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); + $depth++; //always do this so when we start the element further down, we know where we are + if ( !$to_depth || ($depth < $to_depth) ) { //only descend if we're below $to_depth + $cb_args = array_merge( array($output, $depth - 1), $args); + $output = call_user_func_array(array(&$this, 'start_lvl'), $cb_args); + } + } 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, '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 = 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 - 1), $args); + $output = call_user_func_array(array(&$this, 'end_lvl'), $cb_args); + $cb_args = array_merge( array($output, $parent, $depth - 1), $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); + $output = 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 = call_user_func_array(array(&$this, 'start_el'), $cb_args); + } + } + + $previous_element = $element; + } + + return $output; + } +} + +class Walker_Page extends Walker { + var $tree_type = 'page'; + var $db_fields = array ('parent' => 'post_parent', 'id' => 'ID'); //TODO: decouple this + + function start_lvl($output, $depth) { + $indent = str_repeat("\t", $depth); + $output .= "$indent\n"; + return $output; + } + + function start_el($output, $page, $depth, $current_page, $show_date, $date_format) { + if ( $depth ) + $indent = str_repeat("\t", $depth); + + $css_class = 'page_item'; + if ( $page->ID == $current_page ) + $css_class .= ' current_page_item'; + + $output .= $indent . '
  • ' . $page->post_title . ''; + + 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 end_el($output, $page, $depth) { + $output .= "
  • \n"; + + return $output; + } + +} + +class Walker_PageDropdown extends Walker { + var $tree_type = 'page'; + var $db_fields = array ('parent' => 'post_parent', 'id' => 'ID'); //TODO: decouple this + + function start_el($output, $page, $depth, $args) { + $pad = str_repeat(' ', $depth * 3); + + $output .= "\t\n"; + + return $output; + } +} + +class Walker_Category extends Walker { + var $tree_type = 'category'; + var $db_fields = array ('parent' => 'category_parent', 'id' => 'cat_ID'); //TODO: decouple this + + function start_lvl($output, $depth, $args) { + if ( 'list' != $args['style'] ) + return $output; + + $indent = str_repeat("\t", $depth); + $output .= "$indent\n"; + return $output; + } + + function start_el($output, $category, $depth, $args) { + extract($args); + + $link = 'category_description) ) + $link .= 'title="'. sprintf(__("View all posts filed under %s"), wp_specialchars($category->cat_name)) . '"'; + else + $link .= 'title="' . wp_specialchars(apply_filters('category_description',$category->category_description,$category)) . '"'; + $link .= '>'; + $link .= apply_filters('list_cats', $category->cat_name, $category).''; + + if ( (! empty($feed_image)) || (! empty($feed)) ) { + $link .= ' '; + + if ( empty($feed_image) ) + $link .= '('; + + $link .= ''; + else + $link .= $name; + $link .= ''; + if (empty($feed_image)) + $link .= ')'; + } + + if ( $show_count ) + $link .= ' ('.intval($category->category_count).')'; + + if ( $show_date ) { + $link .= ' ' . gmdate('Y-m-d', $category->last_update_timestamp); + } + + if ( 'list' == $args['style'] ) { + $output .= "\tcat_ID == $current_category) && is_category() ) + $output .= ' class="current-cat"'; + $output .= ">$link\n"; + } else { + $output .= "\t$link
    \n"; + } + + return $output; + } + + function end_el($output, $page, $depth) { + if ( 'list' != $args['style'] ) + return $output; + + $output .= "\n"; + return $output; + } + +} + +class Walker_CategoryDropdown extends Walker { + var $tree_type = 'category'; + var $db_fields = array ('parent' => 'category_parent', 'id' => 'cat_ID'); //TODO: decouple this + + function start_el($output, $category, $depth, $args) { + $pad = str_repeat(' ', $depth * 3); + + $cat_name = apply_filters('list_cats', $category->cat_name, $category); + $output .= "\t\n"; + + return $output; + } +} + ?> diff --git a/wp-includes/functions.php b/wp-includes/functions.php index 84586aa9e9..9a9cdd8b5c 100644 --- a/wp-includes/functions.php +++ b/wp-includes/functions.php @@ -714,128 +714,6 @@ function &get_page(&$page, $output = OBJECT) { } } -function walk_tree($tree_type, $elements, $to_depth, $start_element_callback, $end_element_callback = '', $start_level_callback = '', $end_level_callback = '') { - $args = array_slice(func_get_args(), 7); - $parents = array(); - $depth = 1; - $previous_element = ''; - $output = ''; - - $last_element->post_parent = 0; - $last_element->post_id = 0; - $elements[] = $last_element; - - if ( 'page' == $tree_type ) { - $parent_field = 'post_parent'; - $id_field = 'ID'; - } else { - $parent_field = 'category_parent'; - $id_field = 'cat_ID'; - } - - $flat = false; - if ( $to_depth == -1 ) - $flat = true; - - foreach ( $elements as $element ) { - // If flat, start and end the element and skip the level checks. - if ( $flat) { - // Start the element. - if ( !empty($start_element_callback) && ($element->$id_field != 0) ) { - $cb_args = array_merge( array($output, $element, $depth), $args); - $output = call_user_func_array($start_element_callback, $cb_args); - } - - // End the element. - if ( !empty($end_element_callback) && ($element->$id_field != 0) ) { - $cb_args = array_merge( array($output, $element, $depth), $args); - $output = call_user_func_array($end_element_callback, $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. - $depth++; //always do this so when we start the element further down, we know where we are - array_unshift($parents, $previous_element); - if ( !$to_depth || ($depth < $to_depth) ) { //only descend if we're below $to_depth - if ( !empty($start_level_callback) ) { - $cb_args = array_merge( array($output, $depth), $args); - $output = call_user_func_array($start_level_callback, $cb_args); - } - } - } else if ( $element->$parent_field == $previous_element->$parent_field ) { - // On the same level as previous element, so close the previous - if ( !$to_depth || ($depth <= $to_depth) ) { - if ( !empty($end_element_callback) ) { - $cb_args = array_merge( array($output, $previous_element, $depth), $args); - $output = call_user_func_array($end_element_callback, $cb_args); - } - } - } else if ( $depth > 1 ) { - // Ascend one or more levels. - if ( !$to_depth || ($depth <= $to_depth) ) { - if ( !empty($end_element_callback) ) { - $cb_args = array_merge( array($output, $previous_element, $depth), $args); - $output = call_user_func_array($end_element_callback, $cb_args); - } - } - - while ( $parent = array_shift($parents) ) { - $depth--; - if ( !$to_depth || ($depth < $to_depth) ) { - if ( !empty($end_level_callback) ) { - $cb_args = array_merge( array($output, $depth), $args); - $output = call_user_func_array($end_level_callback, $cb_args); - } - if ( !empty($end_element_callback) ) { - $cb_args = array_merge( array($output, $parent, $depth), $args); - $output = call_user_func_array($end_element_callback, $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) ) { - if ( !empty($end_element_callback) ) { - $cb_args = array_merge( array($output, $previous_element, $depth), $args); - $output = call_user_func_array($end_element_callback, $cb_args); - } - } - } - - // Start the element. - if ( !$to_depth || ($depth <= $to_depth) ) { - if ( !empty($start_element_callback) && ($element->$id_field != 0) ) { - $cb_args = array_merge( array($output, $element, $depth), $args); - $output = call_user_func_array($start_element_callback, $cb_args); - } - } - - $previous_element = $element; - } - - return $output; -} - -function walk_page_tree($pages, $to_depth, $start_element_callback, $end_element_callback = '', $start_level_callback = '', $end_level_callback = '') { - $args = array('page', $pages, $to_depth, $start_element_callback, $end_element_callback, $start_level_callback, $end_level_callback); - $extra_args = array_slice(func_get_args(), 6); - - return call_user_func_array('walk_tree', array_merge($args, $extra_args)); -} - -function walk_category_tree($pages, $to_depth, $start_element_callback, $end_element_callback = '', $start_level_callback = '', $end_level_callback = '') { - $args = array('category', $pages, $to_depth, $start_element_callback, $end_element_callback, $start_level_callback, $end_level_callback); - $extra_args = array_slice(func_get_args(), 6); - return call_user_func_array('walk_tree', array_merge($args, $extra_args)); -} - function get_category_by_path($category_path, $full_match = true, $output = OBJECT) { global $wpdb; $category_path = rawurlencode(urldecode($category_path)); diff --git a/wp-includes/template-functions-category.php b/wp-includes/template-functions-category.php index d76cf0acc2..2886b9ad64 100644 --- a/wp-includes/template-functions-category.php +++ b/wp-includes/template-functions-category.php @@ -1,5 +1,17 @@ \n"; } @@ -197,26 +209,6 @@ function wp_dropdown_categories($args = '') { return $output; } -function _category_dropdown_element($output, $category, $depth, $selected, $args) { - $pad = str_repeat(' ', $depth * 3); - - $cat_name = apply_filters('list_cats', $category->cat_name, $category); - $output .= "\t\n"; - - return $output; -} - function wp_list_categories($args = '') { if ( is_array($args) ) $r = &$args; @@ -245,13 +237,13 @@ function wp_list_categories($args = '') { $output .= __("No categories"); } else { global $wp_query; - $current_category = $wp_query->get_queried_object_id(); + $r['current_category'] = $wp_query->get_queried_object_id(); if ( $hierarchical ) $depth = 0; // Walk the full depth. else $depth = -1; // Flat. - $output .= walk_category_tree($categories, $depth, '_category_list_element_start', '_category_list_element_end', '_category_list_level_start', '_category_list_level_end', $current_category, $r); + $output .= walk_category_tree($categories, $depth, $r); } if ( $title_li && $list ) @@ -260,88 +252,6 @@ function wp_list_categories($args = '') { echo apply_filters('list_cats', $output); } -function _category_list_level_start($output, $depth, $cat, $args) { - if ( 'list' != $args['style'] ) - return $output; - - $indent = str_repeat("\t", $depth); - $output .= "$indent\n"; - return $output; -} - -function _category_list_element_start($output, $category, $depth, $current_category, $args) { - extract($args); - - $link = 'category_description) ) - $link .= 'title="'. sprintf(__("View all posts filed under %s"), wp_specialchars($category->cat_name)) . '"'; - else - $link .= 'title="' . wp_specialchars(apply_filters('category_description',$category->category_description,$category)) . '"'; - $link .= '>'; - $link .= apply_filters('list_cats', $category->cat_name, $category).''; - - if ( (! empty($feed_image)) || (! empty($feed)) ) { - $link .= ' '; - - if ( empty($feed_image) ) - $link .= '('; - - $link .= ''; - else - $link .= $name; - $link .= ''; - if (empty($feed_image)) - $link .= ')'; - } - - if ( $show_count ) - $link .= ' ('.intval($category->category_count).')'; - - if ( $show_date ) { - $link .= ' ' . gmdate('Y-m-d', $category->last_update_timestamp); - } - - if ( 'list' == $args['style'] ) { - $output .= "\tcat_ID == $current_category) && is_category() ) - $output .= ' class="current-cat"'; - $output .= ">$link\n"; - } else { - $output .= "\t$link
    \n"; - } - - return $output; -} - -function _category_list_element_end($output, $category, $depth, $cat, $args) { - if ( 'list' != $args['style'] ) - return $output; - - $output .= "\n"; - return $output; -} - function in_category($category) { // Check if the current post is in the given category global $category_cache, $post; diff --git a/wp-includes/template-functions-post.php b/wp-includes/template-functions-post.php index 26bfdce96a..62a6b312b2 100644 --- a/wp-includes/template-functions-post.php +++ b/wp-includes/template-functions-post.php @@ -278,6 +278,17 @@ function the_meta() { Pages */ +function walk_page_tree() { + $walker = new Walker_Page; + $args = func_get_args(); + return call_user_func_array(array(&$walker, 'walk'), $args); +} + +function walk_page_dropdown_tree() { + $walker = new Walker_PageDropdown; + $args = func_get_args(); + return call_user_func_array(array(&$walker, 'walk'), $args); +} function &get_page_children($page_id, $pages) { global $page_cache; @@ -381,7 +392,7 @@ function wp_dropdown_pages($args = '') { if ( ! empty($pages) ) { $output = "\n"; } @@ -393,20 +404,6 @@ function wp_dropdown_pages($args = '') { return $output; } -function _page_dropdown_element($output, $page, $depth, $selected) { - $pad = str_repeat(' ', $depth * 3); - - $output .= "\t\n"; - - return $output; -} - function wp_list_pages($args = '') { if ( is_array($args) ) $r = &$args; @@ -428,7 +425,7 @@ function wp_list_pages($args = '') { global $wp_query; $current_page = $wp_query->get_queried_object_id(); - $output .= walk_page_tree($pages, $r['depth'], '_page_list_element_start', '_page_list_element_end', '_page_list_level_start', '_page_list_level_end', $current_page, $r['show_date'], $r['date_format']); + $output .= walk_page_tree($pages, $depth, $current_page, $r['show_date'], $r['date_format']); if ( $r['title_li'] ) $output .= ''; @@ -442,46 +439,6 @@ function wp_list_pages($args = '') { return $output; } -function _page_list_level_start($output, $depth) { - $indent = str_repeat("\t", $depth); - $output .= "$indent
      \n"; - return $output; -} - -function _page_list_level_end($output, $depth) { - $indent = str_repeat("\t", $depth); - $output .= "$indent
    \n"; - return $output; -} - -function _page_list_element_start($output, $page, $depth, $current_page, $show_date, $date_format) { - if ( $depth ) - $indent = str_repeat("\t", $depth); - - $css_class = 'page_item'; - if ( $page->ID == $current_page ) - $css_class .= ' current_page_item'; - - $output .= $indent . '
  • ' . $page->post_title . ''; - - 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 _page_list_element_end($output, $page, $depth) { - $output .= "
  • \n"; - - return $output; -} - function the_attachment_link($id = 0, $fullsize = false, $max_dims = false) { echo get_the_attachment_link($id, $fullsize, $max_dims); }