0

I'm using a modified version of the Recent Posts plugin together with WP Total Cache. I'm using post__not_in as I don't want to display the current post again. It works well, but if Object Cache is activated, on some posts post__not_in does not work.

Here is my code:

<?php function nothing_recent_posts_init() {
                register_widget('nothing_recent_posts');
            }
            add_action('widgets_init', 'nothing_recent_posts_init');


            class nothing_recent_posts extends WP_Widget {

                function __construct() {
                    $widget_ops = array('classname' => 'nothing_recent_posts', 'description' => __( "Customized version of Recent Posts. You can choose what to display and add custom classes.") );
                    parent::__construct('nothing-recent-posts', __('Customized Recent Posts'), $widget_ops);
                    $this->alt_option_name = 'nothing_recent_entries';

                    add_action( 'save_post', array($this, 'flush_widget_cache') );
                    add_action( 'deleted_post', array($this, 'flush_widget_cache') );
                    add_action( 'switch_theme', array($this, 'flush_widget_cache') );
                }

                function widget($args, $instance) {
                    $cache = wp_cache_get('nothing_recent_posts', 'widget');

                    if ( !is_array($cache) )
                        $cache = array();

                    if ( ! isset( $args['widget_id'] ) )
                        $args['widget_id'] = $this->id;

                    if ( isset( $cache[ $args['widget_id'] ] ) ) {
                        echo $cache[ $args['widget_id'] ];
                        return;
                    }

                    ob_start();
                    extract($args);

                    $title = ( ! empty( $instance['title'] ) ) ? $instance['title'] : __( 'Recent Posts' );
                    $title = apply_filters( 'widget_title', $title, $instance, $this->id_base );
                    $number = ( ! empty( $instance['number'] ) ) ? absint( $instance['number'] ) : 10;
                    if ( ! $number )
                        $number = 10;
                    $show_title = isset( $instance['show_title'] ) ? $instance['show_title'] : false;
                    $show_date = isset( $instance['show_date'] ) ? $instance['show_date'] : false;
                    $show_img = isset( $instance['show_img'] ) ? $instance['show_img'] : false;
                    $custom_class = ( ! empty( $instance['custom_class'] ) ) ? $instance['custom_class'] : ' ';
                    $query_by_cat = isset( $instance['query_by_cat'] ) ? $instance['query_by_cat'] : false;

                    if( $query_by_cat ){
                        $current_category = wp_get_post_categories( get_the_id() );
                        $r = new WP_Query( apply_filters( 'widget_posts_args', array(
                            'category__in' => $current_category,
                            'posts_per_page' => $number,
                            'no_found_rows' => true,
                            'post_status' => 'publish',
                            'ignore_sticky_posts' => true,
                            'post__not_in' => array(get_the_id())
                        ) ) );
                    }else{
                        $r = new WP_Query( apply_filters( 'widget_posts_args', array(
                            'posts_per_page' => $number,
                            'no_found_rows' => true,
                            'post_status' => 'publish',
                            'ignore_sticky_posts' => true,
                            'post__not_in' => array(get_the_id())
                        ) ) );
                    }
                    if ($r->have_posts()) : ?>
                    <?php echo $before_widget; ?>
                    <?php if ( $title ) echo $before_title . $title . $after_title; ?>

                    <?php while ( $r->have_posts() ) : $r->the_post(); ?>

                    <article class="hentry <?php echo $custom_class; ?>">
                        <a href="<?php the_permalink(); ?>" rel="bookmark" title='Den Beitrag "<?php the_title(); ?>" ansehen'>

                            <?php if ( $show_img ) : ?>
                            <div class="entry-thumbnail">
                                <?php the_post_thumbnail( 'thumbnail' ); ?>
                            </div><!-- .entry-thumbnail -->
                            <?php endif; ?>

                            <?php if ( $show_title ) : ?>
                            <header class="widget-entry-header">
                            <div class="inner">
                                <h2><?php the_title(); ?></h2>
                            </div>
                            </header><!-- .entry-header -->
                            <?php endif; ?>

                            <?php if ( $show_date ) : ?>
                                <span class="post-date"><?php echo get_the_date(); ?></span>
                            <?php endif; ?>
                        </a>
                    </article>
                    <?php endwhile; ?>

                    <?php echo $after_widget; ?>
                    <?php wp_reset_postdata();

                    endif;

                    $cache[$args['widget_id']] = ob_get_flush();
                    wp_cache_set('nothing_recent_posts', $cache, 'widget');
                }

                function update( $new_instance, $old_instance ) {
                    $instance = $old_instance;
                    $instance['title'] = strip_tags($new_instance['title']);
                    $instance['number'] = (int) $new_instance['number'];
                    $instance['show_date'] = isset( $new_instance['show_date'] ) ? (bool) $new_instance['show_date'] : false;
                    $instance['show_title'] = isset( $new_instance['show_title'] ) ? (bool) $new_instance['show_title'] : false;
                    $instance['show_img'] = isset( $new_instance['show_img'] ) ? (bool) $new_instance['show_img'] : false;
                    $instance['custom_class'] = strip_tags($new_instance['custom_class']);
                    $instance['query_by_cat'] = isset( $new_instance['query_by_cat'] ) ? (bool) $new_instance['query_by_cat'] : false;
                    $this->flush_widget_cache();

                    $alloptions = wp_cache_get( 'alloptions', 'options' );
                    if ( isset($alloptions['nothing_recent_entries']) )
                        delete_option('nothing_recent_entries');

                    return $instance;
                }

                function flush_widget_cache() {
                    wp_cache_delete('nothing_recent_posts', 'widget');
                }

                function form( $instance ) {
                    $title     = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
                    $number    = isset( $instance['number'] ) ? absint( $instance['number'] ) : 5;
                    $show_title = isset( $instance['show_title'] ) ? (bool) $instance['show_title'] : true;
                    $show_date = isset( $instance['show_date'] ) ? (bool) $instance['show_date'] : false;
                    $show_img = isset( $instance['show_img'] ) ? (bool) $instance['show_img'] : false;
                    $custom_class     = isset( $instance['custom_class'] ) ? esc_attr( $instance['custom_class'] ) : '';
                    $query_by_cat = isset( $instance['query_by_cat'] ) ? (bool) $instance['query_by_cat'] : false;
            ?>
                    <p><label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
                    <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo $title; ?>" /></p>

                    <p><label for="<?php echo $this->get_field_id( 'number' ); ?>"><?php _e( 'Number of posts to show:' ); ?></label>
                    <input id="<?php echo $this->get_field_id( 'number' ); ?>" name="<?php echo $this->get_field_name( 'number' ); ?>" type="text" value="<?php echo $number; ?>" size="3" /></p>

                    <p><input class="checkbox" type="checkbox" <?php checked( $show_title ); ?> id="<?php echo $this->get_field_id( 'show_title' ); ?>" name="<?php echo $this->get_field_name( 'show_title' ); ?>" />
                    <label for="<?php echo $this->get_field_id( 'show_title' ); ?>"><?php _e( 'Display post title?' ); ?></label></p>

                    <p><input class="checkbox" type="checkbox" <?php checked( $show_date ); ?> id="<?php echo $this->get_field_id( 'show_date' ); ?>" name="<?php echo $this->get_field_name( 'show_date' ); ?>" />
                    <label for="<?php echo $this->get_field_id( 'show_date' ); ?>"><?php _e( 'Display post date?' ); ?></label></p>

                    <p><input class="checkbox" type="checkbox" <?php checked( $show_img ); ?> id="<?php echo $this->get_field_id( 'show_img' ); ?>" name="<?php echo $this->get_field_name( 'show_img' ); ?>" />
                    <label for="<?php echo $this->get_field_id( 'show_img' ); ?>"><?php _e( 'Display post image?' ); ?></label></p>

                    <p><label for="<?php echo $this->get_field_id( 'custom_class' ); ?>"><?php _e( 'Custom class:' ); ?></label>
                    <input class="widefat" id="<?php echo $this->get_field_id( 'custom_class' ); ?>" name="<?php echo $this->get_field_name( 'custom_class' ); ?>" type="text" value="<?php echo $custom_class; ?>" /></p>

                    <p><input class="checkbox" type="checkbox" <?php checked( $query_by_cat ); ?> id="<?php echo $this->get_field_id( 'query_by_cat' ); ?>" name="<?php echo $this->get_field_name( 'query_by_cat' ); ?>" />
                    <label for="<?php echo $this->get_field_id( 'query_by_cat' ); ?>"><?php _e( 'Filter by current category?' ); ?></label></p>

            <?php
                }
            }
  • 2
    I'm not sure but you set/get the cache based on wiget ID and the widget ID it is the same always in your site. I mean, if you add a widget in sidebar "A", the widget ID is the same every time sidebar "A" is rendered. If you add the same widget to sidebar "B", the widget ID will be different form the widget ID from sidebar "A" but always the same within "sidebar B". Don't expect it to have different cached instances based of that identifier. – cybmeta Sep 1 '14 at 10:31
0

If you have followed the code of the recent page widget then what you are trying to achieve can't be done as naively as you are trying to do it. Recent posts widget caching is based on the assumption that the same output is displayed everywhere which is why it can calculate the cache on any page and use it on any other page, but this assumption do not apply to your case as you want different output on some pages.

The easiest way to go around it is to have a different cache key for each post like recent-posts-{post id}.

0

Did you ensuring that there are no possible collisions in your cache keys; i.e. ensure that the post-specific hash is used in the key naming?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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