1

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!

0

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.

  • 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

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.