<?php
/*!\mainpage
Plugin Name: Show Category Posts

Version: 1.4.1 (Burt)

Plugin URI: http://mookitty.co.uk/devblog/catagories/show-categories/

Description: Creates a <code>$scp_posts</code> global variable containing the posts of the specified categories for use in a WP loop. Creates a <code>$hcp_posts</code> global variable to replace <code>$posts</code> in the WP loop, with the specified categories removed. Format of <code>$scp_posts</code> <code>$hcp_posts</code> is the same as <code>$posts</code><br />(c) 2004, licensed under the GPL

Author: Kitten

Author URI: http://blog.mookitty.co.uk

\section change_sec Changelog:
1.0 - Initial release

1.1 - Fix SQL error when no optional params are passed

1.2 - Added 'LIMIT' option - thanks Vincent <nolageek@yahoo.com>

1.3 - Logic rewrite & add hide_category_posts()

1.3.1 - Fix permalink display & add 'hide_always' option

1.4 - Make hide_category_post() accept negation

\section qi_sec Quick Install:
Drop showcategories.php into your plugins folder and activate using the plugins control panel.

\section dis_sec Description:
This plugin adds two functions to your WordPress blog:

<strong>show_category_posts()</strong> - Creates a new global variable: $scp_posts. Which contains the posts in the categories you specify.

<strong>hide_category_posts()</strong> - Creats a new global variable: $hcp_posts. Which is a replacement for the built-in WordPress variable $posts. $hcp_posts contains the posts that would normally be shown on the page except for the categories that you wish to omit. <em>Also, if you supply a negative category number this function will show only the posts in that category.</em>

<em>NOTE: if a post is in 2 or more categories, and one of those categories is in the hide list, the post will be hidden.</em>

\section use_sect Usage:
The two functions each fill a different need, and are used differently.

<code>show_category_posts()</code> is used strictly for showing posts in specified categories. These posts show under almost all conditions, and if $scp_posts is used in the main WP loop, the results will be unpredictable at best. This is because it doesn't check the page enviroment, and doesn't care if you're looking at a permalink or all the posts for a certain day. It's job is to show posts. Of course this makes it perfect for displaying sidebar content!

Now, <code>hide_category_posts()</code> is a different animal. It (and <code>$hcp_posts</code>)is made specifically for replacing <code>$posts</code> in the WP loop. It respects the user enviroment and will display the page correctly regardless if a permalink is clicked or search results are displayed. It's able to hide multiple categories and supports the negation ('-') operatior for easy exclusion of all but one category. In a negated context, e.g. <code>hide_category_posts('category=-5')</code> all posts NOT in category 5 will be hidden. This is to provide a universal way to hide posts w/o having to abuse <code>show_category_posts()</code>.

\section hcp_sect Hiding Categories:
To omit categories from your pages, do the following:

In <code>index.php</code> replace:

<code><?php if ($posts) : foreach ($posts as $post) : start_wp(); ?></code>

with:

<code><?php hide_category_posts( 'category=1' ); ?></code>

<code><?php if ($hcp_posts) : foreach ($hcp_posts as $post) : start_wp(); ?></code>


This example hides the category numbered '1'. You can hide as many categories as you want in the following
format:

To hide categories 2, 5, 8 and 15 do this:

<code><?php hide_category_posts( 'category=2,5,8,15' ); ?></code>

To not display the category in the category menu do the following:

Change:

<code><?php wp_list_cats(); ?></code>

To:

<code><?php wp_list_cats('exclude=2,5,8,15'); ?></code>

\subsection hcopt_sec Options:
The following options are available when calling hide_category_posts():

\subsubsection hcpara_sec Parameters Used:

<em>NOTE: parameters are passed in 'URL GET' format, where parameters are assigned a value with an equal sign and seperated by an amperstand:</em>

<code>'value1=foo&value2=bar'</code>

<strong>category</strong> -    This is the number of the category to hide all posts from. If negative all posts will be hidden except for the posts in the specified category.

To hide all posts from category 1 on the front page:

<code><?php hide_category_posts('category=1'); ?></code>

To hide all categories except 15 do this:

<code><?php hide_category_posts( 'category=-15' ); ?></code>

<strong>hide_always</strong> -    By default hide_category_posts() will display posts from hidden categories under the following conditions:

(1)    When a date on the calendar is clicked upon

(2)    If the hidden categories are still listed in the category menu AND there is only one post in the category.

(3)    When a post in a hidden category is searched for and found.

To make sure that your hidden categories stay hidden when a date is clicked on (condition 1) call the function like so:

To hide all posts from category 1 on the front page and from date searches:

<code><?php hide_category_posts('category=1&hide_always=true'); ?></code>

<em>NOTE: Conditions 2 & 3 will always return the post, to do otherwise would break things like commenting and permalinking on that post.</em>

\section scp_sec Selecting Categories:

To create a custom WP loop using the $scp_posts, refer to the following for an example. This creates a mini-blog in a div named "leftcol", that shows posts from category 10 that are published, sorted by post name in a decending manner. The actual layout is up to you, using the same functions that are used in the main WP loop. You can see an example of this on http://mookitty.co.uk/devblog. The two boxes on the left side are created using this technique. show_category_posts() also supports advandced selection logic using negitive numbers.

In index.php add:<br>
<code>&lt;div id=&quot;leftcol&quot;&gt;<br>
&lt;ul&gt;\<br>
&lt;li&gt;&lt;?php echo show_category_posts('category=10&amp;scp_status=publish&amp;sort_order=DESC&amp;sort_field=post_name'); ?&gt;&lt;/li&gt;<br>
&lt;ul&gt;<br>
&lt;?php if ($scp_posts) : foreach ($scp_posts as $post) : start_wp(); ?&gt;<br>
&lt;li&gt;&lt;a href=&quot;&lt;?php the_permalink() ?&gt;&quot; rel=&quot;bookmark&quot; title=&quot;Permanent Link: &lt;?php the_title(); ?&gt;&quot;&gt;&lt;?php the_title(); ?&gt;&lt;/a&gt;&amp;nbsp;&lt;?php echo $post-&gt;post_excerpt ?&gt;
&lt;br /&gt;<br>
&lt;span class=&quot;sidecomments&quot;&gt;<br>
&lt;?php comments_popup_link(__('Comments (0)'), __('Comments (1)'), __('Comments (%)')); ?&gt;&lt;/span&gt;&lt;/li&gt;<br>
&lt;?php endforeach; ?&gt;<br>
&lt;/ul&gt;<br>
&lt;?php else: ?&gt;<br>
&lt;p&gt;&lt;?php _e('Sorry, no posts matched your criteria.'); ?&gt;&lt;/p&gt;
&lt;?php endif; ?&gt;<br>
&lt;/ul&gt;<br>
&lt;/div&gt;<br></code>

\subsection scp_opts Options:
The following options are available when calling show_category_posts():

\subsubsection scp_para Parameters Used:

<em>NOTE: parameters are passed in 'URL GET' format, where parameters are assigned a value with an equal sign and seperated by an amperstand:</em>

<code>'value1=foo&value2=bar'</code>

<strong>category</strong> -    This is the number of the category to show all posts from. Use a negative number to return all posts NOT in that category.

Get all posts from category 1:

<code><?php show_category_posts('category=1'); ?></code>

Get all posts not in category 1:

<code><?php show_category_posts('category=-1'); ?></code>

Get all posts in category 1 and 3 but not in category 5:

<code><?php show_category_posts('category=1,3,-5'); ?></code>

<em>NOTE: Using the function with a negative number to exclude    a category will cause the excluded category name to appear    as the output of the function. If you use a negative number,    it's advised to also pass a title to be returned.</em>

<strong>scp_title</strong> -     By default the tag returns the category name of the first category number that was passed in the first parameter. By using this parameter you can have the output be anything you like:

<code><?php show_category_posts('category=1&scp_title=Mini-Blog'); ?></code>

<strong>sort_order</strong> -    The default sort order is Decending (highest to lowest) date order, to have the oldest posts at the top, call the fuction like so:

<code><?php show_category_posts('category=1&sort_order=ASC'); ?></code>

<strong>sort_field</strong> -    The default is to sort by categories and then post dates. You can sort on any field that is in the wp_posts table. To change this to have all posts be sorted by name call the plugin like so:

<code><?php show_category_posts('category=1&sort_field=post_name'); ?></code>

<strong>scp_limit</strong> -     The default returns all posts that are found in the chosen categories. You can change this to limit the number of posts returned. To get the 15 most recent posts, call the plugin like so:

<code><?php show_category_posts('category=1&scp_limit=15'); ?></code>

<strong>scp_status</strong> -    The default returns all post that are found in the chosen categories, regardless of status. To change this to return only published posts, call the plugin like so:

<code><?php show_category_posts('category=1&scp_status=publish'); ?></code>

Good Luck!
*/

// Format: show_category_posts( 'category=1,5,6,-4&scp_title=Mini-Blog&scp_status=publish&sort_order=DESC
//                                 &sort_field=post_date&scp_limit=10' );
function show_category_posts$str_to_parse ) {

    global 
$wpdb$tableposts$tablepost2cat$tablecategories$m$scp_posts;
    
parse_str($str_to_parse);
    
$cat_array explode','$category ); // Make array of cats & nocats

    
for( $i=0$i count($cat_array); $i++ ) {
        if( 
$cat_array[$i] < ) {
            
$get_cats_exclude[] = "$tablecategories.cat_ID != ".abs$cat_array[$i] ).' ';
        } else {
            
$get_cats_include[] = "$tablecategories.cat_ID  = ".abs$cat_array[$i] ).' ';
        }
    }
    if( 
count($get_cats_include) > ) {
        
$get_cats ' AND ( '.implode' OR '$get_cats_include ).' ) ';
    }
    if( 
count($get_cats_exclude) > ) {
        
$get_cats .= 'AND ( '.implode' OR '$get_cats_exclude ).' ) ';
    }
    if( !empty(
$scp_status) ) {
        
$scp_status "AND ( post_status = '$scp_status' ) ";
    }

    
// If a date ($m) is specified in the querystring, load that month
    
if ('' != $m) {
    
$m '' preg_replace('|[^0-9]|'''$m);
    
$scp_date .= ' AND YEAR(post_date)=' substr($m04);
    if (
strlen($m)>5)
        
$scp_date .= ' AND MONTH(post_date)=' substr($m42);
    if (
strlen($m)>7)
        
$scp_date .= ' AND DAYOFMONTH(post_date)=' substr($m62);
    if (
strlen($m)>9)
        
$scp_date .= ' AND HOUR(post_date)=' substr($m82);
    if (
strlen($m)>11)
        
$scp_date .= ' AND MINUTE(post_date)=' substr($m102);
    if (
strlen($m)>13)
        
$scp_date .= ' AND SECOND(post_date)=' substr($m122);
    }

    
// Make query meat:
    
$scp_request  "SELECT DISTINCT * FROM $tableposts";
    
$scp_request .= " LEFT JOIN $tablepost2cat ON ($tableposts.ID = $tablepost2cat.post_id)";
    
$scp_request .= " LEFT JOIN $tablecategories ON ($tablepost2cat.category_id = $tablecategories.cat_ID)";
    
$scp_request .= " WHERE 1=1 $scp_status $get_cats $scp_date";
    
$scp_request .= " GROUP BY $tableposts.ID";

    if( empty( 
$sort_order) ) {
        
$sort_order 'DESC';
    }
    if( !empty( 
$sort_field ) ) {
    
$scp_request .=    " ORDER BY $sort_field $sort_order";
    } else {
    
$scp_request .= " ORDER BY $tablecategories.cat_ID, post_date $sort_order";
    }
    if( !empty( 
$scp_limit ) ) {
        
$scp_request .= " LIMIT $scp_limit";
    }
    
$scp_posts $wpdb->get_results$scp_request );

    if( empty( 
$scp_title ) ) {
        return( 
get_the_category_by_IDabs$cat_array[0] ) ) );
    } else {
        return( 
$scp_title );
    }
// end of show_category_posts()

//    Format: hide_category_posts( 'category=1,5,6&hide_always=true' );
function hide_category_posts $str_to_parse ) {
    global 
$hcp_posts$wpdb$posts$tableposts$tablepost2cat$tablecategories;
    global 
$search$whichcat$whichauthor$monthnum$year$m;
    
parse_str($str_to_parse);

    if( 
count$posts ) == ) {
        
// This usually means that a permalink was clicked on
        
$hcp_posts $posts;
        return;
    } elseif( (!empty(
$search) || !empty($whichcat) || !empty($whichauthor) || !empty($monthnum ) || !empty($year) || !empty($m)) && $hide_always != 'true' ) {
        
//Let's not screw with any results
        
$hcp_posts $posts;
        return;
    } else {
    
// It's ok to mess about:
        
$cat_array explode','$category ); // Make array of cats & nocats
        
if( $posts ) {
            foreach( 
$posts as $post ) {
                
$hcp_request  "SELECT post_id, category_id FROM $tablepost2cat";
                
$hcp_request .= " WHERE post_id = $post->ID";
                
$post_cats $wpdb->get_results($hcp_request);
                
$add_to_list '';
                foreach( 
$post_cats as $post_cat ) {
                    foreach( 
$cat_array as $cat ) {
                        if( 
intval($cat) > ) {
                            if( 
$post_cat->category_id == $cat ) {
                                
$add_to_list '';
                                break;
                            } else {
                                
$add_to_list $post;
                            }
                        } else {
                            if( 
$post_cat->category_id != abs($cat) ) {
                                
$add_to_list '';
                                break;
                            } else {
                                
$add_to_list $post;
                            }
                        }
                    }
                }
                if( 
$add_to_list ) {
                    
$hcp_posts[] = $add_to_list;
                }
            }
        }
    }
}    
// end of hide_category_posts()
?>