wp/wp-includes/widgets.php
changeset 5 5e2f62d02dcd
parent 0 d970ebf37754
child 7 cf61fcea0001
equal deleted inserted replaced
4:346c88efed21 5:5e2f62d02dcd
     4  * themes. Includes both internal WordPress routines and theme use routines.
     4  * themes. Includes both internal WordPress routines and theme use routines.
     5  *
     5  *
     6  * This functionality was found in a plugin before WordPress 2.2 release which
     6  * This functionality was found in a plugin before WordPress 2.2 release which
     7  * included it in the core from that point on.
     7  * included it in the core from that point on.
     8  *
     8  *
     9  * @link http://codex.wordpress.org/Plugins/WordPress_Widgets WordPress Widgets
     9  * @link https://codex.wordpress.org/Plugins/WordPress_Widgets WordPress Widgets
    10  * @link http://codex.wordpress.org/Plugins/WordPress_Widgets_Api Widgets API
    10  * @link https://codex.wordpress.org/Plugins/WordPress_Widgets_Api Widgets API
    11  *
    11  *
    12  * @package WordPress
    12  * @package WordPress
    13  * @subpackage Widgets
    13  * @subpackage Widgets
    14  */
    14  */
    15 
    15 
    17  * This class must be extended for each widget and WP_Widget::widget(), WP_Widget::update()
    17  * This class must be extended for each widget and WP_Widget::widget(), WP_Widget::update()
    18  * and WP_Widget::form() need to be over-ridden.
    18  * and WP_Widget::form() need to be over-ridden.
    19  *
    19  *
    20  * @package WordPress
    20  * @package WordPress
    21  * @subpackage Widgets
    21  * @subpackage Widgets
    22  * @since 2.8
    22  * @since 2.8.0
    23  */
    23  */
    24 class WP_Widget {
    24 class WP_Widget {
    25 
    25 
    26 	var $id_base;			// Root id for all widgets of this type.
    26 	/**
    27 	var $name;				// Name for this widget type.
    27 	 * Root ID for all widgets of this type.
    28 	var $widget_options;	// Option array passed to wp_register_sidebar_widget()
    28 	 *
    29 	var $control_options;	// Option array passed to wp_register_widget_control()
    29 	 * @since 2.8.0
    30 
    30 	 * @access public
    31 	var $number = false;	// Unique ID number of the current instance.
    31 	 * @var mixed|string
    32 	var $id = false;		// Unique ID string of the current instance (id_base-number)
    32 	 */
    33 	var $updated = false;	// Set true when we update the data after a POST submit - makes sure we don't do it twice.
    33 	public $id_base;
       
    34 
       
    35 	/**
       
    36 	 * Name for this widget type.
       
    37 	 *
       
    38 	 * @since 2.8.0
       
    39 	 * @access public
       
    40 	 * @var string
       
    41 	 */
       
    42 	public $name;
       
    43 
       
    44 	/**
       
    45 	 * Option array passed to {@see wp_register_sidebar_widget()}.
       
    46 	 *
       
    47 	 * @since 2.8.0
       
    48 	 * @access public
       
    49 	 * @var array
       
    50 	 */
       
    51 	public $widget_options;
       
    52 
       
    53 	/**
       
    54 	 * Option array passed to {@see wp_register_widget_control()}.
       
    55 	 *
       
    56 	 * @since 2.8.0
       
    57 	 * @access public
       
    58 	 * @var array
       
    59 	 */
       
    60 	public $control_options;
       
    61 
       
    62 	/**
       
    63 	 * Unique ID number of the current instance.
       
    64 	 *
       
    65 	 * @since 2.8.0
       
    66 	 * @access public
       
    67 	 * @var bool|int
       
    68 	 */
       
    69 	public $number = false;
       
    70 
       
    71 	/**
       
    72 	 * Unique ID string of the current instance (id_base-number).
       
    73 	 *
       
    74 	 * @since 2.8.0
       
    75 	 * @access public
       
    76 	 * @var bool|string
       
    77 	 */
       
    78 	public $id = false;
       
    79 
       
    80 	/**
       
    81 	 * Whether the widget data has been updated.
       
    82 	 *
       
    83 	 * Set to true when the data is updated after a POST submit - ensures it does
       
    84 	 * not happen twice.
       
    85 	 *
       
    86 	 * @since 2.8.0
       
    87 	 * @access public
       
    88 	 * @var bool
       
    89 	 */
       
    90 	public $updated = false;
    34 
    91 
    35 	// Member functions that you must over-ride.
    92 	// Member functions that you must over-ride.
    36 
    93 
    37 	/** Echo the widget content.
    94 	/**
       
    95 	 * Echo the widget content.
    38 	 *
    96 	 *
    39 	 * Subclasses should over-ride this function to generate their widget code.
    97 	 * Subclasses should over-ride this function to generate their widget code.
    40 	 *
    98 	 *
    41 	 * @param array $args Display arguments including before_title, after_title, before_widget, and after_widget.
    99 	 * @since 2.8.0
    42 	 * @param array $instance The settings for the particular instance of the widget
   100 	 * @access public
    43 	 */
   101 	 *
    44 	function widget($args, $instance) {
   102 	 * @param array $args     Display arguments including before_title, after_title,
       
   103 	 *                        before_widget, and after_widget.
       
   104 	 * @param array $instance The settings for the particular instance of the widget.
       
   105 	 */
       
   106 	public function widget( $args, $instance ) {
    45 		die('function WP_Widget::widget() must be over-ridden in a sub-class.');
   107 		die('function WP_Widget::widget() must be over-ridden in a sub-class.');
    46 	}
   108 	}
    47 
   109 
    48 	/** Update a particular instance.
   110 	/**
    49 	 *
   111 	 * Update a particular instance.
    50 	 * This function should check that $new_instance is set correctly.
   112 	 *
    51 	 * The newly calculated value of $instance should be returned.
   113 	 * This function should check that $new_instance is set correctly. The newly-calculated
    52 	 * If "false" is returned, the instance won't be saved/updated.
   114 	 * value of `$instance` should be returned. If false is returned, the instance won't be
    53 	 *
   115 	 * saved/updated.
    54 	 * @param array $new_instance New settings for this instance as input by the user via form()
   116 	 *
    55 	 * @param array $old_instance Old settings for this instance
   117 	 * @since 2.8.0
    56 	 * @return array Settings to save or bool false to cancel saving
   118 	 * @access public
    57 	 */
   119 	 *
    58 	function update($new_instance, $old_instance) {
   120 	 * @param array $new_instance New settings for this instance as input by the user via
       
   121 	 *                            {@see WP_Widget::form()}.
       
   122 	 * @param array $old_instance Old settings for this instance.
       
   123 	 * @return array Settings to save or bool false to cancel saving.
       
   124 	 */
       
   125 	public function update( $new_instance, $old_instance ) {
    59 		return $new_instance;
   126 		return $new_instance;
    60 	}
   127 	}
    61 
   128 
    62 	/** Echo the settings update form
   129 	/**
    63 	 *
   130 	 * Output the settings update form.
    64 	 * @param array $instance Current settings
   131 	 *
    65 	 */
   132 	 * @since 2.8.0
    66 	function form($instance) {
   133 	 * @access public
       
   134 	 *
       
   135 	 * @param array $instance Current settings.
       
   136 	 * @return string Default return is 'noform'.
       
   137 	 */
       
   138 	public function form($instance) {
    67 		echo '<p class="no-options-widget">' . __('There are no options for this widget.') . '</p>';
   139 		echo '<p class="no-options-widget">' . __('There are no options for this widget.') . '</p>';
    68 		return 'noform';
   140 		return 'noform';
    69 	}
   141 	}
    70 
   142 
    71 	// Functions you'll need to call.
   143 	// Functions you'll need to call.
    72 
   144 
    73 	/**
   145 	/**
    74 	 * PHP5 constructor
   146 	 * PHP5 constructor.
    75 	 *
   147 	 *
    76 	 * @param string $id_base Optional Base ID for the widget, lower case,
   148 	 * @since 2.8.0
    77 	 * if left empty a portion of the widget's class name will be used. Has to be unique.
   149 	 * @access public
    78 	 * @param string $name Name for the widget displayed on the configuration page.
   150 	 *
    79 	 * @param array $widget_options Optional Passed to wp_register_sidebar_widget()
   151 	 * @param string $id_base         Optional Base ID for the widget, lowercase and unique. If left empty,
    80 	 *	 - description: shown on the configuration page
   152 	 *                                a portion of the widget's class name will be used Has to be unique.
    81 	 *	 - classname
   153 	 * @param string $name            Name for the widget displayed on the configuration page.
    82 	 * @param array $control_options Optional Passed to wp_register_widget_control()
   154 	 * @param array  $widget_options  Optional. Widget options. See {@see wp_register_sidebar_widget()} for
    83 	 *	 - width: required if more than 250px
   155 	 *                                information on accepted arguments. Default empty array.
    84 	 *	 - height: currently not used but may be needed in the future
   156 	 * @param array  $control_options Optional. Widget control options. See {@see wp_register_widget_control()}
    85 	 */
   157 	 *                                for information on accepted arguments. Default empty array.
    86 	function __construct( $id_base, $name, $widget_options = array(), $control_options = array() ) {
   158 	 */
       
   159 	public function __construct( $id_base, $name, $widget_options = array(), $control_options = array() ) {
    87 		$this->id_base = empty($id_base) ? preg_replace( '/(wp_)?widget_/', '', strtolower(get_class($this)) ) : strtolower($id_base);
   160 		$this->id_base = empty($id_base) ? preg_replace( '/(wp_)?widget_/', '', strtolower(get_class($this)) ) : strtolower($id_base);
    88 		$this->name = $name;
   161 		$this->name = $name;
    89 		$this->option_name = 'widget_' . $this->id_base;
   162 		$this->option_name = 'widget_' . $this->id_base;
    90 		$this->widget_options = wp_parse_args( $widget_options, array('classname' => $this->option_name) );
   163 		$this->widget_options = wp_parse_args( $widget_options, array('classname' => $this->option_name) );
    91 		$this->control_options = wp_parse_args( $control_options, array('id_base' => $this->id_base) );
   164 		$this->control_options = wp_parse_args( $control_options, array('id_base' => $this->id_base) );
    92 	}
   165 	}
    93 
   166 
    94 	/**
   167 	/**
    95 	 * PHP4 constructor
   168 	 * PHP4 constructor
    96 	 */
   169 	 *
    97 	function WP_Widget( $id_base, $name, $widget_options = array(), $control_options = array() ) {
   170 	 * @param string $id_base
       
   171 	 * @param string $name
       
   172 	 * @param array  $widget_options
       
   173 	 * @param array  $control_options
       
   174 	 */
       
   175 	public function WP_Widget( $id_base, $name, $widget_options = array(), $control_options = array() ) {
    98 		WP_Widget::__construct( $id_base, $name, $widget_options, $control_options );
   176 		WP_Widget::__construct( $id_base, $name, $widget_options, $control_options );
    99 	}
   177 	}
   100 
   178 
   101 	/**
   179 	/**
   102 	 * Constructs name attributes for use in form() fields
   180 	 * Constructs name attributes for use in form() fields
   104 	 * This function should be used in form() methods to create name attributes for fields to be saved by update()
   182 	 * This function should be used in form() methods to create name attributes for fields to be saved by update()
   105 	 *
   183 	 *
   106 	 * @param string $field_name Field name
   184 	 * @param string $field_name Field name
   107 	 * @return string Name attribute for $field_name
   185 	 * @return string Name attribute for $field_name
   108 	 */
   186 	 */
   109 	function get_field_name($field_name) {
   187 	public function get_field_name($field_name) {
   110 		return 'widget-' . $this->id_base . '[' . $this->number . '][' . $field_name . ']';
   188 		return 'widget-' . $this->id_base . '[' . $this->number . '][' . $field_name . ']';
   111 	}
   189 	}
   112 
   190 
   113 	/**
   191 	/**
   114 	 * Constructs id attributes for use in form() fields
   192 	 * Constructs id attributes for use in {@see WP_Widget::form()} fields.
   115 	 *
   193 	 *
   116 	 * This function should be used in form() methods to create id attributes for fields to be saved by update()
   194 	 * This function should be used in form() methods to create id attributes
   117 	 *
   195 	 * for fields to be saved by {@see WP_Widget::update()}.
   118 	 * @param string $field_name Field name
   196 	 *
   119 	 * @return string ID attribute for $field_name
   197 	 * @since 2.8.0
   120 	 */
   198 	 * @access public
   121 	function get_field_id($field_name) {
   199 	 *
       
   200 	 * @param string $field_name Field name.
       
   201 	 * @return string ID attribute for `$field_name`.
       
   202 	 */
       
   203 	public function get_field_id( $field_name ) {
   122 		return 'widget-' . $this->id_base . '-' . $this->number . '-' . $field_name;
   204 		return 'widget-' . $this->id_base . '-' . $this->number . '-' . $field_name;
   123 	}
   205 	}
   124 
   206 
   125 	// Private Functions. Don't worry about these.
   207 	/**
   126 
   208 	 * Register all widget instances of this widget class.
   127 	function _register() {
   209 	 *
       
   210 	 * @since 2.8.0
       
   211 	 * @access private
       
   212 	 */
       
   213 	public function _register() {
   128 		$settings = $this->get_settings();
   214 		$settings = $this->get_settings();
   129 		$empty = true;
   215 		$empty = true;
   130 
   216 
   131 		if ( is_array($settings) ) {
   217 		if ( is_array($settings) ) {
   132 			foreach ( array_keys($settings) as $number ) {
   218 			foreach ( array_keys($settings) as $number ) {
   144 			$this->_set(1);
   230 			$this->_set(1);
   145 			$this->_register_one();
   231 			$this->_register_one();
   146 		}
   232 		}
   147 	}
   233 	}
   148 
   234 
   149 	function _set($number) {
   235 	/**
       
   236 	 * Set the internal order number for the widget instance.
       
   237 	 *
       
   238 	 * @since 2.8.0
       
   239 	 * @access private
       
   240 	 *
       
   241 	 * @param int $number The unique order number of this widget instance compared to other
       
   242 	 *                    instances of the same class.
       
   243 	 */
       
   244 	public function _set($number) {
   150 		$this->number = $number;
   245 		$this->number = $number;
   151 		$this->id = $this->id_base . '-' . $number;
   246 		$this->id = $this->id_base . '-' . $number;
   152 	}
   247 	}
   153 
   248 
   154 	function _get_display_callback() {
   249 	public function _get_display_callback() {
   155 		return array($this, 'display_callback');
   250 		return array($this, 'display_callback');
   156 	}
   251 	}
   157 
   252 
   158 	function _get_update_callback() {
   253 	public function _get_update_callback() {
   159 		return array($this, 'update_callback');
   254 		return array($this, 'update_callback');
   160 	}
   255 	}
   161 
   256 
   162 	function _get_form_callback() {
   257 	public function _get_form_callback() {
   163 		return array($this, 'form_callback');
   258 		return array($this, 'form_callback');
   164 	}
   259 	}
   165 
   260 
   166 	/** Generate the actual widget content.
   261 	/**
   167 	 *	Just finds the instance and calls widget().
   262 	 * Determine whether the current request is inside the Customizer preview.
   168 	 *	Do NOT over-ride this function. */
   263 	 *
   169 	function display_callback( $args, $widget_args = 1 ) {
   264 	 * If true -- the current request is inside the Customizer preview, then
       
   265 	 * the object cache gets suspended and widgets should check this to decide
       
   266 	 * whether they should store anything persistently to the object cache,
       
   267 	 * to transients, or anywhere else.
       
   268 	 *
       
   269 	 * @since 3.9.0
       
   270 	 * @access public
       
   271 	 *
       
   272 	 * @return bool True if within the Customizer preview, false if not.
       
   273 	 */
       
   274 	public function is_preview() {
       
   275 		global $wp_customize;
       
   276 		return ( isset( $wp_customize ) && $wp_customize->is_preview() ) ;
       
   277 	}
       
   278 
       
   279 	/**
       
   280 	 * Generate the actual widget content (Do NOT override).
       
   281 	 *
       
   282 	 * Finds the instance and calls {@see WP_Widget::widget()}.
       
   283 	 *
       
   284 	 * @since 2.8.0
       
   285 	 * @access public
       
   286 	 *
       
   287 	 * @param array     $args        Display arguments. See {@see WP_Widget::widget()} for information
       
   288 	 *                               on accepted arguments.
       
   289 	 * @param int|array $widget_args {
       
   290 	 *     Optional. Internal order number of the widget instance, or array of multi-widget arguments.
       
   291 	 *     Default 1.
       
   292 	 *
       
   293 	 *     @type int $number Number increment used for multiples of the same widget.
       
   294 	 * }
       
   295 	 */
       
   296 	public function display_callback( $args, $widget_args = 1 ) {
   170 		if ( is_numeric($widget_args) )
   297 		if ( is_numeric($widget_args) )
   171 			$widget_args = array( 'number' => $widget_args );
   298 			$widget_args = array( 'number' => $widget_args );
   172 
   299 
   173 		$widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );
   300 		$widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );
   174 		$this->_set( $widget_args['number'] );
   301 		$this->_set( $widget_args['number'] );
   175 		$instance = $this->get_settings();
   302 		$instance = $this->get_settings();
   176 
   303 
   177 		if ( array_key_exists( $this->number, $instance ) ) {
   304 		if ( array_key_exists( $this->number, $instance ) ) {
   178 			$instance = $instance[$this->number];
   305 			$instance = $instance[$this->number];
   179 			// filters the widget's settings, return false to stop displaying the widget
   306 
   180 			$instance = apply_filters('widget_display_callback', $instance, $this, $args);
   307 			/**
   181 			if ( false !== $instance )
   308 			 * Filter the settings for a particular widget instance.
   182 				$this->widget($args, $instance);
   309 			 *
   183 		}
   310 			 * Returning false will effectively short-circuit display of the widget.
   184 	}
   311 			 *
   185 
   312 			 * @since 2.8.0
   186 	/** Deal with changed settings.
   313 			 *
   187 	 *	Do NOT over-ride this function. */
   314 			 * @param array     $instance The current widget instance's settings.
   188 	function update_callback( $widget_args = 1 ) {
   315 			 * @param WP_Widget $this     The current widget instance.
       
   316 			 * @param array     $args     An array of default widget arguments.
       
   317 			 */
       
   318 			$instance = apply_filters( 'widget_display_callback', $instance, $this, $args );
       
   319 
       
   320 			if ( false === $instance ) {
       
   321 				return;
       
   322 			}
       
   323 
       
   324 			$was_cache_addition_suspended = wp_suspend_cache_addition();
       
   325 			if ( $this->is_preview() && ! $was_cache_addition_suspended ) {
       
   326 				wp_suspend_cache_addition( true );
       
   327 			}
       
   328 
       
   329 			$this->widget( $args, $instance );
       
   330 
       
   331 			if ( $this->is_preview() ) {
       
   332 				wp_suspend_cache_addition( $was_cache_addition_suspended );
       
   333 			}
       
   334 		}
       
   335 	}
       
   336 
       
   337 	/**
       
   338 	 * Deal with changed settings (Do NOT override).
       
   339 	 *
       
   340 	 * @since 2.8.0
       
   341 	 * @access public
       
   342 	 *
       
   343 	 * @param int $deprecated Not used.
       
   344 	 */
       
   345 	public function update_callback( $deprecated = 1 ) {
   189 		global $wp_registered_widgets;
   346 		global $wp_registered_widgets;
   190 
   347 
   191 		if ( is_numeric($widget_args) )
       
   192 			$widget_args = array( 'number' => $widget_args );
       
   193 
       
   194 		$widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );
       
   195 		$all_instances = $this->get_settings();
   348 		$all_instances = $this->get_settings();
   196 
   349 
   197 		// We need to update the data
   350 		// We need to update the data
   198 		if ( $this->updated )
   351 		if ( $this->updated )
   199 			return;
   352 			return;
   200 
       
   201 		$sidebars_widgets = wp_get_sidebars_widgets();
       
   202 
   353 
   203 		if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
   354 		if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
   204 			// Delete the settings for this instance of the widget
   355 			// Delete the settings for this instance of the widget
   205 			if ( isset($_POST['the-widget-id']) )
   356 			if ( isset($_POST['the-widget-id']) )
   206 				$del_id = $_POST['the-widget-id'];
   357 				$del_id = $_POST['the-widget-id'];
   227 				$new_instance = stripslashes_deep($new_instance);
   378 				$new_instance = stripslashes_deep($new_instance);
   228 				$this->_set($number);
   379 				$this->_set($number);
   229 
   380 
   230 				$old_instance = isset($all_instances[$number]) ? $all_instances[$number] : array();
   381 				$old_instance = isset($all_instances[$number]) ? $all_instances[$number] : array();
   231 
   382 
   232 				$instance = $this->update($new_instance, $old_instance);
   383 				$was_cache_addition_suspended = wp_suspend_cache_addition();
   233 
   384 				if ( $this->is_preview() && ! $was_cache_addition_suspended ) {
   234 				// filters the widget's settings before saving, return false to cancel saving (keep the old settings if updating)
   385 					wp_suspend_cache_addition( true );
   235 				$instance = apply_filters('widget_update_callback', $instance, $new_instance, $old_instance, $this);
   386 				}
   236 				if ( false !== $instance )
   387 
       
   388 				$instance = $this->update( $new_instance, $old_instance );
       
   389 
       
   390 				if ( $this->is_preview() ) {
       
   391 					wp_suspend_cache_addition( $was_cache_addition_suspended );
       
   392 				}
       
   393 
       
   394 				/**
       
   395 				 * Filter a widget's settings before saving.
       
   396 				 *
       
   397 				 * Returning false will effectively short-circuit the widget's ability
       
   398 				 * to update settings.
       
   399 				 *
       
   400 				 * @since 2.8.0
       
   401 				 *
       
   402 				 * @param array     $instance     The current widget instance's settings.
       
   403 				 * @param array     $new_instance Array of new widget settings.
       
   404 				 * @param array     $old_instance Array of old widget settings.
       
   405 				 * @param WP_Widget $this         The current widget instance.
       
   406 				 */
       
   407 				$instance = apply_filters( 'widget_update_callback', $instance, $new_instance, $old_instance, $this );
       
   408 				if ( false !== $instance ) {
   237 					$all_instances[$number] = $instance;
   409 					$all_instances[$number] = $instance;
       
   410 				}
   238 
   411 
   239 				break; // run only once
   412 				break; // run only once
   240 			}
   413 			}
   241 		}
   414 		}
   242 
   415 
   243 		$this->save_settings($all_instances);
   416 		$this->save_settings($all_instances);
   244 		$this->updated = true;
   417 		$this->updated = true;
   245 	}
   418 	}
   246 
   419 
   247 	/** Generate the control form.
   420 	/**
   248 	 *	Do NOT over-ride this function. */
   421 	 * Generate the widget control form (Do NOT override).
   249 	function form_callback( $widget_args = 1 ) {
   422 	 *
       
   423 	 * @since 2.8.0
       
   424 	 * @access public
       
   425 	 *
       
   426 	 * @param int|array $widget_args Widget instance number or array of widget arguments.
       
   427 	 */
       
   428 	public function form_callback( $widget_args = 1 ) {
   250 		if ( is_numeric($widget_args) )
   429 		if ( is_numeric($widget_args) )
   251 			$widget_args = array( 'number' => $widget_args );
   430 			$widget_args = array( 'number' => $widget_args );
   252 
   431 
   253 		$widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );
   432 		$widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );
   254 		$all_instances = $this->get_settings();
   433 		$all_instances = $this->get_settings();
   260 		} else {
   439 		} else {
   261 			$this->_set($widget_args['number']);
   440 			$this->_set($widget_args['number']);
   262 			$instance = $all_instances[ $widget_args['number'] ];
   441 			$instance = $all_instances[ $widget_args['number'] ];
   263 		}
   442 		}
   264 
   443 
   265 		// filters the widget admin form before displaying, return false to stop displaying it
   444 		/**
   266 		$instance = apply_filters('widget_form_callback', $instance, $this);
   445 		 * Filter the widget instance's settings before displaying the control form.
       
   446 		 *
       
   447 		 * Returning false effectively short-circuits display of the control form.
       
   448 		 *
       
   449 		 * @since 2.8.0
       
   450 		 *
       
   451 		 * @param array     $instance The current widget instance's settings.
       
   452 		 * @param WP_Widget $this     The current widget instance.
       
   453 		 */
       
   454 		$instance = apply_filters( 'widget_form_callback', $instance, $this );
   267 
   455 
   268 		$return = null;
   456 		$return = null;
   269 		if ( false !== $instance ) {
   457 		if ( false !== $instance ) {
   270 			$return = $this->form($instance);
   458 			$return = $this->form($instance);
   271 			// add extra fields in the widget form - be sure to set $return to null if you add any
   459 
   272 			// if the widget has no form the text echoed from the default form method can be hidden using css
   460 			/**
   273 			do_action_ref_array( 'in_widget_form', array(&$this, &$return, $instance) );
   461 			 * Fires at the end of the widget control form.
       
   462 			 *
       
   463 			 * Use this hook to add extra fields to the widget form. The hook
       
   464 			 * is only fired if the value passed to the 'widget_form_callback'
       
   465 			 * hook is not false.
       
   466 			 *
       
   467 			 * Note: If the widget has no form, the text echoed from the default
       
   468 			 * form method can be hidden using CSS.
       
   469 			 *
       
   470 			 * @since 2.8.0
       
   471 			 *
       
   472 			 * @param WP_Widget $this     The widget instance, passed by reference.
       
   473 			 * @param null      $return   Return null if new fields are added.
       
   474 			 * @param array     $instance An array of the widget's settings.
       
   475 			 */
       
   476 			do_action_ref_array( 'in_widget_form', array( &$this, &$return, $instance ) );
   274 		}
   477 		}
   275 		return $return;
   478 		return $return;
   276 	}
   479 	}
   277 
   480 
   278 	/** Helper function: Registers a single instance. */
   481 	/**
   279 	function _register_one($number = -1) {
   482 	 * Register an instance of the widget class.
       
   483 	 *
       
   484 	 * @since 2.8.0
       
   485 	 * @access private
       
   486 	 *
       
   487 	 * @param integer $number Optional. The unique order number of this widget instance
       
   488 	 *                        compared to other instances of the same class. Default -1.
       
   489 	 */
       
   490 	public function _register_one( $number = -1 ) {
   280 		wp_register_sidebar_widget(	$this->id, $this->name,	$this->_get_display_callback(), $this->widget_options, array( 'number' => $number ) );
   491 		wp_register_sidebar_widget(	$this->id, $this->name,	$this->_get_display_callback(), $this->widget_options, array( 'number' => $number ) );
   281 		_register_widget_update_callback( $this->id_base, $this->_get_update_callback(), $this->control_options, array( 'number' => -1 ) );
   492 		_register_widget_update_callback( $this->id_base, $this->_get_update_callback(), $this->control_options, array( 'number' => -1 ) );
   282 		_register_widget_form_callback(	$this->id, $this->name,	$this->_get_form_callback(), $this->control_options, array( 'number' => $number ) );
   493 		_register_widget_form_callback(	$this->id, $this->name,	$this->_get_form_callback(), $this->control_options, array( 'number' => $number ) );
   283 	}
   494 	}
   284 
   495 
   285 	function save_settings($settings) {
   496 	/**
       
   497 	 * Save the settings for all instances of the widget class.
       
   498 	 *
       
   499 	 * @since 2.8.0
       
   500 	 * @access public
       
   501 	 *
       
   502 	 * @param array $settings Multi-dimensional array of widget instance settings.
       
   503 	 */
       
   504 	public function save_settings( $settings ) {
   286 		$settings['_multiwidget'] = 1;
   505 		$settings['_multiwidget'] = 1;
   287 		update_option( $this->option_name, $settings );
   506 		update_option( $this->option_name, $settings );
   288 	}
   507 	}
   289 
   508 
   290 	function get_settings() {
   509 	/**
       
   510 	 * Get the settings for all instances of the widget class.
       
   511 	 *
       
   512 	 * @since 2.8.0
       
   513 	 * @access public
       
   514 	 *
       
   515 	 * @return array Multi-dimensional array of widget instance settings.
       
   516 	 */
       
   517 	public function get_settings() {
       
   518 
   291 		$settings = get_option($this->option_name);
   519 		$settings = get_option($this->option_name);
   292 
   520 
   293 		if ( false === $settings && isset($this->alt_option_name) )
   521 		if ( false === $settings && isset($this->alt_option_name) )
   294 			$settings = get_option($this->alt_option_name);
   522 			$settings = get_option($this->alt_option_name);
   295 
   523 
   309 /**
   537 /**
   310  * Singleton that registers and instantiates WP_Widget classes.
   538  * Singleton that registers and instantiates WP_Widget classes.
   311  *
   539  *
   312  * @package WordPress
   540  * @package WordPress
   313  * @subpackage Widgets
   541  * @subpackage Widgets
   314  * @since 2.8
   542  * @since 2.8.0
   315  */
   543  */
   316 class WP_Widget_Factory {
   544 class WP_Widget_Factory {
   317 	var $widgets = array();
   545 	public $widgets = array();
   318 
   546 
   319 	function WP_Widget_Factory() {
   547 	public function WP_Widget_Factory() {
   320 		add_action( 'widgets_init', array( $this, '_register_widgets' ), 100 );
   548 		add_action( 'widgets_init', array( $this, '_register_widgets' ), 100 );
   321 	}
   549 	}
   322 
   550 
   323 	function register($widget_class) {
   551 	/**
       
   552 	 * Register a widget subclass.
       
   553 	 *
       
   554 	 * @since 2.8.0
       
   555 	 * @access public
       
   556 	 *
       
   557 	 * @param string $widget_class The name of a {@see WP_Widget} subclass.
       
   558 	 */
       
   559 	public function register( $widget_class ) {
   324 		$this->widgets[$widget_class] = new $widget_class();
   560 		$this->widgets[$widget_class] = new $widget_class();
   325 	}
   561 	}
   326 
   562 
   327 	function unregister($widget_class) {
   563 	/**
       
   564 	 * Un-register a widget subclass.
       
   565 	 *
       
   566 	 * @since 2.8.0
       
   567 	 * @access public
       
   568 	 *
       
   569 	 * @param string $widget_class The name of a {@see WP_Widget} subclass.
       
   570 	 */
       
   571 	public function unregister( $widget_class ) {
   328 		if ( isset($this->widgets[$widget_class]) )
   572 		if ( isset($this->widgets[$widget_class]) )
   329 			unset($this->widgets[$widget_class]);
   573 			unset($this->widgets[$widget_class]);
   330 	}
   574 	}
   331 
   575 
   332 	function _register_widgets() {
   576 	/**
       
   577 	 * Utility method for adding widgets to the registered widgets global.
       
   578 	 *
       
   579 	 * @since 2.8.0
       
   580 	 * @access public
       
   581 	 */
       
   582 	public function _register_widgets() {
   333 		global $wp_registered_widgets;
   583 		global $wp_registered_widgets;
   334 		$keys = array_keys($this->widgets);
   584 		$keys = array_keys($this->widgets);
   335 		$registered = array_keys($wp_registered_widgets);
   585 		$registered = array_keys($wp_registered_widgets);
   336 		$registered = array_map('_get_widget_id_base', $registered);
   586 		$registered = array_map('_get_widget_id_base', $registered);
   337 
   587 
   383 $_wp_sidebars_widgets = array();
   633 $_wp_sidebars_widgets = array();
   384 
   634 
   385 /**
   635 /**
   386  * Private
   636  * Private
   387  */
   637  */
   388  $GLOBALS['_wp_deprecated_widgets_callbacks'] = array(
   638 $GLOBALS['_wp_deprecated_widgets_callbacks'] = array(
   389  	'wp_widget_pages',
   639 	'wp_widget_pages',
   390 	'wp_widget_pages_control',
   640 	'wp_widget_pages_control',
   391 	'wp_widget_calendar',
   641 	'wp_widget_calendar',
   392 	'wp_widget_calendar_control',
   642 	'wp_widget_calendar_control',
   393 	'wp_widget_archives',
   643 	'wp_widget_archives',
   394 	'wp_widget_archives_control',
   644 	'wp_widget_archives_control',
   406 	'wp_widget_text_control',
   656 	'wp_widget_text_control',
   407 	'wp_widget_rss',
   657 	'wp_widget_rss',
   408 	'wp_widget_rss_control',
   658 	'wp_widget_rss_control',
   409 	'wp_widget_recent_comments',
   659 	'wp_widget_recent_comments',
   410 	'wp_widget_recent_comments_control'
   660 	'wp_widget_recent_comments_control'
   411  );
   661 );
   412 
   662 
   413 /* Template tags & API functions */
   663 /* Template tags & API functions */
   414 
   664 
   415 /**
   665 /**
   416  * Register a widget
   666  * Register a widget
   454 /**
   704 /**
   455  * Creates multiple sidebars.
   705  * Creates multiple sidebars.
   456  *
   706  *
   457  * If you wanted to quickly create multiple sidebars for a theme or internally.
   707  * If you wanted to quickly create multiple sidebars for a theme or internally.
   458  * This function will allow you to do so. If you don't pass the 'name' and/or
   708  * This function will allow you to do so. If you don't pass the 'name' and/or
   459  * 'id' in $args, then they will be built for you.
   709  * 'id' in `$args`, then they will be built for you.
   460  *
       
   461  * The default for the name is "Sidebar #", with '#' being replaced with the
       
   462  * number the sidebar is currently when greater than one. If first sidebar, the
       
   463  * name will be just "Sidebar". The default for id is "sidebar-" followed by the
       
   464  * number the sidebar creation is currently at. If the id is provided, and multiple
       
   465  * sidebars are being defined, the id will have "-2" appended, and so on.
       
   466  *
   710  *
   467  * @since 2.2.0
   711  * @since 2.2.0
   468  *
   712  *
   469  * @see register_sidebar() The second parameter is documented by register_sidebar() and is the same here.
   713  * @see register_sidebar() The second parameter is documented by register_sidebar() and is the same here.
   470  * @uses parse_str() Converts a string to an array to be used in the rest of the function.
   714  *
   471  * @uses register_sidebar() Sends single sidebar information [name, id] to this
   715  * @param int          $number Optional. Number of sidebars to create. Default 1.
   472  *	function to handle building the sidebar.
   716  * @param array|string $args {
   473  *
   717  *     Optional. Array or string of arguments for building a sidebar.
   474  * @param int $number Number of sidebars to create.
   718  *
   475  * @param string|array $args Builds Sidebar based off of 'name' and 'id' values.
   719  *     @type string $id   The base string of the unique identifier for each sidebar. If provided, and multiple
   476  */
   720  *                        sidebars are being defined, the id will have "-2" appended, and so on.
   477 function register_sidebars($number = 1, $args = array()) {
   721  *                        Default 'sidebar-' followed by the number the sidebar creation is currently at.
       
   722  *     @type string $name The name or title for the sidebars displayed in the admin dashboard. If registering
       
   723  *                        more than one sidebar, include '%d' in the string as a placeholder for the uniquely
       
   724  *                        assigned number for each sidebar.
       
   725  *                        Default 'Sidebar' for the first sidebar, otherwise 'Sidebar %d'.
       
   726  * }
       
   727  */
       
   728 function register_sidebars( $number = 1, $args = array() ) {
   478 	global $wp_registered_sidebars;
   729 	global $wp_registered_sidebars;
   479 	$number = (int) $number;
   730 	$number = (int) $number;
   480 
   731 
   481 	if ( is_string($args) )
   732 	if ( is_string($args) )
   482 		parse_str($args, $args);
   733 		parse_str($args, $args);
   519  * on what other plugins and themes are installed.
   770  * on what other plugins and themes are installed.
   520  *
   771  *
   521  * If theme support for 'widgets' has not yet been added when this function is
   772  * If theme support for 'widgets' has not yet been added when this function is
   522  * called, it will be automatically enabled through the use of add_theme_support()
   773  * called, it will be automatically enabled through the use of add_theme_support()
   523  *
   774  *
   524  * Arguments passed as a string should be separated by '&':
       
   525  *
       
   526  *     e.g. 'name=Sidebar&id=my_prefix_sidebar'
       
   527  *
       
   528  * The same arguments passed as an array:
       
   529  *
       
   530  *     array(
       
   531  *         'name' => 'Sidebar',
       
   532  *         'id'   => 'my_prefix_sidebar',
       
   533  *     )
       
   534  *
       
   535  * Arguments:
       
   536  *     name          - The name or title of the sidebar displayed in the admin dashboard.
       
   537  *     id            - The unique identifier by which the sidebar will be called.
       
   538  *     before_widget - HTML content that will be prepended to each widget's HTML output
       
   539  *                     when assigned to this sidebar.
       
   540  *     after_widget  - HTML content that will be appended to each widget's HTML output
       
   541  *                     when assigned to this sidebar.
       
   542  *     before_title  - HTML content that will be prepended to the sidebar title when displayed.
       
   543  *     after_title   - HTML content that will be appended to the sidebar title when displayed.
       
   544  *
       
   545  * @since 2.2.0
   775  * @since 2.2.0
   546  * @uses $wp_registered_sidebars Stores the new sidebar in this array by sidebar ID.
   776  *
   547  * @uses add_theme_support() to ensure widget support has been added.
   777  * @global array $wp_registered_sidebars Stores the new sidebar in this array by sidebar ID.
   548  *
   778  *
   549  * @param string|array $args Arguments for the sidebar being registered.
   779  * @param array|string $args {
       
   780  *     Optional. Array or string of arguments for the sidebar being registered.
       
   781  *
       
   782  *     @type string $name          The name or title of the sidebar displayed in the Widgets
       
   783  *                                 interface. Default 'Sidebar $instance'.
       
   784  *     @type string $id            The unique identifier by which the sidebar will be called.
       
   785  *                                 Default 'sidebar-$instance'.
       
   786  *     @type string $description   Description of the sidebar, displayed in the Widgets interface.
       
   787  *                                 Default empty string.
       
   788  *     @type string $class         Extra CSS class to assign to the sidebar in the Widgets interface.
       
   789  *                                 Default empty.
       
   790  *     @type string $before_widget HTML content to prepend to each widget's HTML output when
       
   791  *                                 assigned to this sidebar. Default is an opening list item element.
       
   792  *     @type string $after_widget  HTML content to append to each widget's HTML output when
       
   793  *                                 assigned to this sidebar. Default is a closing list item element.
       
   794  *     @type string $before_title  HTML content to prepend to the sidebar title when displayed.
       
   795  *                                 Default is an opening h2 element.
       
   796  *     @type string $after_title   HTML content to append to the sidebar title when displayed.
       
   797  *                                 Default is a closing h2 element.
       
   798  * }
   550  * @return string Sidebar ID added to $wp_registered_sidebars global.
   799  * @return string Sidebar ID added to $wp_registered_sidebars global.
   551  */
   800  */
   552 function register_sidebar($args = array()) {
   801 function register_sidebar($args = array()) {
   553 	global $wp_registered_sidebars;
   802 	global $wp_registered_sidebars;
   554 
   803 
   555 	$i = count($wp_registered_sidebars) + 1;
   804 	$i = count($wp_registered_sidebars) + 1;
       
   805 
       
   806 	$id_is_empty = empty( $args['id'] );
   556 
   807 
   557 	$defaults = array(
   808 	$defaults = array(
   558 		'name' => sprintf(__('Sidebar %d'), $i ),
   809 		'name' => sprintf(__('Sidebar %d'), $i ),
   559 		'id' => "sidebar-$i",
   810 		'id' => "sidebar-$i",
   560 		'description' => '',
   811 		'description' => '',
   565 		'after_title' => "</h2>\n",
   816 		'after_title' => "</h2>\n",
   566 	);
   817 	);
   567 
   818 
   568 	$sidebar = wp_parse_args( $args, $defaults );
   819 	$sidebar = wp_parse_args( $args, $defaults );
   569 
   820 
       
   821 	if ( $id_is_empty ) {
       
   822 		/* translators: 1: the id argument, 2: sidebar name, 3: recommended id value */
       
   823 		_doing_it_wrong( __FUNCTION__, sprintf( __( 'No %1$s was set in the arguments array for the "%2$s" sidebar. Defaulting to "%3$s". Manually set the %1$s to "%3$s" to silence this notice and keep existing sidebar content.' ), '<code>id</code>', $sidebar['name'], $sidebar['id'] ), '4.2.0' );
       
   824 	}
       
   825 
   570 	$wp_registered_sidebars[$sidebar['id']] = $sidebar;
   826 	$wp_registered_sidebars[$sidebar['id']] = $sidebar;
   571 
   827 
   572 	add_theme_support('widgets');
   828 	add_theme_support('widgets');
   573 
   829 
       
   830 	/**
       
   831 	 * Fires once a sidebar has been registered.
       
   832 	 *
       
   833 	 * @since 3.0.0
       
   834 	 *
       
   835 	 * @param array $sidebar Parsed arguments for the registered sidebar.
       
   836 	 */
   574 	do_action( 'register_sidebar', $sidebar );
   837 	do_action( 'register_sidebar', $sidebar );
   575 
   838 
   576 	return $sidebar['id'];
   839 	return $sidebar['id'];
   577 }
   840 }
   578 
   841 
   591 	if ( isset( $wp_registered_sidebars[$name] ) )
   854 	if ( isset( $wp_registered_sidebars[$name] ) )
   592 		unset( $wp_registered_sidebars[$name] );
   855 		unset( $wp_registered_sidebars[$name] );
   593 }
   856 }
   594 
   857 
   595 /**
   858 /**
   596  * Register widget for use in sidebars.
   859  * Register an instance of a widget.
   597  *
   860  *
   598  * The default widget option is 'classname' that can be override.
   861  * The default widget option is 'classname' that can be overridden.
   599  *
   862  *
   600  * The function can also be used to unregister widgets when $output_callback
   863  * The function can also be used to un-register widgets when `$output_callback`
   601  * parameter is an empty string.
   864  * parameter is an empty string.
   602  *
   865  *
   603  * @since 2.2.0
   866  * @since 2.2.0
   604  *
   867  *
   605  * @uses $wp_registered_widgets Uses stored registered widgets.
   868  * @global array $wp_registered_widgets       Uses stored registered widgets.
   606  * @uses $wp_register_widget_defaults Retrieves widget defaults.
   869  * @global array $wp_register_widget_defaults Retrieves widget defaults.
   607  *
   870  *
   608  * @param int|string $id Widget ID.
   871  * @param int|string $id              Widget ID.
   609  * @param string $name Widget display title.
   872  * @param string     $name            Widget display title.
   610  * @param callback $output_callback Run when widget is called.
   873  * @param callback   $output_callback Run when widget is called.
   611  * @param array|string $options Optional. Widget Options.
   874  * @param array      $options {
   612  * @param mixed $params,... Widget parameters to add to widget.
   875  *     Optional. An array of supplementary widget options for the instance.
   613  * @return null Will return if $output_callback is empty after removing widget.
   876  *
   614  */
   877  *     @type string $classname   Class name for the widget's HTML container. Default is a shortened
   615 function wp_register_sidebar_widget($id, $name, $output_callback, $options = array()) {
   878  *                               version of the output callback name.
       
   879  *     @type string $description Widget description for display in the widget administration
       
   880  *                               panel and/or theme.
       
   881  * }
       
   882  * @return null Will return if `$output_callback` is empty after removing widget.
       
   883  */
       
   884 function wp_register_sidebar_widget( $id, $name, $output_callback, $options = array() ) {
   616 	global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates, $_wp_deprecated_widgets_callbacks;
   885 	global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates, $_wp_deprecated_widgets_callbacks;
   617 
   886 
   618 	$id = strtolower($id);
   887 	$id = strtolower($id);
   619 
   888 
   620 	if ( empty($output_callback) ) {
   889 	if ( empty($output_callback) ) {
   642 		'params' => array_slice(func_get_args(), 4)
   911 		'params' => array_slice(func_get_args(), 4)
   643 	);
   912 	);
   644 	$widget = array_merge($widget, $options);
   913 	$widget = array_merge($widget, $options);
   645 
   914 
   646 	if ( is_callable($output_callback) && ( !isset($wp_registered_widgets[$id]) || did_action( 'widgets_init' ) ) ) {
   915 	if ( is_callable($output_callback) && ( !isset($wp_registered_widgets[$id]) || did_action( 'widgets_init' ) ) ) {
       
   916 
       
   917 		/**
       
   918 		 * Fires once for each registered widget.
       
   919 		 *
       
   920 		 * @since 3.0.0
       
   921 		 *
       
   922 		 * @param array $widget An array of default widget arguments.
       
   923 		 */
   647 		do_action( 'wp_register_sidebar_widget', $widget );
   924 		do_action( 'wp_register_sidebar_widget', $widget );
   648 		$wp_registered_widgets[$id] = $widget;
   925 		$wp_registered_widgets[$id] = $widget;
   649 	}
   926 	}
   650 }
   927 }
   651 
   928 
   677  * When registering sidebars a 'description' parameter can be included that
   954  * When registering sidebars a 'description' parameter can be included that
   678  * describes the sidebar for display on the widget administration panel.
   955  * describes the sidebar for display on the widget administration panel.
   679  *
   956  *
   680  * @since 2.9.0
   957  * @since 2.9.0
   681  *
   958  *
   682  * @param int|string $id sidebar ID.
   959  * @param string $id sidebar ID.
   683  * @return string Sidebar description, if available. Null on failure to retrieve description.
   960  * @return string Sidebar description, if available. Null on failure to retrieve description.
   684  */
   961  */
   685 function wp_sidebar_description( $id ) {
   962 function wp_sidebar_description( $id ) {
   686 	if ( !is_scalar($id) )
   963 	if ( !is_scalar($id) )
   687 		return;
   964 		return;
   698  * @since 2.2.0
   975  * @since 2.2.0
   699  *
   976  *
   700  * @param int|string $id Widget ID.
   977  * @param int|string $id Widget ID.
   701  */
   978  */
   702 function wp_unregister_sidebar_widget($id) {
   979 function wp_unregister_sidebar_widget($id) {
       
   980 
       
   981 	/**
       
   982 	 * Fires just before a widget is removed from a sidebar.
       
   983 	 *
       
   984 	 * @since 3.0.0
       
   985 	 *
       
   986 	 * @param int $id The widget ID.
       
   987 	 */
   703 	do_action( 'wp_unregister_sidebar_widget', $id );
   988 	do_action( 'wp_unregister_sidebar_widget', $id );
   704 
   989 
   705 	wp_register_sidebar_widget($id, '', '');
   990 	wp_register_sidebar_widget($id, '', '');
   706 	wp_unregister_widget_control($id);
   991 	wp_unregister_widget_control($id);
   707 }
   992 }
   712  * The options contains the 'height', 'width', and 'id_base' keys. The 'height'
   997  * The options contains the 'height', 'width', and 'id_base' keys. The 'height'
   713  * option is never used. The 'width' option is the width of the fully expanded
   998  * option is never used. The 'width' option is the width of the fully expanded
   714  * control form, but try hard to use the default width. The 'id_base' is for
   999  * control form, but try hard to use the default width. The 'id_base' is for
   715  * multi-widgets (widgets which allow multiple instances such as the text
  1000  * multi-widgets (widgets which allow multiple instances such as the text
   716  * widget), an id_base must be provided. The widget id will end up looking like
  1001  * widget), an id_base must be provided. The widget id will end up looking like
   717  * {$id_base}-{$unique_number}.
  1002  * `{$id_base}-{$unique_number}`.
   718  *
  1003  *
   719  * @since 2.2.0
  1004  * @since 2.2.0
   720  *
  1005  *
   721  * @param int|string $id Sidebar ID.
  1006  * @todo Document `$options` as a hash notation, re: WP_Widget::__construct() cross-reference.
   722  * @param string $name Sidebar display name.
  1007  * @todo `$params` parameter?
   723  * @param callback $control_callback Run when sidebar is displayed.
  1008  *
   724  * @param array|string $options Optional. Widget options. See above long description.
  1009  * @param int|string   $id               Sidebar ID.
   725  * @param mixed $params,... Optional. Additional parameters to add to widget.
  1010  * @param string       $name             Sidebar display name.
   726  */
  1011  * @param callback     $control_callback Run when sidebar is displayed.
   727 function wp_register_widget_control($id, $name, $control_callback, $options = array()) {
  1012  * @param array|string $options          Optional. Widget options. See description above. Default empty array.
       
  1013  */
       
  1014 function wp_register_widget_control( $id, $name, $control_callback, $options = array() ) {
   728 	global $wp_registered_widget_controls, $wp_registered_widget_updates, $wp_registered_widgets, $_wp_deprecated_widgets_callbacks;
  1015 	global $wp_registered_widget_controls, $wp_registered_widget_updates, $wp_registered_widgets, $_wp_deprecated_widgets_callbacks;
   729 
  1016 
   730 	$id = strtolower($id);
  1017 	$id = strtolower($id);
   731 	$id_base = _get_widget_id_base($id);
  1018 	$id_base = _get_widget_id_base($id);
   732 
  1019 
   769 
  1056 
   770 	unset($widget['width'], $widget['height'], $widget['name'], $widget['id']);
  1057 	unset($widget['width'], $widget['height'], $widget['name'], $widget['id']);
   771 	$wp_registered_widget_updates[$id_base] = $widget;
  1058 	$wp_registered_widget_updates[$id_base] = $widget;
   772 }
  1059 }
   773 
  1060 
       
  1061 /**
       
  1062  *
       
  1063  * @global array $wp_registered_widget_updates
       
  1064  * @param string   $id_base
       
  1065  * @param callable $update_callback
       
  1066  * @param array    $options
       
  1067  */
   774 function _register_widget_update_callback($id_base, $update_callback, $options = array()) {
  1068 function _register_widget_update_callback($id_base, $update_callback, $options = array()) {
   775 	global $wp_registered_widget_updates;
  1069 	global $wp_registered_widget_updates;
   776 
  1070 
   777 	if ( isset($wp_registered_widget_updates[$id_base]) ) {
  1071 	if ( isset($wp_registered_widget_updates[$id_base]) ) {
   778 		if ( empty($update_callback) )
  1072 		if ( empty($update_callback) )
   787 
  1081 
   788 	$widget = array_merge($widget, $options);
  1082 	$widget = array_merge($widget, $options);
   789 	$wp_registered_widget_updates[$id_base] = $widget;
  1083 	$wp_registered_widget_updates[$id_base] = $widget;
   790 }
  1084 }
   791 
  1085 
       
  1086 /**
       
  1087  *
       
  1088  * @global array $wp_registered_widget_controls
       
  1089  * @param int|string $id
       
  1090  * @param string     $name
       
  1091  * @param callable   $form_callback
       
  1092  * @param array      $options
       
  1093  * @return null
       
  1094  */
   792 function _register_widget_form_callback($id, $name, $form_callback, $options = array()) {
  1095 function _register_widget_form_callback($id, $name, $form_callback, $options = array()) {
   793 	global $wp_registered_widget_controls;
  1096 	global $wp_registered_widget_controls;
   794 
  1097 
   795 	$id = strtolower($id);
  1098 	$id = strtolower($id);
   796 
  1099 
   820 
  1123 
   821 /**
  1124 /**
   822  * Remove control callback for widget.
  1125  * Remove control callback for widget.
   823  *
  1126  *
   824  * @since 2.2.0
  1127  * @since 2.2.0
   825  * @uses wp_register_widget_control() Unregisters by using empty callback.
       
   826  *
  1128  *
   827  * @param int|string $id Widget ID.
  1129  * @param int|string $id Widget ID.
   828  */
  1130  */
   829 function wp_unregister_widget_control($id) {
  1131 function wp_unregister_widget_control($id) {
   830 	return wp_register_widget_control($id, '', '');
  1132 	return wp_register_widget_control($id, '', '');
   857 		}
  1159 		}
   858 	}
  1160 	}
   859 
  1161 
   860 	$sidebars_widgets = wp_get_sidebars_widgets();
  1162 	$sidebars_widgets = wp_get_sidebars_widgets();
   861 	if ( empty( $wp_registered_sidebars[ $index ] ) || empty( $sidebars_widgets[ $index ] ) || ! is_array( $sidebars_widgets[ $index ] ) ) {
  1163 	if ( empty( $wp_registered_sidebars[ $index ] ) || empty( $sidebars_widgets[ $index ] ) || ! is_array( $sidebars_widgets[ $index ] ) ) {
   862 		return false;
  1164 		/** This action is documented in wp-includes/widgets.php */
   863 	}
  1165 		do_action( 'dynamic_sidebar_before', $index, false );
   864 
  1166 		/** This action is documented in wp-includes/widgets.php */
       
  1167 		do_action( 'dynamic_sidebar_after',  $index, false );
       
  1168 		/** This filter is documented in wp-includes/widgets.php */
       
  1169 		return apply_filters( 'dynamic_sidebar_has_widgets', false, $index );
       
  1170 	}
       
  1171 
       
  1172 	/**
       
  1173 	 * Fires before widgets are rendered in a dynamic sidebar.
       
  1174 	 *
       
  1175 	 * Note: The action also fires for empty sidebars, and on both the front-end
       
  1176 	 * and back-end, including the Inactive Widgets sidebar on the Widgets screen.
       
  1177 	 *
       
  1178 	 * @since 3.9.0
       
  1179 	 *
       
  1180 	 * @param int|string $index       Index, name, or ID of the dynamic sidebar.
       
  1181 	 * @param bool       $has_widgets Whether the sidebar is populated with widgets.
       
  1182 	 *                                Default true.
       
  1183 	 */
       
  1184 	do_action( 'dynamic_sidebar_before', $index, true );
   865 	$sidebar = $wp_registered_sidebars[$index];
  1185 	$sidebar = $wp_registered_sidebars[$index];
   866 
  1186 
   867 	$did_one = false;
  1187 	$did_one = false;
   868 	foreach ( (array) $sidebars_widgets[$index] as $id ) {
  1188 	foreach ( (array) $sidebars_widgets[$index] as $id ) {
   869 
  1189 
   883 				$classname_ .= '_' . get_class($cn);
  1203 				$classname_ .= '_' . get_class($cn);
   884 		}
  1204 		}
   885 		$classname_ = ltrim($classname_, '_');
  1205 		$classname_ = ltrim($classname_, '_');
   886 		$params[0]['before_widget'] = sprintf($params[0]['before_widget'], $id, $classname_);
  1206 		$params[0]['before_widget'] = sprintf($params[0]['before_widget'], $id, $classname_);
   887 
  1207 
       
  1208 		/**
       
  1209 		 * Filter the parameters passed to a widget's display callback.
       
  1210 		 *
       
  1211 		 * Note: The filter is evaluated on both the front-end and back-end,
       
  1212 		 * including for the Inactive Widgets sidebar on the Widgets screen.
       
  1213 		 *
       
  1214 		 * @since 2.5.0
       
  1215 		 *
       
  1216 		 * @see register_sidebar()
       
  1217 		 *
       
  1218 		 * @param array $params {
       
  1219 		 *     @type array $args  {
       
  1220 		 *         An array of widget display arguments.
       
  1221 		 *
       
  1222 		 *         @type string $name          Name of the sidebar the widget is assigned to.
       
  1223 		 *         @type string $id            ID of the sidebar the widget is assigned to.
       
  1224 		 *         @type string $description   The sidebar description.
       
  1225 		 *         @type string $class         CSS class applied to the sidebar container.
       
  1226 		 *         @type string $before_widget HTML markup to prepend to each widget in the sidebar.
       
  1227 		 *         @type string $after_widget  HTML markup to append to each widget in the sidebar.
       
  1228 		 *         @type string $before_title  HTML markup to prepend to the widget title when displayed.
       
  1229 		 *         @type string $after_title   HTML markup to append to the widget title when displayed.
       
  1230 		 *         @type string $widget_id     ID of the widget.
       
  1231 		 *         @type string $widget_name   Name of the widget.
       
  1232 		 *     }
       
  1233 		 *     @type array $widget_args {
       
  1234 		 *         An array of multi-widget arguments.
       
  1235 		 *
       
  1236 		 *         @type int $number Number increment used for multiples of the same widget.
       
  1237 		 *     }
       
  1238 		 * }
       
  1239 		 */
   888 		$params = apply_filters( 'dynamic_sidebar_params', $params );
  1240 		$params = apply_filters( 'dynamic_sidebar_params', $params );
   889 
  1241 
   890 		$callback = $wp_registered_widgets[$id]['callback'];
  1242 		$callback = $wp_registered_widgets[$id]['callback'];
   891 
  1243 
   892 		do_action( 'dynamic_sidebar', $wp_registered_widgets[$id] );
  1244 		/**
       
  1245 		 * Fires before a widget's display callback is called.
       
  1246 		 *
       
  1247 		 * Note: The action fires on both the front-end and back-end, including
       
  1248 		 * for widgets in the Inactive Widgets sidebar on the Widgets screen.
       
  1249 		 *
       
  1250 		 * The action is not fired for empty sidebars.
       
  1251 		 *
       
  1252 		 * @since 3.0.0
       
  1253 		 *
       
  1254 		 * @param array $widget_id {
       
  1255 		 *     An associative array of widget arguments.
       
  1256 		 *
       
  1257 		 *     @type string $name                Name of the widget.
       
  1258 		 *     @type string $id                  Widget ID.
       
  1259 		 *     @type array|callback $callback    When the hook is fired on the front-end, $callback is an array
       
  1260 		 *                                       containing the widget object. Fired on the back-end, $callback
       
  1261 		 *                                       is 'wp_widget_control', see $_callback.
       
  1262 		 *     @type array          $params      An associative array of multi-widget arguments.
       
  1263 		 *     @type string         $classname   CSS class applied to the widget container.
       
  1264 		 *     @type string         $description The widget description.
       
  1265 		 *     @type array          $_callback   When the hook is fired on the back-end, $_callback is populated
       
  1266 		 *                                       with an array containing the widget object, see $callback.
       
  1267 		 * }
       
  1268 		 */
       
  1269 		do_action( 'dynamic_sidebar', $wp_registered_widgets[ $id ] );
   893 
  1270 
   894 		if ( is_callable($callback) ) {
  1271 		if ( is_callable($callback) ) {
   895 			call_user_func_array($callback, $params);
  1272 			call_user_func_array($callback, $params);
   896 			$did_one = true;
  1273 			$did_one = true;
   897 		}
  1274 		}
   898 	}
  1275 	}
       
  1276 
       
  1277 	/**
       
  1278 	 * Fires after widgets are rendered in a dynamic sidebar.
       
  1279 	 *
       
  1280 	 * Note: The action also fires for empty sidebars, and on both the front-end
       
  1281 	 * and back-end, including the Inactive Widgets sidebar on the Widgets screen.
       
  1282 	 *
       
  1283 	 * @since 3.9.0
       
  1284 	 *
       
  1285 	 * @param int|string $index       Index, name, or ID of the dynamic sidebar.
       
  1286 	 * @param bool       $has_widgets Whether the sidebar is populated with widgets.
       
  1287 	 *                                Default true.
       
  1288 	 */
       
  1289 	do_action( 'dynamic_sidebar_after', $index, true );
       
  1290 
       
  1291 	/**
       
  1292 	 * Filter whether a sidebar has widgets.
       
  1293 	 *
       
  1294 	 * Note: The filter is also evaluated for empty sidebars, and on both the front-end
       
  1295 	 * and back-end, including the Inactive Widgets sidebar on the Widgets screen.
       
  1296 	 *
       
  1297 	 * @since 3.9.0
       
  1298 	 *
       
  1299 	 * @param bool       $did_one Whether at least one widget was rendered in the sidebar.
       
  1300 	 *                            Default false.
       
  1301 	 * @param int|string $index   Index, name, or ID of the dynamic sidebar.
       
  1302 	 */
       
  1303 
       
  1304 	$did_one = apply_filters( 'dynamic_sidebar_has_widgets', $did_one, $index );
   899 
  1305 
   900 	return $did_one;
  1306 	return $did_one;
   901 }
  1307 }
   902 
  1308 
   903 /**
  1309 /**
   926 
  1332 
   927 	$sidebars_widgets = wp_get_sidebars_widgets();
  1333 	$sidebars_widgets = wp_get_sidebars_widgets();
   928 
  1334 
   929 	if ( is_array($sidebars_widgets) ) {
  1335 	if ( is_array($sidebars_widgets) ) {
   930 		foreach ( $sidebars_widgets as $sidebar => $widgets ) {
  1336 		foreach ( $sidebars_widgets as $sidebar => $widgets ) {
   931 			if ( $skip_inactive && 'wp_inactive_widgets' == $sidebar )
  1337 			if ( $skip_inactive && ( 'wp_inactive_widgets' === $sidebar || 'orphaned_widgets' === substr( $sidebar, 0, 16 ) ) ) {
   932 				continue;
  1338 				continue;
       
  1339 			}
   933 
  1340 
   934 			if ( is_array($widgets) ) {
  1341 			if ( is_array($widgets) ) {
   935 				foreach ( $widgets as $widget ) {
  1342 				foreach ( $widgets as $widget ) {
   936 					if ( ( $callback && isset($wp_registered_widgets[$widget]['callback']) && $wp_registered_widgets[$widget]['callback'] == $callback ) || ( $id_base && _get_widget_id_base($widget) == $id_base ) ) {
  1343 					if ( ( $callback && isset($wp_registered_widgets[$widget]['callback']) && $wp_registered_widgets[$widget]['callback'] == $callback ) || ( $id_base && _get_widget_id_base($widget) == $id_base ) ) {
   937 						if ( !$widget_id || $widget_id == $wp_registered_widgets[$widget]['id'] )
  1344 						if ( !$widget_id || $widget_id == $wp_registered_widgets[$widget]['id'] )
   965 }
  1372 }
   966 
  1373 
   967 /**
  1374 /**
   968  * Whether a sidebar is in use.
  1375  * Whether a sidebar is in use.
   969  *
  1376  *
   970  * @since 2.8
  1377  * @since 2.8.0
   971  *
  1378  *
   972  * @param mixed $index Sidebar name, id or number to check.
  1379  * @param string|int $index Sidebar name, id or number to check.
   973  * @return bool true if the sidebar is in use, false otherwise.
  1380  * @return bool true if the sidebar is in use, false otherwise.
   974  */
  1381  */
   975 function is_active_sidebar( $index ) {
  1382 function is_active_sidebar( $index ) {
   976 	$index = ( is_int($index) ) ? "sidebar-$index" : sanitize_title($index);
  1383 	$index = ( is_int($index) ) ? "sidebar-$index" : sanitize_title($index);
   977 	$sidebars_widgets = wp_get_sidebars_widgets();
  1384 	$sidebars_widgets = wp_get_sidebars_widgets();
   978 	$is_active_sidebar = ! empty( $sidebars_widgets[$index] );
  1385 	$is_active_sidebar = ! empty( $sidebars_widgets[$index] );
   979 	return $is_active_sidebar;
  1386 
       
  1387 	/**
       
  1388 	 * Filter whether a dynamic sidebar is considered "active".
       
  1389 	 *
       
  1390 	 * @since 3.9.0
       
  1391 	 *
       
  1392 	 * @param bool       $is_active_sidebar Whether or not the sidebar should be considered "active".
       
  1393 	 *                                      In other words, whether the sidebar contains any widgets.
       
  1394 	 * @param int|string $index             Index, name, or ID of the dynamic sidebar.
       
  1395 	 */
       
  1396 	return apply_filters( 'is_active_sidebar', $is_active_sidebar, $index );
   980 }
  1397 }
   981 
  1398 
   982 /* Internal Functions */
  1399 /* Internal Functions */
   983 
  1400 
   984 /**
  1401 /**
   985  * Retrieve full list of sidebars and their widgets.
  1402  * Retrieve full list of sidebars and their widget instance IDs.
   986  *
  1403  *
   987  * Will upgrade sidebar widget list, if needed. Will also save updated list, if
  1404  * Will upgrade sidebar widget list, if needed. Will also save updated list, if
   988  * needed.
  1405  * needed.
   989  *
  1406  *
   990  * @since 2.2.0
  1407  * @since 2.2.0
   991  * @access private
  1408  * @access private
   992  *
  1409  *
   993  * @param bool $deprecated Not used (deprecated).
  1410  * @param bool $deprecated Not used (argument deprecated).
   994  * @return array Upgraded list of widgets to version 3 array format when called from the admin.
  1411  * @return array Upgraded list of widgets to version 3 array format when called from the admin.
   995  */
  1412  */
   996 function wp_get_sidebars_widgets($deprecated = true) {
  1413 function wp_get_sidebars_widgets( $deprecated = true ) {
   997 	if ( $deprecated !== true )
  1414 	if ( $deprecated !== true )
   998 		_deprecated_argument( __FUNCTION__, '2.8.1' );
  1415 		_deprecated_argument( __FUNCTION__, '2.8.1' );
   999 
  1416 
  1000 	global $_wp_sidebars_widgets, $sidebars_widgets;
  1417 	global $_wp_sidebars_widgets, $sidebars_widgets;
  1001 
  1418 
  1011 	}
  1428 	}
  1012 
  1429 
  1013 	if ( is_array( $sidebars_widgets ) && isset($sidebars_widgets['array_version']) )
  1430 	if ( is_array( $sidebars_widgets ) && isset($sidebars_widgets['array_version']) )
  1014 		unset($sidebars_widgets['array_version']);
  1431 		unset($sidebars_widgets['array_version']);
  1015 
  1432 
  1016 	$sidebars_widgets = apply_filters('sidebars_widgets', $sidebars_widgets);
  1433 	/**
       
  1434 	 * Filter the list of sidebars and their widgets.
       
  1435 	 *
       
  1436 	 * @since 2.7.0
       
  1437 	 *
       
  1438 	 * @param array $sidebars_widgets An associative array of sidebars and their widgets.
       
  1439 	 */
       
  1440 	$sidebars_widgets = apply_filters( 'sidebars_widgets', $sidebars_widgets );
  1017 	return $sidebars_widgets;
  1441 	return $sidebars_widgets;
  1018 }
  1442 }
  1019 
  1443 
  1020 /**
  1444 /**
  1021  * Set the sidebar widget option to update sidebars.
  1445  * Set the sidebar widget option to update sidebars.
  1053 /**
  1477 /**
  1054  * Convert the widget settings from single to multi-widget format.
  1478  * Convert the widget settings from single to multi-widget format.
  1055  *
  1479  *
  1056  * @since 2.8.0
  1480  * @since 2.8.0
  1057  *
  1481  *
       
  1482  * @param string $base_name
       
  1483  * @param string $option_name
       
  1484  * @param array  $settings
  1058  * @return array
  1485  * @return array
  1059  */
  1486  */
  1060 function wp_convert_widget_settings($base_name, $option_name, $settings) {
  1487 function wp_convert_widget_settings($base_name, $option_name, $settings) {
  1061 	// This test may need expanding.
  1488 	// This test may need expanding.
  1062 	$single = $changed = false;
  1489 	$single = $changed = false;
  1107 
  1534 
  1108 	return $settings;
  1535 	return $settings;
  1109 }
  1536 }
  1110 
  1537 
  1111 /**
  1538 /**
  1112  * Output an arbitrary widget as a template tag
  1539  * Output an arbitrary widget as a template tag.
  1113  *
  1540  *
  1114  * @since 2.8
  1541  * @since 2.8.0
  1115  *
  1542  *
  1116  * @param string $widget the widget's PHP class name (see default-widgets.php)
  1543  * @param string $widget   The widget's PHP class name (see default-widgets.php).
  1117  * @param array $instance the widget's instance settings
  1544  * @param array  $instance Optional. The widget's instance settings. Default empty array.
  1118  * @param array $args the widget's sidebar args
  1545  * @param array  $args {
  1119  * @return void
  1546  *     Optional. Array of arguments to configure the display of the widget.
  1120  **/
  1547  *
  1121 function the_widget($widget, $instance = array(), $args = array()) {
  1548  *     @type string $before_widget HTML content that will be prepended to the widget's HTML output.
       
  1549  *                                 Default `<div class="widget %s">`, where `%s` is the widget's class name.
       
  1550  *     @type string $after_widget  HTML content that will be appended to the widget's HTML output.
       
  1551  *                                 Default `</div>`.
       
  1552  *     @type string $before_title  HTML content that will be prepended to the widget's title when displayed.
       
  1553  *                                 Default `<h2 class="widgettitle">`.
       
  1554  *     @type string $after_title   HTML content that will be appended to the widget's title when displayed.
       
  1555  *                                 Default `</h2>`.
       
  1556  * }
       
  1557  */
       
  1558 function the_widget( $widget, $instance = array(), $args = array() ) {
  1122 	global $wp_widget_factory;
  1559 	global $wp_widget_factory;
  1123 
  1560 
  1124 	$widget_obj = $wp_widget_factory->widgets[$widget];
  1561 	$widget_obj = $wp_widget_factory->widgets[$widget];
  1125 	if ( !is_a($widget_obj, 'WP_Widget') )
  1562 	if ( ! ( $widget_obj instanceof WP_Widget ) ) {
  1126 		return;
  1563 		return;
       
  1564 	}
  1127 
  1565 
  1128 	$before_widget = sprintf('<div class="widget %s">', $widget_obj->widget_options['classname'] );
  1566 	$before_widget = sprintf('<div class="widget %s">', $widget_obj->widget_options['classname'] );
  1129 	$default_args = array( 'before_widget' => $before_widget, 'after_widget' => "</div>", 'before_title' => '<h2 class="widgettitle">', 'after_title' => '</h2>' );
  1567 	$default_args = array( 'before_widget' => $before_widget, 'after_widget' => "</div>", 'before_title' => '<h2 class="widgettitle">', 'after_title' => '</h2>' );
  1130 
  1568 
  1131 	$args = wp_parse_args($args, $default_args);
  1569 	$args = wp_parse_args($args, $default_args);
  1132 	$instance = wp_parse_args($instance);
  1570 	$instance = wp_parse_args($instance);
  1133 
  1571 
       
  1572 	/**
       
  1573 	 * Fires before rendering the requested widget.
       
  1574 	 *
       
  1575 	 * @since 3.0.0
       
  1576 	 *
       
  1577 	 * @param string $widget   The widget's class name.
       
  1578 	 * @param array  $instance The current widget instance's settings.
       
  1579 	 * @param array  $args     An array of the widget's sidebar arguments.
       
  1580 	 */
  1134 	do_action( 'the_widget', $widget, $instance, $args );
  1581 	do_action( 'the_widget', $widget, $instance, $args );
  1135 
  1582 
  1136 	$widget_obj->_set(-1);
  1583 	$widget_obj->_set(-1);
  1137 	$widget_obj->widget($args, $instance);
  1584 	$widget_obj->widget($args, $instance);
  1138 }
  1585 }
  1157 		$sidebars_widgets = wp_get_sidebars_widgets();
  1604 		$sidebars_widgets = wp_get_sidebars_widgets();
  1158 
  1605 
  1159 	retrieve_widgets(true);
  1606 	retrieve_widgets(true);
  1160 }
  1607 }
  1161 
  1608 
  1162 // look for "lost" widgets, this has to run at least on each theme change
  1609 /**
  1163 function retrieve_widgets($theme_changed = false) {
  1610  * Look for "lost" widgets, this has to run at least on each theme change.
       
  1611  *
       
  1612  * @since 2.8.0
       
  1613  *
       
  1614  * @param string|bool $theme_changed Whether the theme was changed as a boolean. A value
       
  1615  *                                   of 'customize' defers updates for the Customizer.
       
  1616  * @return array
       
  1617  */
       
  1618 function retrieve_widgets( $theme_changed = false ) {
  1164 	global $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;
  1619 	global $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;
  1165 
  1620 
  1166 	$registered_sidebar_keys = array_keys( $wp_registered_sidebars );
  1621 	$registered_sidebar_keys = array_keys( $wp_registered_sidebars );
  1167 	$orphaned = 0;
  1622 	$orphaned = 0;
  1168 
  1623 
  1169 	$old_sidebars_widgets = get_theme_mod( 'sidebars_widgets' );
  1624 	$old_sidebars_widgets = get_theme_mod( 'sidebars_widgets' );
  1170 	if ( is_array( $old_sidebars_widgets ) ) {
  1625 	if ( is_array( $old_sidebars_widgets ) ) {
  1171 		// time() that sidebars were stored is in $old_sidebars_widgets['time']
  1626 		// time() that sidebars were stored is in $old_sidebars_widgets['time']
  1172 		$_sidebars_widgets = $old_sidebars_widgets['data'];
  1627 		$_sidebars_widgets = $old_sidebars_widgets['data'];
  1173 		remove_theme_mod( 'sidebars_widgets' );
  1628 
       
  1629 		if ( 'customize' !== $theme_changed ) {
       
  1630 			remove_theme_mod( 'sidebars_widgets' );
       
  1631 		}
  1174 
  1632 
  1175 		foreach ( $_sidebars_widgets as $sidebar => $widgets ) {
  1633 		foreach ( $_sidebars_widgets as $sidebar => $widgets ) {
  1176 			if ( 'wp_inactive_widgets' == $sidebar || 'orphaned_widgets' == substr( $sidebar, 0, 16 ) )
  1634 			if ( 'wp_inactive_widgets' === $sidebar || 'orphaned_widgets' === substr( $sidebar, 0, 16 ) ) {
  1177 				continue;
  1635 				continue;
       
  1636 			}
  1178 
  1637 
  1179 			if ( !in_array( $sidebar, $registered_sidebar_keys ) ) {
  1638 			if ( !in_array( $sidebar, $registered_sidebar_keys ) ) {
  1180 				$_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $widgets;
  1639 				$_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $widgets;
  1181 				unset( $_sidebars_widgets[$sidebar] );
  1640 				unset( $_sidebars_widgets[$sidebar] );
  1182 			}
  1641 			}
  1251 
  1710 
  1252 		$lost_widgets[] = $key;
  1711 		$lost_widgets[] = $key;
  1253 	}
  1712 	}
  1254 
  1713 
  1255 	$sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']);
  1714 	$sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']);
  1256 	wp_set_sidebars_widgets($sidebars_widgets);
  1715 	if ( 'customize' !== $theme_changed ) {
       
  1716 		wp_set_sidebars_widgets( $sidebars_widgets );
       
  1717 	}
  1257 
  1718 
  1258 	return $sidebars_widgets;
  1719 	return $sidebars_widgets;
  1259 }
  1720 }