[ Index ]

WordPress Cross Reference

title

Body

[close]

/wp-includes/ -> class-wp-customize-manager.php (source)

   1  <?php
   2  /**
   3   * Customize Manager.
   4   *
   5   * @package WordPress
   6   * @subpackage Customize
   7   * @since 3.4.0
   8   */
   9  final class WP_Customize_Manager {
  10      protected $theme;
  11      protected $original_stylesheet;
  12  
  13      protected $previewing = false;
  14  
  15      protected $settings = array();
  16      protected $sections = array();
  17      protected $controls = array();
  18  
  19      protected $nonce_tick;
  20  
  21      protected $customized;
  22  
  23      private $_post_values;
  24  
  25      /**
  26       * Constructor.
  27       *
  28       * @since 3.4.0
  29       */
  30  	public function __construct() {
  31          require ( ABSPATH . WPINC . '/class-wp-customize-setting.php' );
  32          require ( ABSPATH . WPINC . '/class-wp-customize-section.php' );
  33          require ( ABSPATH . WPINC . '/class-wp-customize-control.php' );
  34  
  35          add_filter( 'wp_die_handler', array( $this, 'wp_die_handler' ) );
  36  
  37          add_action( 'setup_theme',  array( $this, 'setup_theme' ) );
  38          add_action( 'wp_loaded',    array( $this, 'wp_loaded' ) );
  39  
  40          // Run wp_redirect_status late to make sure we override the status last.
  41          add_action( 'wp_redirect_status', array( $this, 'wp_redirect_status' ), 1000 );
  42  
  43          // Do not spawn cron (especially the alternate cron) while running the customizer.
  44          remove_action( 'init', 'wp_cron' );
  45  
  46          // Do not run update checks when rendering the controls.
  47          remove_action( 'admin_init', '_maybe_update_core' );
  48          remove_action( 'admin_init', '_maybe_update_plugins' );
  49          remove_action( 'admin_init', '_maybe_update_themes' );
  50  
  51          add_action( 'wp_ajax_customize_save', array( $this, 'save' ) );
  52  
  53          add_action( 'customize_register',                 array( $this, 'register_controls' ) );
  54          add_action( 'customize_controls_init',            array( $this, 'prepare_controls' ) );
  55          add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_control_scripts' ) );
  56      }
  57  
  58      /**
  59       * Return true if it's an AJAX request.
  60       *
  61       * @since 3.4.0
  62       *
  63       * @return bool
  64       */
  65  	public function doing_ajax() {
  66          return isset( $_POST['customized'] ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX );
  67      }
  68  
  69      /**
  70       * Custom wp_die wrapper. Returns either the standard message for UI
  71       * or the AJAX message.
  72       *
  73       * @since 3.4.0
  74       *
  75       * @param mixed $ajax_message AJAX return
  76       * @param mixed $message UI message
  77       */
  78  	protected function wp_die( $ajax_message, $message = null ) {
  79          if ( $this->doing_ajax() )
  80              wp_die( $ajax_message );
  81  
  82          if ( ! $message )
  83              $message = __( 'Cheatin&#8217; uh?' );
  84  
  85          wp_die( $message );
  86      }
  87  
  88      /**
  89       * Return the AJAX wp_die() handler if it's a customized request.
  90       *
  91       * @since 3.4.0
  92       *
  93       * @return string
  94       */
  95  	public function wp_die_handler() {
  96          if ( $this->doing_ajax() )
  97              return '_ajax_wp_die_handler';
  98  
  99          return '_default_wp_die_handler';
 100      }
 101  
 102      /**
 103       * Start preview and customize theme.
 104       *
 105       * Check if customize query variable exist. Init filters to filter the current theme.
 106       *
 107       * @since 3.4.0
 108       */
 109  	public function setup_theme() {
 110          send_origin_headers();
 111  
 112          if ( is_admin() && ! $this->doing_ajax() )
 113              auth_redirect();
 114          elseif ( $this->doing_ajax() && ! is_user_logged_in() )
 115              $this->wp_die( 0 );
 116  
 117          show_admin_bar( false );
 118  
 119          if ( ! current_user_can( 'edit_theme_options' ) )
 120              $this->wp_die( -1 );
 121  
 122          $this->original_stylesheet = get_stylesheet();
 123  
 124          $this->theme = wp_get_theme( isset( $_REQUEST['theme'] ) ? $_REQUEST['theme'] : null );
 125  
 126          if ( $this->is_theme_active() ) {
 127              // Once the theme is loaded, we'll validate it.
 128              add_action( 'after_setup_theme', array( $this, 'after_setup_theme' ) );
 129          } else {
 130              if ( ! current_user_can( 'switch_themes' ) )
 131                  $this->wp_die( -1 );
 132  
 133              // If the theme isn't active, you can't preview it if it is not allowed or has errors.
 134              if ( $this->theme()->errors() )
 135                  $this->wp_die( -1 );
 136  
 137              if ( ! $this->theme()->is_allowed() )
 138                  $this->wp_die( -1 );
 139          }
 140  
 141          $this->start_previewing_theme();
 142      }
 143  
 144      /**
 145       * Callback to validate a theme once it is loaded
 146       *
 147       * @since 3.4.0
 148       */
 149  	function after_setup_theme() {
 150          if ( ! $this->doing_ajax() && ! validate_current_theme() ) {
 151              wp_redirect( 'themes.php?broken=true' );
 152              exit;
 153          }
 154      }
 155  
 156      /**
 157       * Start previewing the selected theme.
 158       *
 159       * Adds filters to change the current theme.
 160       *
 161       * @since 3.4.0
 162       */
 163  	public function start_previewing_theme() {
 164          // Bail if we're already previewing.
 165          if ( $this->is_preview() )
 166              return;
 167  
 168          $this->previewing = true;
 169  
 170          if ( ! $this->is_theme_active() ) {
 171              add_filter( 'template', array( $this, 'get_template' ) );
 172              add_filter( 'stylesheet', array( $this, 'get_stylesheet' ) );
 173              add_filter( 'pre_option_current_theme', array( $this, 'current_theme' ) );
 174  
 175              // @link: http://core.trac.wordpress.org/ticket/20027
 176              add_filter( 'pre_option_stylesheet', array( $this, 'get_stylesheet' ) );
 177              add_filter( 'pre_option_template', array( $this, 'get_template' ) );
 178  
 179              // Handle custom theme roots.
 180              add_filter( 'pre_option_stylesheet_root', array( $this, 'get_stylesheet_root' ) );
 181              add_filter( 'pre_option_template_root', array( $this, 'get_template_root' ) );
 182          }
 183  
 184          do_action( 'start_previewing_theme', $this );
 185      }
 186  
 187      /**
 188       * Stop previewing the selected theme.
 189       *
 190       * Removes filters to change the current theme.
 191       *
 192       * @since 3.4.0
 193       */
 194  	public function stop_previewing_theme() {
 195          if ( ! $this->is_preview() )
 196              return;
 197  
 198          $this->previewing = false;
 199  
 200          if ( ! $this->is_theme_active() ) {
 201              remove_filter( 'template', array( $this, 'get_template' ) );
 202              remove_filter( 'stylesheet', array( $this, 'get_stylesheet' ) );
 203              remove_filter( 'pre_option_current_theme', array( $this, 'current_theme' ) );
 204  
 205              // @link: http://core.trac.wordpress.org/ticket/20027
 206              remove_filter( 'pre_option_stylesheet', array( $this, 'get_stylesheet' ) );
 207              remove_filter( 'pre_option_template', array( $this, 'get_template' ) );
 208  
 209              // Handle custom theme roots.
 210              remove_filter( 'pre_option_stylesheet_root', array( $this, 'get_stylesheet_root' ) );
 211              remove_filter( 'pre_option_template_root', array( $this, 'get_template_root' ) );
 212          }
 213  
 214          do_action( 'stop_previewing_theme', $this );
 215      }
 216  
 217      /**
 218       * Get the theme being customized.
 219       *
 220       * @since 3.4.0
 221       *
 222       * @return WP_Theme
 223       */
 224  	public function theme() {
 225          return $this->theme;
 226      }
 227  
 228      /**
 229       * Get the registered settings.
 230       *
 231       * @since 3.4.0
 232       *
 233       * @return array
 234       */
 235  	public function settings() {
 236          return $this->settings;
 237      }
 238  
 239      /**
 240       * Get the registered controls.
 241       *
 242       * @since 3.4.0
 243       *
 244       * @return array
 245       */
 246  	public function controls() {
 247          return $this->controls;
 248      }
 249  
 250      /**
 251       * Get the registered sections.
 252       *
 253       * @since 3.4.0
 254       *
 255       * @return array
 256       */
 257  	public function sections() {
 258          return $this->sections;
 259      }
 260  
 261      /**
 262       * Checks if the current theme is active.
 263       *
 264       * @since 3.4.0
 265       *
 266       * @return bool
 267       */
 268  	public function is_theme_active() {
 269          return $this->get_stylesheet() == $this->original_stylesheet;
 270      }
 271  
 272      /**
 273       * Register styles/scripts and initialize the preview of each setting
 274       *
 275       * @since 3.4.0
 276       */
 277  	public function wp_loaded() {
 278          do_action( 'customize_register', $this );
 279  
 280          if ( $this->is_preview() && ! is_admin() )
 281              $this->customize_preview_init();
 282      }
 283  
 284      /**
 285       * Prevents AJAX requests from following redirects when previewing a theme
 286       * by issuing a 200 response instead of a 30x.
 287       *
 288       * Instead, the JS will sniff out the location header.
 289       *
 290       * @since 3.4.0
 291       *
 292       * @param $status
 293       * @return int
 294       */
 295  	public function wp_redirect_status( $status ) {
 296          if ( $this->is_preview() && ! is_admin() )
 297              return 200;
 298  
 299          return $status;
 300      }
 301  
 302      /**
 303       * Decode the $_POST attribute used to override the WP_Customize_Setting values.
 304       *
 305       * @since 3.4.0
 306       *
 307       * @param mixed $setting A WP_Customize_Setting derived object
 308       * @return string Sanitized attribute
 309       */
 310  	public function post_value( $setting ) {
 311          if ( ! isset( $this->_post_values ) ) {
 312              if ( isset( $_POST['customized'] ) )
 313                  $this->_post_values = json_decode( wp_unslash( $_POST['customized'] ), true );
 314              else
 315                  $this->_post_values = false;
 316          }
 317  
 318          if ( isset( $this->_post_values[ $setting->id ] ) )
 319              return $setting->sanitize( $this->_post_values[ $setting->id ] );
 320      }
 321  
 322      /**
 323       * Print javascript settings.
 324       *
 325       * @since 3.4.0
 326       */
 327  	public function customize_preview_init() {
 328          $this->nonce_tick = check_ajax_referer( 'preview-customize_' . $this->get_stylesheet(), 'nonce' );
 329  
 330          $this->prepare_controls();
 331  
 332          wp_enqueue_script( 'customize-preview' );
 333          add_action( 'wp_head', array( $this, 'customize_preview_base' ) );
 334          add_action( 'wp_head', array( $this, 'customize_preview_html5' ) );
 335          add_action( 'wp_footer', array( $this, 'customize_preview_settings' ), 20 );
 336          add_action( 'shutdown', array( $this, 'customize_preview_signature' ), 1000 );
 337          add_filter( 'wp_die_handler', array( $this, 'remove_preview_signature' ) );
 338  
 339          foreach ( $this->settings as $setting ) {
 340              $setting->preview();
 341          }
 342  
 343          do_action( 'customize_preview_init', $this );
 344      }
 345  
 346      /**
 347       * Print base element for preview frame.
 348       *
 349       * @since 3.4.0
 350       */
 351  	public function customize_preview_base() {
 352          ?><base href="<?php echo home_url( '/' ); ?>" /><?php
 353      }
 354  
 355      /**
 356       * Print a workaround to handle HTML5 tags in IE < 9
 357       *
 358       * @since 3.4.0
 359       */
 360  	public function customize_preview_html5() { ?>
 361          <!--[if lt IE 9]>
 362          <script type="text/javascript">
 363              var e = [ 'abbr', 'article', 'aside', 'audio', 'canvas', 'datalist', 'details',
 364                  'figure', 'footer', 'header', 'hgroup', 'mark', 'menu', 'meter', 'nav',
 365                  'output', 'progress', 'section', 'time', 'video' ];
 366              for ( var i = 0; i < e.length; i++ ) {
 367                  document.createElement( e[i] );
 368              }
 369          </script>
 370          <![endif]--><?php
 371      }
 372  
 373      /**
 374       * Print javascript settings for preview frame.
 375       *
 376       * @since 3.4.0
 377       */
 378  	public function customize_preview_settings() {
 379          $settings = array(
 380              'values'  => array(),
 381              'channel' => esc_js( $_POST['customize_messenger_channel'] ),
 382          );
 383  
 384          if ( 2 == $this->nonce_tick ) {
 385              $settings['nonce'] = array(
 386                  'save' => wp_create_nonce( 'save-customize_' . $this->get_stylesheet() ),
 387                  'preview' => wp_create_nonce( 'preview-customize_' . $this->get_stylesheet() )
 388              );
 389          }
 390  
 391          foreach ( $this->settings as $id => $setting ) {
 392              $settings['values'][ $id ] = $setting->js_value();
 393          }
 394  
 395          ?>
 396          <script type="text/javascript">
 397              var _wpCustomizeSettings = <?php echo json_encode( $settings ); ?>;
 398          </script>
 399          <?php
 400      }
 401  
 402      /**
 403       * Prints a signature so we can ensure the customizer was properly executed.
 404       *
 405       * @since 3.4.0
 406       */
 407  	public function customize_preview_signature() {
 408          echo 'WP_CUSTOMIZER_SIGNATURE';
 409      }
 410  
 411      /**
 412       * Removes the signature in case we experience a case where the customizer was not properly executed.
 413       *
 414       * @since 3.4.0
 415       */
 416  	public function remove_preview_signature( $return = null ) {
 417          remove_action( 'shutdown', array( $this, 'customize_preview_signature' ), 1000 );
 418  
 419          return $return;
 420      }
 421  
 422      /**
 423       * Is it a theme preview?
 424       *
 425       * @since 3.4.0
 426       *
 427       * @return bool True if it's a preview, false if not.
 428       */
 429  	public function is_preview() {
 430          return (bool) $this->previewing;
 431      }
 432  
 433      /**
 434       * Retrieve the template name of the previewed theme.
 435       *
 436       * @since 3.4.0
 437       *
 438       * @return string Template name.
 439       */
 440  	public function get_template() {
 441          return $this->theme()->get_template();
 442      }
 443  
 444      /**
 445       * Retrieve the stylesheet name of the previewed theme.
 446       *
 447       * @since 3.4.0
 448       *
 449       * @return string Stylesheet name.
 450       */
 451  	public function get_stylesheet() {
 452          return $this->theme()->get_stylesheet();
 453      }
 454  
 455      /**
 456       * Retrieve the template root of the previewed theme.
 457       *
 458       * @since 3.4.0
 459       *
 460       * @return string Theme root.
 461       */
 462  	public function get_template_root() {
 463          return get_raw_theme_root( $this->get_template(), true );
 464      }
 465  
 466      /**
 467       * Retrieve the stylesheet root of the previewed theme.
 468       *
 469       * @since 3.4.0
 470       *
 471       * @return string Theme root.
 472       */
 473  	public function get_stylesheet_root() {
 474          return get_raw_theme_root( $this->get_stylesheet(), true );
 475      }
 476  
 477      /**
 478       * Filter the current theme and return the name of the previewed theme.
 479       *
 480       * @since 3.4.0
 481       *
 482       * @param $current_theme {@internal Parameter is not used}
 483       * @return string Theme name.
 484       */
 485  	public function current_theme( $current_theme ) {
 486          return $this->theme()->display('Name');
 487      }
 488  
 489      /**
 490       * Switch the theme and trigger the save action of each setting.
 491       *
 492       * @since 3.4.0
 493       */
 494  	public function save() {
 495          if ( ! $this->is_preview() )
 496              die;
 497  
 498          check_ajax_referer( 'save-customize_' . $this->get_stylesheet(), 'nonce' );
 499  
 500          // Do we have to switch themes?
 501          if ( ! $this->is_theme_active() ) {
 502              // Temporarily stop previewing the theme to allow switch_themes()
 503              // to operate properly.
 504              $this->stop_previewing_theme();
 505              switch_theme( $this->get_stylesheet() );
 506              $this->start_previewing_theme();
 507          }
 508  
 509          do_action( 'customize_save', $this );
 510  
 511          foreach ( $this->settings as $setting ) {
 512              $setting->save();
 513          }
 514  
 515          do_action( 'customize_save_after', $this );
 516  
 517          die;
 518      }
 519  
 520      /**
 521       * Add a customize setting.
 522       *
 523       * @since 3.4.0
 524       *
 525       * @param string $id A specific ID of the setting. Can be a
 526       *                   theme mod or option name.
 527       * @param array $args Setting arguments.
 528       */
 529  	public function add_setting( $id, $args = array() ) {
 530          if ( is_a( $id, 'WP_Customize_Setting' ) )
 531              $setting = $id;
 532          else
 533              $setting = new WP_Customize_Setting( $this, $id, $args );
 534  
 535          $this->settings[ $setting->id ] = $setting;
 536      }
 537  
 538      /**
 539       * Retrieve a customize setting.
 540       *
 541       * @since 3.4.0
 542       *
 543       * @param string $id A specific ID of the setting.
 544       * @return object The settings object.
 545       */
 546  	public function get_setting( $id ) {
 547          if ( isset( $this->settings[ $id ] ) )
 548              return $this->settings[ $id ];
 549      }
 550  
 551      /**
 552       * Remove a customize setting.
 553       *
 554       * @since 3.4.0
 555       *
 556       * @param string $id A specific ID of the setting.
 557       */
 558  	public function remove_setting( $id ) {
 559          unset( $this->settings[ $id ] );
 560      }
 561  
 562      /**
 563       * Add a customize section.
 564       *
 565       * @since 3.4.0
 566       *
 567       * @param string $id A specific ID of the section.
 568       * @param array $args Section arguments.
 569       */
 570  	public function add_section( $id, $args = array() ) {
 571          if ( is_a( $id, 'WP_Customize_Section' ) )
 572              $section = $id;
 573          else
 574              $section = new WP_Customize_Section( $this, $id, $args );
 575  
 576          $this->sections[ $section->id ] = $section;
 577      }
 578  
 579      /**
 580       * Retrieve a customize section.
 581       *
 582       * @since 3.4.0
 583       *
 584       * @param string $id A specific ID of the section.
 585       * @return object The section object.
 586       */
 587  	public function get_section( $id ) {
 588          if ( isset( $this->sections[ $id ] ) )
 589              return $this->sections[ $id ];
 590      }
 591  
 592      /**
 593       * Remove a customize section.
 594       *
 595       * @since 3.4.0
 596       *
 597       * @param string $id A specific ID of the section.
 598       */
 599  	public function remove_section( $id ) {
 600          unset( $this->sections[ $id ] );
 601      }
 602  
 603      /**
 604       * Add a customize control.
 605       *
 606       * @since 3.4.0
 607       *
 608       * @param string $id A specific ID of the control.
 609       * @param array $args Setting arguments.
 610       */
 611  	public function add_control( $id, $args = array() ) {
 612          if ( is_a( $id, 'WP_Customize_Control' ) )
 613              $control = $id;
 614          else
 615              $control = new WP_Customize_Control( $this, $id, $args );
 616  
 617          $this->controls[ $control->id ] = $control;
 618      }
 619  
 620      /**
 621       * Retrieve a customize control.
 622       *
 623       * @since 3.4.0
 624       *
 625       * @param string $id A specific ID of the control.
 626       * @return object The settings object.
 627       */
 628  	public function get_control( $id ) {
 629          if ( isset( $this->controls[ $id ] ) )
 630              return $this->controls[ $id ];
 631      }
 632  
 633      /**
 634       * Remove a customize setting.
 635       *
 636       * @since 3.4.0
 637       *
 638       * @param string $id A specific ID of the control.
 639       */
 640  	public function remove_control( $id ) {
 641          unset( $this->controls[ $id ] );
 642      }
 643  
 644      /**
 645       * Helper function to compare two objects by priority.
 646       *
 647       * @since 3.4.0
 648       *
 649       * @param object $a Object A.
 650       * @param object $b Object B.
 651       * @return int
 652       */
 653  	protected final function _cmp_priority( $a, $b ) {
 654          $ap = $a->priority;
 655          $bp = $b->priority;
 656  
 657          if ( $ap == $bp )
 658              return 0;
 659          return ( $ap > $bp ) ? 1 : -1;
 660      }
 661  
 662      /**
 663       * Prepare settings and sections.
 664       *
 665       * @since 3.4.0
 666       */
 667  	public function prepare_controls() {
 668          // Prepare controls
 669          // Reversing makes uasort sort by time added when conflicts occur.
 670  
 671          $this->controls = array_reverse( $this->controls );
 672          $controls = array();
 673  
 674          foreach ( $this->controls as $id => $control ) {
 675              if ( ! isset( $this->sections[ $control->section ] ) || ! $control->check_capabilities() )
 676                  continue;
 677  
 678              $this->sections[ $control->section ]->controls[] = $control;
 679              $controls[ $id ] = $control;
 680          }
 681          $this->controls = $controls;
 682  
 683          // Prepare sections
 684          $this->sections = array_reverse( $this->sections );
 685          uasort( $this->sections, array( $this, '_cmp_priority' ) );
 686          $sections = array();
 687  
 688          foreach ( $this->sections as $section ) {
 689              if ( ! $section->check_capabilities() || ! $section->controls )
 690                  continue;
 691  
 692              usort( $section->controls, array( $this, '_cmp_priority' ) );
 693              $sections[] = $section;
 694          }
 695          $this->sections = $sections;
 696      }
 697  
 698      /**
 699       * Enqueue scripts for customize controls.
 700       *
 701       * @since 3.4.0
 702       */
 703  	public function enqueue_control_scripts() {
 704          foreach ( $this->controls as $control ) {
 705              $control->enqueue();
 706          }
 707      }
 708  
 709      /**
 710       * Register some default controls.
 711       *
 712       * @since 3.4.0
 713       */
 714  	public function register_controls() {
 715  
 716          /* Site Title & Tagline */
 717  
 718          $this->add_section( 'title_tagline', array(
 719              'title'    => __( 'Site Title & Tagline' ),
 720              'priority' => 20,
 721          ) );
 722  
 723          $this->add_setting( 'blogname', array(
 724              'default'    => get_option( 'blogname' ),
 725              'type'       => 'option',
 726              'capability' => 'manage_options',
 727          ) );
 728  
 729          $this->add_control( 'blogname', array(
 730              'label'      => __( 'Site Title' ),
 731              'section'    => 'title_tagline',
 732          ) );
 733  
 734          $this->add_setting( 'blogdescription', array(
 735              'default'    => get_option( 'blogdescription' ),
 736              'type'       => 'option',
 737              'capability' => 'manage_options',
 738          ) );
 739  
 740          $this->add_control( 'blogdescription', array(
 741              'label'      => __( 'Tagline' ),
 742              'section'    => 'title_tagline',
 743          ) );
 744  
 745          /* Colors */
 746  
 747          $this->add_section( 'colors', array(
 748              'title'          => __( 'Colors' ),
 749              'priority'       => 40,
 750          ) );
 751  
 752          $this->add_setting( 'header_textcolor', array(
 753              'theme_supports' => array( 'custom-header', 'header-text' ),
 754              'default'        => get_theme_support( 'custom-header', 'default-text-color' ),
 755  
 756              'sanitize_callback'    => array( $this, '_sanitize_header_textcolor' ),
 757              'sanitize_js_callback' => 'maybe_hash_hex_color',
 758          ) );
 759  
 760          // Input type: checkbox
 761          // With custom value
 762          $this->add_control( 'display_header_text', array(
 763              'settings' => 'header_textcolor',
 764              'label'    => __( 'Display Header Text' ),
 765              'section'  => 'title_tagline',
 766              'type'     => 'checkbox',
 767          ) );
 768  
 769          $this->add_control( new WP_Customize_Color_Control( $this, 'header_textcolor', array(
 770              'label'   => __( 'Header Text Color' ),
 771              'section' => 'colors',
 772          ) ) );
 773  
 774          // Input type: Color
 775          // With sanitize_callback
 776          $this->add_setting( 'background_color', array(
 777              'default'        => get_theme_support( 'custom-background', 'default-color' ),
 778              'theme_supports' => 'custom-background',
 779  
 780              'sanitize_callback'    => 'sanitize_hex_color_no_hash',
 781              'sanitize_js_callback' => 'maybe_hash_hex_color',
 782          ) );
 783  
 784          $this->add_control( new WP_Customize_Color_Control( $this, 'background_color', array(
 785              'label'   => __( 'Background Color' ),
 786              'section' => 'colors',
 787          ) ) );
 788  
 789  
 790          /* Custom Header */
 791  
 792          $this->add_section( 'header_image', array(
 793              'title'          => __( 'Header Image' ),
 794              'theme_supports' => 'custom-header',
 795              'priority'       => 60,
 796          ) );
 797  
 798          $this->add_setting( new WP_Customize_Filter_Setting( $this, 'header_image', array(
 799              'default'        => get_theme_support( 'custom-header', 'default-image' ),
 800              'theme_supports' => 'custom-header',
 801          ) ) );
 802  
 803          $this->add_setting( new WP_Customize_Header_Image_Setting( $this, 'header_image_data', array(
 804              // 'default'        => get_theme_support( 'custom-header', 'default-image' ),
 805              'theme_supports' => 'custom-header',
 806          ) ) );
 807  
 808          $this->add_control( new WP_Customize_Header_Image_Control( $this ) );
 809  
 810          /* Custom Background */
 811  
 812          $this->add_section( 'background_image', array(
 813              'title'          => __( 'Background Image' ),
 814              'theme_supports' => 'custom-background',
 815              'priority'       => 80,
 816          ) );
 817  
 818          $this->add_setting( 'background_image', array(
 819              'default'        => get_theme_support( 'custom-background', 'default-image' ),
 820              'theme_supports' => 'custom-background',
 821          ) );
 822  
 823          $this->add_setting( new WP_Customize_Background_Image_Setting( $this, 'background_image_thumb', array(
 824              'theme_supports' => 'custom-background',
 825          ) ) );
 826  
 827          $this->add_control( new WP_Customize_Background_Image_Control( $this ) );
 828  
 829          $this->add_setting( 'background_repeat', array(
 830              'default'        => 'repeat',
 831              'theme_supports' => 'custom-background',
 832          ) );
 833  
 834          $this->add_control( 'background_repeat', array(
 835              'label'      => __( 'Background Repeat' ),
 836              'section'    => 'background_image',
 837              'type'       => 'radio',
 838              'choices'    => array(
 839                  'no-repeat'  => __('No Repeat'),
 840                  'repeat'     => __('Tile'),
 841                  'repeat-x'   => __('Tile Horizontally'),
 842                  'repeat-y'   => __('Tile Vertically'),
 843              ),
 844          ) );
 845  
 846          $this->add_setting( 'background_position_x', array(
 847              'default'        => 'left',
 848              'theme_supports' => 'custom-background',
 849          ) );
 850  
 851          $this->add_control( 'background_position_x', array(
 852              'label'      => __( 'Background Position' ),
 853              'section'    => 'background_image',
 854              'type'       => 'radio',
 855              'choices'    => array(
 856                  'left'       => __('Left'),
 857                  'center'     => __('Center'),
 858                  'right'      => __('Right'),
 859              ),
 860          ) );
 861  
 862          $this->add_setting( 'background_attachment', array(
 863              'default'        => 'fixed',
 864              'theme_supports' => 'custom-background',
 865          ) );
 866  
 867          $this->add_control( 'background_attachment', array(
 868              'label'      => __( 'Background Attachment' ),
 869              'section'    => 'background_image',
 870              'type'       => 'radio',
 871              'choices'    => array(
 872                  'fixed'      => __('Fixed'),
 873                  'scroll'     => __('Scroll'),
 874              ),
 875          ) );
 876  
 877          // If the theme is using the default background callback, we can update
 878          // the background CSS using postMessage.
 879          if ( get_theme_support( 'custom-background', 'wp-head-callback' ) === '_custom_background_cb' ) {
 880              foreach ( array( 'color', 'image', 'position_x', 'repeat', 'attachment' ) as $prop ) {
 881                  $this->get_setting( 'background_' . $prop )->transport = 'postMessage';
 882              }
 883          }
 884  
 885          /* Nav Menus */
 886  
 887          $locations      = get_registered_nav_menus();
 888          $menus          = wp_get_nav_menus();
 889          $menu_locations = get_nav_menu_locations();
 890          $num_locations  = count( array_keys( $locations ) );
 891  
 892          $this->add_section( 'nav', array(
 893              'title'          => __( 'Navigation' ),
 894              'theme_supports' => 'menus',
 895              'priority'       => 100,
 896              'description'    => sprintf( _n('Your theme supports %s menu. Select which menu you would like to use.', 'Your theme supports %s menus. Select which menu appears in each location.', $num_locations ), number_format_i18n( $num_locations ) ) . "\n\n" . __('You can edit your menu content on the Menus screen in the Appearance section.'),
 897          ) );
 898  
 899          if ( $menus ) {
 900              $choices = array( 0 => __( '&mdash; Select &mdash;' ) );
 901              foreach ( $menus as $menu ) {
 902                  $choices[ $menu->term_id ] = wp_html_excerpt( $menu->name, 40, '&hellip;' );
 903              }
 904  
 905              foreach ( $locations as $location => $description ) {
 906                  $menu_setting_id = "nav_menu_locations[{$location}]";
 907  
 908                  $this->add_setting( $menu_setting_id, array(
 909                      'sanitize_callback' => 'absint',
 910                      'theme_supports'    => 'menus',
 911                  ) );
 912  
 913                  $this->add_control( $menu_setting_id, array(
 914                      'label'   => $description,
 915                      'section' => 'nav',
 916                      'type'    => 'select',
 917                      'choices' => $choices,
 918                  ) );
 919              }
 920          }
 921  
 922          /* Static Front Page */
 923          // #WP19627
 924  
 925          $this->add_section( 'static_front_page', array(
 926              'title'          => __( 'Static Front Page' ),
 927          //    'theme_supports' => 'static-front-page',
 928              'priority'       => 120,
 929              'description'    => __( 'Your theme supports a static front page.' ),
 930          ) );
 931  
 932          $this->add_setting( 'show_on_front', array(
 933              'default'        => get_option( 'show_on_front' ),
 934              'capability'     => 'manage_options',
 935              'type'           => 'option',
 936          //    'theme_supports' => 'static-front-page',
 937          ) );
 938  
 939          $this->add_control( 'show_on_front', array(
 940              'label'   => __( 'Front page displays' ),
 941              'section' => 'static_front_page',
 942              'type'    => 'radio',
 943              'choices' => array(
 944                  'posts' => __( 'Your latest posts' ),
 945                  'page'  => __( 'A static page' ),
 946              ),
 947          ) );
 948  
 949          $this->add_setting( 'page_on_front', array(
 950              'type'       => 'option',
 951              'capability' => 'manage_options',
 952          //    'theme_supports' => 'static-front-page',
 953          ) );
 954  
 955          $this->add_control( 'page_on_front', array(
 956              'label'      => __( 'Front page' ),
 957              'section'    => 'static_front_page',
 958              'type'       => 'dropdown-pages',
 959          ) );
 960  
 961          $this->add_setting( 'page_for_posts', array(
 962              'type'           => 'option',
 963              'capability'     => 'manage_options',
 964          //    'theme_supports' => 'static-front-page',
 965          ) );
 966  
 967          $this->add_control( 'page_for_posts', array(
 968              'label'      => __( 'Posts page' ),
 969              'section'    => 'static_front_page',
 970              'type'       => 'dropdown-pages',
 971          ) );
 972      }
 973  
 974      /**
 975       * Callback for validating the header_textcolor value.
 976       *
 977       * Accepts 'blank', and otherwise uses sanitize_hex_color_no_hash().
 978       * Returns default text color if hex color is empty.
 979       *
 980       * @since 3.4.0
 981       *
 982       * @param string $color
 983       * @return string
 984       */
 985  	public function _sanitize_header_textcolor( $color ) {
 986          if ( 'blank' === $color )
 987              return 'blank';
 988  
 989          $color = sanitize_hex_color_no_hash( $color );
 990          if ( empty( $color ) )
 991              $color = get_theme_support( 'custom-header', 'default-text-color' );
 992  
 993          return $color;
 994      }
 995  };
 996  
 997  /**
 998   * Validates a hex color.
 999   *
1000   * Returns either '', a 3 or 6 digit hex color (with #), or null.
1001   * For validating values without a #, see sanitize_hex_color_no_hash().
1002   *
1003   * @since 3.4.0
1004   *
1005   * @param string $color
1006   * @return string|null
1007   */
1008  function sanitize_hex_color( $color ) {
1009      if ( '' === $color )
1010          return '';
1011  
1012      // 3 or 6 hex digits, or the empty string.
1013      if ( preg_match('|^#([A-Fa-f0-9]{3}){1,2}$|', $color ) )
1014          return $color;
1015  
1016      return null;
1017  }
1018  
1019  /**
1020   * Sanitizes a hex color without a hash. Use sanitize_hex_color() when possible.
1021   *
1022   * Saving hex colors without a hash puts the burden of adding the hash on the
1023   * UI, which makes it difficult to use or upgrade to other color types such as
1024   * rgba, hsl, rgb, and html color names.
1025   *
1026   * Returns either '', a 3 or 6 digit hex color (without a #), or null.
1027   *
1028   * @since 3.4.0
1029   * @uses sanitize_hex_color()
1030   *
1031   * @param string $color
1032   * @return string|null
1033   */
1034  function sanitize_hex_color_no_hash( $color ) {
1035      $color = ltrim( $color, '#' );
1036  
1037      if ( '' === $color )
1038          return '';
1039  
1040      return sanitize_hex_color( '#' . $color ) ? $color : null;
1041  }
1042  
1043  /**
1044   * Ensures that any hex color is properly hashed.
1045   * Otherwise, returns value untouched.
1046   *
1047   * This method should only be necessary if using sanitize_hex_color_no_hash().
1048   *
1049   * @since 3.4.0
1050   *
1051   * @param string $color
1052   * @return string
1053   */
1054  function maybe_hash_hex_color( $color ) {
1055      if ( $unhashed = sanitize_hex_color_no_hash( $color ) )
1056          return '#' . $unhashed;
1057  
1058      return $color;
1059  }


Generated: Tue Mar 25 01:41:18 2014 WordPress honlapkészítés: online1.hu