Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

So this widget i created is killing all other widgets registered in the same sidebar. Meaning, nothing renders after this widget does. No other widget markup makes it to the DOM. After hours of hair pulling, I've found that the culprit has something to do with the get_posts method found in _get_featured_posts(). It's like calling that method stops all other widget processing. Here's my widget code:

class Featured_newsroom_posts extends WP_Widget {
function __construct() {
    parent::__construct(
        'featured_newsroom_posts', // Base ID
        __('CUMC: Featured Newsroom Posts', 'text_domain'), // Name
        array( 'description' => __( 'Featured posts to show on the newsroom homepage ordered by publish date.', 'text_domain' ), ) // Args
    );
}

public function widget( $args, $instance ) {
    $title = apply_filters( 'widget_title', $instance['title'] );
    echo $args['before_widget'];
    if ( ! empty( $title ) ){
        echo $args['before_title'] . $title . $args['after_title'];
    }

    $featured_posts = $this->_get_featured_posts();
    if (!empty($featured_posts)) {
        $count = 1;
        foreach ($featured_posts as $inner) {
            echo '
                <article class="headline">
                    <a href="' . $inner->guid . '">
                        <strong class="headline-source">' . $inner->post_title . '</strong>
                    </a>
                </article>';
            if ($count === (int)$instance['count']) {
                break;
            }
            $count++;
        }
    } else {
        echo 'No recent posts found.';
    }
    echo $args['after_widget'];
}

public function form( $instance ) {
    if ( isset( $instance['title'] ) ) {
        $title = $instance['title'];
    }
    else {
        $title = __( 'Featured Posts', 'text_domain' );
    }
    ?>
    <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 esc_attr( $title ); ?>" />
        <p></p>
        <label for="<?php echo $this->get_field_id( 'count' ); ?>"><?php _e( 'Number of posts to display:' ); ?></label>
        <select name="<?php echo $this->get_field_name( 'count' ); ?>">
            <?php 
                for($i = 1; $i <= 8; $i++){
                    echo '<option value="' . $i . '" ' . ($i === (int)$instance[ 'count' ] ? 'selected' : '' ) . '>' . $i . '</option>';
                }
            ?>
        </select>
    </p>
    <?php 
}

public function update( $new_instance, $old_instance ) {
    $instance = array();
    $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
    $instance['count'] = $new_instance['count'];

    return $instance;
}

private function _get_featured_posts(){
    global $wpdb;
    //Get all the blog ids
    $sites = wp_get_sites(array('public' => 1, 'offset' => 1));

    $all_posts = array();
    foreach($sites as $site) {
        switch_to_blog($site['blog_id']);
        //Find posts that are marked for listing in the newsroom
        $posts = get_posts(array('meta_key' => 'list_in_newsroom', 'meta_value' => '1'));
        if($posts){
            $all_posts = array_merge($all_posts, $posts);
        }
    }
    restore_current_blog();
    return $all_posts;
}
}

function register_custom_widgets() {
register_widget( 'Featured_newsroom_posts' );
}
add_action( 'widgets_init', 'register_custom_widgets' );

Any help would be totally awesome! Thanks!

share|improve this question
    
It looks like you ain't got debugging activated. Please enable debugging - blueprint for wp-config.php - and file an edit so we can look at your error messages. –  kaiser Dec 21 '13 at 6:53

1 Answer 1

up vote 0 down vote accepted

I can already see a problem. It is your use of switch_to_blog(). You are potentially doing multiple switch_to_blog() calls; calling restore_current_blog() once at the end of the loop is meaningless. Please review the codex with examples - http://codex.wordpress.org/Function_Reference/switch_to_blog

A quick fix is putting restore_current_blog() within the foreach loop. What happens if you do not use switch_to_blog() and restore_current_blog() correctly is that WP globals are disrupted and potentially break WP APIs called afterwards.

share|improve this answer
1  
This. Each time you switch_to_blog, it adds the switch to a stack. Calling restore_current_blog goes back in the stack one space. So if you switch to blog 1 and then switch to blog 2, then restore, you'll be back at blog 1, not at the blog you started from. You need to call restore as many times as you call switch. –  Otto Dec 21 '13 at 7:53
    
Yup, i stumbled onto that late last night. I thought that restore_current_blog() always brought you back to the current blog rather than work in a stacking fashion. Guess I should have read the manual a bit closer. Thanks guys! –  Matt Kaye Dec 21 '13 at 16:10

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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