Ticket #27534: 27534.diff
File 27534.diff, 23.8 KB (added by , 11 years ago) |
---|
-
src/wp-includes/class-wp-customize-widgets.php
1 1 <?php 2 2 /** 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 4 10 */ 5 11 class WP_Customize_Widgets { 6 12 const UPDATE_WIDGET_AJAX_ACTION = 'update-widget'; … … 9 15 /** 10 16 * All id_bases for widgets defined in core 11 17 * 18 * @since 3.9.0 19 * @static 20 * @access protected 12 21 * @var array 13 22 */ 14 23 protected static $core_widget_id_bases = array( … … 28 37 ); 29 38 30 39 /** 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 /** 31 72 * Initial loader. 73 * 74 * @since 3.9.0 75 * @static 76 * @access public 32 77 */ 33 78 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' ) ); 38 83 add_action( 'customize_controls_print_footer_scripts', array( __CLASS__, 'output_widget_control_templates' ) ); 39 add_action( 'customize_preview_init', array( __CLASS__, 'customize_preview_init' ) );84 add_action( 'customize_preview_init', array( __CLASS__, 'customize_preview_init' ) ); 40 85 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 );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 ); 44 89 } 45 90 46 91 /** 47 * Get an unslashed post value , or return a default92 * Get an unslashed post value or return a default. 48 93 * 49 * @param string $name 50 * @param mixed $default 51 * @return mixed 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. 52 102 */ 53 103 static function get_post_value( $name, $default = null ) { 54 if ( ! isset( $_POST[ $name] ) ) {104 if ( ! isset( $_POST[ $name ] ) ) { 55 105 return $default; 56 106 } 57 107 return wp_unslash( $_POST[$name] ); 58 108 } 59 109 60 protected static $_customized;61 protected static $_prepreview_added_filters = array();62 63 110 /** 111 * 112 * 64 113 * Since the widgets get registered (widgets_init) before the customizer settings are set up (customize_register), 65 114 * we have to filter the options similarly to how the setting previewer will filter the options later. 66 115 * 67 * @action after_setup_theme 116 * @since 3.9.0 117 * 118 * @static 119 * @access public 120 * @global WP_Customize_Manager $wp_customize 68 121 */ 69 122 static function setup_widget_addition_previews() { 70 123 global $wp_customize; … … 99 152 return; 100 153 } 101 154 102 // Input from customizer preview 155 // Input from customizer preview. 103 156 if ( isset( $_POST['customized'] ) ) { 104 157 $customized = json_decode( self::get_post_value( 'customized' ), true ); 105 158 } 106 // Input from ajax widget update request 159 160 // Input from ajax widget update request. 107 161 else { 108 162 $customized = array(); 109 163 $id_base = self::get_post_value( 'id_base' ); … … 152 206 } 153 207 154 208 /** 209 * 210 * 155 211 * Ensure that newly-added widgets will appear in the widgets_sidebars. 156 212 * This is necessary because the customizer's setting preview filters are added after the widgets_init action, 157 213 * which is too late for the widgets to be set up properly. 158 214 * 159 * @param array $sidebars_widgets 215 * @since 3.9.0 216 * @static 217 * @access public 218 * 219 * @param array $sidebars_widgets Array of 160 220 * @return array 161 221 */ 162 222 static function prepreview_added_sidebars_widgets( $sidebars_widgets ) { … … 170 230 } 171 231 172 232 /** 233 * 234 * 173 235 * Ensure that newly-added widgets will have empty instances so that they will be recognized. 174 236 * This is necessary because the customizer's setting preview filters are added after the widgets_init action, 175 237 * which is too late for the widgets to be set up properly. 176 238 * 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. 180 246 */ 181 247 static function prepreview_added_widget_instance( $instance, $setting_id ) { 182 248 if ( isset( self::$_customized[$setting_id] ) ) { … … 206 272 * Remove filters added in setup_widget_addition_previews() which ensure that 207 273 * widgets are populating the options during widgets_init 208 274 * 209 * @action wp_loaded 275 * @since 3.9.0 276 * @static 277 * @access public 210 278 */ 211 279 static function remove_prepreview_filters() { 212 280 foreach ( self::$_prepreview_added_filters as $prepreview_added_filter ) { … … 218 286 /** 219 287 * Make sure that all widgets get loaded into customizer; these actions are also done in the wp_ajax_save_widget() 220 288 * 221 * @see wp_ajax_save_widget() 222 * @action customize_controls_init 289 * @since 3.9.0 290 * @static 291 * @access public 223 292 */ 224 293 static function customize_controls_init() { 225 294 do_action( 'load-widgets.php' ); … … 230 299 /** 231 300 * When in preview, invoke customize_register for settings after WordPress is 232 301 * 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. 233 308 */ 234 309 static function schedule_customize_register( $wp_customize ) { 235 310 if ( is_admin() ) { // @todo for some reason, $wp_customize->is_preview() is true here? … … 242 317 /** 243 318 * Register customizer settings and controls for all sidebars and widgets 244 319 * 245 * @action customize_register 320 * @since 3.9.0 321 * @static 322 * @access public 323 * 324 * @param WP_Customize_Manager $wp_customize Customizer instance. 246 325 */ 247 326 static function customize_register( $wp_customize = null ) { 248 327 global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_sidebars; … … 258 337 259 338 $new_setting_ids = array(); 260 339 261 /* *340 /* 262 341 * Register a setting for all widgets, including those which are active, inactive, and orphaned 263 342 * since a widget may get suppressed from a sidebar via a plugin (like Widget Visibility). 264 343 */ … … 318 397 } 319 398 } 320 399 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). 324 401 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. 326 404 if ( ! $is_active_sidebar || ! isset( $GLOBALS['wp_registered_widgets'][$widget_id] ) ) { 327 405 continue; 328 406 } … … 349 427 } 350 428 } 351 429 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. 356 433 */ 357 434 if ( did_action( 'customize_preview_init' ) ) { 358 435 foreach ( $new_setting_ids as $new_setting_id ) { … … 366 443 /** 367 444 * Covert a widget_id into its corresponding customizer setting id (option name) 368 445 * 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. 372 452 */ 373 453 static function get_setting_id( $widget_id ) { 374 454 $parsed_widget_id = self::parse_widget_id( $widget_id ); … … 387 467 * not wide, but this can be overridden with the is_wide_widget_in_customizer 388 468 * filter. 389 469 * 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. 392 476 */ 393 477 static function is_wide_widget( $widget_id ) { 394 478 global $wp_registered_widget_controls; … … 396 480 $width = $wp_registered_widget_controls[$widget_id]['width']; 397 481 $is_core = in_array( $parsed_widget_id['id_base'], self::$core_widget_id_bases ); 398 482 $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 */ 399 492 $is_wide = apply_filters( 'is_wide_widget_in_customizer', $is_wide, $widget_id ); 400 493 return $is_wide; 401 494 } 402 495 403 496 /** 404 * Covert a widget ID into its id_base and number components 497 * Covert a widget ID into its id_base and number components. 405 498 * 406 * @param string $widget_id 407 * @return array 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. 408 505 */ 409 506 static function parse_widget_id( $widget_id ) { 410 507 $parsed = array( … … 422 519 } 423 520 424 521 /** 425 * Convert a widget setting ID (option path) to its id_base and number components 522 * Convert a widget setting ID (option path) to its id_base and number components. 426 523 * 427 * @param string $setting_id 428 * @return WP_Error|array 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. 429 531 */ 430 532 static function parse_widget_setting_id( $setting_id ) { 431 533 if ( ! preg_match( '/^(widget_(.+?))(?:\[(\d+)\])?$/', $setting_id, $matches ) ) { … … 438 540 } 439 541 440 542 /** 441 * Enqueue scripts and styles for customizer panel and export data to JS 543 * Enqueue scripts and styles for customizer panel and export data to JS. 442 544 * 443 * @action customize_controls_enqueue_scripts 545 * @since 3.9.0 546 * @static 547 * @access public 444 548 */ 445 549 static function customize_controls_enqueue_deps() { 446 550 wp_enqueue_style( 'customize-widgets' ); … … 482 586 ' 483 587 ); 484 588 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. 486 590 global $wp_scripts; 487 591 $exports = array( 488 592 'update_widget_ajax_action' => self::UPDATE_WIDGET_AJAX_ACTION, … … 518 622 /** 519 623 * Render the widget form control templates into the DOM so that plugin scripts can manipulate them 520 624 * 521 * @action customize_controls_print_footer_scripts 625 * @since 3.9.0 626 * @static 627 * @access public 522 628 */ 523 629 static function output_widget_control_templates() { 524 630 ?> … … 540 646 /** 541 647 * Get common arguments to supply when constructing a customizer setting 542 648 * 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. 546 656 */ 547 657 static function get_setting_args( $id, $overrides = array() ) { 548 658 $args = array( … … 560 670 * Make sure that a sidebars_widgets[x] only ever consists of actual widget IDs. 561 671 * Used as sanitize_callback for each sidebars_widgets setting. 562 672 * 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. 565 679 */ 566 680 static function sanitize_sidebar_widgets( $widget_ids ) { 567 681 global $wp_registered_widgets; … … 576 690 } 577 691 578 692 /** 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. 580 694 * 695 * @since 3.9.0 696 * @static 697 * @access public 698 * 581 699 * @see wp_list_widgets() 582 700 * @return array 583 701 */ … … 660 778 } 661 779 662 780 /** 663 * Replace with inline closure once on PHP 5.3: 664 * sort( $array, function ( $a, $b ) { return strnatcasecmp( $a['name'], $b['name'] ); } ); 781 * Naturally order available widgets by name. 665 782 * 666 * @access private 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. 667 790 */ 668 static function _sort_name_callback( $ a, $b ) {669 return strnatcasecmp( $ a['name'], $b['name'] );791 static function _sort_name_callback( $widget_a, $widget_b ) { 792 return strnatcasecmp( $widget_a['name'], $widget_b['name'] ); 670 793 } 671 794 672 795 /** 673 796 * Invoke wp_widget_control() but capture the output buffer and transform the markup 674 797 * so that it can be used in the customizer. 675 798 * 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. 679 805 */ 680 806 static function get_widget_control( $args ) { 681 807 ob_start(); … … 692 818 /** 693 819 * Add hooks for the customizer preview 694 820 * 695 * @action customize_preview_init 821 * @since 3.9.0 822 * @static 823 * @access public 696 824 */ 697 825 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 ); 699 827 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 );828 add_action( 'wp_print_styles', array( __CLASS__, 'inject_preview_css' ), 1 ); 829 add_action( 'wp_footer', array( __CLASS__, 'export_preview_data' ), 20 ); 702 830 } 703 831 704 832 /** 833 * 834 * 705 835 * When previewing, make sure the proper previewing widgets are used. Because wp_get_sidebars_widgets() 706 836 * gets called early at init (via wp_convert_widget_settings()) and can set global variable 707 837 * $_wp_sidebars_widgets to the value of get_option( 'sidebars_widgets' ) before the customizer 708 838 * preview filter is added, we have to reset it after the filter has been added. 709 839 * 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. 711 845 */ 712 846 static function preview_sidebars_widgets( $sidebars_widgets ) { 713 847 $sidebars_widgets = get_option( 'sidebars_widgets' ); … … 718 852 /** 719 853 * Enqueue scripts for the customizer preview 720 854 * 721 * @action wp_enqueue_scripts 855 * @since 3.9.0 856 * @static 857 * @access public 722 858 */ 723 859 static function customize_preview_enqueue() { 724 860 wp_enqueue_script( 'customize-preview-widgets' ); … … 728 864 * Insert default style for highlighted widget at early point so theme 729 865 * stylesheet can override. 730 866 * 867 * @since 3.9.0 868 * @static 869 * @access public 870 * 731 871 * @action wp_print_styles 732 872 */ 733 873 static function inject_preview_css() { … … 745 885 } 746 886 747 887 /** 748 * At the very end of the page, at the very end of the wp_footer, communicate the sidebars that appeared on the page 888 * At the very end of the page, at the very end of the wp_footer, communicate the sidebars that appeared on the page. 749 889 * 750 * @action wp_footer 890 * @since 3.9.0 891 * @static 892 * @access public 751 893 */ 752 894 static function export_preview_data() { 753 895 // Prepare customizer settings to pass to Javascript. … … 771 913 <?php 772 914 } 773 915 774 static protected $rendered_sidebars = array();775 static protected $rendered_widgets = array();776 777 916 /** 778 917 * Keep track of the widgets that were rendered 779 918 * 780 * @action dynamic_sidebar 919 * @since 3.9.0 920 * @static 921 * @access public 922 * 923 * @param array $widget Rendered widget to tally. 781 924 */ 782 925 static function tally_rendered_widgets( $widget ) { 783 926 self::$rendered_widgets[$widget['id']] = true; … … 787 930 * Keep track of the times that is_active_sidebar() is called in the template, and assume that this 788 931 * means that the sidebar would be rendered on the template if there were widgets populating it. 789 932 * 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. 791 939 */ 792 940 static function tally_sidebars_via_is_active_sidebar_calls( $is_active, $sidebar_id ) { 793 941 if ( isset( $GLOBALS['wp_registered_sidebars'][$sidebar_id] ) ) { … … 802 950 * Keep track of the times that dynamic_sidebar() is called in the template, and assume that this 803 951 * means that the sidebar would be rendered on the template if there were widgets populating it. 804 952 * 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. 806 959 */ 807 960 static function tally_sidebars_via_dynamic_sidebar_calls( $has_widgets, $sidebar_id ) { 808 961 if ( isset( $GLOBALS['wp_registered_sidebars'][$sidebar_id] ) ) { 809 962 self::$rendered_sidebars[] = $sidebar_id; 810 963 } 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 */ 813 968 return $has_widgets; 814 969 } 815 970 816 971 /** 972 * Get a widget instance's hash key. 973 * 817 974 * Serialize an instance and hash it with the AUTH_KEY; when a JS value is 818 975 * posted back to save, this instance hash key is used to ensure that the 819 976 * serialized_instance was not tampered with, but that it had originated 820 977 * from WordPress and so is sanitized. 821 978 * 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. 824 985 */ 825 986 protected static function get_instance_hash_key( $instance ) { 826 987 $hash = md5( AUTH_KEY . serialize( $instance ) ); … … 828 989 } 829 990 830 991 /** 992 * Sanitize a widget instance. 993 * 831 994 * Unserialize the JS-instance for storing in the options. It's important 832 995 * that this filter only get applied to an instance once. 833 996 * 997 * @since 3.9.0 998 * @static 999 * @access public 1000 * 834 1001 * @see Widget_Customizer::sanitize_widget_js_instance() 835 1002 * 836 * @param array $value 837 * @return array 1003 * @param array $value Widget instance to sanitize. 1004 * @return array Sanitized widget instance. 838 1005 */ 839 1006 static function sanitize_widget_instance( $value ) { 840 1007 if ( $value === array() ) { … … 865 1032 } 866 1033 867 1034 /** 868 * Convert widget instance into JSON-representable format 1035 * Convert widget instance into JSON-representable format. 869 1036 * 1037 * @since 3.9.0 1038 * @static 1039 * @access public 1040 * 870 1041 * @see Widget_Customizer::sanitize_widget_instance() 871 1042 * 872 * @param array $value 873 * @return array 1043 * @param array $value Widget instance to convert to JSON. 1044 * @return array JSON-converted widget instance. 874 1045 */ 875 1046 static function sanitize_widget_js_instance( $value ) { 876 1047 if ( empty( $value['is_widget_customizer_js_value'] ) ) { … … 889 1060 * Strip out widget IDs for widgets which are no longer registered, such 890 1061 * as the case when a plugin orphans a widget in a sidebar when it is deactivated. 891 1062 * 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. 894 1069 */ 895 1070 static function sanitize_sidebar_widgets_js_instance( $widget_ids ) { 896 1071 global $wp_registered_widgets; … … 899 1074 } 900 1075 901 1076 /** 902 * Find and invoke the widget update and control callbacks. Requires that 903 * $_POST be populated with the instance data. 1077 * Find and invoke the widget update and control callbacks. 904 1078 * 905 * @param string $widget_id 906 * @return WP_Error|array 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. 907 1087 */ 908 1088 static function call_widget_update( $widget_id ) { 909 1089 global $wp_registered_widget_updates, $wp_registered_widget_controls; … … 914 1094 $parsed_id = self::parse_widget_id( $widget_id ); 915 1095 $option_name = 'widget_' . $parsed_id['id_base']; 916 1096 917 /* *1097 /* 918 1098 * If a previously-sanitized instance is provided, populate the input vars 919 1099 * with its values so that the widget update callback will read this instance 920 1100 */ … … 946 1126 } 947 1127 } 948 1128 949 /** 950 * Invoke the widget update callback 951 */ 1129 // Invoke the widget update callback. 952 1130 foreach ( (array) $wp_registered_widget_updates as $name => $control ) { 953 1131 if ( $name === $parsed_id['id_base'] && is_callable( $control['callback'] ) ) { 954 1132 ob_start(); … … 964 1142 unset( $_REQUEST[$key] ); 965 1143 } 966 1144 967 /** 968 * Make sure the expected option was updated 969 */ 1145 // Make sure the expected option was updated. 970 1146 if ( 0 !== $options_transaction->count() ) { 971 1147 if ( count( $options_transaction->options ) > 1 ) { 972 1148 $options_transaction->rollback(); … … 980 1156 } 981 1157 } 982 1158 983 /** 984 * Obtain the widget control with the updated instance in place 985 */ 1159 // Obtain the widget control with the updated instance in place. 986 1160 ob_start(); 987 1161 $form = $wp_registered_widget_controls[$widget_id]; 988 1162 if ( $form ) { … … 990 1164 } 991 1165 $form = ob_get_clean(); 992 1166 993 /** 994 * Obtain the widget instance 995 */ 1167 // Obtain the widget instance. 996 1168 $option = get_option( $option_name ); 997 1169 if ( null !== $parsed_id['number'] ) { 998 1170 $instance = $option[$parsed_id['number']]; … … 1009 1181 * instance info via Ajax instead of saving it to the options table. 1010 1182 * Most code here copied from wp_ajax_save_widget() 1011 1183 * 1184 * @since 3.9.0 1185 * @static 1186 * @access public 1187 * 1012 1188 * @see wp_ajax_save_widget 1013 1189 * @todo Reuse wp_ajax_save_widget now that we have option transactions? 1014 1190 * @action wp_ajax_update_widget