WordPress.org

Make WordPress Core

Ticket #20801: 20801.patch

File 20801.patch, 42.0 KB (added by hakre, 3 years ago)
  • wp-includes/widgets.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
    <+><?php\n/**\n * API for creating dynamic sidebar without hardcoding functionality into\n * themes. Includes both internal WordPress routines and theme use routines.\n *\n * This functionality was found in a plugin before WordPress 2.2 release which\n * included it in the core from that point on.\n *\n * @link http://codex.wordpress.org/Plugins/WordPress_Widgets WordPress Widgets\n * @link http://codex.wordpress.org/Plugins/WordPress_Widgets_Api Widgets API\n *\n * @package WordPress\n * @subpackage Widgets\n */\n\n/**\n * This class must be extended for each widget and WP_Widget::widget(), WP_Widget::update()\n * and WP_Widget::form() need to be over-ridden.\n *\n * @package WordPress\n * @subpackage Widgets\n * @since 2.8\n */\nclass WP_Widget {\n\n\tvar $id_base;\t\t\t// Root id for all widgets of this type.\n\tvar $name;\t\t\t\t// Name for this widget type.\n\tvar $widget_options;\t// Option array passed to wp_register_sidebar_widget()\n\tvar $control_options;\t// Option array passed to wp_register_widget_control()\n\n\tvar $number = false;\t// Unique ID number of the current instance.\n\tvar $id = false;\t\t// Unique ID string of the current instance (id_base-number)\n\tvar $updated = false;\t// Set true when we update the data after a POST submit - makes sure we don't do it twice.\n\n\t// Member functions that you must over-ride.\n\n\t/** Echo the widget content.\n\t *\n\t * Subclasses should over-ride this function to generate their widget code.\n\t *\n\t * @param array $args Display arguments including before_title, after_title, before_widget, and after_widget.\n\t * @param array $instance The settings for the particular instance of the widget\n\t */\n\tfunction widget($args, $instance) {\n\t\tdie('function WP_Widget::widget() must be over-ridden in a sub-class.');\n\t}\n\n\t/** Update a particular instance.\n\t *\n\t * This function should check that $new_instance is set correctly.\n\t * The newly calculated value of $instance should be returned.\n\t * If \"false\" is returned, the instance won't be saved/updated.\n\t *\n\t * @param array $new_instance New settings for this instance as input by the user via form()\n\t * @param array $old_instance Old settings for this instance\n\t * @return array Settings to save or bool false to cancel saving\n\t */\n\tfunction update($new_instance, $old_instance) {\n\t\treturn $new_instance;\n\t}\n\n\t/** Echo the settings update form\n\t *\n\t * @param array $instance Current settings\n\t */\n\tfunction form($instance) {\n\t\techo '<p class=\"no-options-widget\">' . __('There are no options for this widget.') . '</p>';\n\t\treturn 'noform';\n\t}\n\n\t// Functions you'll need to call.\n\n\t/**\n\t * PHP4 constructor\n\t */\n\tfunction WP_Widget( $id_base = false, $name, $widget_options = array(), $control_options = array() ) {\n\t\tWP_Widget::__construct( $id_base, $name, $widget_options, $control_options );\n\t}\n\n\t/**\n\t * PHP5 constructor\n\t *\n\t * @param string $id_base Optional Base ID for the widget, lower case,\n\t * if left empty a portion of the widget's class name will be used. Has to be unique.\n\t * @param string $name Name for the widget displayed on the configuration page.\n\t * @param array $widget_options Optional Passed to wp_register_sidebar_widget()\n\t *\t - description: shown on the configuration page\n\t *\t - classname\n\t * @param array $control_options Optional Passed to wp_register_widget_control()\n\t *\t - width: required if more than 250px\n\t *\t - height: currently not used but may be needed in the future\n\t */\n\tfunction __construct( $id_base = false, $name, $widget_options = array(), $control_options = array() ) {\n\t\t$this->id_base = empty($id_base) ? preg_replace( '/(wp_)?widget_/', '', strtolower(get_class($this)) ) : strtolower($id_base);\n\t\t$this->name = $name;\n\t\t$this->option_name = 'widget_' . $this->id_base;\n\t\t$this->widget_options = wp_parse_args( $widget_options, array('classname' => $this->option_name) );\n\t\t$this->control_options = wp_parse_args( $control_options, array('id_base' => $this->id_base) );\n\t}\n\n\t/**\n\t * Constructs name attributes for use in form() fields\n\t *\n\t * This function should be used in form() methods to create name attributes for fields to be saved by update()\n\t *\n\t * @param string $field_name Field name\n\t * @return string Name attribute for $field_name\n\t */\n\tfunction get_field_name($field_name) {\n\t\treturn 'widget-' . $this->id_base . '[' . $this->number . '][' . $field_name . ']';\n\t}\n\n\t/**\n\t * Constructs id attributes for use in form() fields\n\t *\n\t * This function should be used in form() methods to create id attributes for fields to be saved by update()\n\t *\n\t * @param string $field_name Field name\n\t * @return string ID attribute for $field_name\n\t */\n\tfunction get_field_id($field_name) {\n\t\treturn 'widget-' . $this->id_base . '-' . $this->number . '-' . $field_name;\n\t}\n\n\t// Private Functions. Don't worry about these.\n\n\tfunction _register() {\n\t\t$settings = $this->get_settings();\n\t\t$empty = true;\n\n\t\tif ( is_array($settings) ) {\n\t\t\tforeach ( array_keys($settings) as $number ) {\n\t\t\t\tif ( is_numeric($number) ) {\n\t\t\t\t\t$this->_set($number);\n\t\t\t\t\t$this->_register_one($number);\n\t\t\t\t\t$empty = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( $empty ) {\n\t\t\t// If there are none, we register the widget's existence with a\n\t\t\t// generic template\n\t\t\t$this->_set(1);\n\t\t\t$this->_register_one();\n\t\t}\n\t}\n\n\tfunction _set($number) {\n\t\t$this->number = $number;\n\t\t$this->id = $this->id_base . '-' . $number;\n\t}\n\n\tfunction _get_display_callback() {\n\t\treturn array(&$this, 'display_callback');\n\t}\n\n\tfunction _get_update_callback() {\n\t\treturn array(&$this, 'update_callback');\n\t}\n\n\tfunction _get_form_callback() {\n\t\treturn array(&$this, 'form_callback');\n\t}\n\n\t/** Generate the actual widget content.\n\t *\tJust finds the instance and calls widget().\n\t *\tDo NOT over-ride this function. */\n\tfunction display_callback( $args, $widget_args = 1 ) {\n\t\tif ( is_numeric($widget_args) )\n\t\t\t$widget_args = array( 'number' => $widget_args );\n\n\t\t$widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );\n\t\t$this->_set( $widget_args['number'] );\n\t\t$instance = $this->get_settings();\n\n\t\tif ( array_key_exists( $this->number, $instance ) ) {\n\t\t\t$instance = $instance[$this->number];\n\t\t\t// filters the widget's settings, return false to stop displaying the widget\n\t\t\t$instance = apply_filters('widget_display_callback', $instance, $this, $args);\n\t\t\tif ( false !== $instance )\n\t\t\t\t$this->widget($args, $instance);\n\t\t}\n\t}\n\n\t/** Deal with changed settings.\n\t *\tDo NOT over-ride this function. */\n\tfunction update_callback( $widget_args = 1 ) {\n\t\tglobal $wp_registered_widgets;\n\n\t\tif ( is_numeric($widget_args) )\n\t\t\t$widget_args = array( 'number' => $widget_args );\n\n\t\t$widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );\n\t\t$all_instances = $this->get_settings();\n\n\t\t// We need to update the data\n\t\tif ( $this->updated )\n\t\t\treturn;\n\n\t\t$sidebars_widgets = wp_get_sidebars_widgets();\n\n\t\tif ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {\n\t\t\t// Delete the settings for this instance of the widget\n\t\t\tif ( isset($_POST['the-widget-id']) )\n\t\t\t\t$del_id = $_POST['the-widget-id'];\n\t\t\telse\n\t\t\t\treturn;\n\n\t\t\tif ( isset($wp_registered_widgets[$del_id]['params'][0]['number']) ) {\n\t\t\t\t$number = $wp_registered_widgets[$del_id]['params'][0]['number'];\n\n\t\t\t\tif ( $this->id_base . '-' . $number == $del_id )\n\t\t\t\t\tunset($all_instances[$number]);\n\t\t\t}\n\t\t} else {\n\t\t\tif ( isset($_POST['widget-' . $this->id_base]) && is_array($_POST['widget-' . $this->id_base]) ) {\n\t\t\t\t$settings = $_POST['widget-' . $this->id_base];\n\t\t\t} elseif ( isset($_POST['id_base']) && $_POST['id_base'] == $this->id_base ) {\n\t\t\t\t$num = $_POST['multi_number'] ? (int) $_POST['multi_number'] : (int) $_POST['widget_number'];\n\t\t\t\t$settings = array( $num => array() );\n\t\t\t} else {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tforeach ( $settings as $number => $new_instance ) {\n\t\t\t\t$new_instance = stripslashes_deep($new_instance);\n\t\t\t\t$this->_set($number);\n\n\t\t\t\t$old_instance = isset($all_instances[$number]) ? $all_instances[$number] : array();\n\n\t\t\t\t$instance = $this->update($new_instance, $old_instance);\n\n\t\t\t\t// filters the widget's settings before saving, return false to cancel saving (keep the old settings if updating)\n\t\t\t\t$instance = apply_filters('widget_update_callback', $instance, $new_instance, $old_instance, $this);\n\t\t\t\tif ( false !== $instance )\n\t\t\t\t\t$all_instances[$number] = $instance;\n\n\t\t\t\tbreak; // run only once\n\t\t\t}\n\t\t}\n\n\t\t$this->save_settings($all_instances);\n\t\t$this->updated = true;\n\t}\n\n\t/** Generate the control form.\n\t *\tDo NOT over-ride this function. */\n\tfunction form_callback( $widget_args = 1 ) {\n\t\tif ( is_numeric($widget_args) )\n\t\t\t$widget_args = array( 'number' => $widget_args );\n\n\t\t$widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );\n\t\t$all_instances = $this->get_settings();\n\n\t\tif ( -1 == $widget_args['number'] ) {\n\t\t\t// We echo out a form where 'number' can be set later\n\t\t\t$this->_set('__i__');\n\t\t\t$instance = array();\n\t\t} else {\n\t\t\t$this->_set($widget_args['number']);\n\t\t\t$instance = $all_instances[ $widget_args['number'] ];\n\t\t}\n\n\t\t// filters the widget admin form before displaying, return false to stop displaying it\n\t\t$instance = apply_filters('widget_form_callback', $instance, $this);\n\n\t\t$return = null;\n\t\tif ( false !== $instance ) {\n\t\t\t$return = $this->form($instance);\n\t\t\t// add extra fields in the widget form - be sure to set $return to null if you add any\n\t\t\t// if the widget has no form the text echoed from the default form method can be hidden using css\n\t\t\tdo_action_ref_array( 'in_widget_form', array(&$this, &$return, $instance) );\n\t\t}\n\t\treturn $return;\n\t}\n\n\t/** Helper function: Registers a single instance. */\n\tfunction _register_one($number = -1) {\n\t\twp_register_sidebar_widget(\t$this->id, $this->name,\t$this->_get_display_callback(), $this->widget_options, array( 'number' => $number ) );\n\t\t_register_widget_update_callback( $this->id_base, $this->_get_update_callback(), $this->control_options, array( 'number' => -1 ) );\n\t\t_register_widget_form_callback(\t$this->id, $this->name,\t$this->_get_form_callback(), $this->control_options, array( 'number' => $number ) );\n\t}\n\n\tfunction save_settings($settings) {\n\t\t$settings['_multiwidget'] = 1;\n\t\tupdate_option( $this->option_name, $settings );\n\t}\n\n\tfunction get_settings() {\n\t\t$settings = get_option($this->option_name);\n\n\t\tif ( false === $settings && isset($this->alt_option_name) )\n\t\t\t$settings = get_option($this->alt_option_name);\n\n\t\tif ( !is_array($settings) )\n\t\t\t$settings = array();\n\n\t\tif ( !empty($settings) && !array_key_exists('_multiwidget', $settings) ) {\n\t\t\t// old format, convert if single widget\n\t\t\t$settings = wp_convert_widget_settings($this->id_base, $this->option_name, $settings);\n\t\t}\n\n\t\tunset($settings['_multiwidget'], $settings['__i__']);\n\t\treturn $settings;\n\t}\n}\n\n/**\n * Singleton that registers and instantiates WP_Widget classes.\n *\n * @package WordPress\n * @subpackage Widgets\n * @since 2.8\n */\nclass WP_Widget_Factory {\n\tvar $widgets = array();\n\n\tfunction WP_Widget_Factory() {\n\t\tadd_action( 'widgets_init', array( &$this, '_register_widgets' ), 100 );\n\t}\n\n\tfunction register($widget_class) {\n\t\t$this->widgets[$widget_class] = new $widget_class();\n\t}\n\n\tfunction unregister($widget_class) {\n\t\tif ( isset($this->widgets[$widget_class]) )\n\t\t\tunset($this->widgets[$widget_class]);\n\t}\n\n\tfunction _register_widgets() {\n\t\tglobal $wp_registered_widgets;\n\t\t$keys = array_keys($this->widgets);\n\t\t$registered = array_keys($wp_registered_widgets);\n\t\t$registered = array_map('_get_widget_id_base', $registered);\n\n\t\tforeach ( $keys as $key ) {\n\t\t\t// don't register new widget if old widget with the same id is already registered\n\t\t\tif ( in_array($this->widgets[$key]->id_base, $registered, true) ) {\n\t\t\t\tunset($this->widgets[$key]);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t$this->widgets[$key]->_register();\n\t\t}\n\t}\n}\n\n/* Global Variables */\n\n/** @ignore */\nglobal $wp_registered_sidebars, $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates;\n\n/**\n * Stores the sidebars, since many themes can have more than one.\n *\n * @global array $wp_registered_sidebars\n * @since 2.2.0\n */\n$wp_registered_sidebars = array();\n\n/**\n * Stores the registered widgets.\n *\n * @global array $wp_registered_widgets\n * @since 2.2.0\n */\n$wp_registered_widgets = array();\n\n/**\n * Stores the registered widget control (options).\n *\n * @global array $wp_registered_widget_controls\n * @since 2.2.0\n */\n$wp_registered_widget_controls = array();\n$wp_registered_widget_updates = array();\n\n/**\n * Private\n */\n$_wp_sidebars_widgets = array();\n\n/**\n * Private\n */\n $GLOBALS['_wp_deprecated_widgets_callbacks'] = array(\n \t'wp_widget_pages',\n\t'wp_widget_pages_control',\n\t'wp_widget_calendar',\n\t'wp_widget_calendar_control',\n\t'wp_widget_archives',\n\t'wp_widget_archives_control',\n\t'wp_widget_links',\n\t'wp_widget_meta',\n\t'wp_widget_meta_control',\n\t'wp_widget_search',\n\t'wp_widget_recent_entries',\n\t'wp_widget_recent_entries_control',\n\t'wp_widget_tag_cloud',\n\t'wp_widget_tag_cloud_control',\n\t'wp_widget_categories',\n\t'wp_widget_categories_control',\n\t'wp_widget_text',\n\t'wp_widget_text_control',\n\t'wp_widget_rss',\n\t'wp_widget_rss_control',\n\t'wp_widget_recent_comments',\n\t'wp_widget_recent_comments_control'\n );\n\n/* Template tags & API functions */\n\n/**\n * Register a widget\n *\n * Registers a WP_Widget widget\n *\n * @since 2.8.0\n *\n * @see WP_Widget\n * @see WP_Widget_Factory\n * @uses WP_Widget_Factory\n *\n * @param string $widget_class The name of a class that extends WP_Widget\n */\nfunction register_widget($widget_class) {\n\tglobal $wp_widget_factory;\n\n\t$wp_widget_factory->register($widget_class);\n}\n\n/**\n * Unregister a widget\n *\n * Unregisters a WP_Widget widget. Useful for unregistering default widgets.\n * Run within a function hooked to the widgets_init action.\n *\n * @since 2.8.0\n *\n * @see WP_Widget\n * @see WP_Widget_Factory\n * @uses WP_Widget_Factory\n *\n * @param string $widget_class The name of a class that extends WP_Widget\n */\nfunction unregister_widget($widget_class) {\n\tglobal $wp_widget_factory;\n\n\t$wp_widget_factory->unregister($widget_class);\n}\n\n/**\n * Creates multiple sidebars.\n *\n * If you wanted to quickly create multiple sidebars for a theme or internally.\n * This function will allow you to do so. If you don't pass the 'name' and/or\n * 'id' in $args, then they will be built for you.\n *\n * The default for the name is \"Sidebar #\", with '#' being replaced with the\n * number the sidebar is currently when greater than one. If first sidebar, the\n * name will be just \"Sidebar\". The default for id is \"sidebar-\" followed by the\n * number the sidebar creation is currently at. If the id is provided, and multiple\n * sidebars are being defined, the id will have \"-2\" appended, and so on.\n *\n * @since 2.2.0\n *\n * @see register_sidebar() The second parameter is documented by register_sidebar() and is the same here.\n * @uses parse_str() Converts a string to an array to be used in the rest of the function.\n * @uses register_sidebar() Sends single sidebar information [name, id] to this\n *\tfunction to handle building the sidebar.\n *\n * @param int $number Number of sidebars to create.\n * @param string|array $args Builds Sidebar based off of 'name' and 'id' values.\n */\nfunction register_sidebars($number = 1, $args = array()) {\n\tglobal $wp_registered_sidebars;\n\t$number = (int) $number;\n\n\tif ( is_string($args) )\n\t\tparse_str($args, $args);\n\n\tfor ( $i = 1; $i <= $number; $i++ ) {\n\t\t$_args = $args;\n\n\t\tif ( $number > 1 )\n\t\t\t$_args['name'] = isset($args['name']) ? sprintf($args['name'], $i) : sprintf(__('Sidebar %d'), $i);\n\t\telse\n\t\t\t$_args['name'] = isset($args['name']) ? $args['name'] : __('Sidebar');\n\n\t\t// Custom specified ID's are suffixed if they exist already.\n\t\t// Automatically generated sidebar names need to be suffixed regardless starting at -0\n\t\tif ( isset($args['id']) ) {\n\t\t\t$_args['id'] = $args['id'];\n\t\t\t$n = 2; // Start at -2 for conflicting custom ID's\n\t\t\twhile ( isset($wp_registered_sidebars[$_args['id']]) )\n\t\t\t\t$_args['id'] = $args['id'] . '-' . $n++;\n\t\t} else {\n\t\t\t$n = count($wp_registered_sidebars);\n\t\t\tdo {\n\t\t\t\t$_args['id'] = 'sidebar-' . ++$n;\n\t\t\t} while ( isset($wp_registered_sidebars[$_args['id']]) );\n\t\t}\n\t\tregister_sidebar($_args);\n\t}\n}\n\n/**\n * Builds the definition for a single sidebar and returns the ID.\n *\n * The $args parameter takes either a string or an array with 'name' and 'id'\n * contained in either usage. It will be noted that the values will be applied\n * to all sidebars, so if creating more than one, it will be advised to allow\n * for WordPress to create the defaults for you.\n *\n * Example for string would be <code>'name=whatever;id=whatever1'</code> and for\n * the array it would be <code>array(\n *    'name' => 'whatever',\n *    'id' => 'whatever1')</code>.\n *\n * name - The name of the sidebar, which presumably the title which will be\n *     displayed.\n * id - The unique identifier by which the sidebar will be called by.\n * before_widget - The content that will prepended to the widgets when they are\n *     displayed.\n * after_widget - The content that will be appended to the widgets when they are\n *     displayed.\n * before_title - The content that will be prepended to the title when displayed.\n * after_title - the content that will be appended to the title when displayed.\n *\n * <em>Content</em> is assumed to be HTML and should be formatted as such, but\n * doesn't have to be.\n *\n * @since 2.2.0\n * @uses $wp_registered_sidebars Stores the new sidebar in this array by sidebar ID.\n *\n * @param string|array $args Builds Sidebar based off of 'name' and 'id' values\n * @return string The sidebar id that was added.\n */\nfunction register_sidebar($args = array()) {\n\tglobal $wp_registered_sidebars;\n\n\t$i = count($wp_registered_sidebars) + 1;\n\n\t$defaults = array(\n\t\t'name' => sprintf(__('Sidebar %d'), $i ),\n\t\t'id' => \"sidebar-$i\",\n\t\t'description' => '',\n\t\t'class' => '',\n\t\t'before_widget' => '<li id=\"%1$s\" class=\"widget %2$s\">',\n\t\t'after_widget' => \"</li>\\n\",\n\t\t'before_title' => '<h2 class=\"widgettitle\">',\n\t\t'after_title' => \"</h2>\\n\",\n\t);\n\n\t$sidebar = wp_parse_args( $args, $defaults );\n\n\t$wp_registered_sidebars[$sidebar['id']] = $sidebar;\n\n\tadd_theme_support('widgets');\n\n\tdo_action( 'register_sidebar', $sidebar );\n\n\treturn $sidebar['id'];\n}\n\n/**\n * Removes a sidebar from the list.\n *\n * @since 2.2.0\n *\n * @uses $wp_registered_sidebars Stores the new sidebar in this array by sidebar ID.\n *\n * @param string $name The ID of the sidebar when it was added.\n */\nfunction unregister_sidebar( $name ) {\n\tglobal $wp_registered_sidebars;\n\n\tif ( isset( $wp_registered_sidebars[$name] ) )\n\t\tunset( $wp_registered_sidebars[$name] );\n}\n\n/**\n * Register widget for use in sidebars.\n *\n * The default widget option is 'classname' that can be override.\n *\n * The function can also be used to unregister widgets when $output_callback\n * parameter is an empty string.\n *\n * @since 2.2.0\n *\n * @uses $wp_registered_widgets Uses stored registered widgets.\n * @uses $wp_register_widget_defaults Retrieves widget defaults.\n *\n * @param int|string $id Widget ID.\n * @param string $name Widget display title.\n * @param callback $output_callback Run when widget is called.\n * @param array|string $options Optional. Widget Options.\n * @param mixed $params,... Widget parameters to add to widget.\n * @return null Will return if $output_callback is empty after removing widget.\n */\nfunction wp_register_sidebar_widget($id, $name, $output_callback, $options = array()) {\n\tglobal $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates, $_wp_deprecated_widgets_callbacks;\n\n\t$id = strtolower($id);\n\n\tif ( empty($output_callback) ) {\n\t\tunset($wp_registered_widgets[$id]);\n\t\treturn;\n\t}\n\n\t$id_base = _get_widget_id_base($id);\n\tif ( in_array($output_callback, $_wp_deprecated_widgets_callbacks, true) && !is_callable($output_callback) ) {\n\t\tif ( isset($wp_registered_widget_controls[$id]) )\n\t\t\tunset($wp_registered_widget_controls[$id]);\n\n\t\tif ( isset($wp_registered_widget_updates[$id_base]) )\n\t\t\tunset($wp_registered_widget_updates[$id_base]);\n\n\t\treturn;\n\t}\n\n\t$defaults = array('classname' => $output_callback);\n\t$options = wp_parse_args($options, $defaults);\n\t$widget = array(\n\t\t'name' => $name,\n\t\t'id' => $id,\n\t\t'callback' => $output_callback,\n\t\t'params' => array_slice(func_get_args(), 4)\n\t);\n\t$widget = array_merge($widget, $options);\n\n\tif ( is_callable($output_callback) && ( !isset($wp_registered_widgets[$id]) || did_action( 'widgets_init' ) ) ) {\n\t\tdo_action( 'wp_register_sidebar_widget', $widget );\n\t\t$wp_registered_widgets[$id] = $widget;\n\t}\n}\n\n/**\n * Retrieve description for widget.\n *\n * When registering widgets, the options can also include 'description' that\n * describes the widget for display on the widget administration panel or\n * in the theme.\n *\n * @since 2.5.0\n *\n * @param int|string $id Widget ID.\n * @return string Widget description, if available. Null on failure to retrieve description.\n */\nfunction wp_widget_description( $id ) {\n\tif ( !is_scalar($id) )\n\t\treturn;\n\n\tglobal $wp_registered_widgets;\n\n\tif ( isset($wp_registered_widgets[$id]['description']) )\n\t\treturn esc_html( $wp_registered_widgets[$id]['description'] );\n}\n\n/**\n * Retrieve description for a sidebar.\n *\n * When registering sidebars a 'description' parameter can be included that\n * describes the sidebar for display on the widget administration panel.\n *\n * @since 2.9.0\n *\n * @param int|string $id sidebar ID.\n * @return string Sidebar description, if available. Null on failure to retrieve description.\n */\nfunction wp_sidebar_description( $id ) {\n\tif ( !is_scalar($id) )\n\t\treturn;\n\n\tglobal $wp_registered_sidebars;\n\n\tif ( isset($wp_registered_sidebars[$id]['description']) )\n\t\treturn esc_html( $wp_registered_sidebars[$id]['description'] );\n}\n\n/**\n * Remove widget from sidebar.\n *\n * @since 2.2.0\n *\n * @param int|string $id Widget ID.\n */\nfunction wp_unregister_sidebar_widget($id) {\n\tdo_action( 'wp_unregister_sidebar_widget', $id );\n\n\twp_register_sidebar_widget($id, '', '');\n\twp_unregister_widget_control($id);\n}\n\n/**\n * Registers widget control callback for customizing options.\n *\n * The options contains the 'height', 'width', and 'id_base' keys. The 'height'\n * option is never used. The 'width' option is the width of the fully expanded\n * control form, but try hard to use the default width. The 'id_base' is for\n * multi-widgets (widgets which allow multiple instances such as the text\n * widget), an id_base must be provided. The widget id will end up looking like\n * {$id_base}-{$unique_number}.\n *\n * @since 2.2.0\n *\n * @param int|string $id Sidebar ID.\n * @param string $name Sidebar display name.\n * @param callback $control_callback Run when sidebar is displayed.\n * @param array|string $options Optional. Widget options. See above long description.\n * @param mixed $params,... Optional. Additional parameters to add to widget.\n */\nfunction wp_register_widget_control($id, $name, $control_callback, $options = array()) {\n\tglobal $wp_registered_widget_controls, $wp_registered_widget_updates, $wp_registered_widgets, $_wp_deprecated_widgets_callbacks;\n\n\t$id = strtolower($id);\n\t$id_base = _get_widget_id_base($id);\n\n\tif ( empty($control_callback) ) {\n\t\tunset($wp_registered_widget_controls[$id]);\n\t\tunset($wp_registered_widget_updates[$id_base]);\n\t\treturn;\n\t}\n\n\tif ( in_array($control_callback, $_wp_deprecated_widgets_callbacks, true) && !is_callable($control_callback) ) {\n\t\tif ( isset($wp_registered_widgets[$id]) )\n\t\t\tunset($wp_registered_widgets[$id]);\n\n\t\treturn;\n\t}\n\n\tif ( isset($wp_registered_widget_controls[$id]) && !did_action( 'widgets_init' ) )\n\t\treturn;\n\n\t$defaults = array('width' => 250, 'height' => 200 ); // height is never used\n\t$options = wp_parse_args($options, $defaults);\n\t$options['width'] = (int) $options['width'];\n\t$options['height'] = (int) $options['height'];\n\n\t$widget = array(\n\t\t'name' => $name,\n\t\t'id' => $id,\n\t\t'callback' => $control_callback,\n\t\t'params' => array_slice(func_get_args(), 4)\n\t);\n\t$widget = array_merge($widget, $options);\n\n\t$wp_registered_widget_controls[$id] = $widget;\n\n\tif ( isset($wp_registered_widget_updates[$id_base]) )\n\t\treturn;\n\n\tif ( isset($widget['params'][0]['number']) )\n\t\t$widget['params'][0]['number'] = -1;\n\n\tunset($widget['width'], $widget['height'], $widget['name'], $widget['id']);\n\t$wp_registered_widget_updates[$id_base] = $widget;\n}\n\nfunction _register_widget_update_callback($id_base, $update_callback, $options = array()) {\n\tglobal $wp_registered_widget_updates;\n\n\tif ( isset($wp_registered_widget_updates[$id_base]) ) {\n\t\tif ( empty($update_callback) )\n\t\t\tunset($wp_registered_widget_updates[$id_base]);\n\t\treturn;\n\t}\n\n\t$widget = array(\n\t\t'callback' => $update_callback,\n\t\t'params' => array_slice(func_get_args(), 3)\n\t);\n\n\t$widget = array_merge($widget, $options);\n\t$wp_registered_widget_updates[$id_base] = $widget;\n}\n\nfunction _register_widget_form_callback($id, $name, $form_callback, $options = array()) {\n\tglobal $wp_registered_widget_controls;\n\n\t$id = strtolower($id);\n\n\tif ( empty($form_callback) ) {\n\t\tunset($wp_registered_widget_controls[$id]);\n\t\treturn;\n\t}\n\n\tif ( isset($wp_registered_widget_controls[$id]) && !did_action( 'widgets_init' ) )\n\t\treturn;\n\n\t$defaults = array('width' => 250, 'height' => 200 );\n\t$options = wp_parse_args($options, $defaults);\n\t$options['width'] = (int) $options['width'];\n\t$options['height'] = (int) $options['height'];\n\n\t$widget = array(\n\t\t'name' => $name,\n\t\t'id' => $id,\n\t\t'callback' => $form_callback,\n\t\t'params' => array_slice(func_get_args(), 4)\n\t);\n\t$widget = array_merge($widget, $options);\n\n\t$wp_registered_widget_controls[$id] = $widget;\n}\n\n/**\n * Remove control callback for widget.\n *\n * @since 2.2.0\n * @uses wp_register_widget_control() Unregisters by using empty callback.\n *\n * @param int|string $id Widget ID.\n */\nfunction wp_unregister_widget_control($id) {\n\treturn wp_register_widget_control($id, '', '');\n}\n\n/**\n * Display dynamic sidebar.\n *\n * By default it displays the default sidebar or 'sidebar-1'. The 'sidebar-1' is\n * not named by the theme, the actual name is '1', but 'sidebar-' is added to\n * the registered sidebars for the name. If you named your sidebar 'after-post',\n * then the parameter $index will still be 'after-post', but the lookup will be\n * for 'sidebar-after-post'.\n *\n * It is confusing for the $index parameter, but just know that it should just\n * work. When you register the sidebar in the theme, you will use the same name\n * for this function or \"Pay no heed to the man behind the curtain.\" Just accept\n * it as an oddity of WordPress sidebar register and display.\n *\n * @since 2.2.0\n *\n * @param int|string $index Optional, default is 1. Name or ID of dynamic sidebar.\n * @return bool True, if widget sidebar was found and called. False if not found or not called.\n */\nfunction dynamic_sidebar($index = 1) {\n\tglobal $wp_registered_sidebars, $wp_registered_widgets;\n\n\tif ( is_int($index) ) {\n\t\t$index = \"sidebar-$index\";\n\t} else {\n\t\t$index = sanitize_title($index);\n\t\tforeach ( (array) $wp_registered_sidebars as $key => $value ) {\n\t\t\tif ( sanitize_title($value['name']) == $index ) {\n\t\t\t\t$index = $key;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t$sidebars_widgets = wp_get_sidebars_widgets();\n\tif ( empty( $sidebars_widgets ) )\n\t\treturn false;\n\n\tif ( empty($wp_registered_sidebars[$index]) || !array_key_exists($index, $sidebars_widgets) || !is_array($sidebars_widgets[$index]) || empty($sidebars_widgets[$index]) )\n\t\treturn false;\n\n\t$sidebar = $wp_registered_sidebars[$index];\n\n\t$did_one = false;\n\tforeach ( (array) $sidebars_widgets[$index] as $id ) {\n\n\t\tif ( !isset($wp_registered_widgets[$id]) ) continue;\n\n\t\t$params = array_merge(\n\t\t\tarray( array_merge( $sidebar, array('widget_id' => $id, 'widget_name' => $wp_registered_widgets[$id]['name']) ) ),\n\t\t\t(array) $wp_registered_widgets[$id]['params']\n\t\t);\n\n\t\t// Substitute HTML id and class attributes into before_widget\n\t\t$classname_ = '';\n\t\tforeach ( (array) $wp_registered_widgets[$id]['classname'] as $cn ) {\n\t\t\tif ( is_string($cn) )\n\t\t\t\t$classname_ .= '_' . $cn;\n\t\t\telseif ( is_object($cn) )\n\t\t\t\t$classname_ .= '_' . get_class($cn);\n\t\t}\n\t\t$classname_ = ltrim($classname_, '_');\n\t\t$params[0]['before_widget'] = sprintf($params[0]['before_widget'], $id, $classname_);\n\n\t\t$params = apply_filters( 'dynamic_sidebar_params', $params );\n\n\t\t$callback = $wp_registered_widgets[$id]['callback'];\n\n\t\tdo_action( 'dynamic_sidebar', $wp_registered_widgets[$id] );\n\n\t\tif ( is_callable($callback) ) {\n\t\t\tcall_user_func_array($callback, $params);\n\t\t\t$did_one = true;\n\t\t}\n\t}\n\n\treturn $did_one;\n}\n\n/**\n * Whether widget is displayed on the front-end.\n *\n * Either $callback or $id_base can be used\n * $id_base is the first argument when extending WP_Widget class\n * Without the optional $widget_id parameter, returns the ID of the first sidebar\n * in which the first instance of the widget with the given callback or $id_base is found.\n * With the $widget_id parameter, returns the ID of the sidebar where\n * the widget with that callback/$id_base AND that ID is found.\n *\n * NOTE: $widget_id and $id_base are the same for single widgets. To be effective\n * this function has to run after widgets have initialized, at action 'init' or later.\n *\n * @since 2.2.0\n *\n * @param string $callback Optional, Widget callback to check.\n * @param int $widget_id Optional, but needed for checking. Widget ID.\n * @param string $id_base Optional, the base ID of a widget created by extending WP_Widget.\n * @param bool $skip_inactive Optional, whether to check in 'wp_inactive_widgets'.\n * @return mixed false if widget is not active or id of sidebar in which the widget is active.\n */\nfunction is_active_widget($callback = false, $widget_id = false, $id_base = false, $skip_inactive = true) {\n\tglobal $wp_registered_widgets;\n\n\t$sidebars_widgets = wp_get_sidebars_widgets();\n\n\tif ( is_array($sidebars_widgets) ) {\n\t\tforeach ( $sidebars_widgets as $sidebar => $widgets ) {\n\t\t\tif ( $skip_inactive && 'wp_inactive_widgets' == $sidebar )\n\t\t\t\tcontinue;\n\n\t\t\tif ( is_array($widgets) ) {\n\t\t\t\tforeach ( $widgets as $widget ) {\n\t\t\t\t\tif ( ( $callback && isset($wp_registered_widgets[$widget]['callback']) && $wp_registered_widgets[$widget]['callback'] == $callback ) || ( $id_base && _get_widget_id_base($widget) == $id_base ) ) {\n\t\t\t\t\t\tif ( !$widget_id || $widget_id == $wp_registered_widgets[$widget]['id'] )\n\t\t\t\t\t\t\treturn $sidebar;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n}\n\n/**\n * Whether the dynamic sidebar is enabled and used by theme.\n *\n * @since 2.2.0\n *\n * @return bool True, if using widgets. False, if not using widgets.\n */\nfunction is_dynamic_sidebar() {\n\tglobal $wp_registered_widgets, $wp_registered_sidebars;\n\t$sidebars_widgets = get_option('sidebars_widgets');\n\tforeach ( (array) $wp_registered_sidebars as $index => $sidebar ) {\n\t\tif ( count($sidebars_widgets[$index]) ) {\n\t\t\tforeach ( (array) $sidebars_widgets[$index] as $widget )\n\t\t\t\tif ( array_key_exists($widget, $wp_registered_widgets) )\n\t\t\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\n/**\n * Whether a sidebar is in use.\n *\n * @since 2.8\n *\n * @param mixed $index Sidebar name, id or number to check.\n * @return bool true if the sidebar is in use, false otherwise.\n */\nfunction is_active_sidebar( $index ) {\n\t$index = ( is_int($index) ) ? \"sidebar-$index\" : sanitize_title($index);\n\t$sidebars_widgets = wp_get_sidebars_widgets();\n\tif ( !empty($sidebars_widgets[$index]) )\n\t\treturn true;\n\n\treturn false;\n}\n\n/* Internal Functions */\n\n/**\n * Retrieve full list of sidebars and their widgets.\n *\n * Will upgrade sidebar widget list, if needed. Will also save updated list, if\n * needed.\n *\n * @since 2.2.0\n * @access private\n *\n * @param bool $deprecated Not used (deprecated).\n * @return array Upgraded list of widgets to version 3 array format when called from the admin.\n */\nfunction wp_get_sidebars_widgets($deprecated = true) {\n\tif ( $deprecated !== true )\n\t\t_deprecated_argument( __FUNCTION__, '2.8.1' );\n\n\tglobal $wp_registered_widgets, $_wp_sidebars_widgets, $sidebars_widgets;\n\n\t// If loading from front page, consult $_wp_sidebars_widgets rather than options\n\t// to see if wp_convert_widget_settings() has made manipulations in memory.\n\tif ( !is_admin() ) {\n\t\tif ( empty($_wp_sidebars_widgets) )\n\t\t\t$_wp_sidebars_widgets = get_option('sidebars_widgets', array());\n\n\t\t$sidebars_widgets = $_wp_sidebars_widgets;\n\t} else {\n\t\t$sidebars_widgets = get_option('sidebars_widgets', array());\n\t}\n\n\tif ( is_array( $sidebars_widgets ) && isset($sidebars_widgets['array_version']) )\n\t\tunset($sidebars_widgets['array_version']);\n\n\t$sidebars_widgets = apply_filters('sidebars_widgets', $sidebars_widgets);\n\treturn $sidebars_widgets;\n}\n\n/**\n * Set the sidebar widget option to update sidebars.\n *\n * @since 2.2.0\n * @access private\n *\n * @param array $sidebars_widgets Sidebar widgets and their settings.\n */\nfunction wp_set_sidebars_widgets( $sidebars_widgets ) {\n\tif ( !isset( $sidebars_widgets['array_version'] ) )\n\t\t$sidebars_widgets['array_version'] = 3;\n\tupdate_option( 'sidebars_widgets', $sidebars_widgets );\n}\n\n/**\n * Retrieve default registered sidebars list.\n *\n * @since 2.2.0\n * @access private\n *\n * @return array\n */\nfunction wp_get_widget_defaults() {\n\tglobal $wp_registered_sidebars;\n\n\t$defaults = array();\n\n\tforeach ( (array) $wp_registered_sidebars as $index => $sidebar )\n\t\t$defaults[$index] = array();\n\n\treturn $defaults;\n}\n\n/**\n * Convert the widget settings from single to multi-widget format.\n *\n * @since 2.8.0\n *\n * @return array\n */\nfunction wp_convert_widget_settings($base_name, $option_name, $settings) {\n\t// This test may need expanding.\n\t$single = $changed = false;\n\tif ( empty($settings) ) {\n\t\t$single = true;\n\t} else {\n\t\tforeach ( array_keys($settings) as $number ) {\n\t\t\tif ( 'number' == $number )\n\t\t\t\tcontinue;\n\t\t\tif ( !is_numeric($number) ) {\n\t\t\t\t$single = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( $single ) {\n\t\t$settings = array( 2 => $settings );\n\n\t\t// If loading from the front page, update sidebar in memory but don't save to options\n\t\tif ( is_admin() ) {\n\t\t\t$sidebars_widgets = get_option('sidebars_widgets');\n\t\t} else {\n\t\t\tif ( empty($GLOBALS['_wp_sidebars_widgets']) )\n\t\t\t\t$GLOBALS['_wp_sidebars_widgets'] = get_option('sidebars_widgets', array());\n\t\t\t$sidebars_widgets = &$GLOBALS['_wp_sidebars_widgets'];\n\t\t}\n\n\t\tforeach ( (array) $sidebars_widgets as $index => $sidebar ) {\n\t\t\tif ( is_array($sidebar) ) {\n\t\t\t\tforeach ( $sidebar as $i => $name ) {\n\t\t\t\t\tif ( $base_name == $name ) {\n\t\t\t\t\t\t$sidebars_widgets[$index][$i] = \"$name-2\";\n\t\t\t\t\t\t$changed = true;\n\t\t\t\t\t\tbreak 2;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( is_admin() && $changed )\n\t\t\tupdate_option('sidebars_widgets', $sidebars_widgets);\n\t}\n\n\t$settings['_multiwidget'] = 1;\n\tif ( is_admin() )\n\t\tupdate_option( $option_name, $settings );\n\n\treturn $settings;\n}\n\n/**\n * Output an arbitrary widget as a template tag\n *\n * @since 2.8\n *\n * @param string $widget the widget's PHP class name (see default-widgets.php)\n * @param array $instance the widget's instance settings\n * @param array $args the widget's sidebar args\n * @return void\n **/\nfunction the_widget($widget, $instance = array(), $args = array()) {\n\tglobal $wp_widget_factory;\n\n\t$widget_obj = $wp_widget_factory->widgets[$widget];\n\tif ( !is_a($widget_obj, 'WP_Widget') )\n\t\treturn;\n\n\t$before_widget = sprintf('<div class=\"widget %s\">', $widget_obj->widget_options['classname'] );\n\t$default_args = array( 'before_widget' => $before_widget, 'after_widget' => \"</div>\", 'before_title' => '<h2 class=\"widgettitle\">', 'after_title' => '</h2>' );\n\n\t$args = wp_parse_args($args, $default_args);\n\t$instance = wp_parse_args($instance);\n\n\tdo_action( 'the_widget', $widget, $instance, $args );\n\n\t$widget_obj->_set(-1);\n\t$widget_obj->widget($args, $instance);\n}\n\n/**\n * Private\n */\nfunction _get_widget_id_base($id) {\n\treturn preg_replace( '/-[0-9]+$/', '', $id );\n}\n\n/**\n * Handle sidebars config after theme change\n *\n * @access private\n * @since 3.3.0\n */\nfunction _wp_sidebars_changed() {\n\tglobal $sidebars_widgets;\n\n\tif ( ! is_array( $sidebars_widgets ) )\n\t\t$sidebars_widgets = wp_get_sidebars_widgets();\n\n\tretrieve_widgets(true);\n}\n\n// look for \"lost\" widgets, this has to run at least on each theme change\nfunction retrieve_widgets($theme_changed = false) {\n\tglobal $wp_registered_widget_updates, $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;\n\n\t$registered_sidebar_keys = array_keys( $wp_registered_sidebars );\n\t$orphaned = 0;\n\n\t$old_sidebars_widgets = get_theme_mod( 'sidebars_widgets' );\n\tif ( is_array( $old_sidebars_widgets ) ) {\n\t\t// time() that sidebars were stored is in $old_sidebars_widgets['time']\n\t\t$_sidebars_widgets = $old_sidebars_widgets['data'];\n\t\tremove_theme_mod( 'sidebars_widgets' );\n\n\t\tforeach ( $_sidebars_widgets as $sidebar => $widgets ) {\n\t\t\tif ( 'wp_inactive_widgets' == $sidebar || 'orphaned_widgets' == substr( $sidebar, 0, 16 ) )\n\t\t\t\tcontinue;\n\n\t\t\tif ( !in_array( $sidebar, $registered_sidebar_keys ) ) {\n\t\t\t\t$_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $widgets;\n\t\t\t\tunset( $_sidebars_widgets[$sidebar] );\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif ( empty( $sidebars_widgets ) )\n\t\t\treturn;\n\n\t\tunset( $sidebars_widgets['array_version'] );\n\n\t\t$old = array_keys($sidebars_widgets);\n\t\tsort($old);\n\t\tsort($registered_sidebar_keys);\n\n\t\tif ( $old == $registered_sidebar_keys )\n\t\t\treturn;\n\n\t\t$_sidebars_widgets = array(\n\t\t\t'wp_inactive_widgets' => !empty( $sidebars_widgets['wp_inactive_widgets'] ) ? $sidebars_widgets['wp_inactive_widgets'] : array()\n\t\t);\n\n\t\tunset( $sidebars_widgets['wp_inactive_widgets'] );\n\n\t\tforeach ( $wp_registered_sidebars as $id => $settings ) {\n\t\t\tif ( $theme_changed ) {\n\t\t\t\t$_sidebars_widgets[$id] = array_shift( $sidebars_widgets );\n\t\t\t} else {\n\t\t\t\t// no theme change, grab only sidebars that are currently registered\n\t\t\t\tif ( isset( $sidebars_widgets[$id] ) ) {\n\t\t\t\t\t$_sidebars_widgets[$id] = $sidebars_widgets[$id];\n\t\t\t\t\tunset( $sidebars_widgets[$id] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tforeach ( $sidebars_widgets as $val ) {\n\t\t\tif ( is_array($val) && ! empty( $val ) )\n\t\t\t\t$_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $val;\n\t\t}\n\t}\n\n\t// discard invalid, theme-specific widgets from sidebars\n\t$shown_widgets = array();\n\n\tforeach ( $_sidebars_widgets as $sidebar => $widgets ) {\n\t\tif ( !is_array($widgets) )\n\t\t\tcontinue;\n\n\t\t$_widgets = array();\n\t\tforeach ( $widgets as $widget ) {\n\t\t\tif ( isset($wp_registered_widgets[$widget]) )\n\t\t\t\t$_widgets[] = $widget;\n\t\t}\n\n\t\t$_sidebars_widgets[$sidebar] = $_widgets;\n\t\t$shown_widgets = array_merge($shown_widgets, $_widgets);\n\t}\n\n\t$sidebars_widgets = $_sidebars_widgets;\n\tunset($_sidebars_widgets, $_widgets);\n\n\t// find hidden/lost multi-widget instances\n\t$lost_widgets = array();\n\tforeach ( $wp_registered_widgets as $key => $val ) {\n\t\tif ( in_array($key, $shown_widgets, true) )\n\t\t\tcontinue;\n\n\t\t$number = preg_replace('/.+?-([0-9]+)$/', '$1', $key);\n\n\t\tif ( 2 > (int) $number )\n\t\t\tcontinue;\n\n\t\t$lost_widgets[] = $key;\n\t}\n\n\t$sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']);\n\twp_set_sidebars_widgets($sidebars_widgets);\n\n\treturn $sidebars_widgets;\n}\n
     
    7171        // Functions you'll need to call. 
    7272 
    7373        /** 
    74          * PHP4 constructor 
    75          */ 
    76         function WP_Widget( $id_base = false, $name, $widget_options = array(), $control_options = array() ) { 
    77                 WP_Widget::__construct( $id_base, $name, $widget_options, $control_options ); 
    78         } 
    79  
    80         /** 
    81          * PHP5 constructor 
     74         * Constructor 
    8275         * 
    8376         * @param string $id_base Optional Base ID for the widget, lower case, 
    8477         * if left empty a portion of the widget's class name will be used. Has to be unique. 
     
    9689                $this->option_name = 'widget_' . $this->id_base; 
    9790                $this->widget_options = wp_parse_args( $widget_options, array('classname' => $this->option_name) ); 
    9891                $this->control_options = wp_parse_args( $control_options, array('id_base' => $this->id_base) ); 
     92        } 
     93 
     94        /** 
     95         * Deprecated constructor (dates back PHP4 times) 
     96         * 
     97         * @deprecated 3.4.0 
     98         */ 
     99        function WP_Widget( $id_base = false, $name, $widget_options = array(), $control_options = array() ) { 
     100                _deprecated_function( __FUNCTION__, '3.4.0', 'the default constructor' ); 
     101                self::__construct( $id_base, $name, $widget_options, $control_options ); 
    99102        } 
    100103 
    101104        /**