2006-06-04 17:36:52 -04:00
< ? php
function get_all_category_ids () {
global $wpdb ;
if ( ! $cat_ids = wp_cache_get ( 'all_category_ids' , 'category' ) ) {
$cat_ids = $wpdb -> get_col ( " SELECT cat_ID FROM $wpdb->categories " );
2007-04-11 22:27:12 -04:00
wp_cache_add ( 'all_category_ids' , $cat_ids , 'category' );
2006-06-04 17:36:52 -04:00
}
return $cat_ids ;
}
function & get_categories ( $args = '' ) {
global $wpdb , $category_links ;
if ( is_array ( $args ) )
$r = & $args ;
else
parse_str ( $args , $r );
$defaults = array ( 'type' => 'post' , 'child_of' => 0 , 'orderby' => 'name' , 'order' => 'ASC' ,
2006-09-19 19:56:28 -04:00
'hide_empty' => true , 'include_last_update_time' => false , 'hierarchical' => 1 , 'exclude' => '' , 'include' => '' ,
2007-01-09 03:45:05 -05:00
'number' => '' , 'pad_counts' => false );
2006-06-04 17:36:52 -04:00
$r = array_merge ( $defaults , $r );
2006-07-11 14:01:53 -04:00
if ( 'count' == $r [ 'orderby' ] )
$r [ 'orderby' ] = 'category_count' ;
else
$r [ 'orderby' ] = " cat_ " . $r [ 'orderby' ]; // restricts order by to cat_ID and cat_name fields
2006-07-11 14:15:24 -04:00
$r [ 'number' ] = ( int ) $r [ 'number' ];
2006-06-04 17:36:52 -04:00
extract ( $r );
2006-11-23 11:52:42 -05:00
$key = md5 ( serialize ( $r ) );
if ( $cache = wp_cache_get ( 'get_categories' , 'category' ) )
if ( isset ( $cache [ $key ] ) )
2007-01-31 00:57:54 -05:00
return apply_filters ( 'get_categories' , $cache [ $key ], $r );
2006-11-23 11:52:42 -05:00
2006-06-04 17:36:52 -04:00
$where = 'cat_ID > 0' ;
$inclusions = '' ;
if ( ! empty ( $include ) ) {
2006-07-10 23:33:25 -04:00
$child_of = 0 ; //ignore child_of and exclude params if using include
$exclude = '' ;
2006-06-04 17:36:52 -04:00
$incategories = preg_split ( '/[\s,]+/' , $include );
if ( count ( $incategories ) ) {
foreach ( $incategories as $incat ) {
if ( empty ( $inclusions ))
$inclusions = ' AND ( cat_ID = ' . intval ( $incat ) . ' ' ;
else
$inclusions .= ' OR cat_ID = ' . intval ( $incat ) . ' ' ;
}
}
}
2006-07-10 23:33:25 -04:00
if ( ! empty ( $inclusions ))
$inclusions .= ')' ;
2006-06-04 17:36:52 -04:00
$where .= $inclusions ;
$exclusions = '' ;
if ( ! empty ( $exclude ) ) {
$excategories = preg_split ( '/[\s,]+/' , $exclude );
if ( count ( $excategories ) ) {
foreach ( $excategories as $excat ) {
if ( empty ( $exclusions ))
$exclusions = ' AND ( cat_ID <> ' . intval ( $excat ) . ' ' ;
else
$exclusions .= ' AND cat_ID <> ' . intval ( $excat ) . ' ' ;
// TODO: Exclude children of excluded cats? Note: children are getting excluded
}
}
}
2006-07-10 23:33:25 -04:00
if ( ! empty ( $exclusions ))
2006-06-04 17:36:52 -04:00
$exclusions .= ')' ;
2006-07-10 23:33:25 -04:00
$exclusions = apply_filters ( 'list_cats_exclusions' , $exclusions , $r );
2006-06-04 17:36:52 -04:00
$where .= $exclusions ;
2006-08-17 00:46:16 -04:00
if ( $hide_empty && ! $hierarchical ) {
2006-06-04 17:36:52 -04:00
if ( 'link' == $type )
2006-07-24 14:24:56 -04:00
$where .= ' AND link_count > 0' ;
2006-06-04 17:36:52 -04:00
else
2006-07-24 14:24:56 -04:00
$where .= ' AND category_count > 0' ;
2006-06-04 17:36:52 -04:00
}
2006-07-11 14:15:24 -04:00
if ( ! empty ( $number ) )
$number = 'LIMIT ' . $number ;
else
$number = '' ;
2006-07-24 14:24:56 -04:00
$categories = $wpdb -> get_results ( " SELECT * FROM $wpdb->categories WHERE $where ORDER BY $orderby $order $number " );
2006-06-04 17:36:52 -04:00
if ( empty ( $categories ) )
return array ();
// TODO: Integrate this into the main query.
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 ];
2006-07-10 23:33:25 -04:00
return $cat ;
2006-06-04 17:36:52 -04:00
}
$categories = array_map ( 'stamp_cat' , $categories );
unset ( $cat_stamps );
}
2007-04-04 16:44:45 -04:00
if ( $child_of || $hierarchical ) {
$children = _get_category_hierarchy ();
if ( ! empty ( $children ) )
$categories = & _get_cat_children ( $child_of , $categories );
}
2006-06-04 17:36:52 -04:00
2006-08-17 00:46:16 -04:00
// Update category counts to include children.
2007-01-09 03:45:05 -05:00
if ( $pad_counts )
_pad_category_counts ( $type , $categories );
// Make sure we show empty categories that have children.
if ( $hierarchical && $hide_empty ) {
2006-08-17 00:46:16 -04:00
foreach ( $categories as $k => $category ) {
2007-01-09 03:45:05 -05:00
if ( ! $category -> { 'link' == $type ? 'link_count' : 'category_count' } ) {
$children = _get_cat_children ( $category -> cat_ID , $categories );
2006-08-17 00:46:16 -04:00
foreach ( $children as $child )
2007-01-09 03:45:05 -05:00
if ( $child -> { 'link' == $type ? 'link_count' : 'category_count' } )
continue 2 ;
// It really is empty
2006-08-17 00:46:16 -04:00
unset ( $categories [ $k ]);
2007-01-09 03:45:05 -05:00
}
2006-08-17 00:46:16 -04:00
}
}
reset ( $categories );
2006-11-23 11:52:42 -05:00
$cache [ $key ] = $categories ;
2007-04-11 22:27:12 -04:00
wp_cache_add ( 'get_categories' , $cache , 'category' );
2006-11-23 11:52:42 -05:00
2007-04-07 01:24:37 -04:00
$categories = apply_filters ( 'get_categories' , $categories , $r );
return $categories ;
2006-06-04 17:36:52 -04:00
}
// Retrieves category data given a category ID or category object.
// Handles category caching.
function & get_category ( & $category , $output = OBJECT ) {
global $wpdb ;
if ( empty ( $category ) )
return null ;
if ( is_object ( $category ) ) {
wp_cache_add ( $category -> cat_ID , $category , 'category' );
$_category = $category ;
} else {
2007-03-27 19:45:41 -04:00
$category = ( int ) $category ;
2006-06-04 17:36:52 -04:00
if ( ! $_category = wp_cache_get ( $category , 'category' ) ) {
$_category = $wpdb -> get_row ( " SELECT * FROM $wpdb->categories WHERE cat_ID = ' $category ' LIMIT 1 " );
2007-04-11 22:27:12 -04:00
wp_cache_add ( $category , $_category , 'category' );
2006-06-04 17:36:52 -04:00
}
}
2006-07-10 12:11:43 -04:00
$_category = apply_filters ( 'get_category' , $_category );
2006-06-04 17:36:52 -04:00
if ( $output == OBJECT ) {
return $_category ;
} elseif ( $output == ARRAY_A ) {
return get_object_vars ( $_category );
} elseif ( $output == ARRAY_N ) {
return array_values ( get_object_vars ( $_category ));
} else {
return $_category ;
}
}
function get_category_by_path ( $category_path , $full_match = true , $output = OBJECT ) {
global $wpdb ;
$category_path = rawurlencode ( urldecode ( $category_path ));
$category_path = str_replace ( '%2F' , '/' , $category_path );
$category_path = str_replace ( '%20' , ' ' , $category_path );
$category_paths = '/' . trim ( $category_path , '/' );
$leaf_path = sanitize_title ( basename ( $category_paths ));
$category_paths = explode ( '/' , $category_paths );
2006-12-09 01:35:22 -05:00
$full_path = '' ;
foreach ( ( array ) $category_paths as $pathdir )
$full_path .= ( $pathdir != '' ? '/' : '' ) . sanitize_title ( $pathdir );
2006-06-04 17:36:52 -04:00
$categories = $wpdb -> get_results ( " SELECT cat_ID, category_nicename, category_parent FROM $wpdb->categories WHERE category_nicename = ' $leaf_path ' " );
2006-07-10 23:33:25 -04:00
if ( empty ( $categories ) )
2006-06-04 17:36:52 -04:00
return NULL ;
foreach ( $categories as $category ) {
$path = '/' . $leaf_path ;
$curcategory = $category ;
2006-09-07 13:42:24 -04:00
while ( ( $curcategory -> category_parent != 0 ) && ( $curcategory -> category_parent != $curcategory -> cat_ID ) ) {
2006-06-04 17:36:52 -04:00
$curcategory = $wpdb -> get_row ( " SELECT cat_ID, category_nicename, category_parent FROM $wpdb->categories WHERE cat_ID = ' $curcategory->category_parent ' " );
$path = '/' . $curcategory -> category_nicename . $path ;
}
if ( $path == $full_path )
return get_category ( $category -> cat_ID , $output );
}
// If full matching is not required, return the first cat that matches the leaf.
if ( ! $full_match )
return get_category ( $categories [ 0 ] -> cat_ID , $output );
return NULL ;
}
// Get the ID of a category from its name
function get_cat_ID ( $cat_name = 'General' ) {
global $wpdb ;
$cid = $wpdb -> get_var ( " SELECT cat_ID FROM $wpdb->categories WHERE cat_name=' $cat_name ' " );
return $cid ? $cid : 1 ; // default to cat 1
}
// Deprecate
function get_catname ( $cat_ID ) {
return get_cat_name ( $cat_ID );
}
// Get the name of a category from its ID
function get_cat_name ( $cat_id ) {
$cat_id = ( int ) $cat_id ;
$category = & get_category ( $cat_id );
return $category -> cat_name ;
}
2006-11-24 11:37:44 -05:00
function cat_is_ancestor_of ( $cat1 , $cat2 ) {
if ( is_int ( $cat1 ) )
$cat1 = & get_category ( $cat1 );
if ( is_int ( $cat2 ) )
$cat2 = & get_category ( $cat2 );
if ( ! $cat1 -> cat_ID || ! $cat2 -> category_parent )
return false ;
if ( $cat2 -> category_parent == $cat1 -> cat_ID )
return true ;
return cat_is_ancestor_of ( $cat1 , get_category ( $cat2 -> parent_category ));
}
2006-06-04 17:36:52 -04:00
//
// Private
//
function & _get_cat_children ( $category_id , $categories ) {
if ( empty ( $categories ) )
return array ();
$category_list = array ();
2007-04-23 16:31:47 -04:00
$has_children = _get_category_hierarchy ();
2007-04-04 18:32:24 -04:00
2007-04-23 16:31:47 -04:00
if ( ( 0 != $category_id ) && ! isset ( $has_children [ $category_id ]) )
2007-04-04 18:32:24 -04:00
return array ();
2006-06-04 17:36:52 -04:00
foreach ( $categories as $category ) {
2006-09-07 13:42:24 -04:00
if ( $category -> cat_ID == $category_id )
continue ;
2006-06-04 17:36:52 -04:00
if ( $category -> category_parent == $category_id ) {
$category_list [] = $category ;
2007-04-04 18:32:24 -04:00
2007-04-23 16:31:47 -04:00
if ( ! isset ( $has_children [ $category -> cat_ID ]) )
2007-04-04 16:44:45 -04:00
continue ;
2007-04-23 16:31:47 -04:00
2006-06-04 17:36:52 -04:00
if ( $children = _get_cat_children ( $category -> cat_ID , $categories ) )
$category_list = array_merge ( $category_list , $children );
}
}
return $category_list ;
}
2007-01-09 03:45:05 -05:00
// Recalculates link or post counts by including items from child categories
// Assumes all relevant children are already in the $categories argument
function _pad_category_counts ( $type , & $categories ) {
global $wpdb ;
// Set up some useful arrays
foreach ( $categories as $key => $cat ) {
$cats [ $cat -> cat_ID ] = & $categories [ $key ];
$cat_IDs [] = $cat -> cat_ID ;
}
// Get the relevant post2cat or link2cat records and stick them in a lookup table
if ( $type == 'post' ) {
$results = $wpdb -> get_results ( " SELECT post_id, category_id FROM $wpdb->post2cat LEFT JOIN $wpdb->posts ON post_id = ID WHERE category_id IN ( " . join ( ',' , $cat_IDs ) . " ) AND post_type = 'post' AND post_status = 'publish' " );
foreach ( $results as $row )
++ $cat_items [ $row -> category_id ][ $row -> post_id ];
} else {
$results = $wpdb -> get_results ( " SELECT $wpdb->link2cat .link_id, category_id FROM $wpdb->link2cat LEFT JOIN $wpdb->links USING (link_id) WHERE category_id IN ( " . join ( ',' , $cat_IDs ) . " ) AND link_visible = 'Y' " );
foreach ( $results as $row )
++ $cat_items [ $row -> category_id ][ $row -> link_id ];
}
// Touch every ancestor's lookup row for each post in each category
foreach ( $cat_IDs as $cat_ID ) {
$child = $cat_ID ;
while ( $parent = $cats [ $child ] -> category_parent ) {
if ( ! empty ( $cat_items [ $cat_ID ]) )
foreach ( $cat_items [ $cat_ID ] as $item_id => $touches )
++ $cat_items [ $parent ][ $item_id ];
$child = $parent ;
}
}
// Transfer the touched cells
2007-01-10 15:42:17 -05:00
foreach ( ( array ) $cat_items as $id => $items )
2007-01-09 03:45:05 -05:00
if ( isset ( $cats [ $id ]) )
$cats [ $id ] -> { 'link' == $type ? 'link_count' : 'category_count' } = count ( $items );
}
2007-04-04 16:44:45 -04:00
function _get_category_hierarchy () {
$children = get_option ( 'category_children' );
if ( is_array ( $children ) )
return $children ;
$children = array ();
$categories = get_categories ( 'hide_empty=0&hierarchical=0' );
foreach ( $categories as $cat ) {
if ( $cat -> category_parent > 0 )
$children [ $cat -> category_parent ][] = $cat -> cat_ID ;
}
update_option ( 'category_children' , $children );
return $children ;
}
2006-06-04 17:36:52 -04:00
?>