<?php
/*
Plugin Name: Category Visibility
Plugin URI: http://www.gudlyf.com/archives/2005/03/08/wordpress-plugin-category-visibility/
Description: Alter the visibility settings for categories.
Author: Keith McDuffee
Version: 0.31
Author URI: http://www.gudlyf.com/
*/ 

$cat_visibility $table_prefix "cat_visibility";

function 
category_vis_menu () {

    
add_submenu_page('edit.php''Category Visibility''Category Visibility'9basename(__FILE__), 'category_visibility');

}

function 
category_visibility () {

    global 
$wpdb;
    global 
$cat_visibility;
    global 
$user_level;

    
get_currentuserinfo();

    if (empty(
$user_level)) $user_level 0;
    if (!
is_numeric($user_level)) $user_level 0;

    if(
$wpdb->query("CREATE TABLE IF NOT EXISTS $cat_visibility (
            cat_ID bigint(20) UNIQUE,
            front int(4) NOT NULL default 1,
            list int(4) NOT NULL default 1,
            search int(4) NOT NULL default 1,
            feed int(4) NOT NULL default 1,
            archives int(4) NOT NULL default 1,
            user_level int(4) NOT NULL default 0
            )"
));
    
?>
<?php 
if ($_POST["action"] == "editcatvis"): ?>
<div class="updated"><p><strong><?php _e('Changes Submitted.'); ?></p></div>
<?php endif; ?>
<div class="wrap">
<?php if ( $user_level ) : ?>
<?php 
else : ?>
        <h2><?php _e('Category Visibility'?> </h2>
<?php endif; ?>
<form name="catvis" id="catvis" action="edit.php?page=<?php echo basename(__FILE__); ?>" method="post">
<table width="100%" cellpadding="3" cellspacing="3">
        <tr>
        <th scope="col"><?php _e('ID'?></th>
        <th scope="col"><?php _e('Name'?></th>
        <th scope="col"><?php _e('Visibility'?></th>
        </tr>
<?php
if ($_POST["action"] == "editcatvis") {
    
edit_cat_vis();
}

my_cat_rows();
?>
</table>
<p>
<strong>Front:</strong> Visibility on the front/main page.<br />
<strong>List:</strong> Visibility on the list of categories on the home page.<br />
<strong>Search:</strong> Visibility in search results.<br />
<strong>Feed:</strong> Visibility in RSS/RSS2/Atom feeds.<br />
<strong>Archive:</strong> Visibility in archive links (i.e., calendar links).<br />
<strong>User Level:</strong> Visibility on user level basis. All users up to this level can see posts as checked. Does not affect feed visibility, obviously.
</p>
<p class="submit"><input type="hidden" name="action" value="editcatvis" /><input type="submit" name="submit" value="<?php _e('Submit Changes &raquo;'?>" />
</p>
</form>

</div>
<?php
}

function 
my_cat_rows($parent 0$level 0$categories 0) {

        global 
$wpdb$class$user_level;
    global 
$cat_visibility;

    
get_currentuserinfo();

    if (empty(
$user_level)) $user_level 0;
    if (!
is_numeric($user_level)) $user_level 0;

        if (!
$categories)
                
$categories $wpdb->get_results("SELECT * FROM $wpdb->categories ORDER BY cat_name");

        if (
$categories) {
                foreach (
$categories as $category) {
                        if (
$category->category_parent == $parent) {
                                
$category->cat_name wp_specialchars($category->cat_name);
                                
$pad str_repeat('&#8212; '$level);
                                if ( 
$user_level ) {
                            
$catvis $wpdb->get_results("SELECT * FROM $cat_visibility WHERE cat_ID=$category->cat_ID LIMIT 1");
                    
$catvis $catvis[0];
                    if (
$catvis->front == || $catvis == 0$catvis_front "checked"; else $catvis_front "";
                    if (
$catvis->list == || $catvis == 0$catvis_list "checked"; else $catvis_list "";
                    if (
$catvis->search == || $catvis == 0$catvis_search "checked"; else $catvis_search "";
                    if (
$catvis->feed == || $catvis == 0$catvis_feed "checked"; else $catvis_feed "";
                    if (
$catvis->archives == || $catvis == 0$catvis_archives "checked"; else $catvis_archives "";
                    
$catvis_user_level $catvis->user_level;
                                        
$edit "Front: <input name='" $category->cat_ID "_front' class='edit' type='checkbox' $catvis_front />&nbsp;&nbsp;";
                                        
$edit .= "List: <input name='" $category->cat_ID "_list' class='edit' type='checkbox' $catvis_list />&nbsp;&nbsp;";
                                        
$edit .= "Search: <input name='" $category->cat_ID "_search' class='edit' type='checkbox' $catvis_search />&nbsp;&nbsp;";
                                        
$edit .= "Feed: <input name='" $category->cat_ID "_feed' class='edit' type='checkbox' $catvis_feed />&nbsp;&nbsp;";
                                        
$edit .= "Archives: <input name='" $category->cat_ID "_archives' class='edit' type='checkbox' $catvis_archives />&nbsp;&nbsp;";
                                        
$edit .= "User Level: <input name='" $category->cat_ID "_user_level' class='edit' type='text' size='3' value='" $catvis_user_level "' />";
                }
                                else
                                        
$edit '';

                                
$class = ('alternate' == $class) ? '' 'alternate';
                                echo 
"<tr class='$class'><th scope='row'>$category->cat_ID</th><td>$pad $category->cat_name</td>
                                <td style='text-align: center'>$edit</td>
                                </tr>"
;
                                
my_cat_rows($category->cat_ID$level 1$categories);
                        }
                }
        } else {
                return 
false;
        }
}

function 
edit_cat_vis () {

    global 
$wpdb;
    global 
$cat_visibility;

        if (!
$categories)
                
$categories $wpdb->get_results("SELECT cat_ID FROM $wpdb->categories");

        if (
$categories) {
                foreach (
$categories as $category) {
            
$front $category->cat_ID "_front";
            
$list $category->cat_ID "_list";
            
$search $category->cat_ID "_search";
            
$feed $category->cat_ID "_feed";
            
$archives $category->cat_ID "_archives";
            
$user_level $category->cat_ID "_user_level";

            if (
$_POST["$front"] == "on"$front 1; else $front 0;
            if (
$_POST["$list"] == "on"$list 1; else $list 0;
            if (
$_POST["$search"] == "on"$search 1; else $search 0;
            if (
$_POST["$feed"] == "on"$feed 1; else $feed 0;
            if (
$_POST["$archives"] == "on"$archives 1; else $archives 0;
            
$user_level $_POST["$user_level"];

            if (empty(
$user_level)) $user_level 0;
            if(!
is_numeric($user_level)) $user_level 0;
        
            
$wpdb->query("REPLACE INTO $cat_visibility SET cat_ID=$category->cat_ID, front=$front, list=$list, search=$search, feed=$feed, archives=$archives, user_level=$user_level");
        }
    }


}


function 
alter_vis_posts ($posts) {

    global 
$wpdb$wp_query;
    global 
$pagenow;
    global 
$cat_visibility;
    global 
$user_level;

    
get_currentuserinfo();

    if (empty(
$user_level)) $user_level 0;
    if (!
is_numeric($user_level)) $user_level 0;

    
/* If no posts for the selection, just return */
    
if (!$posts)
        return;

    
/* If we're in the admin menu, return unfiltered */
    
if ($pagenow == 'edit.php')
        return 
$posts;

    
/* If table is empty, show all for now */
    
if(!$wpdb->get_results("SELECT cat_ID from $cat_visibility"))
        return 
$posts;

    
$visposts = array();

    
$q $wp_query->query_vars;

    
/* Check if the category page itself should show posts */
    
if (isset($q['category_name'])) {
        
$cat_nicename rtrim($q['category_name'], "/");
        
$cat_nicename array_pop(explode("/"$cat_nicename));
        
$cats $wpdb->get_results("SELECT cat_ID FROM $wpdb->categories WHERE category_nicename='$cat_nicename' LIMIT 1");
        if(
$cats) {
            foreach (
$cats as $cat) {
                
$thiscat $cat->cat_ID;
            }
        }
        if(
$wpdb->query("SELECT cat_ID FROM $cat_visibility WHERE cat_ID=$thiscat AND archives=1 AND user_level<=$user_level"))
            return 
$posts;
        else
            return;
    }

    
/* Check if archived pages should show posts */
    
if(isset($q['year'])) {
        foreach (
$posts as $post) {
            
$categories get_the_category($post->ID);
            
$visible 0;
            foreach (
$categories as $category) {
                if(
$wpdb->query("SELECT cat_ID FROM $cat_visibility WHERE cat_ID=$category->cat_ID AND archives=1 AND user_level<=$user_level"))
                    
$visible 1;
            }
            if (
$visible == 1)
                
array_push($visposts$post);
        }    
        return 
$visposts;
    }    

    
/* Check if search results should show posts */
    
if (isset ($q['s'])) {
        foreach (
$posts as $post) {
            
$categories get_the_category($post->ID);
            
$visible 0;
            foreach (
$categories as $category) {
                if(
$wpdb->query("SELECT cat_ID FROM $cat_visibility WHERE cat_ID=$category->cat_ID AND search=1 AND user_level<=$user_level"))
                    
$visible 1;
            }
            if (
$visible == 1)
                
array_push($visposts$post);
        }    
        return 
$visposts;
    }

    
/* Continue with front page */

    
foreach ($posts as $post) {
        
$visible 0;
        if(
$categories get_the_category($post->ID)) {
            foreach (
$categories as $category) {
                if(isset (
$q['feed'])) {
                    if(
$wpdb->query("SELECT cat_ID FROM $cat_visibility WHERE cat_ID=$category->cat_ID AND feed=1")) {
                        
$visible 1;
                    }
                } elseif (
$wpdb->query("SELECT cat_ID FROM $cat_visibility WHERE cat_ID=$category->cat_ID AND front=1 AND user_level<=$user_level")) {
                    
$visible 1;
                }
            }
        } else
            
$visible 1;

        if (
$visible == 1)
            
array_push($visposts$post);
        
    }

    return 
$visposts;
}

function 
alter_vis_catlist ($thelist) {

    global 
$wpdb;
    global 
$cat_visibility;
    global 
$user_level;

    
get_currentuserinfo();

    if (empty(
$user_level)) $user_level 0;
    if (!
is_numeric($user_level)) $user_level 0;

    
/* If table is empty, show all for now */
    
if(!$wpdb->get_results("SELECT cat_ID from $cat_visibility"))
        return 
$thelist;

    if (
preg_match("/href/"$thelist)) {
        
$newlist "";
        
$children 0;
        
$linklist preg_split('/\t/'$thelist);
        foreach (
$linklist as $link) {
            if(
preg_match("/class.*children/"$link)) {
                
$children 1;
                
$newlist .= $link;
            } elseif(
preg_match("/<\/ul>/"$link) && $children) {
                
$children 0;
                
$newlist .= $link;
            } else {
                
$thiscatname strip_tags($link);
                
$thiscatname preg_replace("/\s+\(\d+\)\s+/"""$thiscatname);
                
$thiscatname trim($thiscatname);
                if(!empty(
$thiscatname)) {
                    
$cats $wpdb->get_results("SELECT cat_ID from $wpdb->categories WHERE cat_name='$thiscatname' LIMIT 1");
                    if (
$cats) {
                        foreach (
$cats as $cat) {
                            
$thiscat $cat->cat_ID;
                        }
                        if(
$wpdb->query("SELECT cat_ID FROM $cat_visibility WHERE cat_ID=$thiscat AND list=1 AND user_level<=$user_level"))
                            
$newlist .= $link;
                    }
                }
            }
        }
        return 
$newlist;
    } else {
        
$thiscatname $thelist;
    }

    
$cats $wpdb->get_results("SELECT cat_ID from $wpdb->categories WHERE cat_name='$thiscatname' LIMIT 1");
    if (
$cats) {
        foreach (
$cats as $cat) {
            
$thiscat $cat->cat_ID;
        }
        if(
$wpdb->query("SELECT cat_ID FROM $cat_visibility WHERE cat_ID=$thiscat AND list=1 AND user_level<=$user_level"))
            return 
$thelist;
        else
            return;
    } else {
        return 
$thelist;
    }

}

add_action('admin_menu''category_vis_menu');
add_filter('the_posts''alter_vis_posts');
add_filter('list_cats''alter_vis_catlist');

?>