0

I would like to know is there any way/Plugin to limit the the post number of a category? And whenever user publish new post in that category then the category release the old post automatically?

Like this:

Category A, Category B, Category C

Here Category A is limited which can hold only one (specific number) post. Now user publish a post which is in Category A and Category B. After that user publish a post which is in Category A and Category C.

And here the magic should happen. That the category A release the very first post from it. And the first post will be related to only Category B.

Any ideas?

1 Answer 1

0

My understanding is that you want to set number of posts limit on your categories, so that each category will have specified number of posts. After a very long time I am trying to answer a question on WordPress SE, so I hope I will make sense.

Explanation

Categories does not have meta data, so you are going to need your own custom table to store category limits. Reading and writing to the custom table should be abstracted in your custom meta functions. For example get_post_count_limit. Once the get and set functions are ready, then you can then hook up to your desired WordPress actions (as you mentioned publish post, so in the code below I have used the publish_post action).

In the function hooked to publish_post action, you simple loop over all the categories assigned to the post, check their limit using the custom function and then check the category_count property. If category_count exceeds the limit, simply fetch the oldest posts and remove category from them.

Code

<?php
/**
 * Plugin Name: Category Post Count Limit
 * Description: Allows to set limit on number of posts in a category
 * Author: Hameedullah Khan
 **/



add_action( 'publish_post', 'cpcl_check_post_limit' );
function cpcl_check_post_limit( $post_id ) {
    $cat_ids = wp_get_post_categories( $post_id );
    foreach( $cat_ids as $cat_id ) {
        $cat = get_category( $cat_id );
        $post_count_limit = get_post_count_limit( $cat_id );
        if ( $post_count_limit < 1 ) { // limit lower then 1 means unlimited.
            continue;
        }
        $category_count = $cat->category_count;
        if ( $category_count > $post_count_limit ) {
            $numposts = $category_count - $post_count_limit;
            $query = new WP_Query( array( 'category__in' => array( $cat_id ), 'orderby' => 'date', 'posts_per_page' => $numposts, 'order' => 'ASC' ) );
            while ($query->have_posts() ) {
                $query->next_post();
                $cp_cat_ids = wp_get_post_categories( $query->post->ID );
                unset( $cp_cat_ids[array_search( $cat_id, $cp_cat_ids )] );
                $cp_cat_ids = array_values( $cp_cat_ids );
                wp_set_post_categories( $query->post->ID, $cp_cat_ids );

            }
            wp_reset_postdata();
        }
    }
}

add_action( 'category_add_form_fields', 'cpcl_field_add', 10, 1);
function cpcl_field_add( $cat ) {
?>
    <div class="form-field">
        <label for="post-count">Post Count Limit</label><input type="text" name="post-count" type="text" /></label>
    </div>
<?php
}

add_action( 'category_edit_form_fields', 'cpcl_field_edit', 10, 1 );
function cpcl_field_edit( $cat ) {
    $post_count = get_post_count_limit( $cat->term_id );
?>
    <tr class="form-field">
        <th scope="row" valign="top">
            <label for="post-count">Post Count Limit</label>
        </th>
        <td>
            <input type="text" name="post-count" type="text" value="<?php echo $post_count; ?>" /></label>
        </td>
    </tr>
<?php
}


add_action( 'created_category', 'cpcl_save_post_count_limit', 10, 1 );
add_action( 'edited_category', 'cpcl_save_post_count_limit', 10, 1 );
function cpcl_save_post_count_limit( $cat_id ) {
    if (current_user_can( 'manage_categories' ) && isset( $_POST['post-count'] ) ) {
        $post_count_limit = ( int ) $_POST['post-count'];
        update_post_count_limit( $cat_id, $post_count_limit );
    }

}

function get_post_count_limit( $cat_id, $return_null = false ) {
    global $wpdb;

    $table_name = $wpdb->prefix . 'cat_post_count_limit';

    $cpcl_meta = $wpdb->get_row( "SELECT * FROM $table_name WHERE cat_id = $cat_id" );

    if ( ! $cpcl_meta ) {
        if ( $return_null && $cpcl_meta == null ) {
            return null;
        } else {
            return 0;
        }
    } else {
        return $cpcl_meta->post_count;
    }
}
function update_post_count_limit( $cat_id, $post_count_limit ) {
    global $wpdb;

    $table_name = $wpdb->prefix . 'cat_post_count_limit';

    if ( get_post_count_limit( $cat_id, true) == null )  {
        $wpdb->insert( 
            $table_name, 
            array(
                'cat_id' => $cat_id,
                'post_count' => $post_count_limit
            ),
            array(
                '%d',
                '%d'
            )
        );
        return $wpdb->insert_id;
    } else {

        return $wpdb->update(
            $table_name,
            array(
                'post_count' => $post_count_limit
            ),
            array(
                'cat_id' => $cat_id
            ),
            array( '%d' ),
            array( '%d' )
        );
    }
}

function cpcl_initialize_categories() {
    global $wpdb;

    $table_name = $wpdb->prefix . 'cat_post_count_limit';

    $sql = "CREATE TABLE IF NOT EXISTS `$table_name` (
        `cpcl_id` int(11) NOT NULL AUTO_INCREMENT,
        `cat_id` int(11) NOT NULL,
        `post_count` int(11) NOT NULL,
        PRIMARY KEY (`cpcl_id`)
    )";
    require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
    dbDelta( $sql );
}
register_activation_hook( __FILE__, 'cpcl_initialize_categories' );
?>

Note: Use the above code as plugin, so the custom table can be create on plugin creation. If you don't want to use it as plugin you will have to create the custom table manually.

Really looking forward for suggestions on improving my answer and/or code.

3
  • Thanks. It works first time. But when I write new post and publish it it does't remove leave the old post from the category. Any fix for that?
    – pervez
    Commented Dec 7, 2013 at 6:00
  • It should work. What is your Wordpress version? Commented Dec 8, 2013 at 5:49
  • My Wordpress version 3.7.1 And I set post count limit 5 but it holds now almost 7 post and counting on... But thanks for the plugin. That category had almost 1000+ post. After installing this plugin first time it does the job to post count but now it remain as past.
    – pervez
    Commented Dec 10, 2013 at 15:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.