wp_list_cats() rework. Add walk_tree() and walk_category_tree(). Use get_categories() for query.

git-svn-id: http://svn.automattic.com/wordpress/trunk@3582 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
ryan 2006-03-01 13:30:19 +00:00
parent 6452ec1bbc
commit 459c030ef3
2 changed files with 239 additions and 175 deletions

View File

@ -726,32 +726,62 @@ function &get_page(&$page, $output = OBJECT) {
}
}
function walk_page_tree($pages, $to_depth, $start_element_callback, $end_element_callback = '', $start_level_callback = '', $end_level_callback = '') {
$args = array_slice(func_get_args(), 6);
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 = 0;
$previous_page = '';
$previous_element = '';
$output = '';
$last_page->post_parent = 0;
$last_page->post_id = 0;
$pages[] = $last_page;
$last_element->post_parent = 0;
$last_element->post_id = 0;
$elements[] = $last_element;
foreach ( $pages as $page ) {
if ( !empty($previous_page) && ($page->post_parent == $previous_page->ID) ) {
// Previous page is my parent. Descend a level.
array_unshift($parents, $previous_page);
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.
array_unshift($parents, $previous_element);
$depth++;
if ( !$to_depth || ($depth < $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 ( $depth && ($page->post_parent == $previous_page->post_parent) ) {
// On the same level as previous page.
} else if ( $depth && ($element->$parent_field == $previous_element->$parent_field) ) {
// On the same level as previous element.
if ( !$to_depth || ($depth < $to_depth) ) {
if ( !empty($end_element_callback) ) {
$cb_args = array_merge( array($output, $previous_page, $depth), $args);
$cb_args = array_merge( array($output, $previous_element, $depth), $args);
$output = call_user_func_array($end_element_callback, $cb_args);
}
}
@ -759,7 +789,7 @@ function walk_page_tree($pages, $to_depth, $start_element_callback, $end_element
// Ascend one or more levels.
if ( !$to_depth || ($depth < $to_depth) ) {
if ( !empty($end_element_callback) ) {
$cb_args = array_merge( array($output, $previous_page, $depth), $args);
$cb_args = array_merge( array($output, $previous_element, $depth), $args);
$output = call_user_func_array($end_element_callback, $cb_args);
}
}
@ -776,34 +806,47 @@ function walk_page_tree($pages, $to_depth, $start_element_callback, $end_element
$output = call_user_func_array($end_element_callback, $cb_args);
}
}
if ( $page->post_parent == $parents[0]->ID ) {
if ( $element->$parent_field == $parents[0]->$id_field ) {
break;
}
}
} else if ( !empty($previous_page) ) {
// Close off previous page.
} 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_page, $depth), $args);
$cb_args = array_merge( array($output, $previous_element, $depth), $args);
$output = call_user_func_array($end_element_callback, $cb_args);
}
}
}
// Start the page.
// Start the element.
if ( !$to_depth || ($depth < $to_depth) ) {
if ( !empty($start_element_callback) && ($page->ID != 0) ) {
$cb_args = array_merge( array($output, $page, $depth), $args);
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_page = $page;
$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));

View File

@ -252,14 +252,8 @@ function wp_list_cats($args = '') {
$r['hide_empty'] = 1;
if ( !isset($r['use_desc_for_title']) )
$r['use_desc_for_title'] = 1;
if ( !isset($r['children']) )
$r['children'] = true;
if ( !isset($r['child_of']) )
$r['child_of'] = 0;
if ( !isset($r['categories']) )
$r['categories'] = 0;
if ( !isset($r['recurse']) )
$r['recurse'] = 0;
if ( !isset($r['feed']) )
$r['feed'] = '';
if ( !isset($r['feed_image']) )
@ -267,138 +261,132 @@ function wp_list_cats($args = '') {
if ( !isset($r['exclude']) )
$r['exclude'] = '';
if ( !isset($r['hierarchical']) )
$r['hierarchical'] = true;
$r['hierarchical'] = false;
if ( !isset($r['title_li']) )
$r['title_li'] = '';
return list_cats($r['optionall'], $r['all'], $r['sort_column'], $r['sort_order'], $r['file'], $r['list'], $r['optiondates'], $r['optioncount'], $r['hide_empty'], $r['use_desc_for_title'], $r['children'], $r['child_of'], $r['categories'], $r['recurse'], $r['feed'], $r['feed_image'], $r['exclude'], $r['hierarchical']);
$q['orderby'] = $r['sort_column'];
$q['order'] = $r['sort_order'];
$q['include_last_update_time'] = $r['optiondates'];
extract($r);
$args = add_query_arg($q, $args);
$categories = get_categories($args);
$output = '';
if ( $title_li && $list )
$output = '<li class="categories">' . $r['title_li'] . '<ul>';
if ( empty($categories) ) {
if ( $list)
$output .= '<li>' . __("No categories") . '</li>';
else
$output .= __("No categories");
} else {
global $wp_query;
$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);
}
if ( $title_li && $list )
$output .= '</ul></li>';
echo apply_filters('list_cats', $output);
}
function _category_list_level_start($output, $depth, $cat, $args) {
if (! $args['list'])
return $output;
$indent = str_repeat("\t", $depth);
$output .= "$indent<ul class='children'>\n";
return $output;
}
function _category_list_level_end($output, $depth, $cat, $args) {
if (! $args['list'])
return $output;
$indent = str_repeat("\t", $depth);
$output .= "$indent</ul>\n";
return $output;
}
function _category_list_element_start($output, $category, $depth, $current_category, $args) {
extract($args);
$link = '<a href="' . get_category_link($category->cat_ID) . '" ';
if ( $use_desc_for_title == 0 || empty($category->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).'</a>';
if ( (! empty($feed_image)) || (! empty($feed)) ) {
$link .= ' ';
if ( empty($feed_image) )
$link .= '(';
$link .= '<a href="' . get_category_rss_link(0, $category->cat_ID, $category->category_nicename) . '"';
if ( !empty($feed) ) {
$title = ' title="' . $feed . '"';
$alt = ' alt="' . $feed . '"';
$name = $feed;
$link .= $title;
}
$link .= '>';
if ( !empty($feed_image) )
$link .= "<img src='$feed_image' $alt$title" . ' />';
else
$link .= $name;
$link .= '</a>';
if (empty($feed_image))
$link .= ')';
}
if ( intval($optioncount) == 1 )
$link .= ' ('.intval($category->category_count).')';
if ( $optiondates ) {
if ( $optiondates == 1 )
$optiondates = 'Y-m-d';
$link .= ' ' . gmdate($optiondates,$category->last_update_timestamp);
}
if ( $list ) {
$output .= "\t<li";
if ( ($category->cat_ID == $current_category) && is_category() )
$output .= ' class="current-cat"';
$output .= ">$link\n";
} else {
$output .= "\t$link<br />\n";
}
return $output;
}
function _category_list_element_end($output, $category, $depth, $cat, $args) {
if (! $args['list'])
return $output;
$output .= "</li>\n";
return $output;
}
function list_cats($optionall = 1, $all = 'All', $sort_column = 'ID', $sort_order = 'asc', $file = '', $list = true, $optiondates = 0, $optioncount = 0, $hide_empty = 1, $use_desc_for_title = 1, $children=FALSE, $child_of=0, $categories=0, $recurse=0, $feed = '', $feed_image = '', $exclude = '', $hierarchical=FALSE) {
global $wpdb, $wp_query;
// Optiondates now works
if ( '' == $file )
$file = get_settings('home') . '/';
$exclusions = '';
if ( !empty($exclude) ) {
$excats = preg_split('/[\s,]+/',$exclude);
if ( count($excats) ) {
foreach ( $excats as $excat ) {
$exclusions .= ' AND cat_ID <> ' . intval($excat) . ' ';
}
}
}
$exclusions = apply_filters('list_cats_exclusions', $exclusions );
if ( intval($categories) == 0 ) {
$sort_column = 'cat_'.$sort_column;
$query = "
SELECT cat_ID, cat_name, category_nicename, category_description, category_parent, category_count
FROM $wpdb->categories
WHERE cat_ID > 0 $exclusions
ORDER BY $sort_column $sort_order";
$categories = $wpdb->get_results($query);
}
if ( $optiondates ) {
$cat_dates = $wpdb->get_results(" SELECT category_id,
UNIX_TIMESTAMP( MAX(post_date) ) AS ts
FROM $wpdb->posts, $wpdb->post2cat, $wpdb->categories
WHERE post_type = 'post' AND post_status = 'publish' AND post_id = ID $exclusions
GROUP BY category_id");
foreach ( $cat_dates as $cat_date ) {
$category_timestamp["$cat_date->category_id"] = $cat_date->ts;
}
}
$num_found=0;
$thelist = "";
foreach ( $categories as $category ) {
if ( ( intval($hide_empty) == 0 || $category->category_count) && (!$hierarchical || $category->category_parent == $child_of) ) {
$num_found++;
$link = '<a href="'.get_category_link($category->cat_ID).'" ';
if ( $use_desc_for_title == 0 || empty($category->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).'</a>';
if ( (! empty($feed_image)) || (! empty($feed)) ) {
$link .= ' ';
if ( empty($feed_image) )
$link .= '(';
$link .= '<a href="' . get_category_rss_link(0, $category->cat_ID, $category->category_nicename) . '"';
if ( !empty($feed) ) {
$title = ' title="' . $feed . '"';
$alt = ' alt="' . $feed . '"';
$name = $feed;
$link .= $title;
}
$link .= '>';
if ( !empty($feed_image) )
$link .= "<img src='$feed_image' $alt$title" . ' />';
else
$link .= $name;
$link .= '</a>';
if (empty($feed_image))
$link .= ')';
}
if ( intval($optioncount) == 1 )
$link .= ' ('.intval($category->category_count).')';
if ( $optiondates ) {
if ( $optiondates == 1 )
$optiondates = 'Y-m-d';
$link .= ' ' . gmdate($optiondates, $category_timestamp["$category->cat_ID"]);
}
if ( $list ) {
$thelist .= "\t<li";
if (($category->cat_ID == $wp_query->get_queried_object_id()) && is_category()) {
$thelist .= ' class="current-cat"';
}
$thelist .= ">$link\n";
} else {
$thelist .= "\t$link<br />\n";
}
if ($hierarchical && $children)
$thelist .= list_cats($optionall, $all, $sort_column, $sort_order, $file, $list, $optiondates, $optioncount, $hide_empty, $use_desc_for_title, $hierarchical, $category->cat_ID, $categories, 1, $feed, $feed_image, $exclude, $hierarchical);
if ($list)
$thelist .= "</li>\n";
}
}
if ( !$num_found && !$child_of ) {
if ( $list ) {
$before = '<li>';
$after = '</li>';
}
echo $before . __("No categories") . $after . "\n";
return;
}
if ( $list && $child_of && $num_found && $recurse ) {
$pre = "\t\t<ul class='children'>";
$post = "\t\t</ul>\n";
} else {
$pre = $post = '';
}
$thelist = $pre . $thelist . $post;
if ( $recurse )
return $thelist;
echo apply_filters('list_cats', $thelist);
$query = "optionall=$optionall&all=$all&sort_column=$sort_column&sort_order=$sort_order&list=$list&optiondates=$optiondates&optioncount=$optioncount&hide_empty=$hide_empty&use_desc_for_title=$use_desc_for_title&child_of=$child_of&feed=$feed&feed_image=$feed_image&exclude=$exclude&hierarchical=$hierarchical";
return wp_list_cats($query);
}
function in_category($category) { // Check if the current post is in the given category
@ -410,6 +398,22 @@ function in_category($category) { // Check if the current post is in the given c
return false;
}
function &_get_cat_children($category_id, $categories) {
if ( empty($categories) )
return array();
$category_list = array();
foreach ( $categories as $category ) {
if ( $category->category_parent == $category_id ) {
$category_list[] = $category;
if ( $children = _get_cat_children($category->cat_ID, $categories) )
$category_list = array_merge($category_list, $children);
}
}
return $category_list;
}
function &get_categories($args = '') {
global $wpdb, $category_links;
@ -425,43 +429,60 @@ function &get_categories($args = '') {
$r['order'] = 'ASC';
if ( !isset($r['hide_empty']) )
$r['hide_empty'] = true;
if ( !isset($r['include_last_update_time']) )
$r['include_last_update_time'] = false;
if ( !isset($r['hierarchical']) )
$r['hierarchical'] = 1;
$r['orderby'] = "cat_" . $r['orderby'];
extract($r);
$exclusions = '';
if ( !empty($r['exclude']) ) {
$excategories = preg_split('/[\s,]+/',$r['exclude']);
$having = '';
$where = 'cat_ID > 0';
$exclusions = '';
if ( !empty($exclude) ) {
$excategories = preg_split('/[\s,]+/',$exclude);
if ( count($excategories) ) {
foreach ( $excategories as $excat ) {
$exclusions .= ' AND cat_ID <> ' . intval($excat) . ' ';
}
}
}
$exclusions = apply_filters('list_cats_exclusions', $exclusions );
$where .= $exclusions;
$categories = $wpdb->get_results("SELECT * " .
"FROM $wpdb->categories " .
"$exclusions " .
"ORDER BY " . $r['orderby'] . " " . $r['order']);
if ( $hide_empty ) {
if ( 'link' == $type )
$having = 'HAVING link_count > 0';
else
$having = 'HAVING category_count > 0';
}
$categories = $wpdb->get_results("SELECT * FROM $wpdb->categories WHERE $where $having ORDER BY $orderby $order");
if ( empty($categories) )
return array();
if ( $r['hide_empty'] ) {
foreach ( $categories as $category ) {
$count = 0;
if ( 'link' == $r['type'] ) {
$count = $category->link_count;
} else {
$count = $category->category_count;
}
if ( $count )
$the_categories[] = $category;
if ( $include_last_update_time ) {
$stamps = $wpdb->get_results("SELECT category_id, UNIX_TIMESTAMP( MAX(post_date) ) AS ts FROM $wpdb->posts, $wpdb->post2cat, $wpdb->categories
WHERE post_status = 'publish' AND post_id = ID AND $where GROUP BY category_id");
global $cat_stamps;
foreach ($stamps as $stamp)
$cat_stamps[$stamp->category_id] = $stamp->ts;
function stamp_cat($cat) {
global $cat_stamps;
$cat->last_update_timestamp = $cat_stamps[$cat->cat_ID];
return $cat;
}
$categories = $the_categories;
$categories = array_map('stamp_cat', $categories);
unset($cat_stamps);
}
/* if ( $r['child_of'] )
$categories = & get_category_children($r['child_of'], $categories); */
if ( $child_of || $hierarchical )
$categories = & _get_cat_children($child_of, $categories);
return $categories;
}