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:
parent
6452ec1bbc
commit
459c030ef3
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue