Wordpress 3.5.2
[autoinstalls/wordpress.git] / wp-includes / widgets.php
index 02fb6aa304229022878606c863d84a9620b7e80c..2277fad192f230a6735b193e0a1f8b326906fdf5 100644 (file)
@@ -74,7 +74,7 @@ class WP_Widget {
         * PHP4 constructor
         */
        function WP_Widget( $id_base = false, $name, $widget_options = array(), $control_options = array() ) {
-               $this->__construct( $id_base, $name, $widget_options, $control_options );
+               WP_Widget::__construct( $id_base, $name, $widget_options, $control_options );
        }
 
        /**
@@ -139,7 +139,7 @@ class WP_Widget {
                }
 
                if ( $empty ) {
-                       // If there are none, we register the widget's existance with a
+                       // If there are none, we register the widget's existence with a
                        // generic template
                        $this->_set(1);
                        $this->_register_one();
@@ -152,15 +152,15 @@ class WP_Widget {
        }
 
        function _get_display_callback() {
-               return array(&$this, 'display_callback');
+               return array($this, 'display_callback');
        }
 
        function _get_update_callback() {
-               return array(&$this, 'update_callback');
+               return array($this, 'update_callback');
        }
 
        function _get_form_callback() {
-               return array(&$this, 'form_callback');
+               return array($this, 'form_callback');
        }
 
        /** Generate the actual widget content.
@@ -296,8 +296,8 @@ class WP_Widget {
                if ( !is_array($settings) )
                        $settings = array();
 
-               if ( !array_key_exists('_multiwidget', $settings) ) {
-                       // old format, conver if single widget
+               if ( !empty($settings) && !array_key_exists('_multiwidget', $settings) ) {
+                       // old format, convert if single widget
                        $settings = wp_convert_widget_settings($this->id_base, $this->option_name, $settings);
                }
 
@@ -317,11 +317,11 @@ class WP_Widget_Factory {
        var $widgets = array();
 
        function WP_Widget_Factory() {
-               add_action( 'widgets_init', array( &$this, '_register_widgets' ), 100 );
+               add_action( 'widgets_init', array( $this, '_register_widgets' ), 100 );
        }
 
        function register($widget_class) {
-               $this->widgets[$widget_class] = new $widget_class();
+               $this->widgets[$widget_class] = new $widget_class();
        }
 
        function unregister($widget_class) {
@@ -385,7 +385,7 @@ $_wp_sidebars_widgets = array();
 /**
  * Private
  */
- $_wp_deprecated_widgets_callbacks = array(
+ $GLOBALS['_wp_deprecated_widgets_callbacks'] = array(
        'wp_widget_pages',
        'wp_widget_pages_control',
        'wp_widget_calendar',
@@ -461,7 +461,7 @@ function unregister_widget($widget_class) {
  * The default for the name is "Sidebar #", with '#' being replaced with the
  * number the sidebar is currently when greater than one. If first sidebar, the
  * name will be just "Sidebar". The default for id is "sidebar-" followed by the
- * number the sidebar creation is currently at. If the id is provided, and mutliple
+ * number the sidebar creation is currently at. If the id is provided, and multiple
  * sidebars are being defined, the id will have "-2" appended, and so on.
  *
  * @since 2.2.0
@@ -547,6 +547,7 @@ function register_sidebar($args = array()) {
                'name' => sprintf(__('Sidebar %d'), $i ),
                'id' => "sidebar-$i",
                'description' => '',
+               'class' => '',
                'before_widget' => '<li id="%1$s" class="widget %2$s">',
                'after_widget' => "</li>\n",
                'before_title' => '<h2 class="widgettitle">',
@@ -596,7 +597,7 @@ function unregister_sidebar( $name ) {
  * @param int|string $id Widget ID.
  * @param string $name Widget display title.
  * @param callback $output_callback Run when widget is called.
- * @param array|string Optional. $options Widget Options.
+ * @param array|string $options Optional. Widget Options.
  * @param mixed $params,... Widget parameters to add to widget.
  * @return null Will return if $output_callback is empty after removing widget.
  */
@@ -680,7 +681,6 @@ function wp_sidebar_description( $id ) {
                return esc_html( $wp_registered_sidebars[$id]['description'] );
 }
 
-
 /**
  * Remove widget from sidebar.
  *
@@ -854,6 +854,8 @@ function dynamic_sidebar($index = 1) {
        }
 
        $sidebars_widgets = wp_get_sidebars_widgets();
+       if ( empty( $sidebars_widgets ) )
+               return false;
 
        if ( empty($wp_registered_sidebars[$index]) || !array_key_exists($index, $sidebars_widgets) || !is_array($sidebars_widgets[$index]) || empty($sidebars_widgets[$index]) )
                return false;
@@ -897,7 +899,7 @@ function dynamic_sidebar($index = 1) {
 }
 
 /**
- * Whether widget is displayied on the front-end.
+ * Whether widget is displayed on the front-end.
  *
  * Either $callback or $id_base can be used
  * $id_base is the first argument when extending WP_Widget class
@@ -911,7 +913,7 @@ function dynamic_sidebar($index = 1) {
  *
  * @since 2.2.0
  *
- * @param callback Optional, Widget callback to check.
+ * @param string $callback Optional, Widget callback to check.
  * @param int $widget_id Optional, but needed for checking. Widget ID.
  * @param string $id_base Optional, the base ID of a widget created by extending WP_Widget.
  * @param bool $skip_inactive Optional, whether to check in 'wp_inactive_widgets'.
@@ -965,7 +967,7 @@ function is_dynamic_sidebar() {
  *
  * @since 2.8
  *
- * @param mixed $index, sidebar name, id or number to check.
+ * @param mixed $index Sidebar name, id or number to check.
  * @return bool true if the sidebar is in use, false otherwise.
  */
 function is_active_sidebar( $index ) {
@@ -988,14 +990,14 @@ function is_active_sidebar( $index ) {
  * @since 2.2.0
  * @access private
  *
- * @param bool $deprecated. Not used.
+ * @param bool $deprecated Not used (deprecated).
  * @return array Upgraded list of widgets to version 3 array format when called from the admin.
  */
 function wp_get_sidebars_widgets($deprecated = true) {
        if ( $deprecated !== true )
                _deprecated_argument( __FUNCTION__, '2.8.1' );
 
-       global $wp_registered_widgets, $wp_registered_sidebars, $_wp_sidebars_widgets;
+       global $wp_registered_widgets, $_wp_sidebars_widgets, $sidebars_widgets;
 
        // If loading from front page, consult $_wp_sidebars_widgets rather than options
        // to see if wp_convert_widget_settings() has made manipulations in memory.
@@ -1006,78 +1008,6 @@ function wp_get_sidebars_widgets($deprecated = true) {
                $sidebars_widgets = $_wp_sidebars_widgets;
        } else {
                $sidebars_widgets = get_option('sidebars_widgets', array());
-               $_sidebars_widgets = array();
-
-               if ( isset($sidebars_widgets['wp_inactive_widgets']) || empty($sidebars_widgets) )
-                       $sidebars_widgets['array_version'] = 3;
-               elseif ( !isset($sidebars_widgets['array_version']) )
-                       $sidebars_widgets['array_version'] = 1;
-
-               switch ( $sidebars_widgets['array_version'] ) {
-                       case 1 :
-                               foreach ( (array) $sidebars_widgets as $index => $sidebar )
-                               if ( is_array($sidebar) )
-                               foreach ( (array) $sidebar as $i => $name ) {
-                                       $id = strtolower($name);
-                                       if ( isset($wp_registered_widgets[$id]) ) {
-                                               $_sidebars_widgets[$index][$i] = $id;
-                                               continue;
-                                       }
-                                       $id = sanitize_title($name);
-                                       if ( isset($wp_registered_widgets[$id]) ) {
-                                               $_sidebars_widgets[$index][$i] = $id;
-                                               continue;
-                                       }
-
-                                       $found = false;
-
-                                       foreach ( $wp_registered_widgets as $widget_id => $widget ) {
-                                               if ( strtolower($widget['name']) == strtolower($name) ) {
-                                                       $_sidebars_widgets[$index][$i] = $widget['id'];
-                                                       $found = true;
-                                                       break;
-                                               } elseif ( sanitize_title($widget['name']) == sanitize_title($name) ) {
-                                                       $_sidebars_widgets[$index][$i] = $widget['id'];
-                                                       $found = true;
-                                                       break;
-                                               }
-                                       }
-
-                                       if ( $found )
-                                               continue;
-
-                                       unset($_sidebars_widgets[$index][$i]);
-                               }
-                               $_sidebars_widgets['array_version'] = 2;
-                               $sidebars_widgets = $_sidebars_widgets;
-                               unset($_sidebars_widgets);
-
-                       case 2 :
-                               $sidebars = array_keys( $wp_registered_sidebars );
-                               if ( !empty( $sidebars ) ) {
-                                       // Move the known-good ones first
-                                       foreach ( (array) $sidebars as $id ) {
-                                               if ( array_key_exists( $id, $sidebars_widgets ) ) {
-                                                       $_sidebars_widgets[$id] = $sidebars_widgets[$id];
-                                                       unset($sidebars_widgets[$id], $sidebars[$id]);
-                                               }
-                                       }
-
-                                       // move the rest to wp_inactive_widgets
-                                       if ( !isset($_sidebars_widgets['wp_inactive_widgets']) )
-                                               $_sidebars_widgets['wp_inactive_widgets'] = array();
-
-                                       if ( !empty($sidebars_widgets) ) {
-                                               foreach ( $sidebars_widgets as $lost => $val ) {
-                                                       if ( is_array($val) )
-                                                               $_sidebars_widgets['wp_inactive_widgets'] = array_merge( (array) $_sidebars_widgets['wp_inactive_widgets'], $val );
-                                               }
-                                       }
-
-                                       $sidebars_widgets = $_sidebars_widgets;
-                                       unset($_sidebars_widgets);
-                               }
-               }
        }
 
        if ( is_array( $sidebars_widgets ) && isset($sidebars_widgets['array_version']) )
@@ -1195,8 +1125,8 @@ function the_widget($widget, $instance = array(), $args = array()) {
        if ( !is_a($widget_obj, 'WP_Widget') )
                return;
 
-       $before_widget = sprintf('<div class="widget %s">', $widget_obj->widget_options['classname']);
-       $default_args = array('before_widget' => $before_widget, 'after_widget' => "</div>", 'before_title' => '<h2 class="widgettitle">', 'after_title' => '</h2>');
+       $before_widget = sprintf('<div class="widget %s">', $widget_obj->widget_options['classname'] );
+       $default_args = array( 'before_widget' => $before_widget, 'after_widget' => "</div>", 'before_title' => '<h2 class="widgettitle">', 'after_title' => '</h2>' );
 
        $args = wp_parse_args($args, $default_args);
        $instance = wp_parse_args($instance);
@@ -1213,3 +1143,117 @@ function the_widget($widget, $instance = array(), $args = array()) {
 function _get_widget_id_base($id) {
        return preg_replace( '/-[0-9]+$/', '', $id );
 }
+
+/**
+ * Handle sidebars config after theme change
+ *
+ * @access private
+ * @since 3.3.0
+ */
+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
+function retrieve_widgets($theme_changed = false) {
+       global $wp_registered_widget_updates, $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'];
+               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']);
+       wp_set_sidebars_widgets($sidebars_widgets);
+
+       return $sidebars_widgets;
+}