Changeset 3582

Show
Ignore:
Timestamp:
03/01/06 13:30:19 (3 years ago)
Author:
ryan
Message:

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

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/wp-includes/functions.php

    r3579 r3582  
    727727} 
    728728 
    729 function walk_page_tree($pages, $to_depth, $start_element_callback, $end_element_callback = '', $start_level_callback = '', $end_level_callback = '') { 
    730     $args = array_slice(func_get_args(), 6); 
     729function walk_tree($tree_type, $elements, $to_depth, $start_element_callback, $end_element_callback = '', $start_level_callback = '', $end_level_callback = '') { 
     730    $args = array_slice(func_get_args(), 7); 
    731731    $parents = array(); 
    732732    $depth = 0; 
    733     $previous_page = ''; 
     733    $previous_element = ''; 
    734734    $output = ''; 
    735735 
    736     $last_page->post_parent = 0; 
    737     $last_page->post_id = 0; 
    738     $pages[] = $last_page; 
    739  
    740     foreach ( $pages as $page ) { 
    741         if ( !empty($previous_page) && ($page->post_parent == $previous_page->ID) ) { 
    742             // Previous page is my parent. Descend a level. 
    743             array_unshift($parents, $previous_page); 
     736    $last_element->post_parent = 0; 
     737    $last_element->post_id = 0; 
     738    $elements[] = $last_element; 
     739 
     740    if ( 'page' == $tree_type ) { 
     741        $parent_field = 'post_parent'; 
     742        $id_field = 'ID';    
     743    } else { 
     744        $parent_field = 'category_parent'; 
     745        $id_field = 'cat_ID';            
     746    } 
     747 
     748    $flat = false; 
     749    if ( $to_depth == -1 ) 
     750        $flat = true; 
     751 
     752    foreach ( $elements as $element ) { 
     753        // If flat, start and end the element and skip the level checks. 
     754        if ( $flat) { 
     755            // Start the element. 
     756            if ( !empty($start_element_callback) && ($element->$id_field != 0) ) { 
     757                $cb_args = array_merge( array($output, $element, $depth), $args); 
     758                $output = call_user_func_array($start_element_callback, $cb_args); 
     759            } 
     760 
     761            // End the element. 
     762            if ( !empty($end_element_callback) && ($element->$id_field != 0) ) { 
     763                $cb_args = array_merge( array($output, $element, $depth), $args); 
     764                $output = call_user_func_array($end_element_callback, $cb_args); 
     765            } 
     766 
     767            continue;    
     768        } 
     769 
     770        // Walk the tree. 
     771        if ( !empty($previous_element) && ($element->$parent_field == $previous_element->$id_field) ) { 
     772            // Previous element is my parent. Descend a level. 
     773            array_unshift($parents, $previous_element); 
    744774            $depth++; 
    745775            if ( !$to_depth || ($depth < $to_depth) ) 
     
    748778                    $output = call_user_func_array($start_level_callback, $cb_args); 
    749779                } 
    750         } else if ( $depth && ($page->post_parent == $previous_page->post_parent) ) { 
    751             // On the same level as previous page
     780        } else if ( $depth && ($element->$parent_field == $previous_element->$parent_field) ) { 
     781            // On the same level as previous element
    752782            if ( !$to_depth || ($depth < $to_depth) ) { 
    753783                if ( !empty($end_element_callback) ) { 
    754                     $cb_args = array_merge( array($output, $previous_page, $depth), $args); 
     784                    $cb_args = array_merge( array($output, $previous_element, $depth), $args); 
    755785                    $output = call_user_func_array($end_element_callback, $cb_args); 
    756786                } 
     
    760790            if ( !$to_depth || ($depth < $to_depth) ) { 
    761791                if ( !empty($end_element_callback) ) { 
    762                     $cb_args = array_merge( array($output, $previous_page, $depth), $args); 
     792                    $cb_args = array_merge( array($output, $previous_element, $depth), $args); 
    763793                    $output = call_user_func_array($end_element_callback, $cb_args); 
    764794                } 
     
    777807                    } 
    778808                } 
    779                 if ( $page->post_parent == $parents[0]->ID ) { 
     809                if ( $element->$parent_field == $parents[0]->$id_field ) { 
    780810                    break; 
    781811                } 
    782812            } 
    783         } else if ( !empty($previous_page) ) { 
    784             // Close off previous page
     813        } else if ( !empty($previous_element) ) { 
     814            // Close off previous element
    785815            if ( !$to_depth || ($depth < $to_depth) ) { 
    786816                if ( !empty($end_element_callback) ) { 
    787                     $cb_args = array_merge( array($output, $previous_page, $depth), $args); 
     817                    $cb_args = array_merge( array($output, $previous_element, $depth), $args); 
    788818                    $output = call_user_func_array($end_element_callback, $cb_args); 
    789819                } 
     
    791821        } 
    792822 
    793         // Start the page
     823        // Start the element
    794824        if ( !$to_depth || ($depth < $to_depth) ) { 
    795             if ( !empty($start_element_callback) && ($page->ID != 0) ) { 
    796                 $cb_args = array_merge( array($output, $page, $depth), $args); 
     825            if ( !empty($start_element_callback) && ($element->$id_field != 0) ) { 
     826                $cb_args = array_merge( array($output, $element, $depth), $args); 
    797827                $output = call_user_func_array($start_element_callback, $cb_args); 
    798828            } 
    799829        } 
    800830 
    801         $previous_page = $page
     831        $previous_element = $element
    802832    } 
    803833 
    804834    return $output; 
     835} 
     836 
     837function walk_page_tree($pages, $to_depth, $start_element_callback, $end_element_callback = '', $start_level_callback = '', $end_level_callback = '') { 
     838    $args = array('page', $pages, $to_depth, $start_element_callback, $end_element_callback, $start_level_callback, $end_level_callback); 
     839    $extra_args = array_slice(func_get_args(), 6); 
     840 
     841    return call_user_func_array('walk_tree', array_merge($args, $extra_args)); 
     842} 
     843 
     844function walk_category_tree($pages, $to_depth, $start_element_callback, $end_element_callback = '', $start_level_callback = '', $end_level_callback = '') { 
     845    $args = array('category', $pages, $to_depth, $start_element_callback, $end_element_callback, $start_level_callback, $end_level_callback); 
     846    $extra_args = array_slice(func_get_args(), 6); 
     847    return call_user_func_array('walk_tree', array_merge($args, $extra_args)); 
    805848} 
    806849 
  • trunk/wp-includes/template-functions-category.php

    r3570 r3582  
    253253    if ( !isset($r['use_desc_for_title']) ) 
    254254        $r['use_desc_for_title'] = 1; 
    255     if ( !isset($r['children']) ) 
    256         $r['children'] = true; 
    257255    if ( !isset($r['child_of']) ) 
    258256        $r['child_of'] = 0; 
    259     if ( !isset($r['categories']) ) 
    260         $r['categories'] = 0; 
    261     if ( !isset($r['recurse']) ) 
    262         $r['recurse'] = 0; 
    263257    if ( !isset($r['feed']) ) 
    264258        $r['feed'] = ''; 
     
    268262        $r['exclude'] = ''; 
    269263    if ( !isset($r['hierarchical']) ) 
    270         $r['hierarchical'] = true; 
    271  
    272     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']); 
     264        $r['hierarchical'] = false; 
     265    if ( !isset($r['title_li']) ) 
     266        $r['title_li'] = ''; 
     267 
     268    $q['orderby'] = $r['sort_column']; 
     269    $q['order'] = $r['sort_order']; 
     270    $q['include_last_update_time'] = $r['optiondates']; 
     271     
     272    extract($r); 
     273 
     274    $args = add_query_arg($q, $args); 
     275    $categories = get_categories($args); 
     276 
     277    $output = ''; 
     278    if ( $title_li && $list ) 
     279            $output = '<li class="categories">' . $r['title_li'] . '<ul>'; 
     280 
     281    if ( empty($categories) ) { 
     282        if ( $list) 
     283            $output .= '<li>' . __("No categories") . '</li>'; 
     284        else 
     285            $output .= __("No categories"); 
     286    } else { 
     287        global $wp_query; 
     288        $current_category = $wp_query->get_queried_object_id(); 
     289        if ( $hierarchical ) 
     290            $depth = 0;  // Walk the full depth. 
     291        else 
     292            $depth = -1; // Flat. 
     293 
     294        $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); 
     295    } 
     296 
     297    if ( $title_li && $list ) 
     298        $output .= '</ul></li>'; 
     299             
     300    echo apply_filters('list_cats', $output); 
     301
     302 
     303function _category_list_level_start($output, $depth, $cat, $args) { 
     304    if (! $args['list']) 
     305        return $output; 
     306 
     307    $indent = str_repeat("\t", $depth); 
     308    $output .= "$indent<ul class='children'>\n"; 
     309    return $output; 
     310
     311 
     312function _category_list_level_end($output, $depth, $cat, $args) { 
     313    if (! $args['list']) 
     314        return $output; 
     315 
     316    $indent = str_repeat("\t", $depth); 
     317    $output .= "$indent</ul>\n"; 
     318    return $output; 
     319
     320 
     321function _category_list_element_start($output, $category, $depth, $current_category, $args) { 
     322    extract($args); 
     323 
     324    $link = '<a href="' . get_category_link($category->cat_ID) . '" '; 
     325    if ( $use_desc_for_title == 0 || empty($category->category_description) ) 
     326        $link .= 'title="'. sprintf(__("View all posts filed under %s"), wp_specialchars($category->cat_name)) . '"'; 
     327    else 
     328        $link .= 'title="' . wp_specialchars(apply_filters('category_description',$category->category_description,$category)) . '"'; 
     329    $link .= '>'; 
     330    $link .= apply_filters('list_cats', $category->cat_name, $category).'</a>'; 
     331 
     332    if ( (! empty($feed_image)) || (! empty($feed)) ) { 
     333        $link .= ' '; 
     334 
     335        if ( empty($feed_image) ) 
     336            $link .= '('; 
     337 
     338        $link .= '<a href="' . get_category_rss_link(0, $category->cat_ID, $category->category_nicename) . '"'; 
     339 
     340        if ( !empty($feed) ) { 
     341            $title = ' title="' . $feed . '"'; 
     342            $alt = ' alt="' . $feed . '"'; 
     343            $name = $feed; 
     344            $link .= $title; 
     345        } 
     346 
     347        $link .= '>'; 
     348 
     349        if ( !empty($feed_image) ) 
     350            $link .= "<img src='$feed_image' $alt$title" . ' />'; 
     351        else 
     352            $link .= $name; 
     353        $link .= '</a>'; 
     354        if (empty($feed_image)) 
     355            $link .= ')'; 
     356    } 
     357 
     358    if ( intval($optioncount) == 1 ) 
     359        $link .= ' ('.intval($category->category_count).')'; 
     360 
     361    if ( $optiondates ) { 
     362        if ( $optiondates == 1 ) 
     363            $optiondates = 'Y-m-d'; 
     364        $link .= ' ' . gmdate($optiondates,$category->last_update_timestamp); 
     365    } 
     366 
     367    if ( $list ) { 
     368        $output .= "\t<li"; 
     369        if ( ($category->cat_ID == $current_category) && is_category() ) 
     370            $output .=  ' class="current-cat"'; 
     371        $output .= ">$link\n"; 
     372    } else { 
     373        $output .= "\t$link<br />\n"; 
     374    } 
     375 
     376    return $output; 
     377
     378 
     379function _category_list_element_end($output, $category, $depth, $cat, $args) { 
     380    if (! $args['list']) 
     381        return $output; 
     382 
     383    $output .= "</li>\n"; 
     384    return $output; 
    273385} 
    274386 
    275387function 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) { 
    276     global $wpdb, $wp_query; 
    277     // Optiondates now works 
    278     if ( '' == $file ) 
    279         $file = get_settings('home') . '/'; 
    280  
    281     $exclusions = ''; 
    282     if ( !empty($exclude) ) { 
    283         $excats = preg_split('/[\s,]+/',$exclude); 
    284         if ( count($excats) ) { 
    285             foreach ( $excats as $excat ) { 
    286                 $exclusions .= ' AND cat_ID <> ' . intval($excat) . ' '; 
    287             } 
    288         } 
    289     } 
    290  
    291     $exclusions = apply_filters('list_cats_exclusions', $exclusions ); 
    292  
    293     if ( intval($categories) == 0 ) { 
    294         $sort_column = 'cat_'.$sort_column; 
    295  
    296         $query = " 
    297             SELECT cat_ID, cat_name, category_nicename, category_description, category_parent, category_count 
    298             FROM $wpdb->categories 
    299             WHERE cat_ID > 0 $exclusions 
    300             ORDER BY $sort_column $sort_order"; 
    301  
    302         $categories = $wpdb->get_results($query); 
    303     } 
    304  
    305     if ( $optiondates ) { 
    306         $cat_dates = $wpdb->get_results("   SELECT category_id, 
    307         UNIX_TIMESTAMP( MAX(post_date) ) AS ts 
    308         FROM $wpdb->posts, $wpdb->post2cat, $wpdb->categories 
    309         WHERE post_type = 'post' AND post_status = 'publish' AND post_id = ID $exclusions 
    310         GROUP BY category_id"); 
    311         foreach ( $cat_dates as $cat_date ) { 
    312             $category_timestamp["$cat_date->category_id"] = $cat_date->ts; 
    313         } 
    314     } 
    315  
    316     $num_found=0; 
    317     $thelist = ""; 
    318  
    319     foreach ( $categories as $category ) { 
    320         if ( ( intval($hide_empty) == 0 || $category->category_count) && (!$hierarchical || $category->category_parent == $child_of) ) { 
    321             $num_found++; 
    322             $link = '<a href="'.get_category_link($category->cat_ID).'" '; 
    323             if ( $use_desc_for_title == 0 || empty($category->category_description) ) 
    324                 $link .= 'title="'. sprintf(__("View all posts filed under %s"), wp_specialchars($category->cat_name)) . '"'; 
    325             else 
    326                 $link .= 'title="' . wp_specialchars(apply_filters('category_description',$category->category_description,$category)) . '"'; 
    327             $link .= '>'; 
    328             $link .= apply_filters('list_cats', $category->cat_name, $category).'</a>'; 
    329  
    330             if ( (! empty($feed_image)) || (! empty($feed)) ) { 
    331  
    332                 $link .= ' '; 
    333  
    334                 if ( empty($feed_image) ) 
    335                     $link .= '('; 
    336  
    337                 $link .= '<a href="' . get_category_rss_link(0, $category->cat_ID, $category->category_nicename) . '"'; 
    338  
    339                 if ( !empty($feed) ) { 
    340                     $title = ' title="' . $feed . '"'; 
    341                     $alt = ' alt="' . $feed . '"'; 
    342                     $name = $feed; 
    343                     $link .= $title; 
    344                 } 
    345  
    346                 $link .= '>'; 
    347  
    348                 if ( !empty($feed_image) ) 
    349                     $link .= "<img src='$feed_image' $alt$title" . ' />'; 
    350                 else 
    351                     $link .= $name; 
    352  
    353                 $link .= '</a>'; 
    354  
    355                 if (empty($feed_image)) 
    356                     $link .= ')'; 
    357             } 
    358  
    359             if ( intval($optioncount) == 1 ) 
    360                 $link .= ' ('.intval($category->category_count).')'; 
    361  
    362             if ( $optiondates ) { 
    363                 if ( $optiondates == 1 ) 
    364                     $optiondates = 'Y-m-d'; 
    365                 $link .= ' ' . gmdate($optiondates, $category_timestamp["$category->cat_ID"]); 
    366             } 
    367  
    368             if ( $list ) { 
    369                 $thelist .= "\t<li"; 
    370                 if (($category->cat_ID == $wp_query->get_queried_object_id()) && is_category()) { 
    371                     $thelist .=  ' class="current-cat"'; 
    372                 } 
    373                 $thelist .= ">$link\n"; 
    374             } else { 
    375                 $thelist .= "\t$link<br />\n"; 
    376             } 
    377  
    378             if ($hierarchical && $children) 
    379                 $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); 
    380             if ($list) 
    381                 $thelist .= "</li>\n"; 
    382         } 
    383     } 
    384     if ( !$num_found && !$child_of ) { 
    385         if ( $list ) { 
    386             $before = '<li>'; 
    387             $after = '</li>'; 
    388         } 
    389         echo $before . __("No categories") . $after . "\n"; 
    390         return; 
    391     } 
    392     if ( $list && $child_of && $num_found && $recurse ) { 
    393         $pre = "\t\t<ul class='children'>"; 
    394         $post = "\t\t</ul>\n"; 
    395     } else { 
    396         $pre = $post = ''; 
    397     } 
    398     $thelist = $pre . $thelist . $post; 
    399     if ( $recurse ) 
    400         return $thelist; 
    401     echo apply_filters('list_cats', $thelist); 
     388    $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"; 
     389    return wp_list_cats($query); 
    402390} 
    403391 
     
    409397    else 
    410398        return false; 
     399} 
     400 
     401function &_get_cat_children($category_id, $categories) { 
     402    if ( empty($categories) ) 
     403        return array(); 
     404 
     405    $category_list = array(); 
     406    foreach ( $categories as $category ) { 
     407        if ( $category->category_parent == $category_id ) { 
     408            $category_list[] = $category; 
     409            if ( $children = _get_cat_children($category->cat_ID, $categories) ) 
     410                $category_list = array_merge($category_list, $children); 
     411        } 
     412    } 
     413 
     414    return $category_list; 
    411415} 
    412416 
     
    426430    if ( !isset($r['hide_empty']) ) 
    427431        $r['hide_empty'] = true; 
     432    if ( !isset($r['include_last_update_time']) ) 
     433        $r['include_last_update_time'] = false; 
     434    if ( !isset($r['hierarchical']) ) 
     435        $r['hierarchical'] = 1; 
    428436 
    429437    $r['orderby'] = "cat_" . $r['orderby']; 
    430438 
     439    extract($r); 
     440 
    431441    $exclusions = ''; 
    432     if ( !empty($r['exclude']) ) { 
    433         $excategories = preg_split('/[\s,]+/',$r['exclude']); 
     442    $having = ''; 
     443    $where = 'cat_ID > 0'; 
     444 
     445    $exclusions = ''; 
     446    if ( !empty($exclude) ) { 
     447        $excategories = preg_split('/[\s,]+/',$exclude); 
    434448        if ( count($excategories) ) { 
    435449            foreach ( $excategories as $excat ) { 
     
    438452        } 
    439453    } 
    440  
    441     $categories = $wpdb->get_results("SELECT * " . 
    442         "FROM $wpdb->categories " . 
    443         "$exclusions " . 
    444         "ORDER BY " . $r['orderby'] . " " . $r['order']); 
     454    $exclusions = apply_filters('list_cats_exclusions', $exclusions ); 
     455    $where .= $exclusions; 
     456 
     457    if ( $hide_empty ) { 
     458        if ( 'link' == $type ) 
     459            $having = 'HAVING link_count > 0'; 
     460        else 
     461            $having = 'HAVING category_count > 0'; 
     462    } 
     463 
     464    $categories = $wpdb->get_results("SELECT * FROM $wpdb->categories WHERE $where $having ORDER BY $orderby $order"); 
    445465 
    446466    if ( empty($categories) ) 
    447467        return array(); 
    448468 
    449     if ( $r['hide_empty'] ) { 
    450         foreach ( $categories as $category ) { 
    451             $count = 0; 
    452             if ( 'link' == $r['type'] ) { 
    453                 $count = $category->link_count; 
    454             } else { 
    455                 $count = $category->category_count;  
    456             } 
    457             if ( $count ) 
    458                 $the_categories[] = $category;  
    459         } 
    460         $categories = $the_categories; 
    461     } 
    462  
    463     /* if ( $r['child_of'] ) 
    464         $categories = & get_category_children($r['child_of'], $categories); */ 
     469    if ( $include_last_update_time ) { 
     470        $stamps = $wpdb->get_results("SELECT category_id, UNIX_TIMESTAMP( MAX(post_date) ) AS ts FROM $wpdb->posts, $wpdb->post2cat, $wpdb->categories 
     471                            WHERE post_status = 'publish' AND post_id = ID AND $where GROUP BY category_id"); 
     472        global $cat_stamps; 
     473        foreach ($stamps as $stamp) 
     474            $cat_stamps[$stamp->category_id] = $stamp->ts; 
     475        function stamp_cat($cat) { 
     476            global $cat_stamps; 
     477            $cat->last_update_timestamp = $cat_stamps[$cat->cat_ID]; 
     478            return $cat;     
     479        } 
     480        $categories = array_map('stamp_cat', $categories); 
     481        unset($cat_stamps); 
     482    } 
     483 
     484    if ( $child_of || $hierarchical ) 
     485        $categories = & _get_cat_children($child_of, $categories); 
    465486 
    466487    return $categories;