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.

Hello WordPress Answers!

I'm having trouble with the widget update function saving values correctly, but first let me explain the situation.

I'm writing a simple news ticker widget plugin, which filters the posts displayed by post type with check boxes in the widget settings form. To generate the check boxes I'm using a foreach loop over the available post types.

However, the widget update function isn't saving the post type values. I confirmed this by doing a print_r in the form function (values exist) and again in the widget function (values do not exist).

Here is my code:

class ami_newsticker_widget extends WP_Widget {

// process the widget
function ami_newsticker_widget () {

    $widget_ops = array(
        'classname' => 'ticketcontainer',
        'description' => 'Display a scrolling newsticker'
    );
    $this->WP_Widget( 'ami_newsticker_widget', 'AMI News Ticker Widget', $widget_ops );
}

// build the widget settings form
function form( $instance ) {
    $defaults   = array( 'num_posts' => 5 );
    $instance   = wp_parse_args( (array) $instance, $defaults );
    $num_posts  = $instance['num_posts'];

foreach ( get_post_types() as $post_type ) {
  $instance['post_types'] .= $post_type . ',';
}
$post_types = $instance['post_types'];
    //echo '<pre>';
//print_r($instance);
    //echo '</pre>';

    ?>

        <p>Number of posts to show: <input class="widefat" name="<?php echo $this->get_field_name( 'num_posts' ); ?>" type="number" value="<?php echo esc_attr( $num_posts ); ?>" /></p>
        <p>Filter by Post Type: <ul>
        <?php foreach ( get_post_types() as $post_type ) { ?>
            <li><input name="<?php echo $this->get_field_name( $post_type ); ?>" type="checkbox" <?php checked( $this->get_field_name( $post_type ) ); ?> /><label for="<?php echo $this->get_field_name( $post_type ); ?>" /><?php echo $post_type; ?></label></li>
        <?php
       } ?>
        </ul></p>

    <?php
echo '<pre>';
print_r($instance);
echo '</pre>';
}

// save the widget settings
function update( $new_instance, $old_instance ) {
    $instance = $old_instance;
    $instance['num_posts'] = strip_tags( $new_instance['num_posts'] );
$instance['post_types'] = strip_tags( $new_instance['post_types'] );

    return $instance;
}

// display the widget
function widget( $args, $instance ) {
        global $wpdb;
        extract( $args );

  echo '<pre>';
  print_r($instance);
  echo '</pre>';

        // load the widget settings
  //foreach ( $instance['post_types'] as $post_type ) {
    //if ( $post_type == 'on' ) {
      //$checked .= $instance['post_types'][$post_type] . ' ,';
    //}
  //}
  //echo $checked;

        // get and clean the db data
        $num_posts = intval( absint( $instance['num_posts'] ) );
        $sql = "SELECT post_title, guid
                        FROM {$wpdb->posts}
                        WHERE post_status = 'publish'
                        ORDER BY post_date DESC
                        LIMIT {$num_posts}";

        $results = $wpdb->get_results( $sql );

        // print the widget
        echo $before_widget;
        echo '<ul id="webticker">';

        foreach ($results as $result) {
            echo '<li><a href="' . $result->guid . '">' . $result->post_title . '</a></li>';
        }

        echo '</ul>';
        echo $after_widget;
}

}

It seems like there is something obvious that I'm missing, but I've been banging my head against a wall on this!

Any help would be greatly appreciated. Thanks in advance!

share|improve this question
2  
I assume this is a class that extends WP_Widget? What is the generated output of the form? What does the HTML look like? –  s_ha_dum Nov 29 '12 at 15:52
    
Yes, sorry should have mentioned that. –  bronzehedwick Nov 29 '12 at 16:13
    
bronze, much better is to edit the Question and include all the relevant code. Oh, yes, welcome to WPSE! –  brasofilo Nov 29 '12 at 17:35
    
brasofilo, Got it. Updated my code to include the entire widget class. –  bronzehedwick Nov 29 '12 at 22:30
add comment

1 Answer

up vote 0 down vote accepted

This took a bit to sort out. :)

You are trying to use $instance['post_types'] in your update() function but are not setting that value at all in the form. I altered a couple of things so that the two match up.

Leaving your form (mostly) as it is, your update() needs to be...

// save the widget settings
function update( $new_instance, $old_instance ) {
    $instance = $old_instance;
    $instance['num_posts'] = strip_tags( $new_instance['num_posts'] );
    // start of the change
    foreach (get_post_types() as $post_type) {
      $instance[$post_type] = $new_instance[$post_type];
    }
    // end of the change
    return $instance;
}

Now, that will get things to save but it won't look like it because your checked() is a little off, so your form() needs to be altered just a little bit. Change the code for the list items to...

<input name="<?php echo $this->get_field_name( $post_type ); ?>" type="checkbox" <?php echo checked( $instance[$post_type] ,'on' ); ?> />
<label for="<?php echo $this->get_field_name( $post_type ); ?>" /><?php echo $post_type; ?></label>

Notice that the checked() function went from checked( $this->get_field_name( $post_type ) ); to checked( $instance[$post_type] ,'on' ); 'on' is the 'true' value.

You were trying to use a 'post_types' array but that didn't match what was in the form, so I altered the update function to match the form. You could do it the other way around and alter the form to create an array. I think my way is easier though.

Some bits of the code you really don't need, like...

foreach ( get_post_types() as $post_type ) {
   $instance['post_types'][$post_type] = '';
} 

And that will cause trouble if you try to use the 'post_types' array. It will overwrite that variable every time.

share|improve this answer
    
That worked! Thank you so so much! It all makes sense now... :) –  bronzehedwick Nov 30 '12 at 16:12
add comment

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.