Hefta-Gaub Development Blog

June 8, 2007

Crazy Globals Bug in Recent Posts Widget

Filed under: bug, development, recent posts, themes, widgets, Wordpress plugins, WordpressMU — zappoman @ 7:42 am

I’ve just discovered and fixed a small problem in the “Recent Posts” widget.

Basically this widget creates a second “loop” and will side effect several of the post globals (like $id and $post). The result will effect any downstream plugin that thinks it can count on these globals being available. This can also manifest in any theme (like Tarski) that has post related template calls AFTER the side bar widget.

I’ve fixed this problem but saving $post in a local variable and then resetting it after the loop call. I also call setup_postdata() to restore the other globals.

I just checked the latest version of widgets.php from “http://svn.wp-plugins.org/widgets/trunk/” and it still has this issue in it.

Here’s the new function…

function widget_recent_entries($args) {
    // This global $post is side effected by the call to $r->the_post()
    // and so in order to protect any uses of $post after our widget is
    // instantiated, we will save the value of the global and restore
    // it at the end of our function.
    global $post;
    $save_global_post = $post;

	extract($args);
	$title = __('Recent Posts', 'widgets');
	$r = new WP_Query('showposts=10');
	if ($r->have_posts()) :
?>
		<?php echo $before_widget; ?>
			<?php echo $before_title . $title . $after_title; ?>
			<ul>
			<?php  while ($r->have_posts()) : $r->the_post(); ?>
			<li><a href="<?php the_permalink() ?>"><?php if ( get_the_title() ) the_title(); else the_ID(); ?> </a></li>
			<?php endwhile; ?>
			</ul>
		<?php echo $after_widget; ?>
<?php
	endif;
    $post = $save_global_post; // restore the global that was side effected by $r->the_post()
    setup_postdata($post); // and restore the other globals that we also side effected when $r->the_post() called setup_postdata()
}

Advertisements

Blog at WordPress.com.