Changeset 27816
- Timestamp:
- 03/28/2014 02:06:10 PM (12 years ago)
- Location:
- trunk/src
- Files:
-
- 4 edited
-
wp-admin/includes/ajax-actions.php (modified) (1 diff)
-
wp-includes/class-wp-customize-control.php (modified) (1 diff)
-
wp-includes/class-wp-customize-manager.php (modified) (2 diffs)
-
wp-includes/class-wp-customize-widgets.php (modified) (85 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-admin/includes/ajax-actions.php
r27576 r27816 1589 1589 1590 1590 function wp_ajax_update_widget() { 1591 WP_Customize_Widgets::wp_ajax_update_widget(); 1591 global $wp_customize; 1592 $wp_customize->widgets->wp_ajax_update_widget(); 1592 1593 } 1593 1594 -
trunk/src/wp-includes/class-wp-customize-control.php
r27722 r27816 1081 1081 1082 1082 $args = wp_list_widget_controls_dynamic_sidebar( array( 0 => $args, 1 => $widget['params'][0] ) ); 1083 echo WP_Customize_Widgets::get_widget_control( $args );1083 echo $this->manager->widgets->get_widget_control( $args ); 1084 1084 } 1085 1085 } -
trunk/src/wp-includes/class-wp-customize-manager.php
r27433 r27816 38 38 protected $previewing = false; 39 39 40 /** 41 * Methods and properties deailing with managing widgets in the customizer. 42 * 43 * @var WP_Customize_Widgets 44 */ 45 public $widgets; 46 40 47 protected $settings = array(); 41 48 protected $sections = array(); … … 64 71 require( ABSPATH . WPINC . '/class-wp-customize-widgets.php' ); 65 72 66 WP_Customize_Widgets::setup(); // This should be integrated.73 $this->widgets = new WP_Customize_Widgets( $this ); 67 74 68 75 add_filter( 'wp_die_handler', array( $this, 'wp_die_handler' ) ); -
trunk/src/wp-includes/class-wp-customize-widgets.php
r27814 r27816 5 5 * Implements widget management in the Customizer. 6 6 * 7 * @since 3.9.08 7 * @package WordPress 9 8 * @subpackage Customize 9 * @since 3.9.0 10 10 */ 11 class WP_Customize_Widgets {11 final class WP_Customize_Widgets { 12 12 const UPDATE_WIDGET_AJAX_ACTION = 'update-widget'; 13 13 const UPDATE_WIDGET_NONCE_POST_KEY = 'update-sidebar-widgets-nonce'; 14 14 15 15 /** 16 * @access public 17 * @var WP_Customize_Manager 18 */ 19 public $manager; 20 21 /** 16 22 * All id_bases for widgets defined in core 17 23 * 18 24 * @since 3.9.0 19 * @static20 25 * @access protected 21 26 * @var array 22 27 */ 23 protected static$core_widget_id_bases = array(28 protected $core_widget_id_bases = array( 24 29 'archives', 25 30 'calendar', … … 39 44 /** 40 45 * @since 3.9.0 41 * @static42 46 * @access protected 43 47 * @var 44 48 */ 45 protected static $_customized; 46 47 /** 48 * @since 3.9.0 49 * @static 49 protected $_customized; 50 51 /** 52 * @since 3.9.0 50 53 * @access protected 51 54 * @var array 52 55 */ 53 protected static $_prepreview_added_filters = array(); 54 55 /** 56 * @since 3.9.0 57 * @static 56 protected $_prepreview_added_filters = array(); 57 58 /** 59 * @since 3.9.0 58 60 * @access protected 59 61 * @var array 60 62 */ 61 static protected $rendered_sidebars = array(); 62 63 /** 64 * @since 3.9.0 65 * @static 63 protected $rendered_sidebars = array(); 64 65 /** 66 * @since 3.9.0 66 67 * @access protected 67 68 * @var array 68 69 */ 69 staticprotected $rendered_widgets = array();70 protected $rendered_widgets = array(); 70 71 71 72 /** … … 73 74 * 74 75 * @since 3.9.0 75 * @static 76 * @access public 77 */ 78 static function setup() { 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' ) ); 83 add_action( 'customize_controls_print_footer_scripts', array( __CLASS__, 'output_widget_control_templates' ) ); 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 ); 76 * @access public 77 */ 78 public function __construct( WP_Customize_Manager $manager ) { 79 $this->manager = $manager; 80 81 add_action( 'after_setup_theme', array( $this, 'setup_widget_addition_previews' ) ); 82 add_action( 'customize_controls_init', array( $this, 'customize_controls_init' ) ); 83 add_action( 'customize_register', array( $this, 'schedule_customize_register' ), 1 ); 84 add_action( 'customize_controls_enqueue_scripts', array( $this, 'customize_controls_enqueue_deps' ) ); 85 add_action( 'customize_controls_print_footer_scripts', array( $this, 'output_widget_control_templates' ) ); 86 add_action( 'customize_preview_init', array( $this, 'customize_preview_init' ) ); 87 88 add_action( 'dynamic_sidebar', array( $this, 'tally_rendered_widgets' ) ); 89 add_filter( 'is_active_sidebar', array( $this, 'tally_sidebars_via_is_active_sidebar_calls' ), 10, 2 ); 90 add_filter( 'dynamic_sidebar_has_widgets', array( $this, 'tally_sidebars_via_dynamic_sidebar_calls' ), 10, 2 ); 89 91 } 90 92 … … 94 96 * @since 3.9.0 95 97 * 96 * @static 97 * @access public 98 * @access protected 98 99 * 99 100 * @param string $name Post value. … … 101 102 * @return mixed Unslashed post value or default value. 102 103 */ 103 staticfunction get_post_value( $name, $default = null ) {104 protected function get_post_value( $name, $default = null ) { 104 105 if ( ! isset( $_POST[ $name ] ) ) { 105 106 return $default; 106 107 } 108 107 109 return wp_unslash( $_POST[$name] ); 108 110 } … … 116 118 * @since 3.9.0 117 119 * 118 * @static119 120 * @access public 120 121 * @global WP_Customize_Manager $wp_customize 121 122 */ 122 static function setup_widget_addition_previews() { 123 global $wp_customize; 123 public function setup_widget_addition_previews() { 124 124 $is_customize_preview = ( 125 ( ! empty( $ wp_customize) )125 ( ! empty( $this->manager ) ) 126 126 && 127 127 ( ! is_admin() ) 128 128 && 129 ( 'on' === self::get_post_value( 'wp_customize' ) )129 ( 'on' === $this->get_post_value( 'wp_customize' ) ) 130 130 && 131 check_ajax_referer( 'preview-customize_' . $ wp_customize->get_stylesheet(), 'nonce', false )131 check_ajax_referer( 'preview-customize_' . $this->manager->get_stylesheet(), 'nonce', false ) 132 132 ); 133 133 … … 135 135 ( defined( 'DOING_AJAX' ) && DOING_AJAX ) 136 136 && 137 self::get_post_value( 'action' ) === self::UPDATE_WIDGET_AJAX_ACTION137 $this->get_post_value( 'action' ) === self::UPDATE_WIDGET_AJAX_ACTION 138 138 && 139 139 check_ajax_referer( self::UPDATE_WIDGET_AJAX_ACTION, self::UPDATE_WIDGET_NONCE_POST_KEY, false ) … … 143 143 ( defined( 'DOING_AJAX' ) && DOING_AJAX ) 144 144 && 145 self::get_post_value( 'action' ) === 'customize_save'145 $this->get_post_value( 'action' ) === 'customize_save' 146 146 && 147 check_ajax_referer( 'save-customize_' . $ wp_customize->get_stylesheet(), 'nonce' )147 check_ajax_referer( 'save-customize_' . $this->manager->get_stylesheet(), 'nonce' ) 148 148 ); 149 149 … … 155 155 // Input from customizer preview. 156 156 if ( isset( $_POST['customized'] ) ) { 157 $customized = json_decode( self::get_post_value( 'customized' ), true );157 $customized = json_decode( $this->get_post_value( 'customized' ), true ); 158 158 } 159 159 … … 161 161 else { 162 162 $customized = array(); 163 $id_base = self::get_post_value( 'id_base' );164 $widget_number = (int) self::get_post_value( 'widget_number' );163 $id_base = $this->get_post_value( 'id_base' ); 164 $widget_number = (int) $this->get_post_value( 'widget_number' ); 165 165 $option_name = 'widget_' . $id_base; 166 166 $customized[$option_name] = array(); … … 171 171 } 172 172 173 $function = array( __CLASS__, 'prepreview_added_sidebars_widgets' );173 $function = array( $this, 'prepreview_added_sidebars_widgets' ); 174 174 175 175 $hook = 'option_sidebars_widgets'; 176 176 add_filter( $hook, $function ); 177 self::$_prepreview_added_filters[] = compact( 'hook', 'function' );177 $this->_prepreview_added_filters[] = compact( 'hook', 'function' ); 178 178 179 179 $hook = 'default_option_sidebars_widgets'; 180 180 add_filter( $hook, $function ); 181 self::$_prepreview_added_filters[] = compact( 'hook', 'function' );181 $this->_prepreview_added_filters[] = compact( 'hook', 'function' ); 182 182 183 183 foreach ( $customized as $setting_id => $value ) { 184 184 if ( preg_match( '/^(widget_.+?)(\[(\d+)\])?$/', $setting_id, $matches ) ) { 185 $body = sprintf( ' return %s::prepreview_added_widget_instance( $value, %s );', __CLASS__, var_export( $setting_id, true ) );185 $body = sprintf( 'global $wp_customize; return $wp_customize->widgets->prepreview_added_widget_instance( $value, %s );', var_export( $setting_id, true ) ); 186 186 $function = create_function( '$value', $body ); 187 // @todo replace above two lines with following once PHP 5.3 happens in WordPress 188 // $self = $this; // not needed in PHP 5.4 189 // $function = function ( $value ) use ( $self, $setting_id ) { 190 // return $self->manager->widgets->prepreview_added_widget_instance( $value, $setting_id ); 191 //}; 192 187 193 $option = $matches[1]; 188 194 189 195 $hook = sprintf( 'option_%s', $option ); 190 196 add_filter( $hook, $function ); 191 self::$_prepreview_added_filters[] = compact( 'hook', 'function' );197 $this->_prepreview_added_filters[] = compact( 'hook', 'function' ); 192 198 193 199 $hook = sprintf( 'default_option_%s', $option ); 194 200 add_filter( $hook, $function ); 195 self::$_prepreview_added_filters[] = compact( 'hook', 'function' );201 $this->_prepreview_added_filters[] = compact( 'hook', 'function' ); 196 202 197 203 /** … … 203 209 } 204 210 205 self::$_customized = $customized;211 $this->_customized = $customized; 206 212 } 207 213 … … 214 220 * 215 221 * @since 3.9.0 216 * @static217 222 * @access public 218 223 * … … 220 225 * @return array 221 226 */ 222 static function prepreview_added_sidebars_widgets( $sidebars_widgets ) {223 foreach ( self::$_customized as $setting_id => $value ) {227 public function prepreview_added_sidebars_widgets( $sidebars_widgets ) { 228 foreach ( $this->_customized as $setting_id => $value ) { 224 229 if ( preg_match( '/^sidebars_widgets\[(.+?)\]$/', $setting_id, $matches ) ) { 225 230 $sidebar_id = $matches[1]; … … 238 243 * 239 244 * @since 3.9.0 240 * @static241 245 * @access public 242 246 * … … 245 249 * @return array Parsed widget instance. 246 250 */ 247 static function prepreview_added_widget_instance( $instance, $setting_id ) {248 if ( isset( self::$_customized[$setting_id] ) ) {249 $parsed_setting_id = self::parse_widget_setting_id( $setting_id );251 public function prepreview_added_widget_instance( $instance, $setting_id ) { 252 if ( isset( $this->_customized[$setting_id] ) ) { 253 $parsed_setting_id = $this->parse_widget_setting_id( $setting_id ); 250 254 $widget_number = $parsed_setting_id['number']; 251 255 … … 274 278 * 275 279 * @since 3.9.0 276 * @static 277 * @access public 278 */ 279 static function remove_prepreview_filters() { 280 foreach ( self::$_prepreview_added_filters as $prepreview_added_filter ) { 280 * @access public 281 */ 282 public function remove_prepreview_filters() { 283 foreach ( $this->_prepreview_added_filters as $prepreview_added_filter ) { 281 284 remove_filter( $prepreview_added_filter['hook'], $prepreview_added_filter['function'] ); 282 285 } 283 self::$_prepreview_added_filters = array();286 $this->_prepreview_added_filters = array(); 284 287 } 285 288 … … 288 291 * 289 292 * @since 3.9.0 290 * @static 291 * @access public 292 */ 293 static function customize_controls_init() { 293 * @access public 294 */ 295 public function customize_controls_init() { 294 296 do_action( 'load-widgets.php' ); 295 297 do_action( 'widgets.php' ); … … 302 304 * 303 305 * @since 3.9.0 304 * @static 305 * @access public 306 * 307 * @param WP_Customize_Manager $wp_customize Customizer instance. 308 */ 309 static function schedule_customize_register( $wp_customize ) { 306 * @access public 307 */ 308 public function schedule_customize_register() { 310 309 if ( is_admin() ) { // @todo for some reason, $wp_customize->is_preview() is true here? 311 self::customize_register( $wp_customize);310 $this->customize_register(); 312 311 } else { 313 add_action( 'wp', array( __CLASS__, 'customize_register' ) );312 add_action( 'wp', array( $this, 'customize_register' ) ); 314 313 } 315 314 } … … 319 318 * 320 319 * @since 3.9.0 321 * @static 322 * @access public 323 * 324 * @param WP_Customize_Manager $wp_customize Customizer instance. 325 */ 326 static function customize_register( $wp_customize = null ) { 320 * @access public 321 */ 322 public function customize_register() { 327 323 global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_sidebars; 328 if ( ! ( $wp_customize instanceof WP_Customize_Manager ) ) {329 $wp_customize = $GLOBALS['wp_customize'];330 }331 324 332 325 $sidebars_widgets = array_merge( … … 343 336 */ 344 337 foreach ( array_keys( $wp_registered_widgets ) as $widget_id ) { 345 $setting_id = self::get_setting_id( $widget_id );346 $setting_args = self::get_setting_args( $setting_id );347 $setting_args['sanitize_callback'] = array( __CLASS__, 'sanitize_widget_instance' );348 $setting_args['sanitize_js_callback'] = array( __CLASS__, 'sanitize_widget_js_instance' );349 $ wp_customize->add_setting( $setting_id, $setting_args );338 $setting_id = $this->get_setting_id( $widget_id ); 339 $setting_args = $this->get_setting_args( $setting_id ); 340 $setting_args['sanitize_callback'] = array( $this, 'sanitize_widget_instance' ); 341 $setting_args['sanitize_js_callback'] = array( $this, 'sanitize_widget_js_instance' ); 342 $this->manager->add_setting( $setting_id, $setting_args ); 350 343 $new_setting_ids[] = $setting_id; 351 344 } … … 364 357 if ( $is_registered_sidebar || $is_inactive_widgets ) { 365 358 $setting_id = sprintf( 'sidebars_widgets[%s]', $sidebar_id ); 366 $setting_args = self::get_setting_args( $setting_id );367 $setting_args['sanitize_callback'] = array( __CLASS__, 'sanitize_sidebar_widgets' );368 $setting_args['sanitize_js_callback'] = array( __CLASS__, 'sanitize_sidebar_widgets_js_instance' );369 $ wp_customize->add_setting( $setting_id, $setting_args );359 $setting_args = $this->get_setting_args( $setting_id ); 360 $setting_args['sanitize_callback'] = array( $this, 'sanitize_sidebar_widgets' ); 361 $setting_args['sanitize_js_callback'] = array( $this, 'sanitize_sidebar_widgets_js_instance' ); 362 $this->manager->add_setting( $setting_id, $setting_args ); 370 363 $new_setting_ids[] = $setting_id; 371 364 … … 382 375 ); 383 376 $section_args = apply_filters( 'customizer_widgets_section_args', $section_args, $section_id, $sidebar_id ); 384 $ wp_customize->add_section( $section_id, $section_args );377 $this->manager->add_section( $section_id, $section_args ); 385 378 386 379 $control = new WP_Widget_Area_Customize_Control( 387 $ wp_customize,380 $this->manager, 388 381 $setting_id, 389 382 array( … … 394 387 ); 395 388 $new_setting_ids[] = $setting_id; 396 $ wp_customize->add_control( $control );389 $this->manager->add_control( $control ); 397 390 } 398 391 } … … 406 399 } 407 400 $registered_widget = $GLOBALS['wp_registered_widgets'][$widget_id]; 408 $setting_id = self::get_setting_id( $widget_id );401 $setting_id = $this->get_setting_id( $widget_id ); 409 402 $id_base = $GLOBALS['wp_registered_widget_controls'][$widget_id]['id_base']; 410 403 assert( false !== is_active_widget( $registered_widget['callback'], $registered_widget['id'], false, false ) ); 411 404 $control = new WP_Widget_Form_Customize_Control( 412 $ wp_customize,405 $this->manager, 413 406 $setting_id, 414 407 array( … … 421 414 'width' => $wp_registered_widget_controls[$widget_id]['width'], 422 415 'height' => $wp_registered_widget_controls[$widget_id]['height'], 423 'is_wide' => self::is_wide_widget( $widget_id ),416 'is_wide' => $this->is_wide_widget( $widget_id ), 424 417 ) 425 418 ); 426 $ wp_customize->add_control( $control );419 $this->manager->add_control( $control ); 427 420 } 428 421 } … … 434 427 if ( did_action( 'customize_preview_init' ) ) { 435 428 foreach ( $new_setting_ids as $new_setting_id ) { 436 $ wp_customize->get_setting( $new_setting_id )->preview();437 } 438 } 439 440 self::remove_prepreview_filters();429 $this->manager->get_setting( $new_setting_id )->preview(); 430 } 431 } 432 433 $this->remove_prepreview_filters(); 441 434 } 442 435 … … 445 438 * 446 439 * @since 3.9.0 447 * @static448 440 * @access public 449 441 * … … 451 443 * @return string Maybe-parsed widget ID. 452 444 */ 453 static function get_setting_id( $widget_id ) {454 $parsed_widget_id = self::parse_widget_id( $widget_id );445 public function get_setting_id( $widget_id ) { 446 $parsed_widget_id = $this->parse_widget_id( $widget_id ); 455 447 $setting_id = sprintf( 'widget_%s', $parsed_widget_id['id_base'] ); 456 448 if ( ! is_null( $parsed_widget_id['number'] ) ) { … … 469 461 * 470 462 * @since 3.9.0 471 * @static472 463 * @access public 473 464 * … … 475 466 * @return bool Whether or not the widget is a "wide" widget. 476 467 */ 477 static function is_wide_widget( $widget_id ) {468 public function is_wide_widget( $widget_id ) { 478 469 global $wp_registered_widget_controls; 479 $parsed_widget_id = self::parse_widget_id( $widget_id );470 $parsed_widget_id = $this->parse_widget_id( $widget_id ); 480 471 $width = $wp_registered_widget_controls[$widget_id]['width']; 481 $is_core = in_array( $parsed_widget_id['id_base'], self::$core_widget_id_bases );472 $is_core = in_array( $parsed_widget_id['id_base'], $this->core_widget_id_bases ); 482 473 $is_wide = ( $width > 250 && ! $is_core ); 483 474 … … 498 489 * 499 490 * @since 3.9.0 500 * @static501 491 * @access public 502 492 * … … 504 494 * @return array Array containing a widget's id_base and number components. 505 495 */ 506 static function parse_widget_id( $widget_id ) {496 public function parse_widget_id( $widget_id ) { 507 497 $parsed = array( 508 498 'number' => null, … … 523 513 * 524 514 * @since 3.9.0 525 * @static526 515 * @access public 527 516 * … … 530 519 * or a WP_Error object. 531 520 */ 532 static function parse_widget_setting_id( $setting_id ) {521 public function parse_widget_setting_id( $setting_id ) { 533 522 if ( ! preg_match( '/^(widget_(.+?))(?:\[(\d+)\])?$/', $setting_id, $matches ) ) { 534 523 return new WP_Error( 'invalid_setting_id', 'Invalid widget setting ID' ); … … 544 533 * 545 534 * @since 3.9.0 546 * @static 547 * @access public 548 */ 549 static function customize_controls_enqueue_deps() { 535 * @access public 536 */ 537 public function customize_controls_enqueue_deps() { 550 538 wp_enqueue_style( 'customize-widgets' ); 551 539 wp_enqueue_script( 'customize-widgets' ); … … 554 542 // since plugins need templates to be in the DOM 555 543 $available_widgets = array(); 556 foreach ( self::get_available_widgets() as $available_widget ) {544 foreach ( $this->get_available_widgets() as $available_widget ) { 557 545 unset( $available_widget['control_tpl'] ); 558 546 $available_widgets[] = $available_widget; … … 602 590 'remove_btn_label' => __( 'Remove' ), 603 591 'remove_btn_tooltip' => ( 'Trash widget by moving it to the inactive widgets sidebar.' ), 604 'error' => __( 'An error has occurred. Please reload the page and try again.'),592 'error' => __( 'An error has occurred. Please reload the page and try again.' ), 605 593 ), 606 594 'tpl' => array( … … 624 612 * 625 613 * @since 3.9.0 626 * @static 627 * @access public 628 */ 629 static function output_widget_control_templates() { 614 * @access public 615 */ 616 public function output_widget_control_templates() { 630 617 ?> 631 618 <div id="widgets-left"><!-- compatibility with JS which looks for widget templates here --> … … 634 621 <input type="search" placeholder="<?php esc_attr_e( 'Find widgets…' ) ?>"> 635 622 </div> 636 <?php foreach ( self::get_available_widgets() as $available_widget ): ?>623 <?php foreach ( $this->get_available_widgets() as $available_widget ): ?> 637 624 <div id="widget-tpl-<?php echo esc_attr( $available_widget['id'] ) ?>" data-widget-id="<?php echo esc_attr( $available_widget['id'] ) ?>" class="widget-tpl <?php echo esc_attr( $available_widget['id'] ) ?>" tabindex="0"> 638 625 <?php echo $available_widget['control_tpl']; // xss ok ?> … … 648 635 * 649 636 * @since 3.9.0 650 * @static651 637 * @access public 652 638 * … … 655 641 * @return array Possibly modified setting arguments. 656 642 */ 657 static function get_setting_args( $id, $overrides = array() ) {643 public function get_setting_args( $id, $overrides = array() ) { 658 644 $args = array( 659 645 'type' => 'option', … … 672 658 * 673 659 * @since 3.9.0 674 * @static675 660 * @access public 676 661 * … … 678 663 * @return array Array of sanitized widget IDs. 679 664 */ 680 static function sanitize_sidebar_widgets( $widget_ids ) {665 public function sanitize_sidebar_widgets( $widget_ids ) { 681 666 global $wp_registered_widgets; 682 667 $widget_ids = array_map( 'strval', (array) $widget_ids ); … … 694 679 * 695 680 * @since 3.9.0 696 * @static697 681 * @access public 698 682 * … … 700 684 * @return array 701 685 */ 702 static function get_available_widgets() {686 public function get_available_widgets() { 703 687 static $available_widgets = array(); 704 688 if ( ! empty( $available_widgets ) ) { … … 710 694 711 695 $sort = $wp_registered_widgets; 712 usort( $sort, array( __CLASS__, '_sort_name_callback' ) );696 usort( $sort, array( $this, '_sort_name_callback' ) ); 713 697 $done = array(); 714 698 … … 754 738 755 739 $list_widget_controls_args = wp_list_widget_controls_dynamic_sidebar( array( 0 => $args, 1 => $widget['params'][0] ) ); 756 $control_tpl = self::get_widget_control( $list_widget_controls_args );740 $control_tpl = $this->get_widget_control( $list_widget_controls_args ); 757 741 758 742 // The properties here are mapped to the Backbone Widget model … … 769 753 'width' => $wp_registered_widget_controls[$widget['id']]['width'], 770 754 'height' => $wp_registered_widget_controls[$widget['id']]['height'], 771 'is_wide' => self::is_wide_widget( $widget['id'] ),755 'is_wide' => $this->is_wide_widget( $widget['id'] ), 772 756 ) 773 757 ); … … 783 767 * @since 3.9.0 784 768 * @static 785 * @access p ublic769 * @access protected 786 770 * 787 771 * @param array $widget_a The first widget to compare. … … 789 773 * @return int Reorder position for the current widget comparison. 790 774 */ 791 staticfunction _sort_name_callback( $widget_a, $widget_b ) {775 protected function _sort_name_callback( $widget_a, $widget_b ) { 792 776 return strnatcasecmp( $widget_a['name'], $widget_b['name'] ); 793 777 } … … 798 782 * 799 783 * @since 3.9.0 800 * @static801 784 * @access public 802 785 * … … 804 787 * @return string Widget control form HTML markup. 805 788 */ 806 static function get_widget_control( $args ) {789 public function get_widget_control( $args ) { 807 790 ob_start(); 808 791 call_user_func_array( 'wp_widget_control', $args ); … … 820 803 * 821 804 * @since 3.9.0 822 * @static 823 * @access public 824 */ 825 static function customize_preview_init() { 826 add_filter( 'sidebars_widgets', array( __CLASS__, 'preview_sidebars_widgets' ), 1 ); 827 add_action( 'wp_enqueue_scripts', array( __CLASS__, 'customize_preview_enqueue' ) ); 828 add_action( 'wp_print_styles', array( __CLASS__, 'inject_preview_css' ), 1 ); 829 add_action( 'wp_footer', array( __CLASS__, 'export_preview_data' ), 20 ); 805 * @access public 806 */ 807 public function customize_preview_init() { 808 add_filter( 'sidebars_widgets', array( $this, 'preview_sidebars_widgets' ), 1 ); 809 add_action( 'wp_enqueue_scripts', array( $this, 'customize_preview_enqueue' ) ); 810 add_action( 'wp_print_styles', array( $this, 'inject_preview_css' ), 1 ); 811 add_action( 'wp_footer', array( $this, 'export_preview_data' ), 20 ); 830 812 } 831 813 … … 839 821 * 840 822 * @since 3.9.0 841 * @static842 823 * @access public 843 824 * 844 825 * @param array $sidebars_widgets List of widgets for the current sidebar. 845 826 */ 846 static function preview_sidebars_widgets( $sidebars_widgets ) {827 public function preview_sidebars_widgets( $sidebars_widgets ) { 847 828 $sidebars_widgets = get_option( 'sidebars_widgets' ); 848 829 unset( $sidebars_widgets['array_version'] ); … … 854 835 * 855 836 * @since 3.9.0 856 * @static 857 * @access public 858 */ 859 static function customize_preview_enqueue() { 837 * @access public 838 */ 839 public function customize_preview_enqueue() { 860 840 wp_enqueue_script( 'customize-preview-widgets' ); 861 }841 } 862 842 863 843 /** … … 866 846 * 867 847 * @since 3.9.0 868 * @static869 848 * @access public 870 849 * 871 850 * @action wp_print_styles 872 851 */ 873 static function inject_preview_css() {852 public function inject_preview_css() { 874 853 ?> 875 854 <style> … … 889 868 * 890 869 * @since 3.9.0 891 * @static 892 * @access public 893 */ 894 static function export_preview_data() { 870 * @access public 871 */ 872 public function export_preview_data() { 895 873 // Prepare customizer settings to pass to Javascript. 896 874 $settings = array( 897 'renderedSidebars' => array_fill_keys( array_unique( self::$rendered_sidebars ), true ),898 'renderedWidgets' => array_fill_keys( array_keys( self::$rendered_widgets ), true ),875 'renderedSidebars' => array_fill_keys( array_unique( $this->rendered_sidebars ), true ), 876 'renderedWidgets' => array_fill_keys( array_keys( $this->rendered_widgets ), true ), 899 877 'registeredSidebars' => array_values( $GLOBALS['wp_registered_sidebars'] ), 900 878 'registeredWidgets' => $GLOBALS['wp_registered_widgets'], … … 918 896 * 919 897 * @since 3.9.0 920 * @static921 898 * @access public 922 899 * 923 900 * @param array $widget Rendered widget to tally. 924 901 */ 925 static function tally_rendered_widgets( $widget ) {926 self::$rendered_widgets[$widget['id']] = true;902 public function tally_rendered_widgets( $widget ) { 903 $this->rendered_widgets[$widget['id']] = true; 927 904 } 928 905 … … 932 909 * 933 910 * @since 3.9.0 934 * @static935 911 * @access public 936 912 * … … 938 914 * @pasram string $sidebar_id Sidebar ID. 939 915 */ 940 static function tally_sidebars_via_is_active_sidebar_calls( $is_active, $sidebar_id ) {916 public function tally_sidebars_via_is_active_sidebar_calls( $is_active, $sidebar_id ) { 941 917 if ( isset( $GLOBALS['wp_registered_sidebars'][$sidebar_id] ) ) { 942 self::$rendered_sidebars[] = $sidebar_id;918 $this->rendered_sidebars[] = $sidebar_id; 943 919 } 944 920 // We may need to force this to true, and also force-true the value for dynamic_sidebar_has_widgets … … 952 928 * 953 929 * @since 3.9.0 954 * @static955 930 * @access public 956 931 * … … 958 933 * @param string $sidebar_id Sidebar ID. 959 934 */ 960 static function tally_sidebars_via_dynamic_sidebar_calls( $has_widgets, $sidebar_id ) {935 public function tally_sidebars_via_dynamic_sidebar_calls( $has_widgets, $sidebar_id ) { 961 936 if ( isset( $GLOBALS['wp_registered_sidebars'][$sidebar_id] ) ) { 962 self::$rendered_sidebars[] = $sidebar_id;937 $this->rendered_sidebars[] = $sidebar_id; 963 938 } 964 939 /* … … 978 953 * 979 954 * @since 3.9.0 980 * @static981 955 * @access protected 982 956 * … … 984 958 * @return string Widget instance's hash key. 985 959 */ 986 protected staticfunction get_instance_hash_key( $instance ) {960 protected function get_instance_hash_key( $instance ) { 987 961 $hash = md5( AUTH_KEY . serialize( $instance ) ); 988 962 return $hash; … … 996 970 * 997 971 * @since 3.9.0 998 * @static999 972 * @access public 1000 973 * … … 1004 977 * @return array Sanitized widget instance. 1005 978 */ 1006 static function sanitize_widget_instance( $value ) {979 public function sanitize_widget_instance( $value ) { 1007 980 if ( $value === array() ) { 1008 981 return $value; … … 1026 999 return null; 1027 1000 } 1028 if ( self::get_instance_hash_key( $instance ) !== $value['instance_hash_key'] ) {1001 if ( $this->get_instance_hash_key( $instance ) !== $value['instance_hash_key'] ) { 1029 1002 return null; 1030 1003 } … … 1036 1009 * 1037 1010 * @since 3.9.0 1038 * @static1039 1011 * @access public 1040 1012 * … … 1044 1016 * @return array JSON-converted widget instance. 1045 1017 */ 1046 static function sanitize_widget_js_instance( $value ) {1018 public function sanitize_widget_js_instance( $value ) { 1047 1019 if ( empty( $value['is_widget_customizer_js_value'] ) ) { 1048 1020 $serialized = serialize( $value ); … … 1051 1023 'title' => empty( $value['title'] ) ? '' : $value['title'], 1052 1024 'is_widget_customizer_js_value' => true, 1053 'instance_hash_key' => self::get_instance_hash_key( $value ),1025 'instance_hash_key' => $this->get_instance_hash_key( $value ), 1054 1026 ); 1055 1027 } … … 1062 1034 * 1063 1035 * @since 3.9.0 1064 * @static1065 1036 * @access public 1066 1037 * … … 1068 1039 * @return array Parsed list of widget IDs. 1069 1040 */ 1070 static function sanitize_sidebar_widgets_js_instance( $widget_ids ) {1041 public function sanitize_sidebar_widgets_js_instance( $widget_ids ) { 1071 1042 global $wp_registered_widgets; 1072 1043 $widget_ids = array_values( array_intersect( $widget_ids, array_keys( $wp_registered_widgets ) ) ); … … 1080 1051 * 1081 1052 * @since 3.9.0 1082 * @static1083 1053 * @access public 1084 1054 * … … 1086 1056 * @return WP_Error|array Array containing the updated widget information. WP_Error, otherwise. 1087 1057 */ 1088 static function call_widget_update( $widget_id ) {1058 public function call_widget_update( $widget_id ) { 1089 1059 global $wp_registered_widget_updates, $wp_registered_widget_controls; 1090 1060 1091 $options_transaction = new Options_Transaction(); 1092 1093 $options_transaction->start(); 1094 $parsed_id = self::parse_widget_id( $widget_id ); 1061 $this->start_capturing_option_updates(); 1062 $parsed_id = $this->parse_widget_id( $widget_id ); 1095 1063 $option_name = 'widget_' . $parsed_id['id_base']; 1096 1064 … … 1101 1069 $added_input_vars = array(); 1102 1070 if ( ! empty( $_POST['sanitized_widget_setting'] ) ) { 1103 $sanitized_widget_setting = json_decode( self::get_post_value( 'sanitized_widget_setting' ), true );1071 $sanitized_widget_setting = json_decode( $this->get_post_value( 'sanitized_widget_setting' ), true ); 1104 1072 if ( empty( $sanitized_widget_setting ) ) { 1105 $ options_transaction->rollback();1073 $this->stop_capturing_option_updates(); 1106 1074 return new WP_Error( 'malformed_data', 'Malformed sanitized_widget_setting' ); 1107 1075 } 1108 1076 1109 $instance = self::sanitize_widget_instance( $sanitized_widget_setting );1077 $instance = $this->sanitize_widget_instance( $sanitized_widget_setting ); 1110 1078 if ( is_null( $instance ) ) { 1111 $ options_transaction->rollback();1079 $this->stop_capturing_option_updates(); 1112 1080 return new WP_Error( 'unsanitary_data', 'Unsanitary sanitized_widget_setting' ); 1113 1081 } … … 1144 1112 1145 1113 // Make sure the expected option was updated. 1146 if ( 0 !== $ options_transaction->count() ) {1147 if ( count( $options_transaction->options) > 1 ) {1148 $ options_transaction->rollback();1114 if ( 0 !== $this->count_captured_options() ) { 1115 if ( $this->count_captured_options() > 1 ) { 1116 $this->stop_capturing_option_updates(); 1149 1117 return new WP_Error( 'unexpected_update', 'Widget unexpectedly updated more than one option.' ); 1150 1118 } 1151 1119 1152 $updated_option_name = key( $ options_transaction->options);1120 $updated_option_name = key( $this->get_captured_options() ); 1153 1121 if ( $updated_option_name !== $option_name ) { 1154 $ options_transaction->rollback();1122 $this->stop_capturing_option_updates(); 1155 1123 return new WP_Error( 'wrong_option', sprintf( 'Widget updated option "%1$s", but expected "%2$s".', $updated_option_name, $option_name ) ); 1156 1124 } … … 1173 1141 } 1174 1142 1175 $ options_transaction->rollback();1143 $this->stop_capturing_option_updates(); 1176 1144 return compact( 'instance', 'form' ); 1177 1145 } … … 1183 1151 * 1184 1152 * @since 3.9.0 1185 * @static1186 1153 * @access public 1187 1154 * … … 1190 1157 * @action wp_ajax_update_widget 1191 1158 */ 1192 static function wp_ajax_update_widget() {1159 public function wp_ajax_update_widget() { 1193 1160 1194 1161 if ( ! is_user_logged_in() ) { … … 1212 1179 do_action( 'sidebar_admin_setup' ); 1213 1180 1214 $widget_id = self::get_post_value( 'widget-id' );1215 $parsed_id = self::parse_widget_id( $widget_id );1181 $widget_id = $this->get_post_value( 'widget-id' ); 1182 $parsed_id = $this->parse_widget_id( $widget_id ); 1216 1183 $id_base = $parsed_id['id_base']; 1217 1184 … … 1220 1187 } 1221 1188 1222 $updated_widget = self::call_widget_update( $widget_id ); // => {instance,form}1189 $updated_widget = $this->call_widget_update( $widget_id ); // => {instance,form} 1223 1190 if ( is_wp_error( $updated_widget ) ) { 1224 1191 wp_send_json_error(); … … 1226 1193 1227 1194 $form = $updated_widget['form']; 1228 $instance = self::sanitize_widget_js_instance( $updated_widget['instance'] );1195 $instance = $this->sanitize_widget_js_instance( $updated_widget['instance'] ); 1229 1196 1230 1197 wp_send_json_success( compact( 'form', 'instance' ) ); 1231 1198 } 1232 } 1233 1234 class Options_Transaction { 1235 1236 /** 1237 * @var array $options values updated while transaction is open 1238 */ 1239 public $options = array(); 1240 1241 protected $_ignore_transients = true; 1242 protected $_is_current = false; 1243 protected $_operations = array(); 1244 1245 function __construct( $ignore_transients = true ) { 1246 $this->_ignore_transients = $ignore_transients; 1247 } 1248 1249 /** 1250 * Determine whether or not the transaction is open 1251 * @return bool 1252 */ 1253 function is_current() { 1254 return $this->_is_current; 1255 } 1199 1200 /*************************************************************************** 1201 * Option Update Capturing 1202 ***************************************************************************/ 1203 1204 /** 1205 * @var array $_captured_options values updated while capturing is happening 1206 */ 1207 protected $_captured_options = array(); 1208 1209 /** 1210 * @var bool $_is_current whether capturing is currently happening or not 1211 */ 1212 protected $_is_capturing_option_updates = false; 1256 1213 1257 1214 /** … … 1259 1216 * @return boolean 1260 1217 */ 1261 function is_option_ignored( $option_name ) { 1262 return ( $this->_ignore_transients && 0 === strpos( $option_name, '_transient_' ) ); 1263 } 1264 1265 /** 1266 * Get the number of operations performed in the transaction 1218 protected function is_option_capture_ignored( $option_name ) { 1219 return ( 0 === strpos( $option_name, '_transient_' ) ); 1220 } 1221 1222 /** 1223 * Get options updated 1224 * @return array 1225 */ 1226 protected function get_captured_options() { 1227 return $this->_captured_options; 1228 } 1229 1230 /** 1231 * Get the number of options updated 1267 1232 * @return bool 1268 1233 */ 1269 function count() {1270 return count( $this->_ operations );1234 protected function count_captured_options() { 1235 return count( $this->_captured_options ); 1271 1236 } 1272 1237 … … 1274 1239 * Start keeping track of changes to options, and cache their new values 1275 1240 */ 1276 function start() { 1277 $this->_is_current = true; 1278 add_action( 'added_option', array( $this, '_capture_added_option' ), 10, 2 ); 1279 add_action( 'updated_option', array( $this, '_capture_updated_option' ), 10, 3 ); 1280 add_action( 'delete_option', array( $this, '_capture_pre_deleted_option' ), 10, 1 ); 1281 add_action( 'deleted_option', array( $this, '_capture_deleted_option' ), 10, 1 ); 1282 } 1283 1284 /** 1285 * @action added_option 1286 * @param $option_name 1287 * @param $new_value 1288 */ 1289 function _capture_added_option( $option_name, $new_value ) { 1290 if ( $this->is_option_ignored( $option_name ) ) { 1241 protected function start_capturing_option_updates() { 1242 if ( $this->_is_capturing_option_updates ) { 1291 1243 return; 1292 1244 } 1293 $this->options[$option_name] = $new_value; 1294 $operation = 'add'; 1295 $this->_operations[] = compact( 'operation', 'option_name', 'new_value' ); 1296 } 1297 1298 /** 1299 * @action updated_option 1245 1246 $this->_is_capturing_option_updates = true; 1247 add_filter( 'pre_update_option', array( $this, '_capture_filter_pre_update_option' ), 10, 3 ); 1248 } 1249 1250 /** 1251 * @access private 1252 * @param mixed $new_value 1300 1253 * @param string $option_name 1301 1254 * @param mixed $old_value 1302 * @ param mixed $new_value1303 */ 1304 function _capture_updated_option( $option_name, $old_value, $new_value ) {1305 if ( $this->is_option_ ignored( $option_name ) ) {1255 * @return mixed 1256 */ 1257 public function _capture_filter_pre_update_option( $new_value, $option_name, $old_value ) { 1258 if ( $this->is_option_capture_ignored( $option_name ) ) { 1306 1259 return; 1307 1260 } 1308 $this->options[$option_name] = $new_value; 1309 $operation = 'update'; 1310 $this->_operations[] = compact( 'operation', 'option_name', 'old_value', 'new_value' ); 1311 } 1312 1313 protected $_pending_delete_option_autoload; 1314 protected $_pending_delete_option_value; 1315 1316 /** 1317 * It's too bad the old_value and autoload aren't passed into the deleted_option action 1318 * @action delete_option 1319 * @param string $option_name 1320 */ 1321 function _capture_pre_deleted_option( $option_name ) { 1322 if ( $this->is_option_ignored( $option_name ) ) { 1261 1262 if ( ! isset( $this->_captured_options[$option_name] ) ) { 1263 add_filter( "pre_option_{$option_name}", array( $this, '_capture_filter_pre_get_option' ) ); 1264 } 1265 1266 $this->_captured_options[$option_name] = $new_value; 1267 1268 return $old_value; 1269 } 1270 1271 /** 1272 * @access private 1273 * @param mixed $value 1274 * @return mixed 1275 */ 1276 public function _capture_filter_pre_get_option( $value ) { 1277 $option_name = preg_replace( '/^pre_option_/', '', current_filter() ); 1278 if ( isset( $this->_captured_options[$option_name] ) ) { 1279 $value = $this->_captured_options[$option_name]; 1280 $value = apply_filters( 'option_' . $option_name, $value ); 1281 } 1282 1283 return $value; 1284 } 1285 1286 /** 1287 * Undo any changes to the options since start_capturing_option_updates() was called 1288 */ 1289 protected function stop_capturing_option_updates() { 1290 if ( ! $this->_is_capturing_option_updates ) { 1323 1291 return; 1324 1292 } 1325 global $wpdb; 1326 $autoload = $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", $option_name ) ); // db call ok; no-cache ok 1327 $this->_pending_delete_option_autoload = $autoload; 1328 $this->_pending_delete_option_value = get_option( $option_name ); 1329 } 1330 1331 /** 1332 * @action deleted_option 1333 * @param string $option_name 1334 */ 1335 function _capture_deleted_option( $option_name ) { 1336 if ( $this->is_option_ignored( $option_name ) ) { 1337 return; 1338 } 1339 unset( $this->options[$option_name] ); 1340 $operation = 'delete'; 1341 $old_value = $this->_pending_delete_option_value; 1342 $autoload = $this->_pending_delete_option_autoload; 1343 $this->_operations[] = compact( 'operation', 'option_name', 'old_value', 'autoload' ); 1344 } 1345 1346 /** 1347 * Undo any changes to the options since start() was called 1348 */ 1349 function rollback() { 1350 remove_action( 'updated_option', array( $this, '_capture_updated_option' ), 10, 3 ); 1351 remove_action( 'added_option', array( $this, '_capture_added_option' ), 10, 2 ); 1352 remove_action( 'delete_option', array( $this, '_capture_pre_deleted_option' ), 10, 1 ); 1353 remove_action( 'deleted_option', array( $this, '_capture_deleted_option' ), 10, 1 ); 1354 while ( 0 !== count( $this->_operations ) ) { 1355 $option_operation = array_pop( $this->_operations ); 1356 if ( 'add' === $option_operation['operation'] ) { 1357 delete_option( $option_operation['option_name'] ); 1358 } 1359 else if ( 'delete' === $option_operation['operation'] ) { 1360 add_option( $option_operation['option_name'], $option_operation['old_value'], null, $option_operation['autoload'] ); 1361 } 1362 else if ( 'update' === $option_operation['operation'] ) { 1363 update_option( $option_operation['option_name'], $option_operation['old_value'] ); 1364 } 1365 } 1366 $this->_is_current = false; 1293 1294 remove_filter( '_capture_filter_pre_update_option', array( $this, '_capture_filter_pre_update_option' ), 10, 3 ); 1295 foreach ( array_keys( $this->_captured_options ) as $option_name ) { 1296 remove_filter( "pre_option_{$option_name}", array( $this, '_capture_filter_pre_get_option' ) ); 1297 } 1298 1299 $this->_captured_options = array(); 1300 $this->_is_capturing_option_updates = false; 1367 1301 } 1368 1302 }
Note: See TracChangeset
for help on using the changeset viewer.