Make WordPress Core


Ignore:
Timestamp:
03/26/2014 10:28:49 PM (11 years ago)
Author:
ocean90
Message:

Widget Customizer: First pass for inline docs.

props DrewAPicture.
see #27534.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-customize-widgets.php

    r27702 r27753  
    11<?php
    22/**
    3  * Widget customizer manager class.
     3 * Customize Widgets Class
     4 *
     5 * Implements widget management in the Customizer.
     6 *
     7 * @since 3.9.0
     8 * @package WordPress
     9 * @subpackage Customize
    410 */
    511class WP_Customize_Widgets {
     
    1016     * All id_bases for widgets defined in core
    1117     *
     18     * @since 3.9.0
     19     * @static
     20     * @access protected
    1221     * @var array
    1322     */
     
    2938
    3039    /**
     40     * @since 3.9.0
     41     * @static
     42     * @access protected
     43     * @var
     44     */
     45    protected static $_customized;
     46
     47    /**
     48     * @since 3.9.0
     49     * @static
     50     * @access protected
     51     * @var array
     52     */
     53    protected static $_prepreview_added_filters = array();
     54
     55    /**
     56     * @since 3.9.0
     57     * @static
     58     * @access protected
     59     * @var array
     60     */
     61    static protected $rendered_sidebars = array();
     62
     63    /**
     64     * @since 3.9.0
     65     * @static
     66     * @access protected
     67     * @var array
     68     */
     69    static protected $rendered_widgets = array();
     70
     71    /**
    3172     * Initial loader.
     73     *
     74     * @since 3.9.0
     75     * @static
     76     * @access public
    3277     */
    3378    static function setup() {
    34         add_action( 'after_setup_theme', array( __CLASS__, 'setup_widget_addition_previews' ) );
    35         add_action( 'customize_controls_init', array( __CLASS__, 'customize_controls_init' ) );
    36         add_action( 'customize_register', array( __CLASS__, 'schedule_customize_register' ), 1 );
    37         add_action( 'customize_controls_enqueue_scripts', array( __CLASS__, 'customize_controls_enqueue_deps' ) );
     79        add_action( 'after_setup_theme',                       array( __CLASS__, 'setup_widget_addition_previews' ) );
     80        add_action( 'customize_controls_init',                 array( __CLASS__, 'customize_controls_init' ) );
     81        add_action( 'customize_register',                      array( __CLASS__, 'schedule_customize_register' ), 1 );
     82        add_action( 'customize_controls_enqueue_scripts',      array( __CLASS__, 'customize_controls_enqueue_deps' ) );
    3883        add_action( 'customize_controls_print_footer_scripts', array( __CLASS__, 'output_widget_control_templates' ) );
    39         add_action( 'customize_preview_init', array( __CLASS__, 'customize_preview_init' ) );
    40 
    41         add_action( 'dynamic_sidebar', array( __CLASS__, 'tally_rendered_widgets' ) );
    42         add_filter( 'is_active_sidebar', array( __CLASS__, 'tally_sidebars_via_is_active_sidebar_calls' ), 10, 2 );
    43         add_filter( 'dynamic_sidebar_has_widgets', array( __CLASS__, 'tally_sidebars_via_dynamic_sidebar_calls' ), 10, 2 );
    44     }
    45 
    46     /**
    47      * Get an unslashed post value, or return a default
    48      *
    49      * @param string $name
    50      * @param mixed $default
    51      * @return mixed
     84        add_action( 'customize_preview_init',                  array( __CLASS__, 'customize_preview_init' ) );
     85
     86        add_action( 'dynamic_sidebar',                         array( __CLASS__, 'tally_rendered_widgets' ) );
     87        add_filter( 'is_active_sidebar',                       array( __CLASS__, 'tally_sidebars_via_is_active_sidebar_calls' ), 10, 2 );
     88        add_filter( 'dynamic_sidebar_has_widgets',             array( __CLASS__, 'tally_sidebars_via_dynamic_sidebar_calls' ), 10, 2 );
     89    }
     90
     91    /**
     92     * Get an unslashed post value or return a default.
     93     *
     94     * @since 3.9.0
     95     *
     96     * @static
     97     * @access public
     98     *
     99     * @param string $name    Post value.
     100     * @param mixed  $default Default post value.
     101     * @return mixed Unslashed post value or default value.
    52102     */
    53103    static function get_post_value( $name, $default = null ) {
    54         if ( ! isset( $_POST[$name] ) ) {
     104        if ( ! isset( $_POST[ $name ] ) ) {
    55105            return $default;
    56106        }
     
    58108    }
    59109
    60     protected static $_customized;
    61     protected static $_prepreview_added_filters = array();
    62 
    63     /**
     110    /**
     111     *
     112     *
    64113     * Since the widgets get registered (widgets_init) before the customizer settings are set up (customize_register),
    65114     * we have to filter the options similarly to how the setting previewer will filter the options later.
    66115     *
    67      * @action after_setup_theme
     116     * @since 3.9.0
     117     *
     118     * @static
     119     * @access public
     120     * @global WP_Customize_Manager $wp_customize
    68121     */
    69122    static function setup_widget_addition_previews() {
     
    100153        }
    101154
    102         // Input from customizer preview
     155        // Input from customizer preview.
    103156        if ( isset( $_POST['customized'] ) ) {
    104157            $customized = json_decode( self::get_post_value( 'customized' ), true );
    105158        }
    106         // Input from ajax widget update request
     159
     160        // Input from ajax widget update request.
    107161        else {
    108162            $customized    = array();
     
    153207
    154208    /**
     209     *
     210     *
    155211     * Ensure that newly-added widgets will appear in the widgets_sidebars.
    156212     * This is necessary because the customizer's setting preview filters are added after the widgets_init action,
    157213     * which is too late for the widgets to be set up properly.
    158214     *
    159      * @param array $sidebars_widgets
     215     * @since 3.9.0
     216     * @static
     217     * @access public
     218     *
     219     * @param array $sidebars_widgets Array of
    160220     * @return array
    161221     */
     
    171231
    172232    /**
     233     *
     234     *
    173235     * Ensure that newly-added widgets will have empty instances so that they will be recognized.
    174236     * This is necessary because the customizer's setting preview filters are added after the widgets_init action,
    175237     * which is too late for the widgets to be set up properly.
    176238     *
    177      * @param array $instance
    178      * @param string $setting_id
    179      * @return array
     239     * @since 3.9.0
     240     * @static
     241     * @access public
     242     *
     243     * @param array $instance    Widget instance.
     244     * @param string $setting_id Widget setting ID.
     245     * @return array Parsed widget instance.
    180246     */
    181247    static function prepreview_added_widget_instance( $instance, $setting_id ) {
     
    207273     * widgets are populating the options during widgets_init
    208274     *
    209      * @action wp_loaded
     275     * @since 3.9.0
     276     * @static
     277     * @access public
    210278     */
    211279    static function remove_prepreview_filters() {
     
    219287     * Make sure that all widgets get loaded into customizer; these actions are also done in the wp_ajax_save_widget()
    220288     *
    221      * @see wp_ajax_save_widget()
    222      * @action customize_controls_init
     289     * @since 3.9.0
     290     * @static
     291     * @access public
    223292     */
    224293    static function customize_controls_init() {
     
    231300     * When in preview, invoke customize_register for settings after WordPress is
    232301     * loaded so that all filters have been initialized (e.g. Widget Visibility)
     302     *
     303     * @since 3.9.0
     304     * @static
     305     * @access public
     306     *
     307     * @param WP_Customize_Manager $wp_customize Customizer instance.
    233308     */
    234309    static function schedule_customize_register( $wp_customize ) {
     
    243318     * Register customizer settings and controls for all sidebars and widgets
    244319     *
    245      * @action customize_register
     320     * @since 3.9.0
     321     * @static
     322     * @access public
     323     *
     324     * @param WP_Customize_Manager $wp_customize Customizer instance.
    246325     */
    247326    static function customize_register( $wp_customize = null ) {
     
    259338        $new_setting_ids = array();
    260339
    261         /**
     340        /*
    262341         * Register a setting for all widgets, including those which are active, inactive, and orphaned
    263342         * since a widget may get suppressed from a sidebar via a plugin (like Widget Visibility).
     
    319398            }
    320399
    321             /**
    322              * Add a control for each active widget (located in a sidebar)
    323              */
     400            // Add a control for each active widget (located in a sidebar).
    324401            foreach ( $sidebar_widget_ids as $i => $widget_id ) {
    325                 // Skip widgets that may have gone away due to a plugin being deactivated
     402
     403                // Skip widgets that may have gone away due to a plugin being deactivated.
    326404                if ( ! $is_active_sidebar || ! isset( $GLOBALS['wp_registered_widgets'][$widget_id] ) ) {
    327405                    continue;
     
    350428        }
    351429
    352         /**
    353          * We have to register these settings later than customize_preview_init so that other
    354          * filters have had a chance to run.
    355          * @see self::schedule_customize_register()
     430        /*
     431         * We have to register these settings later than customize_preview_init
     432         * so that other filters have had a chance to run.
    356433         */
    357434        if ( did_action( 'customize_preview_init' ) ) {
     
    367444     * Covert a widget_id into its corresponding customizer setting id (option name)
    368445     *
    369      * @param string $widget_id
    370      * @see _get_widget_id_base()
    371      * @return string
     446     * @since 3.9.0
     447     * @static
     448     * @access public
     449     *
     450     * @param string $widget_id Widget ID.
     451     * @return string Maybe-parsed widget ID.
    372452     */
    373453    static function get_setting_id( $widget_id ) {
     
    388468     * filter.
    389469     *
    390      * @param string $widget_id
    391      * @return bool
     470     * @since 3.9.0
     471     * @static
     472     * @access public
     473     *
     474     * @param string $widget_id Widget ID.
     475     * @return bool Whether or not the widget is a "wide" widget.
    392476     */
    393477    static function is_wide_widget( $widget_id ) {
     
    397481        $is_core = in_array( $parsed_widget_id['id_base'], self::$core_widget_id_bases );
    398482        $is_wide = ( $width > 250 && ! $is_core );
     483
     484        /**
     485         * Filter whether the given widget is considered "wide".
     486         *
     487         * @since 3.9.0
     488         *
     489         * @param bool   $is_wide   Whether the widget is wide, Default false.
     490         * @param string $widget_id Widget ID.
     491         */
    399492        $is_wide = apply_filters( 'is_wide_widget_in_customizer', $is_wide, $widget_id );
    400493        return $is_wide;
     
    402495
    403496    /**
    404      * Covert a widget ID into its id_base and number components
    405      *
    406      * @param string $widget_id
    407      * @return array
     497     * Covert a widget ID into its id_base and number components.
     498     *
     499     * @since 3.9.0
     500     * @static
     501     * @access public
     502     *
     503     * @param string $widget_id Widget ID.
     504     * @return array Array containing a widget's id_base and number components.
    408505     */
    409506    static function parse_widget_id( $widget_id ) {
     
    423520
    424521    /**
    425      * Convert a widget setting ID (option path) to its id_base and number components
    426      *
    427      * @param string $setting_id
    428      * @return WP_Error|array
     522     * Convert a widget setting ID (option path) to its id_base and number components.
     523     *
     524     * @since 3.9.0
     525     * @static
     526     * @access public
     527     *
     528     * @param string $setting_id Widget setting ID.
     529     * @return WP_Error|array Array contain a widget's id_base and number components,
     530     *                        or a WP_Error object.
    429531     */
    430532    static function parse_widget_setting_id( $setting_id ) {
     
    439541
    440542    /**
    441      * Enqueue scripts and styles for customizer panel and export data to JS
    442      *
    443      * @action customize_controls_enqueue_scripts
     543     * Enqueue scripts and styles for customizer panel and export data to JS.
     544     *
     545     * @since 3.9.0
     546     * @static
     547     * @access public
    444548     */
    445549    static function customize_controls_enqueue_deps() {
     
    483587        );
    484588
    485         // Why not wp_localize_script? Because we're not localizing, and it forces values into strings
     589        // Why not wp_localize_script? Because we're not localizing, and it forces values into strings.
    486590        global $wp_scripts;
    487591        $exports = array(
     
    519623     * Render the widget form control templates into the DOM so that plugin scripts can manipulate them
    520624     *
    521      * @action customize_controls_print_footer_scripts
     625     * @since 3.9.0
     626     * @static
     627     * @access public
    522628     */
    523629    static function output_widget_control_templates() {
     
    541647     * Get common arguments to supply when constructing a customizer setting
    542648     *
    543      * @param string $id
    544      * @param array  [$overrides]
    545      * @return array
     649     * @since 3.9.0
     650     * @static
     651     * @access public
     652     *
     653     * @param string $id        Widget setting ID.
     654     * @param array  $overrides Array of setting overrides.
     655     * @return array Possibly modified setting arguments.
    546656     */
    547657    static function get_setting_args( $id, $overrides = array() ) {
     
    561671     * Used as sanitize_callback for each sidebars_widgets setting.
    562672     *
    563      * @param array $widget_ids
    564      * @return array
     673     * @since 3.9.0
     674     * @static
     675     * @access public
     676     *
     677     * @param array $widget_ids Array of widget IDs.
     678     * @return array Array of sanitized widget IDs.
    565679     */
    566680    static function sanitize_sidebar_widgets( $widget_ids ) {
     
    577691
    578692    /**
    579      * Build up an index of all available widgets for use in Backbone models
     693     * Build up an index of all available widgets for use in Backbone models.
     694     *
     695     * @since 3.9.0
     696     * @static
     697     * @access public
    580698     *
    581699     * @see wp_list_widgets()
     
    661779
    662780    /**
    663      * Replace with inline closure once on PHP 5.3:
    664      * sort( $array, function ( $a, $b ) { return strnatcasecmp( $a['name'], $b['name'] ); } );
    665      *
    666      * @access private
    667      */
    668     static function _sort_name_callback( $a, $b ) {
    669         return strnatcasecmp( $a['name'], $b['name'] );
     781     * Naturally order available widgets by name.
     782     *
     783     * @since 3.9.0
     784     * @static
     785     * @access public
     786     *
     787     * @param array $widget_a The first widget to compare.
     788     * @param array $widget_b The second widget to compare.
     789     * @return int Reorder position for the current widget comparison.
     790     */
     791    static function _sort_name_callback( $widget_a, $widget_b ) {
     792        return strnatcasecmp( $widget_a['name'], $widget_b['name'] );
    670793    }
    671794
     
    674797     * so that it can be used in the customizer.
    675798     *
    676      * @see wp_widget_control()
    677      * @param array $args
    678      * @return string
     799     * @since 3.9.0
     800     * @static
     801     * @access public
     802     *
     803     * @param array $args Widget control arguments.
     804     * @return string Widget control form HTML markup.
    679805     */
    680806    static function get_widget_control( $args ) {
     
    693819     * Add hooks for the customizer preview
    694820     *
    695      * @action customize_preview_init
     821     * @since 3.9.0
     822     * @static
     823     * @access public
    696824     */
    697825    static function customize_preview_init() {
    698         add_filter( 'sidebars_widgets', array( __CLASS__, 'preview_sidebars_widgets' ), 1 );
     826        add_filter( 'sidebars_widgets',   array( __CLASS__, 'preview_sidebars_widgets' ), 1 );
    699827        add_action( 'wp_enqueue_scripts', array( __CLASS__, 'customize_preview_enqueue' ) );
    700         add_action( 'wp_print_styles', array( __CLASS__, 'inject_preview_css' ), 1 );
    701         add_action( 'wp_footer', array( __CLASS__, 'export_preview_data' ), 20 );
    702     }
    703 
    704     /**
     828        add_action( 'wp_print_styles',    array( __CLASS__, 'inject_preview_css' ), 1 );
     829        add_action( 'wp_footer',          array( __CLASS__, 'export_preview_data' ), 20 );
     830    }
     831
     832    /**
     833     *
     834     *
    705835     * When previewing, make sure the proper previewing widgets are used. Because wp_get_sidebars_widgets()
    706836     * gets called early at init (via wp_convert_widget_settings()) and can set global variable
     
    708838     * preview filter is added, we have to reset it after the filter has been added.
    709839     *
    710      * @filter sidebars_widgets
     840     * @since 3.9.0
     841     * @static
     842     * @access public
     843     *
     844     * @param array $sidebars_widgets List of widgets for the current sidebar.
    711845     */
    712846    static function preview_sidebars_widgets( $sidebars_widgets ) {
     
    719853     * Enqueue scripts for the customizer preview
    720854     *
    721      * @action wp_enqueue_scripts
     855     * @since 3.9.0
     856     * @static
     857     * @access public
    722858     */
    723859    static function customize_preview_enqueue() {
     
    728864     * Insert default style for highlighted widget at early point so theme
    729865     * stylesheet can override.
     866     *
     867     * @since 3.9.0
     868     * @static
     869     * @access public
    730870     *
    731871     * @action wp_print_styles
     
    746886
    747887    /**
    748      * At the very end of the page, at the very end of the wp_footer, communicate the sidebars that appeared on the page
    749      *
    750      * @action wp_footer
     888     * At the very end of the page, at the very end of the wp_footer, communicate the sidebars that appeared on the page.
     889     *
     890     * @since 3.9.0
     891     * @static
     892     * @access public
    751893     */
    752894    static function export_preview_data() {
     
    772914    }
    773915
    774     static protected $rendered_sidebars = array();
    775     static protected $rendered_widgets  = array();
    776 
    777916    /**
    778917     * Keep track of the widgets that were rendered
    779918     *
    780      * @action dynamic_sidebar
     919     * @since 3.9.0
     920     * @static
     921     * @access public
     922     *
     923     * @param array $widget Rendered widget to tally.
    781924     */
    782925    static function tally_rendered_widgets( $widget ) {
     
    788931     * means that the sidebar would be rendered on the template if there were widgets populating it.
    789932     *
    790      * @filter is_active_sidebar
     933     * @since 3.9.0
     934     * @static
     935     * @access public
     936     *
     937     * @param bool    $is_active  Whether the sidebar is active.
     938     * @pasram string $sidebar_id Sidebar ID.
    791939     */
    792940    static function tally_sidebars_via_is_active_sidebar_calls( $is_active, $sidebar_id ) {
     
    803951     * means that the sidebar would be rendered on the template if there were widgets populating it.
    804952     *
    805      * @filter dynamic_sidebar_has_widgets
     953     * @since 3.9.0
     954     * @static
     955     * @access public
     956     *
     957     * @param bool   $has_widgets Whether the current sidebar has widgets.
     958     * @param string $sidebar_id  Sidebar ID.
    806959     */
    807960    static function tally_sidebars_via_dynamic_sidebar_calls( $has_widgets, $sidebar_id ) {
     
    809962            self::$rendered_sidebars[] = $sidebar_id;
    810963        }
    811         // We may need to force this to true, and also force-true the value for is_active_sidebar
    812         // if we want to ensure that there is an area to drop widgets into, if the sidebar is empty.
     964        /*
     965         * We may need to force this to true, and also force-true the value for is_active_sidebar
     966         * if we want to ensure that there is an area to drop widgets into, if the sidebar is empty.
     967         */
    813968        return $has_widgets;
    814969    }
    815970
    816971    /**
     972     * Get a widget instance's hash key.
     973     *
    817974     * Serialize an instance and hash it with the AUTH_KEY; when a JS value is
    818975     * posted back to save, this instance hash key is used to ensure that the
     
    820977     * from WordPress and so is sanitized.
    821978     *
    822      * @param array $instance
    823      * @return string
     979     * @since 3.9.0
     980     * @static
     981     * @access protected
     982     *
     983     * @param array $instance Widget instance.
     984     * @return string Widget instance's hash key.
    824985     */
    825986    protected static function get_instance_hash_key( $instance ) {
     
    829990
    830991    /**
     992     * Sanitize a widget instance.
     993     *
    831994     * Unserialize the JS-instance for storing in the options. It's important
    832995     * that this filter only get applied to an instance once.
    833996     *
     997     * @since 3.9.0
     998     * @static
     999     * @access public
     1000     *
    8341001     * @see Widget_Customizer::sanitize_widget_js_instance()
    8351002     *
    836      * @param array $value
    837      * @return array
     1003     * @param array $value Widget instance to sanitize.
     1004     * @return array Sanitized widget instance.
    8381005     */
    8391006    static function sanitize_widget_instance( $value ) {
     
    8661033
    8671034    /**
    868      * Convert widget instance into JSON-representable format
     1035     * Convert widget instance into JSON-representable format.
     1036     *
     1037     * @since 3.9.0
     1038     * @static
     1039     * @access public
    8691040     *
    8701041     * @see Widget_Customizer::sanitize_widget_instance()
    8711042     *
    872      * @param array $value
    873      * @return array
     1043     * @param array $value Widget instance to convert to JSON.
     1044     * @return array JSON-converted widget instance.
    8741045     */
    8751046    static function sanitize_widget_js_instance( $value ) {
     
    8901061     * as the case when a plugin orphans a widget in a sidebar when it is deactivated.
    8911062     *
    892      * @param array $widget_ids
    893      * @return array
     1063     * @since 3.9.0
     1064     * @static
     1065     * @access public
     1066     *
     1067     * @param array $widget_ids List of widget IDs.
     1068     * @return array Parsed list of widget IDs.
    8941069     */
    8951070    static function sanitize_sidebar_widgets_js_instance( $widget_ids ) {
     
    9001075
    9011076    /**
    902      * Find and invoke the widget update and control callbacks. Requires that
    903      * $_POST be populated with the instance data.
    904      *
    905      * @param  string $widget_id
    906      * @return WP_Error|array
     1077     * Find and invoke the widget update and control callbacks.
     1078     *
     1079     * Requires that $_POST be populated with the instance data.
     1080     *
     1081     * @since 3.9.0
     1082     * @static
     1083     * @access public
     1084     *
     1085     * @param  string $widget_id Widget ID.
     1086     * @return WP_Error|array Array containing the updated widget information. WP_Error, otherwise.
    9071087     */
    9081088    static function call_widget_update( $widget_id ) {
     
    9151095        $option_name = 'widget_' . $parsed_id['id_base'];
    9161096
    917         /**
     1097        /*
    9181098         * If a previously-sanitized instance is provided, populate the input vars
    9191099         * with its values so that the widget update callback will read this instance
     
    9471127        }
    9481128
    949         /**
    950          * Invoke the widget update callback
    951          */
     1129        // Invoke the widget update callback.
    9521130        foreach ( (array) $wp_registered_widget_updates as $name => $control ) {
    9531131            if ( $name === $parsed_id['id_base'] && is_callable( $control['callback'] ) ) {
     
    9651143        }
    9661144
    967         /**
    968          * Make sure the expected option was updated
    969          */
     1145        // Make sure the expected option was updated.
    9701146        if ( 0 !== $options_transaction->count() ) {
    9711147            if ( count( $options_transaction->options ) > 1 ) {
     
    9811157        }
    9821158
    983         /**
    984          * Obtain the widget control with the updated instance in place
    985          */
     1159        // Obtain the widget control with the updated instance in place.
    9861160        ob_start();
    9871161        $form = $wp_registered_widget_controls[$widget_id];
     
    9911165        $form = ob_get_clean();
    9921166
    993         /**
    994          * Obtain the widget instance
    995          */
     1167        // Obtain the widget instance.
    9961168        $option = get_option( $option_name );
    9971169        if ( null !== $parsed_id['number'] ) {
     
    10091181     * instance info via Ajax instead of saving it to the options table.
    10101182     * Most code here copied from wp_ajax_save_widget()
     1183     *
     1184     * @since 3.9.0
     1185     * @static
     1186     * @access public
    10111187     *
    10121188     * @see wp_ajax_save_widget
Note: See TracChangeset for help on using the changeset viewer.