PageRenderTime 73ms CodeModel.GetById 35ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-includes/class-wp-customize-control.php

https://gitlab.com/geyson/geyson
PHP | 1971 lines | 944 code | 187 blank | 840 comment | 48 complexity | 9d7f78d6cbec490603b934c9f5c6a34b MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * WordPress Customize Control classes
  4. *
  5. * @package WordPress
  6. * @subpackage Customize
  7. * @since 3.4.0
  8. */
  9. /**
  10. * Customize Control class.
  11. *
  12. * @since 3.4.0
  13. */
  14. class WP_Customize_Control {
  15. /**
  16. * Incremented with each new class instantiation, then stored in $instance_number.
  17. *
  18. * Used when sorting two instances whose priorities are equal.
  19. *
  20. * @since 4.1.0
  21. *
  22. * @static
  23. * @access protected
  24. * @var int
  25. */
  26. protected static $instance_count = 0;
  27. /**
  28. * Order in which this instance was created in relation to other instances.
  29. *
  30. * @since 4.1.0
  31. * @access public
  32. * @var int
  33. */
  34. public $instance_number;
  35. /**
  36. * @access public
  37. * @var WP_Customize_Manager
  38. */
  39. public $manager;
  40. /**
  41. * @access public
  42. * @var string
  43. */
  44. public $id;
  45. /**
  46. * All settings tied to the control.
  47. *
  48. * @access public
  49. * @var array
  50. */
  51. public $settings;
  52. /**
  53. * The primary setting for the control (if there is one).
  54. *
  55. * @access public
  56. * @var string
  57. */
  58. public $setting = 'default';
  59. /**
  60. * @access public
  61. * @var int
  62. */
  63. public $priority = 10;
  64. /**
  65. * @access public
  66. * @var string
  67. */
  68. public $section = '';
  69. /**
  70. * @access public
  71. * @var string
  72. */
  73. public $label = '';
  74. /**
  75. * @access public
  76. * @var string
  77. */
  78. public $description = '';
  79. /**
  80. * @todo: Remove choices
  81. *
  82. * @access public
  83. * @var array
  84. */
  85. public $choices = array();
  86. /**
  87. * @access public
  88. * @var array
  89. */
  90. public $input_attrs = array();
  91. /**
  92. * @deprecated It is better to just call the json() method
  93. * @access public
  94. * @var array
  95. */
  96. public $json = array();
  97. /**
  98. * @access public
  99. * @var string
  100. */
  101. public $type = 'text';
  102. /**
  103. * Callback.
  104. *
  105. * @since 4.0.0
  106. * @access public
  107. *
  108. * @see WP_Customize_Control::active()
  109. *
  110. * @var callable Callback is called with one argument, the instance of
  111. * WP_Customize_Control, and returns bool to indicate whether
  112. * the control is active (such as it relates to the URL
  113. * currently being previewed).
  114. */
  115. public $active_callback = '';
  116. /**
  117. * Constructor.
  118. *
  119. * Supplied $args override class property defaults.
  120. *
  121. * If $args['settings'] is not defined, use the $id as the setting ID.
  122. *
  123. * @since 3.4.0
  124. *
  125. * @param WP_Customize_Manager $manager Customizer bootstrap instance.
  126. * @param string $id Control ID.
  127. * @param array $args Optional. Arguments to override class property defaults.
  128. */
  129. public function __construct( $manager, $id, $args = array() ) {
  130. $keys = array_keys( get_object_vars( $this ) );
  131. foreach ( $keys as $key ) {
  132. if ( isset( $args[ $key ] ) ) {
  133. $this->$key = $args[ $key ];
  134. }
  135. }
  136. $this->manager = $manager;
  137. $this->id = $id;
  138. if ( empty( $this->active_callback ) ) {
  139. $this->active_callback = array( $this, 'active_callback' );
  140. }
  141. self::$instance_count += 1;
  142. $this->instance_number = self::$instance_count;
  143. // Process settings.
  144. if ( empty( $this->settings ) ) {
  145. $this->settings = $id;
  146. }
  147. $settings = array();
  148. if ( is_array( $this->settings ) ) {
  149. foreach ( $this->settings as $key => $setting ) {
  150. $settings[ $key ] = $this->manager->get_setting( $setting );
  151. }
  152. } else {
  153. $this->setting = $this->manager->get_setting( $this->settings );
  154. $settings['default'] = $this->setting;
  155. }
  156. $this->settings = $settings;
  157. }
  158. /**
  159. * Enqueue control related scripts/styles.
  160. *
  161. * @since 3.4.0
  162. */
  163. public function enqueue() {}
  164. /**
  165. * Check whether control is active to current Customizer preview.
  166. *
  167. * @since 4.0.0
  168. * @access public
  169. *
  170. * @return bool Whether the control is active to the current preview.
  171. */
  172. final public function active() {
  173. $control = $this;
  174. $active = call_user_func( $this->active_callback, $this );
  175. /**
  176. * Filter response of WP_Customize_Control::active().
  177. *
  178. * @since 4.0.0
  179. *
  180. * @param bool $active Whether the Customizer control is active.
  181. * @param WP_Customize_Control $control WP_Customize_Control instance.
  182. */
  183. $active = apply_filters( 'customize_control_active', $active, $control );
  184. return $active;
  185. }
  186. /**
  187. * Default callback used when invoking WP_Customize_Control::active().
  188. *
  189. * Subclasses can override this with their specific logic, or they may
  190. * provide an 'active_callback' argument to the constructor.
  191. *
  192. * @since 4.0.0
  193. * @access public
  194. *
  195. * @return true Always true.
  196. */
  197. public function active_callback() {
  198. return true;
  199. }
  200. /**
  201. * Fetch a setting's value.
  202. * Grabs the main setting by default.
  203. *
  204. * @since 3.4.0
  205. *
  206. * @param string $setting_key
  207. * @return mixed The requested setting's value, if the setting exists.
  208. */
  209. final public function value( $setting_key = 'default' ) {
  210. if ( isset( $this->settings[ $setting_key ] ) ) {
  211. return $this->settings[ $setting_key ]->value();
  212. }
  213. }
  214. /**
  215. * Refresh the parameters passed to the JavaScript via JSON.
  216. *
  217. * @since 3.4.0
  218. */
  219. public function to_json() {
  220. $this->json['settings'] = array();
  221. foreach ( $this->settings as $key => $setting ) {
  222. $this->json['settings'][ $key ] = $setting->id;
  223. }
  224. $this->json['type'] = $this->type;
  225. $this->json['priority'] = $this->priority;
  226. $this->json['active'] = $this->active();
  227. $this->json['section'] = $this->section;
  228. $this->json['content'] = $this->get_content();
  229. $this->json['label'] = $this->label;
  230. $this->json['description'] = $this->description;
  231. $this->json['instanceNumber'] = $this->instance_number;
  232. }
  233. /**
  234. * Get the data to export to the client via JSON.
  235. *
  236. * @since 4.1.0
  237. *
  238. * @return array Array of parameters passed to the JavaScript.
  239. */
  240. public function json() {
  241. $this->to_json();
  242. return $this->json;
  243. }
  244. /**
  245. * Check if the theme supports the control and check user capabilities.
  246. *
  247. * @since 3.4.0
  248. *
  249. * @return bool False if theme doesn't support the control or user doesn't have the required permissions, otherwise true.
  250. */
  251. final public function check_capabilities() {
  252. foreach ( $this->settings as $setting ) {
  253. if ( ! $setting->check_capabilities() )
  254. return false;
  255. }
  256. $section = $this->manager->get_section( $this->section );
  257. if ( isset( $section ) && ! $section->check_capabilities() )
  258. return false;
  259. return true;
  260. }
  261. /**
  262. * Get the control's content for insertion into the Customizer pane.
  263. *
  264. * @since 4.1.0
  265. *
  266. * @return string Contents of the control.
  267. */
  268. final public function get_content() {
  269. ob_start();
  270. $this->maybe_render();
  271. return trim( ob_get_clean() );
  272. }
  273. /**
  274. * Check capabilities and render the control.
  275. *
  276. * @since 3.4.0
  277. * @uses WP_Customize_Control::render()
  278. */
  279. final public function maybe_render() {
  280. if ( ! $this->check_capabilities() )
  281. return;
  282. /**
  283. * Fires just before the current Customizer control is rendered.
  284. *
  285. * @since 3.4.0
  286. *
  287. * @param WP_Customize_Control $this WP_Customize_Control instance.
  288. */
  289. do_action( 'customize_render_control', $this );
  290. /**
  291. * Fires just before a specific Customizer control is rendered.
  292. *
  293. * The dynamic portion of the hook name, `$this->id`, refers to
  294. * the control ID.
  295. *
  296. * @since 3.4.0
  297. *
  298. * @param WP_Customize_Control $this {@see WP_Customize_Control} instance.
  299. */
  300. do_action( 'customize_render_control_' . $this->id, $this );
  301. $this->render();
  302. }
  303. /**
  304. * Renders the control wrapper and calls $this->render_content() for the internals.
  305. *
  306. * @since 3.4.0
  307. */
  308. protected function render() {
  309. $id = 'customize-control-' . str_replace( '[', '-', str_replace( ']', '', $this->id ) );
  310. $class = 'customize-control customize-control-' . $this->type;
  311. ?><li id="<?php echo esc_attr( $id ); ?>" class="<?php echo esc_attr( $class ); ?>">
  312. <?php $this->render_content(); ?>
  313. </li><?php
  314. }
  315. /**
  316. * Get the data link attribute for a setting.
  317. *
  318. * @since 3.4.0
  319. *
  320. * @param string $setting_key
  321. * @return string Data link parameter, if $setting_key is a valid setting, empty string otherwise.
  322. */
  323. public function get_link( $setting_key = 'default' ) {
  324. if ( ! isset( $this->settings[ $setting_key ] ) )
  325. return '';
  326. return 'data-customize-setting-link="' . esc_attr( $this->settings[ $setting_key ]->id ) . '"';
  327. }
  328. /**
  329. * Render the data link attribute for the control's input element.
  330. *
  331. * @since 3.4.0
  332. * @uses WP_Customize_Control::get_link()
  333. *
  334. * @param string $setting_key
  335. */
  336. public function link( $setting_key = 'default' ) {
  337. echo $this->get_link( $setting_key );
  338. }
  339. /**
  340. * Render the custom attributes for the control's input element.
  341. *
  342. * @since 4.0.0
  343. * @access public
  344. */
  345. public function input_attrs() {
  346. foreach( $this->input_attrs as $attr => $value ) {
  347. echo $attr . '="' . esc_attr( $value ) . '" ';
  348. }
  349. }
  350. /**
  351. * Render the control's content.
  352. *
  353. * Allows the content to be overriden without having to rewrite the wrapper in $this->render().
  354. *
  355. * Supports basic input types `text`, `checkbox`, `textarea`, `radio`, `select` and `dropdown-pages`.
  356. * Additional input types such as `email`, `url`, `number`, `hidden` and `date` are supported implicitly.
  357. *
  358. * Control content can alternately be rendered in JS. See {@see WP_Customize_Control::print_template()}.
  359. *
  360. * @since 3.4.0
  361. */
  362. protected function render_content() {
  363. switch( $this->type ) {
  364. case 'checkbox':
  365. ?>
  366. <label>
  367. <input type="checkbox" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); checked( $this->value() ); ?> />
  368. <?php echo esc_html( $this->label ); ?>
  369. <?php if ( ! empty( $this->description ) ) : ?>
  370. <span class="description customize-control-description"><?php echo $this->description; ?></span>
  371. <?php endif; ?>
  372. </label>
  373. <?php
  374. break;
  375. case 'radio':
  376. if ( empty( $this->choices ) )
  377. return;
  378. $name = '_customize-radio-' . $this->id;
  379. if ( ! empty( $this->label ) ) : ?>
  380. <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
  381. <?php endif;
  382. if ( ! empty( $this->description ) ) : ?>
  383. <span class="description customize-control-description"><?php echo $this->description ; ?></span>
  384. <?php endif;
  385. foreach ( $this->choices as $value => $label ) :
  386. ?>
  387. <label>
  388. <input type="radio" value="<?php echo esc_attr( $value ); ?>" name="<?php echo esc_attr( $name ); ?>" <?php $this->link(); checked( $this->value(), $value ); ?> />
  389. <?php echo esc_html( $label ); ?><br/>
  390. </label>
  391. <?php
  392. endforeach;
  393. break;
  394. case 'select':
  395. if ( empty( $this->choices ) )
  396. return;
  397. ?>
  398. <label>
  399. <?php if ( ! empty( $this->label ) ) : ?>
  400. <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
  401. <?php endif;
  402. if ( ! empty( $this->description ) ) : ?>
  403. <span class="description customize-control-description"><?php echo $this->description; ?></span>
  404. <?php endif; ?>
  405. <select <?php $this->link(); ?>>
  406. <?php
  407. foreach ( $this->choices as $value => $label )
  408. echo '<option value="' . esc_attr( $value ) . '"' . selected( $this->value(), $value, false ) . '>' . $label . '</option>';
  409. ?>
  410. </select>
  411. </label>
  412. <?php
  413. break;
  414. case 'textarea':
  415. ?>
  416. <label>
  417. <?php if ( ! empty( $this->label ) ) : ?>
  418. <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
  419. <?php endif;
  420. if ( ! empty( $this->description ) ) : ?>
  421. <span class="description customize-control-description"><?php echo $this->description; ?></span>
  422. <?php endif; ?>
  423. <textarea rows="5" <?php $this->link(); ?>><?php echo esc_textarea( $this->value() ); ?></textarea>
  424. </label>
  425. <?php
  426. break;
  427. case 'dropdown-pages':
  428. $dropdown = wp_dropdown_pages(
  429. array(
  430. 'name' => '_customize-dropdown-pages-' . $this->id,
  431. 'echo' => 0,
  432. 'show_option_none' => __( '&mdash; Select &mdash;' ),
  433. 'option_none_value' => '0',
  434. 'selected' => $this->value(),
  435. )
  436. );
  437. // Hackily add in the data link parameter.
  438. $dropdown = str_replace( '<select', '<select ' . $this->get_link(), $dropdown );
  439. printf(
  440. '<label class="customize-control-select"><span class="customize-control-title">%s</span> %s</label>',
  441. $this->label,
  442. $dropdown
  443. );
  444. break;
  445. default:
  446. ?>
  447. <label>
  448. <?php if ( ! empty( $this->label ) ) : ?>
  449. <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
  450. <?php endif;
  451. if ( ! empty( $this->description ) ) : ?>
  452. <span class="description customize-control-description"><?php echo $this->description; ?></span>
  453. <?php endif; ?>
  454. <input type="<?php echo esc_attr( $this->type ); ?>" <?php $this->input_attrs(); ?> value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); ?> />
  455. </label>
  456. <?php
  457. break;
  458. }
  459. }
  460. /**
  461. * Render the control's JS template.
  462. *
  463. * This function is only run for control types that have been registered with
  464. * {@see WP_Customize_Manager::register_control_type()}.
  465. *
  466. * In the future, this will also print the template for the control's container
  467. * element and be override-able.
  468. *
  469. * @since 4.1.0
  470. */
  471. final public function print_template() {
  472. ?>
  473. <script type="text/html" id="tmpl-customize-control-<?php echo $this->type; ?>-content">
  474. <?php $this->content_template(); ?>
  475. </script>
  476. <?php
  477. }
  478. /**
  479. * An Underscore (JS) template for this control's content (but not its container).
  480. *
  481. * Class variables for this control class are available in the `data` JS object;
  482. * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
  483. *
  484. * @see WP_Customize_Control::print_template()
  485. *
  486. * @since 4.1.0
  487. */
  488. protected function content_template() {}
  489. }
  490. /**
  491. * Customize Color Control class.
  492. *
  493. * @since 3.4.0
  494. *
  495. * @see WP_Customize_Control
  496. */
  497. class WP_Customize_Color_Control extends WP_Customize_Control {
  498. /**
  499. * @access public
  500. * @var string
  501. */
  502. public $type = 'color';
  503. /**
  504. * @access public
  505. * @var array
  506. */
  507. public $statuses;
  508. /**
  509. * Constructor.
  510. *
  511. * @since 3.4.0
  512. * @uses WP_Customize_Control::__construct()
  513. *
  514. * @param WP_Customize_Manager $manager Customizer bootstrap instance.
  515. * @param string $id Control ID.
  516. * @param array $args Optional. Arguments to override class property defaults.
  517. */
  518. public function __construct( $manager, $id, $args = array() ) {
  519. $this->statuses = array( '' => __('Default') );
  520. parent::__construct( $manager, $id, $args );
  521. }
  522. /**
  523. * Enqueue scripts/styles for the color picker.
  524. *
  525. * @since 3.4.0
  526. */
  527. public function enqueue() {
  528. wp_enqueue_script( 'wp-color-picker' );
  529. wp_enqueue_style( 'wp-color-picker' );
  530. }
  531. /**
  532. * Refresh the parameters passed to the JavaScript via JSON.
  533. *
  534. * @since 3.4.0
  535. * @uses WP_Customize_Control::to_json()
  536. */
  537. public function to_json() {
  538. parent::to_json();
  539. $this->json['statuses'] = $this->statuses;
  540. $this->json['defaultValue'] = $this->setting->default;
  541. }
  542. /**
  543. * Don't render the control content from PHP, as it's rendered via JS on load.
  544. *
  545. * @since 3.4.0
  546. */
  547. public function render_content() {}
  548. /**
  549. * Render a JS template for the content of the color picker control.
  550. *
  551. * @since 4.1.0
  552. */
  553. public function content_template() {
  554. ?>
  555. <# var defaultValue = '';
  556. if ( data.defaultValue ) {
  557. if ( '#' !== data.defaultValue.substring( 0, 1 ) ) {
  558. defaultValue = '#' + data.defaultValue;
  559. } else {
  560. defaultValue = data.defaultValue;
  561. }
  562. defaultValue = ' data-default-color=' + defaultValue; // Quotes added automatically.
  563. } #>
  564. <label>
  565. <# if ( data.label ) { #>
  566. <span class="customize-control-title">{{{ data.label }}}</span>
  567. <# } #>
  568. <# if ( data.description ) { #>
  569. <span class="description customize-control-description">{{{ data.description }}}</span>
  570. <# } #>
  571. <div class="customize-control-content">
  572. <input class="color-picker-hex" type="text" maxlength="7" placeholder="<?php esc_attr_e( 'Hex Value' ); ?>" {{ defaultValue }} />
  573. </div>
  574. </label>
  575. <?php
  576. }
  577. }
  578. /**
  579. * Customize Media Control class.
  580. *
  581. * @since 4.2.0
  582. *
  583. * @see WP_Customize_Control
  584. */
  585. class WP_Customize_Media_Control extends WP_Customize_Control {
  586. /**
  587. * Control type.
  588. *
  589. * @since 4.2.0
  590. * @access public
  591. * @var string
  592. */
  593. public $type = 'media';
  594. /**
  595. * Media control mime type.
  596. *
  597. * @since 4.2.0
  598. * @access public
  599. * @var string
  600. */
  601. public $mime_type = '';
  602. /**
  603. * Button labels.
  604. *
  605. * @since 4.2.0
  606. * @access public
  607. * @var array
  608. */
  609. public $button_labels = array();
  610. /**
  611. * Constructor.
  612. *
  613. * @since 4.1.0
  614. * @since 4.2.0 Moved from WP_Customize_Upload_Control.
  615. *
  616. * @param WP_Customize_Manager $manager Customizer bootstrap instance.
  617. * @param string $id Control ID.
  618. * @param array $args Optional. Arguments to override class property defaults.
  619. */
  620. public function __construct( $manager, $id, $args = array() ) {
  621. parent::__construct( $manager, $id, $args );
  622. $this->button_labels = array(
  623. 'select' => __( 'Select File' ),
  624. 'change' => __( 'Change File' ),
  625. 'default' => __( 'Default' ),
  626. 'remove' => __( 'Remove' ),
  627. 'placeholder' => __( 'No file selected' ),
  628. 'frame_title' => __( 'Select File' ),
  629. 'frame_button' => __( 'Choose File' ),
  630. );
  631. }
  632. /**
  633. * Enqueue control related scripts/styles.
  634. *
  635. * @since 3.4.0
  636. * @since 4.2.0 Moved from WP_Customize_Upload_Control.
  637. */
  638. public function enqueue() {
  639. wp_enqueue_media();
  640. }
  641. /**
  642. * Refresh the parameters passed to the JavaScript via JSON.
  643. *
  644. * @since 3.4.0
  645. * @since 4.2.0 Moved from WP_Customize_Upload_Control.
  646. *
  647. * @see WP_Customize_Control::to_json()
  648. */
  649. public function to_json() {
  650. parent::to_json();
  651. $this->json['label'] = html_entity_decode( $this->label, ENT_QUOTES, get_bloginfo( 'charset' ) );
  652. $this->json['mime_type'] = $this->mime_type;
  653. $this->json['button_labels'] = $this->button_labels;
  654. $this->json['canUpload'] = current_user_can( 'upload_files' );
  655. $value = $this->value();
  656. if ( is_object( $this->setting ) ) {
  657. if ( $this->setting->default ) {
  658. // Fake an attachment model - needs all fields used by template.
  659. // Note that the default value must be a URL, NOT an attachment ID.
  660. $type = in_array( substr( $this->setting->default, -3 ), array( 'jpg', 'png', 'gif', 'bmp' ) ) ? 'image' : 'document';
  661. $default_attachment = array(
  662. 'id' => 1,
  663. 'url' => $this->setting->default,
  664. 'type' => $type,
  665. 'icon' => wp_mime_type_icon( $type ),
  666. 'title' => basename( $this->setting->default ),
  667. );
  668. if ( 'image' === $type ) {
  669. $default_attachment['sizes'] = array(
  670. 'full' => array( 'url' => $this->setting->default ),
  671. );
  672. }
  673. $this->json['defaultAttachment'] = $default_attachment;
  674. }
  675. if ( $value && $this->setting->default && $value === $this->setting->default ) {
  676. // Set the default as the attachment.
  677. $this->json['attachment'] = $this->json['defaultAttachment'];
  678. } elseif ( $value ) {
  679. $this->json['attachment'] = wp_prepare_attachment_for_js( $value );
  680. }
  681. }
  682. }
  683. /**
  684. * Don't render any content for this control from PHP.
  685. *
  686. * @since 3.4.0
  687. * @since 4.2.0 Moved from WP_Customize_Upload_Control.
  688. *
  689. * @see WP_Customize_Media_Control::content_template()
  690. */
  691. public function render_content() {}
  692. /**
  693. * Render a JS template for the content of the media control.
  694. *
  695. * @since 4.1.0
  696. * @since 4.2.0 Moved from WP_Customize_Upload_Control.
  697. */
  698. public function content_template() {
  699. ?>
  700. <label for="{{ data.settings['default'] }}-button">
  701. <# if ( data.label ) { #>
  702. <span class="customize-control-title">{{ data.label }}</span>
  703. <# } #>
  704. <# if ( data.description ) { #>
  705. <span class="description customize-control-description">{{{ data.description }}}</span>
  706. <# } #>
  707. </label>
  708. <# if ( data.attachment && data.attachment.id ) { #>
  709. <div class="current">
  710. <div class="container">
  711. <div class="attachment-media-view attachment-media-view-{{ data.attachment.type }} {{ data.attachment.orientation }}">
  712. <div class="thumbnail thumbnail-{{ data.attachment.type }}">
  713. <# if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.medium ) { #>
  714. <img class="attachment-thumb" src="{{ data.attachment.sizes.medium.url }}" draggable="false" />
  715. <# } else if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.full ) { #>
  716. <img class="attachment-thumb" src="{{ data.attachment.sizes.full.url }}" draggable="false" />
  717. <# } else if ( 'audio' === data.attachment.type ) { #>
  718. <# if ( data.attachment.image && data.attachment.image.src && data.attachment.image.src !== data.attachment.icon ) { #>
  719. <img src="{{ data.attachment.image.src }}" class="thumbnail" draggable="false" />
  720. <# } else { #>
  721. <img src="{{ data.attachment.icon }}" class="attachment-thumb type-icon" draggable="false" />
  722. <# } #>
  723. <p class="attachment-meta attachment-meta-title">&#8220;{{ data.attachment.title }}&#8221;</p>
  724. <# if ( data.attachment.album || data.attachment.meta.album ) { #>
  725. <p class="attachment-meta"><em>{{ data.attachment.album || data.attachment.meta.album }}</em></p>
  726. <# } #>
  727. <# if ( data.attachment.artist || data.attachment.meta.artist ) { #>
  728. <p class="attachment-meta">{{ data.attachment.artist || data.attachment.meta.artist }}</p>
  729. <# } #>
  730. <audio style="visibility: hidden" controls class="wp-audio-shortcode" width="100%" preload="none">
  731. <source type="{{ data.attachment.mime }}" src="{{ data.attachment.url }}"/>
  732. </audio>
  733. <# } else if ( 'video' === data.attachment.type ) { #>
  734. <div class="wp-media-wrapper wp-video">
  735. <video controls="controls" class="wp-video-shortcode" preload="metadata"
  736. <# if ( data.attachment.image && data.attachment.image.src !== data.attachment.icon ) { #>poster="{{ data.attachment.image.src }}"<# } #>>
  737. <source type="{{ data.attachment.mime }}" src="{{ data.attachment.url }}"/>
  738. </video>
  739. </div>
  740. <# } else { #>
  741. <img class="attachment-thumb type-icon icon" src="{{ data.attachment.icon }}" draggable="false" />
  742. <p class="attachment-title">{{ data.attachment.title }}</p>
  743. <# } #>
  744. </div>
  745. </div>
  746. </div>
  747. </div>
  748. <div class="actions">
  749. <# if ( data.canUpload ) { #>
  750. <button type="button" class="button remove-button"><?php echo $this->button_labels['remove']; ?></button>
  751. <button type="button" class="button upload-button" id="{{ data.settings['default'] }}-button"><?php echo $this->button_labels['change']; ?></button>
  752. <div style="clear:both"></div>
  753. <# } #>
  754. </div>
  755. <# } else { #>
  756. <div class="current">
  757. <div class="container">
  758. <div class="placeholder">
  759. <div class="inner">
  760. <span>
  761. <?php echo $this->button_labels['placeholder']; ?>
  762. </span>
  763. </div>
  764. </div>
  765. </div>
  766. </div>
  767. <div class="actions">
  768. <# if ( data.defaultAttachment ) { #>
  769. <button type="button" class="button default-button"><?php echo $this->button_labels['default']; ?></button>
  770. <# } #>
  771. <# if ( data.canUpload ) { #>
  772. <button type="button" class="button upload-button" id="{{ data.settings['default'] }}-button"><?php echo $this->button_labels['select']; ?></button>
  773. <# } #>
  774. <div style="clear:both"></div>
  775. </div>
  776. <# } #>
  777. <?php
  778. }
  779. }
  780. /**
  781. * Customize Upload Control Class.
  782. *
  783. * @since 3.4.0
  784. *
  785. * @see WP_Customize_Media_Control
  786. */
  787. class WP_Customize_Upload_Control extends WP_Customize_Media_Control {
  788. public $type = 'upload';
  789. public $mime_type = '';
  790. public $button_labels = array();
  791. public $removed = ''; // unused
  792. public $context; // unused
  793. public $extensions = array(); // unused
  794. /**
  795. * Refresh the parameters passed to the JavaScript via JSON.
  796. *
  797. * @since 3.4.0
  798. *
  799. * @uses WP_Customize_Media_Control::to_json()
  800. */
  801. public function to_json() {
  802. parent::to_json();
  803. $value = $this->value();
  804. if ( $value ) {
  805. // Get the attachment model for the existing file.
  806. $attachment_id = attachment_url_to_postid( $value );
  807. if ( $attachment_id ) {
  808. $this->json['attachment'] = wp_prepare_attachment_for_js( $attachment_id );
  809. }
  810. }
  811. }
  812. }
  813. /**
  814. * Customize Image Control class.
  815. *
  816. * @since 3.4.0
  817. *
  818. * @see WP_Customize_Upload_Control
  819. */
  820. class WP_Customize_Image_Control extends WP_Customize_Upload_Control {
  821. public $type = 'image';
  822. public $mime_type = 'image';
  823. /**
  824. * Constructor.
  825. *
  826. * @since 3.4.0
  827. * @uses WP_Customize_Upload_Control::__construct()
  828. *
  829. * @param WP_Customize_Manager $manager Customizer bootstrap instance.
  830. * @param string $id Control ID.
  831. * @param array $args Optional. Arguments to override class property defaults.
  832. */
  833. public function __construct( $manager, $id, $args = array() ) {
  834. parent::__construct( $manager, $id, $args );
  835. $this->button_labels = array(
  836. 'select' => __( 'Select Image' ),
  837. 'change' => __( 'Change Image' ),
  838. 'remove' => __( 'Remove' ),
  839. 'default' => __( 'Default' ),
  840. 'placeholder' => __( 'No image selected' ),
  841. 'frame_title' => __( 'Select Image' ),
  842. 'frame_button' => __( 'Choose Image' ),
  843. );
  844. }
  845. /**
  846. * @since 3.4.2
  847. * @deprecated 4.1.0
  848. */
  849. public function prepare_control() {}
  850. /**
  851. * @since 3.4.0
  852. * @deprecated 4.1.0
  853. *
  854. * @param string $id
  855. * @param string $label
  856. * @param mixed $callback
  857. */
  858. public function add_tab( $id, $label, $callback ) {}
  859. /**
  860. * @since 3.4.0
  861. * @deprecated 4.1.0
  862. *
  863. * @param string $id
  864. */
  865. public function remove_tab( $id ) {}
  866. /**
  867. * @since 3.4.0
  868. * @deprecated 4.1.0
  869. *
  870. * @param string $url
  871. * @param string $thumbnail_url
  872. */
  873. public function print_tab_image( $url, $thumbnail_url = null ) {}
  874. }
  875. /**
  876. * Customize Background Image Control class.
  877. *
  878. * @since 3.4.0
  879. *
  880. * @see WP_Customize_Image_Control
  881. */
  882. class WP_Customize_Background_Image_Control extends WP_Customize_Image_Control {
  883. public $type = 'background';
  884. /**
  885. * Constructor.
  886. *
  887. * @since 3.4.0
  888. * @uses WP_Customize_Image_Control::__construct()
  889. *
  890. * @param WP_Customize_Manager $manager Customizer bootstrap instance.
  891. */
  892. public function __construct( $manager ) {
  893. parent::__construct( $manager, 'background_image', array(
  894. 'label' => __( 'Background Image' ),
  895. 'section' => 'background_image',
  896. ) );
  897. }
  898. /**
  899. * Enqueue control related scripts/styles.
  900. *
  901. * @since 4.1.0
  902. */
  903. public function enqueue() {
  904. parent::enqueue();
  905. wp_localize_script( 'customize-controls', '_wpCustomizeBackground', array(
  906. 'nonces' => array(
  907. 'add' => wp_create_nonce( 'background-add' ),
  908. ),
  909. ) );
  910. }
  911. }
  912. /**
  913. * Customize Cropped Image Control class.
  914. *
  915. * @since 4.3.0
  916. *
  917. * @see WP_Customize_Media_Control
  918. */
  919. class WP_Customize_Cropped_Image_Control extends WP_Customize_Media_Control {
  920. /**
  921. * Control type.
  922. *
  923. * @since 4.3.0
  924. * @access public
  925. * @var string
  926. */
  927. public $type = 'cropped_image';
  928. /**
  929. * Suggested width for cropped image.
  930. *
  931. * @since 4.3.0
  932. * @access public
  933. * @var int
  934. */
  935. public $width = 150;
  936. /**
  937. * Suggested height for cropped image.
  938. *
  939. * @since 4.3.0
  940. * @access public
  941. * @var int
  942. */
  943. public $height = 150;
  944. /**
  945. * Whether the width is flexible.
  946. *
  947. * @since 4.3.0
  948. * @access public
  949. * @var bool
  950. */
  951. public $flex_width = false;
  952. /**
  953. * Whether the height is flexible.
  954. *
  955. * @since 4.3.0
  956. * @access public
  957. * @var bool
  958. */
  959. public $flex_height = false;
  960. /**
  961. * Enqueue control related scripts/styles.
  962. *
  963. * @since 4.3.0
  964. * @access public
  965. */
  966. public function enqueue() {
  967. wp_enqueue_script( 'customize-views' );
  968. parent::enqueue();
  969. }
  970. /**
  971. * Refresh the parameters passed to the JavaScript via JSON.
  972. *
  973. * @since 4.3.0
  974. * @access public
  975. *
  976. * @see WP_Customize_Control::to_json()
  977. */
  978. public function to_json() {
  979. parent::to_json();
  980. $this->json['width'] = absint( $this->width );
  981. $this->json['height'] = absint( $this->height );
  982. $this->json['flex_width'] = absint( $this->flex_width );
  983. $this->json['flex_height'] = absint( $this->flex_height );
  984. }
  985. }
  986. /**
  987. * Customize Site Icon control class.
  988. *
  989. * Used only for custom functionality in JavaScript.
  990. *
  991. * @since 4.3.0
  992. *
  993. * @see WP_Customize_Cropped_Image_Control
  994. */
  995. class WP_Customize_Site_Icon_Control extends WP_Customize_Cropped_Image_Control {
  996. /**
  997. * Control type.
  998. *
  999. * @since 4.3.0
  1000. * @access public
  1001. * @var string
  1002. */
  1003. public $type = 'site_icon';
  1004. /**
  1005. * Constructor.
  1006. *
  1007. * @since 4.3.0
  1008. * @access public
  1009. *
  1010. * @param WP_Customize_Manager $manager Customizer bootstrap instance.
  1011. * @param string $id Control ID.
  1012. * @param array $args Optional. Arguments to override class property defaults.
  1013. */
  1014. public function __construct( $manager, $id, $args = array() ) {
  1015. parent::__construct( $manager, $id, $args );
  1016. add_action( 'customize_controls_print_styles', 'wp_site_icon', 99 );
  1017. }
  1018. }
  1019. /**
  1020. * Customize Header Image Control class.
  1021. *
  1022. * @since 3.4.0
  1023. *
  1024. * @see WP_Customize_Image_Control
  1025. */
  1026. class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control {
  1027. public $type = 'header';
  1028. public $uploaded_headers;
  1029. public $default_headers;
  1030. /**
  1031. * Constructor.
  1032. *
  1033. * @since 3.4.0
  1034. *
  1035. * @param WP_Customize_Manager $manager Customizer bootstrap instance.
  1036. */
  1037. public function __construct( $manager ) {
  1038. parent::__construct( $manager, 'header_image', array(
  1039. 'label' => __( 'Header Image' ),
  1040. 'settings' => array(
  1041. 'default' => 'header_image',
  1042. 'data' => 'header_image_data',
  1043. ),
  1044. 'section' => 'header_image',
  1045. 'removed' => 'remove-header',
  1046. 'get_url' => 'get_header_image',
  1047. ) );
  1048. }
  1049. /**
  1050. * @access public
  1051. */
  1052. public function enqueue() {
  1053. wp_enqueue_media();
  1054. wp_enqueue_script( 'customize-views' );
  1055. $this->prepare_control();
  1056. wp_localize_script( 'customize-views', '_wpCustomizeHeader', array(
  1057. 'data' => array(
  1058. 'width' => absint( get_theme_support( 'custom-header', 'width' ) ),
  1059. 'height' => absint( get_theme_support( 'custom-header', 'height' ) ),
  1060. 'flex-width' => absint( get_theme_support( 'custom-header', 'flex-width' ) ),
  1061. 'flex-height' => absint( get_theme_support( 'custom-header', 'flex-height' ) ),
  1062. 'currentImgSrc' => $this->get_current_image_src(),
  1063. ),
  1064. 'nonces' => array(
  1065. 'add' => wp_create_nonce( 'header-add' ),
  1066. 'remove' => wp_create_nonce( 'header-remove' ),
  1067. ),
  1068. 'uploads' => $this->uploaded_headers,
  1069. 'defaults' => $this->default_headers
  1070. ) );
  1071. parent::enqueue();
  1072. }
  1073. /**
  1074. *
  1075. * @global Custom_Image_Header $custom_image_header
  1076. */
  1077. public function prepare_control() {
  1078. global $custom_image_header;
  1079. if ( empty( $custom_image_header ) ) {
  1080. return;
  1081. }
  1082. // Process default headers and uploaded headers.
  1083. $custom_image_header->process_default_headers();
  1084. $this->default_headers = $custom_image_header->get_default_header_images();
  1085. $this->uploaded_headers = $custom_image_header->get_uploaded_header_images();
  1086. }
  1087. /**
  1088. * @access public
  1089. */
  1090. public function print_header_image_template() {
  1091. ?>
  1092. <script type="text/template" id="tmpl-header-choice">
  1093. <# if (data.random) { #>
  1094. <button type="button" class="button display-options random">
  1095. <span class="dashicons dashicons-randomize dice"></span>
  1096. <# if ( data.type === 'uploaded' ) { #>
  1097. <?php _e( 'Randomize uploaded headers' ); ?>
  1098. <# } else if ( data.type === 'default' ) { #>
  1099. <?php _e( 'Randomize suggested headers' ); ?>
  1100. <# } #>
  1101. </button>
  1102. <# } else { #>
  1103. <# if (data.type === 'uploaded') { #>
  1104. <button type="button" class="dashicons dashicons-no close"><span class="screen-reader-text"><?php _e( 'Remove image' ); ?></span></button>
  1105. <# } #>
  1106. <button type="button" class="choice thumbnail"
  1107. data-customize-image-value="{{{data.header.url}}}"
  1108. data-customize-header-image-data="{{JSON.stringify(data.header)}}">
  1109. <span class="screen-reader-text"><?php _e( 'Set image' ); ?></span>
  1110. <img src="{{{data.header.thumbnail_url}}}" alt="{{{data.header.alt_text || data.header.description}}}">
  1111. </button>
  1112. <# } #>
  1113. </script>
  1114. <script type="text/template" id="tmpl-header-current">
  1115. <# if (data.choice) { #>
  1116. <# if (data.random) { #>
  1117. <div class="placeholder">
  1118. <div class="inner">
  1119. <span><span class="dashicons dashicons-randomize dice"></span>
  1120. <# if ( data.type === 'uploaded' ) { #>
  1121. <?php _e( 'Randomizing uploaded headers' ); ?>
  1122. <# } else if ( data.type === 'default' ) { #>
  1123. <?php _e( 'Randomizing suggested headers' ); ?>
  1124. <# } #>
  1125. </span>
  1126. </div>
  1127. </div>
  1128. <# } else { #>
  1129. <img src="{{{data.header.thumbnail_url}}}" alt="{{{data.header.alt_text || data.header.description}}}" tabindex="0"/>
  1130. <# } #>
  1131. <# } else { #>
  1132. <div class="placeholder">
  1133. <div class="inner">
  1134. <span>
  1135. <?php _e( 'No image set' ); ?>
  1136. </span>
  1137. </div>
  1138. </div>
  1139. <# } #>
  1140. </script>
  1141. <?php
  1142. }
  1143. /**
  1144. * @return string|void
  1145. */
  1146. public function get_current_image_src() {
  1147. $src = $this->value();
  1148. if ( isset( $this->get_url ) ) {
  1149. $src = call_user_func( $this->get_url, $src );
  1150. return $src;
  1151. }
  1152. }
  1153. /**
  1154. * @access public
  1155. */
  1156. public function render_content() {
  1157. $this->print_header_image_template();
  1158. $visibility = $this->get_current_image_src() ? '' : ' style="display:none" ';
  1159. $width = absint( get_theme_support( 'custom-header', 'width' ) );
  1160. $height = absint( get_theme_support( 'custom-header', 'height' ) );
  1161. ?>
  1162. <div class="customize-control-content">
  1163. <p class="customizer-section-intro">
  1164. <?php
  1165. if ( $width && $height ) {
  1166. printf( __( 'While you can crop images to your liking after clicking <strong>Add new image</strong>, your theme recommends a header size of <strong>%s &times; %s</strong> pixels.' ), $width, $height );
  1167. } elseif ( $width ) {
  1168. printf( __( 'While you can crop images to your liking after clicking <strong>Add new image</strong>, your theme recommends a header width of <strong>%s</strong> pixels.' ), $width );
  1169. } else {
  1170. printf( __( 'While you can crop images to your liking after clicking <strong>Add new image</strong>, your theme recommends a header height of <strong>%s</strong> pixels.' ), $height );
  1171. }
  1172. ?>
  1173. </p>
  1174. <div class="current">
  1175. <span class="customize-control-title">
  1176. <?php _e( 'Current header' ); ?>
  1177. </span>
  1178. <div class="container">
  1179. </div>
  1180. </div>
  1181. <div class="actions">
  1182. <?php if ( current_user_can( 'upload_files' ) ): ?>
  1183. <button type="button"<?php echo $visibility; ?> class="button remove" aria-label="<?php esc_attr_e( 'Hide header image' ); ?>"><?php _e( 'Hide image' ); ?></button>
  1184. <button type="button" class="button new" aria-label="<?php esc_attr_e( 'Add new header image' ); ?>"><?php _e( 'Add new image' ); ?></button>
  1185. <div style="clear:both"></div>
  1186. <?php endif; ?>
  1187. </div>
  1188. <div class="choices">
  1189. <span class="customize-control-title header-previously-uploaded">
  1190. <?php _ex( 'Previously uploaded', 'custom headers' ); ?>
  1191. </span>
  1192. <div class="uploaded">
  1193. <div class="list">
  1194. </div>
  1195. </div>
  1196. <span class="customize-control-title header-default">
  1197. <?php _ex( 'Suggested', 'custom headers' ); ?>
  1198. </span>
  1199. <div class="default">
  1200. <div class="list">
  1201. </div>
  1202. </div>
  1203. </div>
  1204. </div>
  1205. <?php
  1206. }
  1207. }
  1208. /**
  1209. * Customize Theme Control class.
  1210. *
  1211. * @since 4.2.0
  1212. *
  1213. * @see WP_Customize_Control
  1214. */
  1215. class WP_Customize_Theme_Control extends WP_Customize_Control {
  1216. /**
  1217. * Customize control type.
  1218. *
  1219. * @since 4.2.0
  1220. * @access public
  1221. * @var string
  1222. */
  1223. public $type = 'theme';
  1224. /**
  1225. * Theme object.
  1226. *
  1227. * @since 4.2.0
  1228. * @access public
  1229. * @var WP_Theme
  1230. */
  1231. public $theme;
  1232. /**
  1233. * Refresh the parameters passed to the JavaScript via JSON.
  1234. *
  1235. * @since 4.2.0
  1236. * @access public
  1237. *
  1238. * @see WP_Customize_Control::to_json()
  1239. */
  1240. public function to_json() {
  1241. parent::to_json();
  1242. $this->json['theme'] = $this->theme;
  1243. }
  1244. /**
  1245. * Don't render the control content from PHP, as it's rendered via JS on load.
  1246. *
  1247. * @since 4.2.0
  1248. * @access public
  1249. */
  1250. public function render_content() {}
  1251. /**
  1252. * Render a JS template for theme display.
  1253. *
  1254. * @since 4.2.0
  1255. * @access public
  1256. */
  1257. public function content_template() {
  1258. $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
  1259. $active_url = esc_url( remove_query_arg( 'theme', $current_url ) );
  1260. $preview_url = esc_url( add_query_arg( 'theme', '__THEME__', $current_url ) ); // Token because esc_url() strips curly braces.
  1261. $preview_url = str_replace( '__THEME__', '{{ data.theme.id }}', $preview_url );
  1262. ?>
  1263. <# if ( data.theme.isActiveTheme ) { #>
  1264. <div class="theme active" tabindex="0" data-preview-url="<?php echo esc_attr( $active_url ); ?>" aria-describedby="{{ data.theme.id }}-action {{ data.theme.id }}-name">
  1265. <# } else { #>
  1266. <div class="theme" tabindex="0" data-preview-url="<?php echo esc_attr( $preview_url ); ?>" aria-describedby="{{ data.theme.id }}-action {{ data.theme.id }}-name">
  1267. <# } #>
  1268. <# if ( data.theme.screenshot[0] ) { #>
  1269. <div class="theme-screenshot">
  1270. <img data-src="{{ data.theme.screenshot[0] }}" alt="" />
  1271. </div>
  1272. <# } else { #>
  1273. <div class="theme-screenshot blank"></div>
  1274. <# } #>
  1275. <# if ( data.theme.isActiveTheme ) { #>
  1276. <span class="more-details" id="{{ data.theme.id }}-action"><?php _e( 'Customize' ); ?></span>
  1277. <# } else { #>
  1278. <span class="more-details" id="{{ data.theme.id }}-action"><?php _e( 'Live Preview' ); ?></span>
  1279. <# } #>
  1280. <div class="theme-author"><?php printf( __( 'By %s' ), '{{ data.theme.author }}' ); ?></div>
  1281. <# if ( data.theme.isActiveTheme ) { #>
  1282. <h3 class="theme-name" id="{{ data.theme.id }}-name">
  1283. <?php
  1284. /* translators: %s: theme name */
  1285. printf( __( '<span>Active:</span> %s' ), '{{{ data.theme.name }}}' );
  1286. ?>
  1287. </h3>
  1288. <# } else { #>
  1289. <h3 class="theme-name" id="{{ data.theme.id }}-name">{{{ data.theme.name }}}</h3>
  1290. <div class="theme-actions">
  1291. <button type="button" class="button theme-details"><?php _e( 'Theme Details' ); ?></button>
  1292. </div>
  1293. <# } #>
  1294. </div>
  1295. <?php
  1296. }
  1297. }
  1298. /**
  1299. * Widget Area Customize Control class.
  1300. *
  1301. * @since 3.9.0
  1302. *
  1303. * @see WP_Customize_Control
  1304. */
  1305. class WP_Widget_Area_Customize_Control extends WP_Customize_Control {
  1306. public $type = 'sidebar_widgets';
  1307. public $sidebar_id;
  1308. public function to_json() {
  1309. parent::to_json();
  1310. $exported_properties = array( 'sidebar_id' );
  1311. foreach ( $exported_properties as $key ) {
  1312. $this->json[ $key ] = $this->$key;
  1313. }
  1314. }
  1315. /**
  1316. * @access public
  1317. */
  1318. public function render_content() {
  1319. ?>
  1320. <span class="button-secondary add-new-widget" tabindex="0">
  1321. <?php _e( 'Add a Widget' ); ?>
  1322. </span>
  1323. <span class="reorder-toggle" tabindex="0">
  1324. <span class="reorder"><?php _ex( 'Reorder', 'Reorder widgets in Customizer' ); ?></span>
  1325. <span class="reorder-done"><?php _ex( 'Done', 'Cancel reordering widgets in Customizer' ); ?></span>
  1326. </span>
  1327. <?php
  1328. }
  1329. }
  1330. /**
  1331. * Widget Form Customize Control class.
  1332. *
  1333. * @since 3.9.0
  1334. *
  1335. * @see WP_Customize_Control
  1336. */
  1337. class WP_Widget_Form_Customize_Control extends WP_Customize_Control {
  1338. public $type = 'widget_form';
  1339. public $widget_id;
  1340. public $widget_id_base;
  1341. public $sidebar_id;
  1342. public $is_new = false;
  1343. public $width;
  1344. public $height;
  1345. public $is_wide = false;
  1346. public function to_json() {
  1347. parent::to_json();
  1348. $exported_properties = array( 'widget_id', 'widget_id_base', 'sidebar_id', 'width', 'height', 'is_wide' );
  1349. foreach ( $exported_properties as $key ) {
  1350. $this->json[ $key ] = $this->$key;
  1351. }
  1352. }
  1353. /**
  1354. *
  1355. * @global array $wp_registered_widgets
  1356. */
  1357. public function render_content() {
  1358. global $wp_registered_widgets;
  1359. require_once ABSPATH . '/wp-admin/includes/widgets.php';
  1360. $widget = $wp_registered_widgets[ $this->widget_id ];
  1361. if ( ! isset( $widget['params'][0] ) ) {
  1362. $widget['params'][0] = array();
  1363. }
  1364. $args = array(
  1365. 'widget_id' => $widget['id'],
  1366. 'widget_name' => $widget['name'],
  1367. );
  1368. $args = wp_list_widget_controls_dynamic_sidebar( array( 0 => $args, 1 => $widget['params'][0] ) );
  1369. echo $this->manager->widgets->get_widget_control( $args );
  1370. }
  1371. /**
  1372. * Whether the current widget is rendered on the page.
  1373. *
  1374. * @since 4.0.0
  1375. * @access public
  1376. *
  1377. * @return bool Whether the widget is rendered.
  1378. */
  1379. public function active_callback() {
  1380. return $this->manager->widgets->is_widget_rendered( $this->widget_id );
  1381. }
  1382. }
  1383. /**
  1384. * Customize Nav Menu Control Class.
  1385. *
  1386. * @since 4.3.0
  1387. */
  1388. class WP_Customize_Nav_Menu_Control extends WP_Customize_Control {
  1389. /**
  1390. * Control type.
  1391. *
  1392. * @since 4.3.0
  1393. * @access public
  1394. * @var string
  1395. */
  1396. public $type = 'nav_menu';
  1397. /**
  1398. * The nav menu setting.
  1399. *
  1400. * @since 4.3.0
  1401. * @access public
  1402. * @var WP_Customize_Nav_Menu_Setting
  1403. */
  1404. public $setting;
  1405. /**
  1406. * Don't render the control's content - it uses a JS template instead.
  1407. *
  1408. * @since 4.3.0
  1409. * @access public
  1410. */
  1411. public function render_content() {}
  1412. /**
  1413. * JS/Underscore template for the control UI.
  1414. *
  1415. * @since 4.3.0
  1416. * @access public
  1417. */
  1418. public function content_template() {
  1419. ?>
  1420. <button type="button" class="button-secondary add-new-menu-item" aria-label="<?php esc_attr_e( 'Add or remove menu items' ); ?>" aria-expanded="false" aria-controls="available-menu-items">
  1421. <?php _e( 'Add Items' ); ?>
  1422. </button>
  1423. <button type="button" class="not-a-button reorder-toggle" aria-label="<?php esc_attr_e( 'Reorder menu items' ); ?>" aria-describedby="reorder-items-desc-{{ data.menu_id }}">
  1424. <span class="reorder"><?php _ex( 'Reorder', 'Reorder menu items in Customizer' ); ?></span>
  1425. <span class="reorder-done"><?php _ex( 'Done', 'Cancel reordering menu items in Customizer' ); ?></span>
  1426. </button>
  1427. <p class="screen-reader-text" id="reorder-items-desc-{{ data.menu_id }}"><?php _e( 'When in reorder mode, additional controls to reorder menu items will be available in the items list above.' ); ?></p>
  1428. <span class="add-menu-item-loading spinner"></span>
  1429. <span class="menu-delete-item">
  1430. <button type="button" class="not-a-button menu-delete">
  1431. <?php _e( 'Delete menu' ); ?> <span class="screen-reader-text">{{ data.menu_name }}</span>
  1432. </button>
  1433. </span>
  1434. <?php if ( current_theme_supports( 'menus' ) ) : ?>
  1435. <ul class="menu-settings">
  1436. <li class="customize-control">
  1437. <span class="customize-control-title"><?php _e( 'Menu locations' ); ?></span>
  1438. </li>
  1439. <?php foreach ( get_registered_nav_menus() as $location => $description ) : ?>
  1440. <li class="customize-control customize-control-checkbox assigned-menu-location">
  1441. <label>
  1442. <input type="checkbox" data-menu-id="{{ data.menu_id }}" data-location-id="<?php echo esc_attr( $location ); ?>" class="menu-location" /> <?php echo $description; ?>
  1443. <span class="theme-location-set"><?php printf( _x( '(Current: %s)', 'Current menu location' ), '<span class="current-menu-location-name-' . esc_attr( $location ) . '"></span>' ); ?></span>
  1444. </label>
  1445. </li>
  1446. <?php endforeach; ?>
  1447. </ul>
  1448. <?php endif;
  1449. }
  1450. /**
  1451. * Return parameters for this control.
  1452. *
  1453. * @since 4.3.0
  1454. * @access public
  1455. *
  1456. * @return array Exported parameters.
  1457. */
  1458. public function json() {
  1459. $exported = parent::json();
  1460. $exported['menu_id'] = $this->setting->term_id;
  1461. return $exported;
  1462. }
  1463. }
  1464. /**
  1465. * Customize control to represent the name field for a given menu.
  1466. *
  1467. * @since 4.3.0
  1468. */
  1469. class WP_Customize_Nav_Menu_Item_Control extends WP_Customize_Control {
  1470. /**
  1471. * Control type.
  1472. *
  1473. * @since 4.3.0
  1474. * @access public
  1475. * @var string
  1476. */
  1477. public $type = 'nav_menu_item';
  1478. /**
  1479. * The nav menu item setting.
  1480. *
  1481. * @since 4.3.0
  1482. * @access public
  1483. * @var WP_Customize_Nav_Menu_Item_Setting
  1484. */
  1485. public $setting;
  1486. /**
  1487. * Constructor.
  1488. *
  1489. * @since 4.3.0
  1490. * @access public
  1491. *
  1492. * @see WP_Customize_Control::__construct()
  1493. *
  1494. * @param WP_Customize_Manager $manager Customizer bootstrap instance.
  1495. * @param string $id The control ID.
  1496. * @param array $args Optional. Overrides class property defaults.
  1497. */
  1498. public function __construct( $manager, $id, $args = array() ) {
  1499. parent::__construct( $manager, $id, $args );
  1500. }
  1501. /**
  1502. * Don't render the control's content - it's rendered with a JS template.
  1503. *
  1504. * @since 4.3.0
  1505. * @access public
  1506. */
  1507. public function render_content() {}
  1508. /**
  1509. * JS/Underscore template for the control UI.
  1510. *
  1511. * @since 4.3.0
  1512. * @access public
  1513. */
  1514. public function content_template() {
  1515. ?>
  1516. <div class="menu-item-bar">
  1517. <div class="menu-item-handle">
  1518. <span class="item-type" aria-hidden="true">{{ data.item_type_label }}</span>
  1519. <span class="item-title" aria-hidden="true">
  1520. <span class="spinner"></span>
  1521. <span class="menu-item-title<# if ( ! data.title ) { #> no-title<# } #>">{{ data.title || wp.customize.Menus.data.l10n.untitled }}</span>
  1522. </span>
  1523. <span class="item-controls">
  1524. <button type="button" class="not-a-button item-edit" aria-expanded="false"><span class="screen-reader-text"><?php
  1525. /* translators: 1: Title of a menu item, 2: Type of a menu item */
  1526. printf( __( 'Edit menu item: %1$s (%2$s)' ), '{{ data.title || wp.customize.Menus.data.l10n.untitled }}', '{{ data.item_type_label }}' );
  1527. ?></span><span class="toggle-indicator" aria-hidden="true"></span></button>
  1528. <button type="button" class="not-a-button item-delete submitdelete deletion"><span class="screen-reader-text"><?php
  1529. /* translators: 1: Title of a menu item, 2: Type of a menu item */
  1530. printf( __( 'Remove Menu Item: %1$s (%2$s)' ), '{{ data.title || wp.customize.Menus.data.l10n.untitled }}', '{{ data.item_type_label }}' );
  1531. ?></span></button>
  1532. </span>
  1533. </div>
  1534. </div>
  1535. <div class="menu-item-settings" id="menu-item-settings-{{ data.menu_item_id }}">
  1536. <# if ( 'custom' === data.item_type ) { #>
  1537. <p class="field-url description description-thin">
  1538. <label for="edit-menu-item-url-{{ data.menu_item_id }}">
  1539. <?php _e( 'URL' ); ?><br />
  1540. <input class="widefat code edit-menu-item-url" type="text" id="edit-menu-item-url-{{ data.menu_item_id }}" name="menu-item-url" />
  1541. </label>
  1542. </p>
  1543. <# } #>
  1544. <p class="description description-thin">
  1545. <label for="edit-menu-item-title-{{ data.menu_item_id }}">
  1546. <?php _e( 'Navigation Label' ); ?><br />
  1547. <input type="text" id="edit-menu-item-title-{{ data.menu_item_id }}" class="widefat edit-menu-item-title" name="menu-item-title" />
  1548. </label>
  1549. </p>
  1550. <p class="field-link-target description description-thin">
  1551. <label for="edit-menu-item-target-{{ data.menu_item_id }}">
  1552. <input type="checkbox" id="edit-menu-item-target-{{ data.menu_item_id }}" class="edit-menu-item-target" value="_blank" name="menu-item-target" />
  1553. <?php _e( 'Open link in a new tab' ); ?>
  1554. </label>
  1555. </p>
  1556. <p class="field-attr-title description description-thin">
  1557. <label for="edit-menu-item-attr-title-{{ data.menu_item_id }}">
  1558. <?php _e( 'Title Attribute' ); ?><br />
  1559. <input type="text" id="edit-menu-item-attr-title-{{ data.menu_item_id }}" class="widefat edit-menu-item-attr-title" name="menu-item-attr-title" />
  1560. </label>
  1561. </p>
  1562. <p class="field-css-classes description description-thin">
  1563. <label for="edit-menu-item-classes-{{ data.menu_item_id }}">
  1564. <?php _e( 'CSS Classes' ); ?><br />
  1565. <input type="text" id="edit-menu-item-classes-{{ data.menu_item_id }}" class="widefat code edit-menu-item-classes" name="menu-item-classes" />
  1566. </label>
  1567. </p>
  1568. <p class="field-xfn description description-thin">
  1569. <label for="edit-menu-item-xfn-{{ data.menu_item_id }}">
  1570. <?php _e( 'Link Relationship (XFN)' ); ?><br />
  1571. <input type="text" id="edit-menu-item-xfn-{{ data.menu_item_id }}" class="widefat code edit-menu-item-xfn" name="menu-item-xfn" />
  1572. </label>
  1573. </p>
  1574. <p class="field-description description description-thin">
  1575. <label for="edit-menu-item-description-{{ data.menu_item_id }}">
  1576. <?php _e( 'Description' ); ?><br />
  1577. <textarea id="edit-menu-item-description-{{ data.menu_item_id }}" class="widefat edit-menu-item-description" rows="3" cols="20" name="menu-item-description">{{ data.description }}</textarea>
  1578. <span class="description"><?php _e( 'The description will be displayed in the menu if the current theme supports it.' ); ?></span>
  1579. </label>
  1580. </p>
  1581. <div class="menu-item-actions description-thin submitbox">
  1582. <# if ( ( 'post_type' === data.item_type || 'taxonomy' === data.item_type ) && '' !== data.original_title ) { #>
  1583. <p class="link-to-original">
  1584. <?php printf( __( 'Original: %s' ), '<a class="original-link" href="{{ data.url }}">{{ data.original_title }}</a>' ); ?>
  1585. </p>
  1586. <# } #>
  1587. <button type="button" class="not-a-button item-delete submitdelete deletion"><?php _e( 'Remove' ); ?></button>
  1588. <span class="spinner"></span>
  1589. </div>
  1590. <input type="hidden" name="menu-item-db-id[{{ data.menu_item_id }}]" class="menu-item-data-db-id" value="{{ data.menu_item_id }}" />
  1591. <input type="hidden" name="menu-item-parent-id[{{ data.menu_item_id }}]" class="menu-item-data-parent-id" value="{{ data.parent }}" />
  1592. </div><!-- .menu-item-settings-->
  1593. <ul class="menu-item-transport"></ul>
  1594. <?php
  1595. }
  1596. /**
  1597. * Return parameters for this control.
  1598. *
  1599. * @since 4.3.0
  1600. * @access public
  1601. *
  1602. * @return array Exported parameters.
  1603. */
  1604. public function json() {
  1605. $exported = parent::json();
  1606. $exported['menu_item_id'] = $this->setting->post_id;
  1607. return $exported;
  1608. }
  1609. }
  1610. /**
  1611. * Customize Menu Location Control Class.
  1612. *
  1613. * …

Large files files are truncated, but you can click here to view the full file