+
+/**
+ * Handle sidebars config after theme change
+ *
+ * @access private
+ * @since 3.3.0
+ *
+ * @global array $sidebars_widgets
+ */
+function _wp_sidebars_changed() {
+ global $sidebars_widgets;
+
+ if ( ! is_array( $sidebars_widgets ) )
+ $sidebars_widgets = wp_get_sidebars_widgets();
+
+ retrieve_widgets(true);
+}
+
+/**
+ * Look for "lost" widgets, this has to run at least on each theme change.
+ *
+ * @since 2.8.0
+ *
+ * @global array $wp_registered_sidebars
+ * @global array $sidebars_widgets
+ * @global array $wp_registered_widgets
+ *
+ * @param string|bool $theme_changed Whether the theme was changed as a boolean. A value
+ * of 'customize' defers updates for the Customizer.
+ * @return array|void
+ */
+function retrieve_widgets( $theme_changed = false ) {
+ global $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;
+
+ $registered_sidebar_keys = array_keys( $wp_registered_sidebars );
+ $orphaned = 0;
+
+ $old_sidebars_widgets = get_theme_mod( 'sidebars_widgets' );
+ if ( is_array( $old_sidebars_widgets ) ) {
+ // time() that sidebars were stored is in $old_sidebars_widgets['time']
+ $_sidebars_widgets = $old_sidebars_widgets['data'];
+
+ if ( 'customize' !== $theme_changed ) {
+ remove_theme_mod( 'sidebars_widgets' );
+ }
+
+ foreach ( $_sidebars_widgets as $sidebar => $widgets ) {
+ if ( 'wp_inactive_widgets' === $sidebar || 'orphaned_widgets' === substr( $sidebar, 0, 16 ) ) {
+ continue;
+ }
+
+ if ( !in_array( $sidebar, $registered_sidebar_keys ) ) {
+ $_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $widgets;
+ unset( $_sidebars_widgets[$sidebar] );
+ }
+ }
+ } else {
+ if ( empty( $sidebars_widgets ) )
+ return;
+
+ unset( $sidebars_widgets['array_version'] );
+
+ $old = array_keys($sidebars_widgets);
+ sort($old);
+ sort($registered_sidebar_keys);
+
+ if ( $old == $registered_sidebar_keys )
+ return;
+
+ $_sidebars_widgets = array(
+ 'wp_inactive_widgets' => !empty( $sidebars_widgets['wp_inactive_widgets'] ) ? $sidebars_widgets['wp_inactive_widgets'] : array()
+ );
+
+ unset( $sidebars_widgets['wp_inactive_widgets'] );
+
+ foreach ( $wp_registered_sidebars as $id => $settings ) {
+ if ( $theme_changed ) {
+ $_sidebars_widgets[$id] = array_shift( $sidebars_widgets );
+ } else {
+ // no theme change, grab only sidebars that are currently registered
+ if ( isset( $sidebars_widgets[$id] ) ) {
+ $_sidebars_widgets[$id] = $sidebars_widgets[$id];
+ unset( $sidebars_widgets[$id] );
+ }
+ }
+ }
+
+ foreach ( $sidebars_widgets as $val ) {
+ if ( is_array($val) && ! empty( $val ) )
+ $_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $val;
+ }
+ }
+
+ // discard invalid, theme-specific widgets from sidebars
+ $shown_widgets = array();
+
+ foreach ( $_sidebars_widgets as $sidebar => $widgets ) {
+ if ( !is_array($widgets) )
+ continue;
+
+ $_widgets = array();
+ foreach ( $widgets as $widget ) {
+ if ( isset($wp_registered_widgets[$widget]) )
+ $_widgets[] = $widget;
+ }
+
+ $_sidebars_widgets[$sidebar] = $_widgets;
+ $shown_widgets = array_merge($shown_widgets, $_widgets);
+ }
+
+ $sidebars_widgets = $_sidebars_widgets;
+ unset($_sidebars_widgets, $_widgets);
+
+ // find hidden/lost multi-widget instances
+ $lost_widgets = array();
+ foreach ( $wp_registered_widgets as $key => $val ) {
+ if ( in_array($key, $shown_widgets, true) )
+ continue;
+
+ $number = preg_replace('/.+?-([0-9]+)$/', '$1', $key);
+
+ if ( 2 > (int) $number )
+ continue;
+
+ $lost_widgets[] = $key;
+ }
+
+ $sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']);
+ if ( 'customize' !== $theme_changed ) {
+ wp_set_sidebars_widgets( $sidebars_widgets );
+ }
+
+ return $sidebars_widgets;
+}
+
+/**
+ * Display the RSS entries in a list.
+ *
+ * @since 2.5.0
+ *
+ * @param string|array|object $rss RSS url.
+ * @param array $args Widget arguments.
+ */
+function wp_widget_rss_output( $rss, $args = array() ) {
+ if ( is_string( $rss ) ) {
+ $rss = fetch_feed($rss);
+ } elseif ( is_array($rss) && isset($rss['url']) ) {
+ $args = $rss;
+ $rss = fetch_feed($rss['url']);
+ } elseif ( !is_object($rss) ) {
+ return;
+ }
+
+ if ( is_wp_error($rss) ) {
+ if ( is_admin() || current_user_can('manage_options') )
+ echo '<p>' . sprintf( __('<strong>RSS Error</strong>: %s'), $rss->get_error_message() ) . '</p>';
+ return;
+ }
+
+ $default_args = array( 'show_author' => 0, 'show_date' => 0, 'show_summary' => 0, 'items' => 0 );
+ $args = wp_parse_args( $args, $default_args );
+
+ $items = (int) $args['items'];
+ if ( $items < 1 || 20 < $items )
+ $items = 10;
+ $show_summary = (int) $args['show_summary'];
+ $show_author = (int) $args['show_author'];
+ $show_date = (int) $args['show_date'];
+
+ if ( !$rss->get_item_quantity() ) {
+ echo '<ul><li>' . __( 'An error has occurred, which probably means the feed is down. Try again later.' ) . '</li></ul>';
+ $rss->__destruct();
+ unset($rss);
+ return;
+ }
+
+ echo '<ul>';
+ foreach ( $rss->get_items( 0, $items ) as $item ) {
+ $link = $item->get_link();
+ while ( stristr( $link, 'http' ) != $link ) {
+ $link = substr( $link, 1 );
+ }
+ $link = esc_url( strip_tags( $link ) );
+
+ $title = esc_html( trim( strip_tags( $item->get_title() ) ) );
+ if ( empty( $title ) ) {
+ $title = __( 'Untitled' );
+ }
+
+ $desc = @html_entity_decode( $item->get_description(), ENT_QUOTES, get_option( 'blog_charset' ) );
+ $desc = esc_attr( wp_trim_words( $desc, 55, ' […]' ) );
+
+ $summary = '';
+ if ( $show_summary ) {
+ $summary = $desc;
+
+ // Change existing [...] to […].
+ if ( '[...]' == substr( $summary, -5 ) ) {
+ $summary = substr( $summary, 0, -5 ) . '[…]';
+ }
+
+ $summary = '<div class="rssSummary">' . esc_html( $summary ) . '</div>';
+ }
+
+ $date = '';
+ if ( $show_date ) {
+ $date = $item->get_date( 'U' );
+
+ if ( $date ) {
+ $date = ' <span class="rss-date">' . date_i18n( get_option( 'date_format' ), $date ) . '</span>';
+ }
+ }
+
+ $author = '';
+ if ( $show_author ) {
+ $author = $item->get_author();
+ if ( is_object($author) ) {
+ $author = $author->get_name();
+ $author = ' <cite>' . esc_html( strip_tags( $author ) ) . '</cite>';
+ }
+ }
+
+ if ( $link == '' ) {
+ echo "<li>$title{$date}{$summary}{$author}</li>";
+ } elseif ( $show_summary ) {
+ echo "<li><a class='rsswidget' href='$link'>$title</a>{$date}{$summary}{$author}</li>";
+ } else {
+ echo "<li><a class='rsswidget' href='$link'>$title</a>{$date}{$author}</li>";
+ }
+ }
+ echo '</ul>';
+ $rss->__destruct();
+ unset($rss);
+}
+
+/**
+ * Display RSS widget options form.
+ *
+ * The options for what fields are displayed for the RSS form are all booleans
+ * and are as follows: 'url', 'title', 'items', 'show_summary', 'show_author',
+ * 'show_date'.
+ *
+ * @since 2.5.0
+ *
+ * @param array|string $args Values for input fields.
+ * @param array $inputs Override default display options.
+ */
+function wp_widget_rss_form( $args, $inputs = null ) {
+ $default_inputs = array( 'url' => true, 'title' => true, 'items' => true, 'show_summary' => true, 'show_author' => true, 'show_date' => true );
+ $inputs = wp_parse_args( $inputs, $default_inputs );
+
+ $args['title'] = isset( $args['title'] ) ? $args['title'] : '';
+ $args['url'] = isset( $args['url'] ) ? $args['url'] : '';
+ $args['items'] = isset( $args['items'] ) ? (int) $args['items'] : 0;
+
+ if ( $args['items'] < 1 || 20 < $args['items'] ) {
+ $args['items'] = 10;
+ }
+
+ $args['show_summary'] = isset( $args['show_summary'] ) ? (int) $args['show_summary'] : (int) $inputs['show_summary'];
+ $args['show_author'] = isset( $args['show_author'] ) ? (int) $args['show_author'] : (int) $inputs['show_author'];
+ $args['show_date'] = isset( $args['show_date'] ) ? (int) $args['show_date'] : (int) $inputs['show_date'];
+
+ if ( ! empty( $args['error'] ) ) {
+ echo '<p class="widget-error"><strong>' . sprintf( __( 'RSS Error: %s' ), $args['error'] ) . '</strong></p>';
+ }
+
+ $esc_number = esc_attr( $args['number'] );
+ if ( $inputs['url'] ) :
+?>
+ <p><label for="rss-url-<?php echo $esc_number; ?>"><?php _e( 'Enter the RSS feed URL here:' ); ?></label>
+ <input class="widefat" id="rss-url-<?php echo $esc_number; ?>" name="widget-rss[<?php echo $esc_number; ?>][url]" type="text" value="<?php echo esc_url( $args['url'] ); ?>" /></p>
+<?php endif; if ( $inputs['title'] ) : ?>
+ <p><label for="rss-title-<?php echo $esc_number; ?>"><?php _e( 'Give the feed a title (optional):' ); ?></label>
+ <input class="widefat" id="rss-title-<?php echo $esc_number; ?>" name="widget-rss[<?php echo $esc_number; ?>][title]" type="text" value="<?php echo esc_attr( $args['title'] ); ?>" /></p>
+<?php endif; if ( $inputs['items'] ) : ?>
+ <p><label for="rss-items-<?php echo $esc_number; ?>"><?php _e( 'How many items would you like to display?' ); ?></label>
+ <select id="rss-items-<?php echo $esc_number; ?>" name="widget-rss[<?php echo $esc_number; ?>][items]">
+ <?php
+ for ( $i = 1; $i <= 20; ++$i ) {
+ echo "<option value='$i' " . selected( $args['items'], $i, false ) . ">$i</option>";
+ }
+ ?>
+ </select></p>
+<?php endif; if ( $inputs['show_summary'] ) : ?>
+ <p><input id="rss-show-summary-<?php echo $esc_number; ?>" name="widget-rss[<?php echo $esc_number; ?>][show_summary]" type="checkbox" value="1" <?php checked( $args['show_summary'] ); ?> />
+ <label for="rss-show-summary-<?php echo $esc_number; ?>"><?php _e( 'Display item content?' ); ?></label></p>
+<?php endif; if ( $inputs['show_author'] ) : ?>
+ <p><input id="rss-show-author-<?php echo $esc_number; ?>" name="widget-rss[<?php echo $esc_number; ?>][show_author]" type="checkbox" value="1" <?php checked( $args['show_author'] ); ?> />
+ <label for="rss-show-author-<?php echo $esc_number; ?>"><?php _e( 'Display item author if available?' ); ?></label></p>
+<?php endif; if ( $inputs['show_date'] ) : ?>
+ <p><input id="rss-show-date-<?php echo $esc_number; ?>" name="widget-rss[<?php echo $esc_number; ?>][show_date]" type="checkbox" value="1" <?php checked( $args['show_date'] ); ?>/>
+ <label for="rss-show-date-<?php echo $esc_number; ?>"><?php _e( 'Display item date?' ); ?></label></p>
+<?php
+ endif;
+ foreach ( array_keys($default_inputs) as $input ) :
+ if ( 'hidden' === $inputs[$input] ) :
+ $id = str_replace( '_', '-', $input );
+?>
+ <input type="hidden" id="rss-<?php echo esc_attr( $id ); ?>-<?php echo $esc_number; ?>" name="widget-rss[<?php echo $esc_number; ?>][<?php echo esc_attr( $input ); ?>]" value="<?php echo esc_attr( $args[ $input ] ); ?>" />
+<?php
+ endif;
+ endforeach;
+}
+
+/**
+ * Process RSS feed widget data and optionally retrieve feed items.
+ *
+ * The feed widget can not have more than 20 items or it will reset back to the
+ * default, which is 10.
+ *
+ * The resulting array has the feed title, feed url, feed link (from channel),
+ * feed items, error (if any), and whether to show summary, author, and date.
+ * All respectively in the order of the array elements.
+ *
+ * @since 2.5.0
+ *
+ * @param array $widget_rss RSS widget feed data. Expects unescaped data.
+ * @param bool $check_feed Optional, default is true. Whether to check feed for errors.
+ * @return array
+ */
+function wp_widget_rss_process( $widget_rss, $check_feed = true ) {
+ $items = (int) $widget_rss['items'];
+ if ( $items < 1 || 20 < $items )
+ $items = 10;
+ $url = esc_url_raw( strip_tags( $widget_rss['url'] ) );
+ $title = isset( $widget_rss['title'] ) ? trim( strip_tags( $widget_rss['title'] ) ) : '';
+ $show_summary = isset( $widget_rss['show_summary'] ) ? (int) $widget_rss['show_summary'] : 0;
+ $show_author = isset( $widget_rss['show_author'] ) ? (int) $widget_rss['show_author'] :0;
+ $show_date = isset( $widget_rss['show_date'] ) ? (int) $widget_rss['show_date'] : 0;
+
+ if ( $check_feed ) {
+ $rss = fetch_feed($url);
+ $error = false;
+ $link = '';
+ if ( is_wp_error($rss) ) {
+ $error = $rss->get_error_message();
+ } else {
+ $link = esc_url(strip_tags($rss->get_permalink()));
+ while ( stristr($link, 'http') != $link )
+ $link = substr($link, 1);
+
+ $rss->__destruct();
+ unset($rss);
+ }
+ }
+
+ return compact( 'title', 'url', 'link', 'items', 'error', 'show_summary', 'show_author', 'show_date' );
+}
+
+/**
+ * Register all of the default WordPress widgets on startup.
+ *
+ * Calls 'widgets_init' action after all of the WordPress widgets have been
+ * registered.
+ *
+ * @since 2.2.0
+ */
+function wp_widgets_init() {
+ if ( !is_blog_installed() )
+ return;
+
+ register_widget('WP_Widget_Pages');
+
+ register_widget('WP_Widget_Calendar');
+
+ register_widget('WP_Widget_Archives');
+
+ if ( get_option( 'link_manager_enabled' ) )
+ register_widget('WP_Widget_Links');
+
+ register_widget('WP_Widget_Meta');
+
+ register_widget('WP_Widget_Search');
+
+ register_widget('WP_Widget_Text');
+
+ register_widget('WP_Widget_Categories');
+
+ register_widget('WP_Widget_Recent_Posts');
+
+ register_widget('WP_Widget_Recent_Comments');
+
+ register_widget('WP_Widget_RSS');
+
+ register_widget('WP_Widget_Tag_Cloud');
+
+ register_widget('WP_Nav_Menu_Widget');
+
+ /**
+ * Fires after all default WordPress widgets have been registered.
+ *
+ * @since 2.2.0
+ */
+ do_action( 'widgets_init' );
+}