Changeset 35389
- Timestamp:
- 10/24/2015 06:56:07 PM (9 years ago)
- Location:
- trunk/src/wp-includes
- Files:
-
- 1 edited
- 17 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/class-wp-customize-control.php
r35304 r35389 550 550 } 551 551 552 /** 553 * Customize Color Control class. 554 * 555 * @since 3.4.0 556 * 557 * @see WP_Customize_Control 558 */ 559 class WP_Customize_Color_Control extends WP_Customize_Control { 560 /** 561 * @access public 562 * @var string 563 */ 564 public $type = 'color'; 565 566 /** 567 * @access public 568 * @var array 569 */ 570 public $statuses; 571 572 /** 573 * Constructor. 574 * 575 * @since 3.4.0 576 * @uses WP_Customize_Control::__construct() 577 * 578 * @param WP_Customize_Manager $manager Customizer bootstrap instance. 579 * @param string $id Control ID. 580 * @param array $args Optional. Arguments to override class property defaults. 581 */ 582 public function __construct( $manager, $id, $args = array() ) { 583 $this->statuses = array( '' => __('Default') ); 584 parent::__construct( $manager, $id, $args ); 585 } 586 587 /** 588 * Enqueue scripts/styles for the color picker. 589 * 590 * @since 3.4.0 591 */ 592 public function enqueue() { 593 wp_enqueue_script( 'wp-color-picker' ); 594 wp_enqueue_style( 'wp-color-picker' ); 595 } 596 597 /** 598 * Refresh the parameters passed to the JavaScript via JSON. 599 * 600 * @since 3.4.0 601 * @uses WP_Customize_Control::to_json() 602 */ 603 public function to_json() { 604 parent::to_json(); 605 $this->json['statuses'] = $this->statuses; 606 $this->json['defaultValue'] = $this->setting->default; 607 } 608 609 /** 610 * Don't render the control content from PHP, as it's rendered via JS on load. 611 * 612 * @since 3.4.0 613 */ 614 public function render_content() {} 615 616 /** 617 * Render a JS template for the content of the color picker control. 618 * 619 * @since 4.1.0 620 */ 621 public function content_template() { 622 ?> 623 <# var defaultValue = ''; 624 if ( data.defaultValue ) { 625 if ( '#' !== data.defaultValue.substring( 0, 1 ) ) { 626 defaultValue = '#' + data.defaultValue; 627 } else { 628 defaultValue = data.defaultValue; 629 } 630 defaultValue = ' data-default-color=' + defaultValue; // Quotes added automatically. 631 } #> 632 <label> 633 <# if ( data.label ) { #> 634 <span class="customize-control-title">{{{ data.label }}}</span> 635 <# } #> 636 <# if ( data.description ) { #> 637 <span class="description customize-control-description">{{{ data.description }}}</span> 638 <# } #> 639 <div class="customize-control-content"> 640 <input class="color-picker-hex" type="text" maxlength="7" placeholder="<?php esc_attr_e( 'Hex Value' ); ?>" {{ defaultValue }} /> 641 </div> 642 </label> 643 <?php 644 } 645 } 646 647 /** 648 * Customize Media Control class. 649 * 650 * @since 4.2.0 651 * 652 * @see WP_Customize_Control 653 */ 654 class WP_Customize_Media_Control extends WP_Customize_Control { 655 /** 656 * Control type. 657 * 658 * @since 4.2.0 659 * @access public 660 * @var string 661 */ 662 public $type = 'media'; 663 664 /** 665 * Media control mime type. 666 * 667 * @since 4.2.0 668 * @access public 669 * @var string 670 */ 671 public $mime_type = ''; 672 673 /** 674 * Button labels. 675 * 676 * @since 4.2.0 677 * @access public 678 * @var array 679 */ 680 public $button_labels = array(); 681 682 /** 683 * Constructor. 684 * 685 * @since 4.1.0 686 * @since 4.2.0 Moved from WP_Customize_Upload_Control. 687 * 688 * @param WP_Customize_Manager $manager Customizer bootstrap instance. 689 * @param string $id Control ID. 690 * @param array $args Optional. Arguments to override class property defaults. 691 */ 692 public function __construct( $manager, $id, $args = array() ) { 693 parent::__construct( $manager, $id, $args ); 694 695 $this->button_labels = array( 696 'select' => __( 'Select File' ), 697 'change' => __( 'Change File' ), 698 'default' => __( 'Default' ), 699 'remove' => __( 'Remove' ), 700 'placeholder' => __( 'No file selected' ), 701 'frame_title' => __( 'Select File' ), 702 'frame_button' => __( 'Choose File' ), 703 ); 704 } 705 706 /** 707 * Enqueue control related scripts/styles. 708 * 709 * @since 3.4.0 710 * @since 4.2.0 Moved from WP_Customize_Upload_Control. 711 */ 712 public function enqueue() { 713 wp_enqueue_media(); 714 } 715 716 /** 717 * Refresh the parameters passed to the JavaScript via JSON. 718 * 719 * @since 3.4.0 720 * @since 4.2.0 Moved from WP_Customize_Upload_Control. 721 * 722 * @see WP_Customize_Control::to_json() 723 */ 724 public function to_json() { 725 parent::to_json(); 726 $this->json['label'] = html_entity_decode( $this->label, ENT_QUOTES, get_bloginfo( 'charset' ) ); 727 $this->json['mime_type'] = $this->mime_type; 728 $this->json['button_labels'] = $this->button_labels; 729 $this->json['canUpload'] = current_user_can( 'upload_files' ); 730 731 $value = $this->value(); 732 733 if ( is_object( $this->setting ) ) { 734 if ( $this->setting->default ) { 735 // Fake an attachment model - needs all fields used by template. 736 // Note that the default value must be a URL, NOT an attachment ID. 737 $type = in_array( substr( $this->setting->default, -3 ), array( 'jpg', 'png', 'gif', 'bmp' ) ) ? 'image' : 'document'; 738 $default_attachment = array( 739 'id' => 1, 740 'url' => $this->setting->default, 741 'type' => $type, 742 'icon' => wp_mime_type_icon( $type ), 743 'title' => basename( $this->setting->default ), 744 ); 745 746 if ( 'image' === $type ) { 747 $default_attachment['sizes'] = array( 748 'full' => array( 'url' => $this->setting->default ), 749 ); 750 } 751 752 $this->json['defaultAttachment'] = $default_attachment; 753 } 754 755 if ( $value && $this->setting->default && $value === $this->setting->default ) { 756 // Set the default as the attachment. 757 $this->json['attachment'] = $this->json['defaultAttachment']; 758 } elseif ( $value ) { 759 $this->json['attachment'] = wp_prepare_attachment_for_js( $value ); 760 } 761 } 762 } 763 764 /** 765 * Don't render any content for this control from PHP. 766 * 767 * @since 3.4.0 768 * @since 4.2.0 Moved from WP_Customize_Upload_Control. 769 * 770 * @see WP_Customize_Media_Control::content_template() 771 */ 772 public function render_content() {} 773 774 /** 775 * Render a JS template for the content of the media control. 776 * 777 * @since 4.1.0 778 * @since 4.2.0 Moved from WP_Customize_Upload_Control. 779 */ 780 public function content_template() { 781 ?> 782 <label for="{{ data.settings['default'] }}-button"> 783 <# if ( data.label ) { #> 784 <span class="customize-control-title">{{ data.label }}</span> 785 <# } #> 786 <# if ( data.description ) { #> 787 <span class="description customize-control-description">{{{ data.description }}}</span> 788 <# } #> 789 </label> 790 791 <# if ( data.attachment && data.attachment.id ) { #> 792 <div class="current"> 793 <div class="container"> 794 <div class="attachment-media-view attachment-media-view-{{ data.attachment.type }} {{ data.attachment.orientation }}"> 795 <div class="thumbnail thumbnail-{{ data.attachment.type }}"> 796 <# if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.medium ) { #> 797 <img class="attachment-thumb" src="{{ data.attachment.sizes.medium.url }}" draggable="false" /> 798 <# } else if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.full ) { #> 799 <img class="attachment-thumb" src="{{ data.attachment.sizes.full.url }}" draggable="false" /> 800 <# } else if ( 'audio' === data.attachment.type ) { #> 801 <# if ( data.attachment.image && data.attachment.image.src && data.attachment.image.src !== data.attachment.icon ) { #> 802 <img src="{{ data.attachment.image.src }}" class="thumbnail" draggable="false" /> 803 <# } else { #> 804 <img src="{{ data.attachment.icon }}" class="attachment-thumb type-icon" draggable="false" /> 805 <# } #> 806 <p class="attachment-meta attachment-meta-title">“{{ data.attachment.title }}”</p> 807 <# if ( data.attachment.album || data.attachment.meta.album ) { #> 808 <p class="attachment-meta"><em>{{ data.attachment.album || data.attachment.meta.album }}</em></p> 809 <# } #> 810 <# if ( data.attachment.artist || data.attachment.meta.artist ) { #> 811 <p class="attachment-meta">{{ data.attachment.artist || data.attachment.meta.artist }}</p> 812 <# } #> 813 <audio style="visibility: hidden" controls class="wp-audio-shortcode" width="100%" preload="none"> 814 <source type="{{ data.attachment.mime }}" src="{{ data.attachment.url }}"/> 815 </audio> 816 <# } else if ( 'video' === data.attachment.type ) { #> 817 <div class="wp-media-wrapper wp-video"> 818 <video controls="controls" class="wp-video-shortcode" preload="metadata" 819 <# if ( data.attachment.image && data.attachment.image.src !== data.attachment.icon ) { #>poster="{{ data.attachment.image.src }}"<# } #>> 820 <source type="{{ data.attachment.mime }}" src="{{ data.attachment.url }}"/> 821 </video> 822 </div> 823 <# } else { #> 824 <img class="attachment-thumb type-icon icon" src="{{ data.attachment.icon }}" draggable="false" /> 825 <p class="attachment-title">{{ data.attachment.title }}</p> 826 <# } #> 827 </div> 828 </div> 829 </div> 830 </div> 831 <div class="actions"> 832 <# if ( data.canUpload ) { #> 833 <button type="button" class="button remove-button"><?php echo $this->button_labels['remove']; ?></button> 834 <button type="button" class="button upload-button" id="{{ data.settings['default'] }}-button"><?php echo $this->button_labels['change']; ?></button> 835 <div style="clear:both"></div> 836 <# } #> 837 </div> 838 <# } else { #> 839 <div class="current"> 840 <div class="container"> 841 <div class="placeholder"> 842 <div class="inner"> 843 <span> 844 <?php echo $this->button_labels['placeholder']; ?> 845 </span> 846 </div> 847 </div> 848 </div> 849 </div> 850 <div class="actions"> 851 <# if ( data.defaultAttachment ) { #> 852 <button type="button" class="button default-button"><?php echo $this->button_labels['default']; ?></button> 853 <# } #> 854 <# if ( data.canUpload ) { #> 855 <button type="button" class="button upload-button" id="{{ data.settings['default'] }}-button"><?php echo $this->button_labels['select']; ?></button> 856 <# } #> 857 <div style="clear:both"></div> 858 </div> 859 <# } #> 860 <?php 861 } 862 } 863 864 /** 865 * Customize Upload Control Class. 866 * 867 * @since 3.4.0 868 * 869 * @see WP_Customize_Media_Control 870 */ 871 class WP_Customize_Upload_Control extends WP_Customize_Media_Control { 872 public $type = 'upload'; 873 public $mime_type = ''; 874 public $button_labels = array(); 875 public $removed = ''; // unused 876 public $context; // unused 877 public $extensions = array(); // unused 878 879 /** 880 * Refresh the parameters passed to the JavaScript via JSON. 881 * 882 * @since 3.4.0 883 * 884 * @uses WP_Customize_Media_Control::to_json() 885 */ 886 public function to_json() { 887 parent::to_json(); 888 889 $value = $this->value(); 890 if ( $value ) { 891 // Get the attachment model for the existing file. 892 $attachment_id = attachment_url_to_postid( $value ); 893 if ( $attachment_id ) { 894 $this->json['attachment'] = wp_prepare_attachment_for_js( $attachment_id ); 895 } 896 } 897 } 898 } 899 900 /** 901 * Customize Image Control class. 902 * 903 * @since 3.4.0 904 * 905 * @see WP_Customize_Upload_Control 906 */ 907 class WP_Customize_Image_Control extends WP_Customize_Upload_Control { 908 public $type = 'image'; 909 public $mime_type = 'image'; 910 911 /** 912 * Constructor. 913 * 914 * @since 3.4.0 915 * @uses WP_Customize_Upload_Control::__construct() 916 * 917 * @param WP_Customize_Manager $manager Customizer bootstrap instance. 918 * @param string $id Control ID. 919 * @param array $args Optional. Arguments to override class property defaults. 920 */ 921 public function __construct( $manager, $id, $args = array() ) { 922 parent::__construct( $manager, $id, $args ); 923 924 $this->button_labels = array( 925 'select' => __( 'Select Image' ), 926 'change' => __( 'Change Image' ), 927 'remove' => __( 'Remove' ), 928 'default' => __( 'Default' ), 929 'placeholder' => __( 'No image selected' ), 930 'frame_title' => __( 'Select Image' ), 931 'frame_button' => __( 'Choose Image' ), 932 ); 933 } 934 935 /** 936 * @since 3.4.2 937 * @deprecated 4.1.0 938 */ 939 public function prepare_control() {} 940 941 /** 942 * @since 3.4.0 943 * @deprecated 4.1.0 944 * 945 * @param string $id 946 * @param string $label 947 * @param mixed $callback 948 */ 949 public function add_tab( $id, $label, $callback ) {} 950 951 /** 952 * @since 3.4.0 953 * @deprecated 4.1.0 954 * 955 * @param string $id 956 */ 957 public function remove_tab( $id ) {} 958 959 /** 960 * @since 3.4.0 961 * @deprecated 4.1.0 962 * 963 * @param string $url 964 * @param string $thumbnail_url 965 */ 966 public function print_tab_image( $url, $thumbnail_url = null ) {} 967 } 968 969 /** 970 * Customize Background Image Control class. 971 * 972 * @since 3.4.0 973 * 974 * @see WP_Customize_Image_Control 975 */ 976 class WP_Customize_Background_Image_Control extends WP_Customize_Image_Control { 977 public $type = 'background'; 978 979 /** 980 * Constructor. 981 * 982 * @since 3.4.0 983 * @uses WP_Customize_Image_Control::__construct() 984 * 985 * @param WP_Customize_Manager $manager Customizer bootstrap instance. 986 */ 987 public function __construct( $manager ) { 988 parent::__construct( $manager, 'background_image', array( 989 'label' => __( 'Background Image' ), 990 'section' => 'background_image', 991 ) ); 992 } 993 994 /** 995 * Enqueue control related scripts/styles. 996 * 997 * @since 4.1.0 998 */ 999 public function enqueue() { 1000 parent::enqueue(); 1001 1002 wp_localize_script( 'customize-controls', '_wpCustomizeBackground', array( 1003 'nonces' => array( 1004 'add' => wp_create_nonce( 'background-add' ), 1005 ), 1006 ) ); 1007 } 1008 } 1009 1010 /** 1011 * Customize Cropped Image Control class. 1012 * 1013 * @since 4.3.0 1014 * 1015 * @see WP_Customize_Image_Control 1016 */ 1017 class WP_Customize_Cropped_Image_Control extends WP_Customize_Image_Control { 1018 1019 /** 1020 * Control type. 1021 * 1022 * @since 4.3.0 1023 * @access public 1024 * @var string 1025 */ 1026 public $type = 'cropped_image'; 1027 1028 /** 1029 * Suggested width for cropped image. 1030 * 1031 * @since 4.3.0 1032 * @access public 1033 * @var int 1034 */ 1035 public $width = 150; 1036 1037 /** 1038 * Suggested height for cropped image. 1039 * 1040 * @since 4.3.0 1041 * @access public 1042 * @var int 1043 */ 1044 public $height = 150; 1045 1046 /** 1047 * Whether the width is flexible. 1048 * 1049 * @since 4.3.0 1050 * @access public 1051 * @var bool 1052 */ 1053 public $flex_width = false; 1054 1055 /** 1056 * Whether the height is flexible. 1057 * 1058 * @since 4.3.0 1059 * @access public 1060 * @var bool 1061 */ 1062 public $flex_height = false; 1063 1064 /** 1065 * Enqueue control related scripts/styles. 1066 * 1067 * @since 4.3.0 1068 * @access public 1069 */ 1070 public function enqueue() { 1071 wp_enqueue_script( 'customize-views' ); 1072 1073 parent::enqueue(); 1074 } 1075 1076 /** 1077 * Refresh the parameters passed to the JavaScript via JSON. 1078 * 1079 * @since 4.3.0 1080 * @access public 1081 * 1082 * @see WP_Customize_Control::to_json() 1083 */ 1084 public function to_json() { 1085 parent::to_json(); 1086 1087 $this->json['width'] = absint( $this->width ); 1088 $this->json['height'] = absint( $this->height ); 1089 $this->json['flex_width'] = absint( $this->flex_width ); 1090 $this->json['flex_height'] = absint( $this->flex_height ); 1091 } 1092 1093 } 1094 1095 /** 1096 * Customize Site Icon control class. 1097 * 1098 * Used only for custom functionality in JavaScript. 1099 * 1100 * @since 4.3.0 1101 * 1102 * @see WP_Customize_Cropped_Image_Control 1103 */ 1104 class WP_Customize_Site_Icon_Control extends WP_Customize_Cropped_Image_Control { 1105 1106 /** 1107 * Control type. 1108 * 1109 * @since 4.3.0 1110 * @access public 1111 * @var string 1112 */ 1113 public $type = 'site_icon'; 1114 1115 /** 1116 * Constructor. 1117 * 1118 * @since 4.3.0 1119 * @access public 1120 * 1121 * @param WP_Customize_Manager $manager Customizer bootstrap instance. 1122 * @param string $id Control ID. 1123 * @param array $args Optional. Arguments to override class property defaults. 1124 */ 1125 public function __construct( $manager, $id, $args = array() ) { 1126 parent::__construct( $manager, $id, $args ); 1127 add_action( 'customize_controls_print_styles', 'wp_site_icon', 99 ); 1128 } 1129 } 1130 1131 /** 1132 * Customize Header Image Control class. 1133 * 1134 * @since 3.4.0 1135 * 1136 * @see WP_Customize_Image_Control 1137 */ 1138 class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control { 1139 public $type = 'header'; 1140 public $uploaded_headers; 1141 public $default_headers; 1142 1143 /** 1144 * Constructor. 1145 * 1146 * @since 3.4.0 1147 * 1148 * @param WP_Customize_Manager $manager Customizer bootstrap instance. 1149 */ 1150 public function __construct( $manager ) { 1151 parent::__construct( $manager, 'header_image', array( 1152 'label' => __( 'Header Image' ), 1153 'settings' => array( 1154 'default' => 'header_image', 1155 'data' => 'header_image_data', 1156 ), 1157 'section' => 'header_image', 1158 'removed' => 'remove-header', 1159 'get_url' => 'get_header_image', 1160 ) ); 1161 1162 } 1163 1164 /** 1165 * @access public 1166 */ 1167 public function enqueue() { 1168 wp_enqueue_media(); 1169 wp_enqueue_script( 'customize-views' ); 1170 1171 $this->prepare_control(); 1172 1173 wp_localize_script( 'customize-views', '_wpCustomizeHeader', array( 1174 'data' => array( 1175 'width' => absint( get_theme_support( 'custom-header', 'width' ) ), 1176 'height' => absint( get_theme_support( 'custom-header', 'height' ) ), 1177 'flex-width' => absint( get_theme_support( 'custom-header', 'flex-width' ) ), 1178 'flex-height' => absint( get_theme_support( 'custom-header', 'flex-height' ) ), 1179 'currentImgSrc' => $this->get_current_image_src(), 1180 ), 1181 'nonces' => array( 1182 'add' => wp_create_nonce( 'header-add' ), 1183 'remove' => wp_create_nonce( 'header-remove' ), 1184 ), 1185 'uploads' => $this->uploaded_headers, 1186 'defaults' => $this->default_headers 1187 ) ); 1188 1189 parent::enqueue(); 1190 } 1191 1192 /** 1193 * 1194 * @global Custom_Image_Header $custom_image_header 1195 */ 1196 public function prepare_control() { 1197 global $custom_image_header; 1198 if ( empty( $custom_image_header ) ) { 1199 return; 1200 } 1201 1202 // Process default headers and uploaded headers. 1203 $custom_image_header->process_default_headers(); 1204 $this->default_headers = $custom_image_header->get_default_header_images(); 1205 $this->uploaded_headers = $custom_image_header->get_uploaded_header_images(); 1206 } 1207 1208 /** 1209 * @access public 1210 */ 1211 public function print_header_image_template() { 1212 ?> 1213 <script type="text/template" id="tmpl-header-choice"> 1214 <# if (data.random) { #> 1215 <button type="button" class="button display-options random"> 1216 <span class="dashicons dashicons-randomize dice"></span> 1217 <# if ( data.type === 'uploaded' ) { #> 1218 <?php _e( 'Randomize uploaded headers' ); ?> 1219 <# } else if ( data.type === 'default' ) { #> 1220 <?php _e( 'Randomize suggested headers' ); ?> 1221 <# } #> 1222 </button> 1223 1224 <# } else { #> 1225 1226 <# if (data.type === 'uploaded') { #> 1227 <button type="button" class="dashicons dashicons-no close"><span class="screen-reader-text"><?php _e( 'Remove image' ); ?></span></button> 1228 <# } #> 1229 1230 <button type="button" class="choice thumbnail" 1231 data-customize-image-value="{{{data.header.url}}}" 1232 data-customize-header-image-data="{{JSON.stringify(data.header)}}"> 1233 <span class="screen-reader-text"><?php _e( 'Set image' ); ?></span> 1234 <img src="{{{data.header.thumbnail_url}}}" alt="{{{data.header.alt_text || data.header.description}}}"> 1235 </button> 1236 1237 <# } #> 1238 </script> 1239 1240 <script type="text/template" id="tmpl-header-current"> 1241 <# if (data.choice) { #> 1242 <# if (data.random) { #> 1243 1244 <div class="placeholder"> 1245 <div class="inner"> 1246 <span><span class="dashicons dashicons-randomize dice"></span> 1247 <# if ( data.type === 'uploaded' ) { #> 1248 <?php _e( 'Randomizing uploaded headers' ); ?> 1249 <# } else if ( data.type === 'default' ) { #> 1250 <?php _e( 'Randomizing suggested headers' ); ?> 1251 <# } #> 1252 </span> 1253 </div> 1254 </div> 1255 1256 <# } else { #> 1257 1258 <img src="{{{data.header.thumbnail_url}}}" alt="{{{data.header.alt_text || data.header.description}}}" tabindex="0"/> 1259 1260 <# } #> 1261 <# } else { #> 1262 1263 <div class="placeholder"> 1264 <div class="inner"> 1265 <span> 1266 <?php _e( 'No image set' ); ?> 1267 </span> 1268 </div> 1269 </div> 1270 1271 <# } #> 1272 </script> 1273 <?php 1274 } 1275 1276 /** 1277 * @return string|void 1278 */ 1279 public function get_current_image_src() { 1280 $src = $this->value(); 1281 if ( isset( $this->get_url ) ) { 1282 $src = call_user_func( $this->get_url, $src ); 1283 return $src; 1284 } 1285 } 1286 1287 /** 1288 * @access public 1289 */ 1290 public function render_content() { 1291 $this->print_header_image_template(); 1292 $visibility = $this->get_current_image_src() ? '' : ' style="display:none" '; 1293 $width = absint( get_theme_support( 'custom-header', 'width' ) ); 1294 $height = absint( get_theme_support( 'custom-header', 'height' ) ); 1295 ?> 1296 <div class="customize-control-content"> 1297 <p class="customizer-section-intro"> 1298 <?php 1299 if ( $width && $height ) { 1300 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 × %s</strong> pixels.' ), $width, $height ); 1301 } elseif ( $width ) { 1302 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 ); 1303 } else { 1304 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 ); 1305 } 1306 ?> 1307 </p> 1308 <div class="current"> 1309 <label for="header_image-button"> 1310 <span class="customize-control-title"> 1311 <?php _e( 'Current header' ); ?> 1312 </span> 1313 </label> 1314 <div class="container"> 1315 </div> 1316 </div> 1317 <div class="actions"> 1318 <?php if ( current_user_can( 'upload_files' ) ): ?> 1319 <button type="button"<?php echo $visibility; ?> class="button remove" aria-label="<?php esc_attr_e( 'Hide header image' ); ?>"><?php _e( 'Hide image' ); ?></button> 1320 <button type="button" class="button new" id="header_image-button" aria-label="<?php esc_attr_e( 'Add new header image' ); ?>"><?php _e( 'Add new image' ); ?></button> 1321 <div style="clear:both"></div> 1322 <?php endif; ?> 1323 </div> 1324 <div class="choices"> 1325 <span class="customize-control-title header-previously-uploaded"> 1326 <?php _ex( 'Previously uploaded', 'custom headers' ); ?> 1327 </span> 1328 <div class="uploaded"> 1329 <div class="list"> 1330 </div> 1331 </div> 1332 <span class="customize-control-title header-default"> 1333 <?php _ex( 'Suggested', 'custom headers' ); ?> 1334 </span> 1335 <div class="default"> 1336 <div class="list"> 1337 </div> 1338 </div> 1339 </div> 1340 </div> 1341 <?php 1342 } 1343 } 1344 1345 /** 1346 * Customize Theme Control class. 1347 * 1348 * @since 4.2.0 1349 * 1350 * @see WP_Customize_Control 1351 */ 1352 class WP_Customize_Theme_Control extends WP_Customize_Control { 1353 1354 /** 1355 * Customize control type. 1356 * 1357 * @since 4.2.0 1358 * @access public 1359 * @var string 1360 */ 1361 public $type = 'theme'; 1362 1363 /** 1364 * Theme object. 1365 * 1366 * @since 4.2.0 1367 * @access public 1368 * @var WP_Theme 1369 */ 1370 public $theme; 1371 1372 /** 1373 * Refresh the parameters passed to the JavaScript via JSON. 1374 * 1375 * @since 4.2.0 1376 * @access public 1377 * 1378 * @see WP_Customize_Control::to_json() 1379 */ 1380 public function to_json() { 1381 parent::to_json(); 1382 $this->json['theme'] = $this->theme; 1383 } 1384 1385 /** 1386 * Don't render the control content from PHP, as it's rendered via JS on load. 1387 * 1388 * @since 4.2.0 1389 * @access public 1390 */ 1391 public function render_content() {} 1392 1393 /** 1394 * Render a JS template for theme display. 1395 * 1396 * @since 4.2.0 1397 * @access public 1398 */ 1399 public function content_template() { 1400 $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); 1401 $active_url = esc_url( remove_query_arg( 'theme', $current_url ) ); 1402 $preview_url = esc_url( add_query_arg( 'theme', '__THEME__', $current_url ) ); // Token because esc_url() strips curly braces. 1403 $preview_url = str_replace( '__THEME__', '{{ data.theme.id }}', $preview_url ); 1404 ?> 1405 <# if ( data.theme.isActiveTheme ) { #> 1406 <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"> 1407 <# } else { #> 1408 <div class="theme" tabindex="0" data-preview-url="<?php echo esc_attr( $preview_url ); ?>" aria-describedby="{{ data.theme.id }}-action {{ data.theme.id }}-name"> 1409 <# } #> 1410 1411 <# if ( data.theme.screenshot[0] ) { #> 1412 <div class="theme-screenshot"> 1413 <img data-src="{{ data.theme.screenshot[0] }}" alt="" /> 1414 </div> 1415 <# } else { #> 1416 <div class="theme-screenshot blank"></div> 1417 <# } #> 1418 1419 <# if ( data.theme.isActiveTheme ) { #> 1420 <span class="more-details" id="{{ data.theme.id }}-action"><?php _e( 'Customize' ); ?></span> 1421 <# } else { #> 1422 <span class="more-details" id="{{ data.theme.id }}-action"><?php _e( 'Live Preview' ); ?></span> 1423 <# } #> 1424 1425 <div class="theme-author"><?php printf( __( 'By %s' ), '{{ data.theme.author }}' ); ?></div> 1426 1427 <# if ( data.theme.isActiveTheme ) { #> 1428 <h3 class="theme-name" id="{{ data.theme.id }}-name"> 1429 <?php 1430 /* translators: %s: theme name */ 1431 printf( __( '<span>Active:</span> %s' ), '{{{ data.theme.name }}}' ); 1432 ?> 1433 </h3> 1434 <# } else { #> 1435 <h3 class="theme-name" id="{{ data.theme.id }}-name">{{{ data.theme.name }}}</h3> 1436 <div class="theme-actions"> 1437 <button type="button" class="button theme-details"><?php _e( 'Theme Details' ); ?></button> 1438 </div> 1439 <# } #> 1440 </div> 1441 <?php 1442 } 1443 } 1444 1445 /** 1446 * Widget Area Customize Control class. 1447 * 1448 * @since 3.9.0 1449 * 1450 * @see WP_Customize_Control 1451 */ 1452 class WP_Widget_Area_Customize_Control extends WP_Customize_Control { 1453 public $type = 'sidebar_widgets'; 1454 public $sidebar_id; 1455 1456 public function to_json() { 1457 parent::to_json(); 1458 $exported_properties = array( 'sidebar_id' ); 1459 foreach ( $exported_properties as $key ) { 1460 $this->json[ $key ] = $this->$key; 1461 } 1462 } 1463 1464 /** 1465 * @access public 1466 */ 1467 public function render_content() { 1468 $id = 'reorder-widgets-desc-' . str_replace( array( '[', ']' ), array( '-', '' ), $this->id ); 1469 ?> 1470 <button type="button" class="button-secondary add-new-widget" aria-expanded="false" aria-controls="available-widgets"> 1471 <?php _e( 'Add a Widget' ); ?> 1472 </button> 1473 <button type="button" class="not-a-button reorder-toggle" aria-label="<?php esc_attr_e( 'Reorder widgets' ); ?>" aria-describedby="<?php echo esc_attr( $id ); ?>"> 1474 <span class="reorder"><?php _ex( 'Reorder', 'Reorder widgets in Customizer' ); ?></span> 1475 <span class="reorder-done"><?php _ex( 'Done', 'Cancel reordering widgets in Customizer' ); ?></span> 1476 </button> 1477 <p class="screen-reader-text" id="<?php echo esc_attr( $id ); ?>"><?php _e( 'When in reorder mode, additional controls to reorder widgets will be available in the widgets list above.' ); ?></p> 1478 <?php 1479 } 1480 1481 } 1482 1483 /** 1484 * Widget Form Customize Control class. 1485 * 1486 * @since 3.9.0 1487 * 1488 * @see WP_Customize_Control 1489 */ 1490 class WP_Widget_Form_Customize_Control extends WP_Customize_Control { 1491 public $type = 'widget_form'; 1492 public $widget_id; 1493 public $widget_id_base; 1494 public $sidebar_id; 1495 public $is_new = false; 1496 public $width; 1497 public $height; 1498 public $is_wide = false; 1499 1500 /** 1501 * Gather control params for exporting to JavaScript. 1502 * 1503 * @global array $wp_registered_widgets 1504 */ 1505 public function to_json() { 1506 global $wp_registered_widgets; 1507 1508 parent::to_json(); 1509 $exported_properties = array( 'widget_id', 'widget_id_base', 'sidebar_id', 'width', 'height', 'is_wide' ); 1510 foreach ( $exported_properties as $key ) { 1511 $this->json[ $key ] = $this->$key; 1512 } 1513 1514 // Get the widget_control and widget_content. 1515 require_once ABSPATH . '/wp-admin/includes/widgets.php'; 1516 1517 $widget = $wp_registered_widgets[ $this->widget_id ]; 1518 if ( ! isset( $widget['params'][0] ) ) { 1519 $widget['params'][0] = array(); 1520 } 1521 1522 $args = array( 1523 'widget_id' => $widget['id'], 1524 'widget_name' => $widget['name'], 1525 ); 1526 1527 $args = wp_list_widget_controls_dynamic_sidebar( array( 0 => $args, 1 => $widget['params'][0] ) ); 1528 $widget_control_parts = $this->manager->widgets->get_widget_control_parts( $args ); 1529 1530 $this->json['widget_control'] = $widget_control_parts['control']; 1531 $this->json['widget_content'] = $widget_control_parts['content']; 1532 } 1533 1534 /** 1535 * Override render_content to be no-op since content is exported via to_json for deferred embedding. 1536 */ 1537 public function render_content() {} 1538 1539 /** 1540 * Whether the current widget is rendered on the page. 1541 * 1542 * @since 4.0.0 1543 * @access public 1544 * 1545 * @return bool Whether the widget is rendered. 1546 */ 1547 public function active_callback() { 1548 return $this->manager->widgets->is_widget_rendered( $this->widget_id ); 1549 } 1550 } 1551 1552 /** 1553 * Customize Nav Menu Control Class. 1554 * 1555 * @since 4.3.0 1556 */ 1557 class WP_Customize_Nav_Menu_Control extends WP_Customize_Control { 1558 1559 /** 1560 * Control type. 1561 * 1562 * @since 4.3.0 1563 * @access public 1564 * @var string 1565 */ 1566 public $type = 'nav_menu'; 1567 1568 /** 1569 * The nav menu setting. 1570 * 1571 * @since 4.3.0 1572 * @access public 1573 * @var WP_Customize_Nav_Menu_Setting 1574 */ 1575 public $setting; 1576 1577 /** 1578 * Don't render the control's content - it uses a JS template instead. 1579 * 1580 * @since 4.3.0 1581 * @access public 1582 */ 1583 public function render_content() {} 1584 1585 /** 1586 * JS/Underscore template for the control UI. 1587 * 1588 * @since 4.3.0 1589 * @access public 1590 */ 1591 public function content_template() { 1592 ?> 1593 <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"> 1594 <?php _e( 'Add Items' ); ?> 1595 </button> 1596 <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 }}"> 1597 <span class="reorder"><?php _ex( 'Reorder', 'Reorder menu items in Customizer' ); ?></span> 1598 <span class="reorder-done"><?php _ex( 'Done', 'Cancel reordering menu items in Customizer' ); ?></span> 1599 </button> 1600 <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> 1601 <span class="add-menu-item-loading spinner"></span> 1602 <span class="menu-delete-item"> 1603 <button type="button" class="not-a-button menu-delete"> 1604 <?php _e( 'Delete menu' ); ?> <span class="screen-reader-text">{{ data.menu_name }}</span> 1605 </button> 1606 </span> 1607 <?php if ( current_theme_supports( 'menus' ) ) : ?> 1608 <ul class="menu-settings"> 1609 <li class="customize-control"> 1610 <span class="customize-control-title"><?php _e( 'Menu locations' ); ?></span> 1611 </li> 1612 1613 <?php foreach ( get_registered_nav_menus() as $location => $description ) : ?> 1614 <li class="customize-control customize-control-checkbox assigned-menu-location"> 1615 <label> 1616 <input type="checkbox" data-menu-id="{{ data.menu_id }}" data-location-id="<?php echo esc_attr( $location ); ?>" class="menu-location" /> <?php echo $description; ?> 1617 <span class="theme-location-set"><?php printf( _x( '(Current: %s)', 'Current menu location' ), '<span class="current-menu-location-name-' . esc_attr( $location ) . '"></span>' ); ?></span> 1618 </label> 1619 </li> 1620 <?php endforeach; ?> 1621 1622 </ul> 1623 <?php endif; 1624 } 1625 1626 /** 1627 * Return parameters for this control. 1628 * 1629 * @since 4.3.0 1630 * @access public 1631 * 1632 * @return array Exported parameters. 1633 */ 1634 public function json() { 1635 $exported = parent::json(); 1636 $exported['menu_id'] = $this->setting->term_id; 1637 1638 return $exported; 1639 } 1640 } 1641 1642 /** 1643 * Customize control to represent the name field for a given menu. 1644 * 1645 * @since 4.3.0 1646 */ 1647 class WP_Customize_Nav_Menu_Item_Control extends WP_Customize_Control { 1648 1649 /** 1650 * Control type. 1651 * 1652 * @since 4.3.0 1653 * @access public 1654 * @var string 1655 */ 1656 public $type = 'nav_menu_item'; 1657 1658 /** 1659 * The nav menu item setting. 1660 * 1661 * @since 4.3.0 1662 * @access public 1663 * @var WP_Customize_Nav_Menu_Item_Setting 1664 */ 1665 public $setting; 1666 1667 /** 1668 * Constructor. 1669 * 1670 * @since 4.3.0 1671 * @access public 1672 * 1673 * @see WP_Customize_Control::__construct() 1674 * 1675 * @param WP_Customize_Manager $manager Customizer bootstrap instance. 1676 * @param string $id The control ID. 1677 * @param array $args Optional. Overrides class property defaults. 1678 */ 1679 public function __construct( $manager, $id, $args = array() ) { 1680 parent::__construct( $manager, $id, $args ); 1681 } 1682 1683 /** 1684 * Don't render the control's content - it's rendered with a JS template. 1685 * 1686 * @since 4.3.0 1687 * @access public 1688 */ 1689 public function render_content() {} 1690 1691 /** 1692 * JS/Underscore template for the control UI. 1693 * 1694 * @since 4.3.0 1695 * @access public 1696 */ 1697 public function content_template() { 1698 ?> 1699 <div class="menu-item-bar"> 1700 <div class="menu-item-handle"> 1701 <span class="item-type" aria-hidden="true">{{ data.item_type_label }}</span> 1702 <span class="item-title" aria-hidden="true"> 1703 <span class="spinner"></span> 1704 <span class="menu-item-title<# if ( ! data.title ) { #> no-title<# } #>">{{ data.title || wp.customize.Menus.data.l10n.untitled }}</span> 1705 </span> 1706 <span class="item-controls"> 1707 <button type="button" class="not-a-button item-edit" aria-expanded="false"><span class="screen-reader-text"><?php 1708 /* translators: 1: Title of a menu item, 2: Type of a menu item */ 1709 printf( __( 'Edit menu item: %1$s (%2$s)' ), '{{ data.title || wp.customize.Menus.data.l10n.untitled }}', '{{ data.item_type_label }}' ); 1710 ?></span><span class="toggle-indicator" aria-hidden="true"></span></button> 1711 <button type="button" class="not-a-button item-delete submitdelete deletion"><span class="screen-reader-text"><?php 1712 /* translators: 1: Title of a menu item, 2: Type of a menu item */ 1713 printf( __( 'Remove Menu Item: %1$s (%2$s)' ), '{{ data.title || wp.customize.Menus.data.l10n.untitled }}', '{{ data.item_type_label }}' ); 1714 ?></span></button> 1715 </span> 1716 </div> 1717 </div> 1718 1719 <div class="menu-item-settings" id="menu-item-settings-{{ data.menu_item_id }}"> 1720 <# if ( 'custom' === data.item_type ) { #> 1721 <p class="field-url description description-thin"> 1722 <label for="edit-menu-item-url-{{ data.menu_item_id }}"> 1723 <?php _e( 'URL' ); ?><br /> 1724 <input class="widefat code edit-menu-item-url" type="text" id="edit-menu-item-url-{{ data.menu_item_id }}" name="menu-item-url" /> 1725 </label> 1726 </p> 1727 <# } #> 1728 <p class="description description-thin"> 1729 <label for="edit-menu-item-title-{{ data.menu_item_id }}"> 1730 <?php _e( 'Navigation Label' ); ?><br /> 1731 <input type="text" id="edit-menu-item-title-{{ data.menu_item_id }}" class="widefat edit-menu-item-title" name="menu-item-title" /> 1732 </label> 1733 </p> 1734 <p class="field-link-target description description-thin"> 1735 <label for="edit-menu-item-target-{{ data.menu_item_id }}"> 1736 <input type="checkbox" id="edit-menu-item-target-{{ data.menu_item_id }}" class="edit-menu-item-target" value="_blank" name="menu-item-target" /> 1737 <?php _e( 'Open link in a new tab' ); ?> 1738 </label> 1739 </p> 1740 <p class="field-attr-title description description-thin"> 1741 <label for="edit-menu-item-attr-title-{{ data.menu_item_id }}"> 1742 <?php _e( 'Title Attribute' ); ?><br /> 1743 <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" /> 1744 </label> 1745 </p> 1746 <p class="field-css-classes description description-thin"> 1747 <label for="edit-menu-item-classes-{{ data.menu_item_id }}"> 1748 <?php _e( 'CSS Classes' ); ?><br /> 1749 <input type="text" id="edit-menu-item-classes-{{ data.menu_item_id }}" class="widefat code edit-menu-item-classes" name="menu-item-classes" /> 1750 </label> 1751 </p> 1752 <p class="field-xfn description description-thin"> 1753 <label for="edit-menu-item-xfn-{{ data.menu_item_id }}"> 1754 <?php _e( 'Link Relationship (XFN)' ); ?><br /> 1755 <input type="text" id="edit-menu-item-xfn-{{ data.menu_item_id }}" class="widefat code edit-menu-item-xfn" name="menu-item-xfn" /> 1756 </label> 1757 </p> 1758 <p class="field-description description description-thin"> 1759 <label for="edit-menu-item-description-{{ data.menu_item_id }}"> 1760 <?php _e( 'Description' ); ?><br /> 1761 <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> 1762 <span class="description"><?php _e( 'The description will be displayed in the menu if the current theme supports it.' ); ?></span> 1763 </label> 1764 </p> 1765 1766 <div class="menu-item-actions description-thin submitbox"> 1767 <# if ( ( 'post_type' === data.item_type || 'taxonomy' === data.item_type ) && '' !== data.original_title ) { #> 1768 <p class="link-to-original"> 1769 <?php printf( __( 'Original: %s' ), '<a class="original-link" href="{{ data.url }}">{{ data.original_title }}</a>' ); ?> 1770 </p> 1771 <# } #> 1772 1773 <button type="button" class="not-a-button item-delete submitdelete deletion"><?php _e( 'Remove' ); ?></button> 1774 <span class="spinner"></span> 1775 </div> 1776 <input type="hidden" name="menu-item-db-id[{{ data.menu_item_id }}]" class="menu-item-data-db-id" value="{{ data.menu_item_id }}" /> 1777 <input type="hidden" name="menu-item-parent-id[{{ data.menu_item_id }}]" class="menu-item-data-parent-id" value="{{ data.parent }}" /> 1778 </div><!-- .menu-item-settings--> 1779 <ul class="menu-item-transport"></ul> 1780 <?php 1781 } 1782 1783 /** 1784 * Return parameters for this control. 1785 * 1786 * @since 4.3.0 1787 * @access public 1788 * 1789 * @return array Exported parameters. 1790 */ 1791 public function json() { 1792 $exported = parent::json(); 1793 $exported['menu_item_id'] = $this->setting->post_id; 1794 1795 return $exported; 1796 } 1797 } 1798 1799 /** 1800 * Customize Menu Location Control Class. 1801 * 1802 * This custom control is only needed for JS. 1803 * 1804 * @since 4.3.0 1805 * 1806 * @see WP_Customize_Control 1807 */ 1808 class WP_Customize_Nav_Menu_Location_Control extends WP_Customize_Control { 1809 1810 /** 1811 * Control type. 1812 * 1813 * @since 4.3.0 1814 * @access public 1815 * @var string 1816 */ 1817 public $type = 'nav_menu_location'; 1818 1819 /** 1820 * Location ID. 1821 * 1822 * @since 4.3.0 1823 * @access public 1824 * @var string 1825 */ 1826 public $location_id = ''; 1827 1828 /** 1829 * Refresh the parameters passed to JavaScript via JSON. 1830 * 1831 * @since 4.3.0 1832 * @access public 1833 * 1834 * @see WP_Customize_Control::to_json() 1835 */ 1836 public function to_json() { 1837 parent::to_json(); 1838 $this->json['locationId'] = $this->location_id; 1839 } 1840 1841 /** 1842 * Render content just like a normal select control. 1843 * 1844 * @since 4.3.0 1845 * @access public 1846 */ 1847 public function render_content() { 1848 if ( empty( $this->choices ) ) { 1849 return; 1850 } 1851 ?> 1852 <label> 1853 <?php if ( ! empty( $this->label ) ) : ?> 1854 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span> 1855 <?php endif; ?> 1856 1857 <?php if ( ! empty( $this->description ) ) : ?> 1858 <span class="description customize-control-description"><?php echo $this->description; ?></span> 1859 <?php endif; ?> 1860 1861 <select <?php $this->link(); ?>> 1862 <?php 1863 foreach ( $this->choices as $value => $label ) : 1864 echo '<option value="' . esc_attr( $value ) . '"' . selected( $this->value(), $value, false ) . '>' . $label . '</option>'; 1865 endforeach; 1866 ?> 1867 </select> 1868 </label> 1869 <?php 1870 } 1871 } 1872 1873 /** 1874 * Customize control to represent the name field for a given menu. 1875 * 1876 * @since 4.3.0 1877 * 1878 * @see WP_Customize_Control 1879 */ 1880 class WP_Customize_Nav_Menu_Name_Control extends WP_Customize_Control { 1881 1882 /** 1883 * Type of control, used by JS. 1884 * 1885 * @since 4.3.0 1886 * @access public 1887 * @var string 1888 */ 1889 public $type = 'nav_menu_name'; 1890 1891 /** 1892 * No-op since we're using JS template. 1893 * 1894 * @since 4.3.0 1895 * @access protected 1896 */ 1897 protected function render_content() {} 1898 1899 /** 1900 * Render the Underscore template for this control. 1901 * 1902 * @since 4.3.0 1903 * @access protected 1904 */ 1905 protected function content_template() { 1906 ?> 1907 <label> 1908 <# if ( data.label ) { #> 1909 <span class="customize-control-title screen-reader-text">{{ data.label }}</span> 1910 <# } #> 1911 <input type="text" class="menu-name-field live-update-section-title" /> 1912 </label> 1913 <?php 1914 } 1915 } 1916 1917 /** 1918 * Customize control to represent the auto_add field for a given menu. 1919 * 1920 * @since 4.3.0 1921 * 1922 * @see WP_Customize_Control 1923 */ 1924 class WP_Customize_Nav_Menu_Auto_Add_Control extends WP_Customize_Control { 1925 1926 /** 1927 * Type of control, used by JS. 1928 * 1929 * @since 4.3.0 1930 * @access public 1931 * @var string 1932 */ 1933 public $type = 'nav_menu_auto_add'; 1934 1935 /** 1936 * No-op since we're using JS template. 1937 * 1938 * @since 4.3.0 1939 * @access protected 1940 */ 1941 protected function render_content() {} 1942 1943 /** 1944 * Render the Underscore template for this control. 1945 * 1946 * @since 4.3.0 1947 * @access protected 1948 */ 1949 protected function content_template() { 1950 ?> 1951 <span class="customize-control-title"><?php _e( 'Menu options' ); ?></span> 1952 <label> 1953 <input type="checkbox" class="auto_add" /> 1954 <?php _e( 'Automatically add new top-level pages to this menu' ); ?> 1955 </label> 1956 <?php 1957 } 1958 } 1959 1960 /** 1961 * Customize control class for new menus. 1962 * 1963 * @since 4.3.0 1964 * 1965 * @see WP_Customize_Control 1966 */ 1967 class WP_Customize_New_Menu_Control extends WP_Customize_Control { 1968 1969 /** 1970 * Control type. 1971 * 1972 * @since 4.3.0 1973 * @access public 1974 * @var string 1975 */ 1976 public $type = 'new_menu'; 1977 1978 /** 1979 * Render the control's content. 1980 * 1981 * @since 4.3.0 1982 * @access public 1983 */ 1984 public function render_content() { 1985 ?> 1986 <button type="button" class="button button-primary" id="create-new-menu-submit"><?php _e( 'Create Menu' ); ?></button> 1987 <span class="spinner"></span> 1988 <?php 1989 } 1990 } 552 /** WP_Customize_Color_Control class */ 553 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-color-control.php' ); 554 555 /** WP_Customize_Media_Control class */ 556 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-media-control.php' ); 557 558 /** WP_Customize_Upload_Control class */ 559 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-upload-control.php' ); 560 561 /** WP_Customize_Image_Control class */ 562 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-image-control.php' ); 563 564 /** WP_Customize_Background_Image_Control class */ 565 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-background-image-control.php' ); 566 567 /** WP_Customize_Cropped_Image_Control class */ 568 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-cropped-image-control.php' ); 569 570 /** WP_Customize_Site_Icon_Control class */ 571 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-site-icon-control.php' ); 572 573 /** WP_Customize_Header_Image_Control class */ 574 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-header-image-control.php' ); 575 576 /** WP_Customize_Theme_Control class */ 577 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-theme-control.php' ); 578 579 /** WP_Widget_Area_Customize_Control class */ 580 require_once( ABSPATH . WPINC . '/customize/class-wp-widget-area-customize-control.php' ); 581 582 /** WP_Widget_Form_Customize_Control class */ 583 require_once( ABSPATH . WPINC . '/customize/class-wp-widget-form-customize-control.php' ); 584 585 /** WP_Customize_Nav_Menu_Control class */ 586 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-control.php' ); 587 588 /** WP_Customize_Nav_Menu_Item_Control class */ 589 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-item-control.php' ); 590 591 /** WP_Customize_Nav_Menu_Location_Control class */ 592 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-location-control.php' ); 593 594 /** WP_Customize_Nav_Menu_Name_Control class */ 595 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-name-control.php' ); 596 597 /** WP_Customize_Nav_Menu_Auto_Add_Control class */ 598 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-auto-add-control.php' ); 599 600 /** WP_Customize_New_Menu_Control class */ 601 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-control.php' ); -
trunk/src/wp-includes/customize/class-wp-customize-background-image-control.php
r35381 r35389 1 1 <?php 2 2 /** 3 * WordPress Customize Control classes3 * Customize API: WP_Customize_Background_Image_Control class 4 4 * 5 5 * @package WordPress 6 6 * @subpackage Customize 7 * @since 3.4.07 * @since 4.4.0 8 8 */ 9 10 /**11 * Customize Control class.12 *13 * @since 3.4.014 */15 class WP_Customize_Control {16 17 /**18 * Incremented with each new class instantiation, then stored in $instance_number.19 *20 * Used when sorting two instances whose priorities are equal.21 *22 * @since 4.1.023 *24 * @static25 * @access protected26 * @var int27 */28 protected static $instance_count = 0;29 30 /**31 * Order in which this instance was created in relation to other instances.32 *33 * @since 4.1.034 * @access public35 * @var int36 */37 public $instance_number;38 39 /**40 * @access public41 * @var WP_Customize_Manager42 */43 public $manager;44 45 /**46 * @access public47 * @var string48 */49 public $id;50 51 /**52 * All settings tied to the control.53 *54 * @access public55 * @var array56 */57 public $settings;58 59 /**60 * The primary setting for the control (if there is one).61 *62 * @access public63 * @var string64 */65 public $setting = 'default';66 67 /**68 * @access public69 * @var int70 */71 public $priority = 10;72 73 /**74 * @access public75 * @var string76 */77 public $section = '';78 79 /**80 * @access public81 * @var string82 */83 public $label = '';84 85 /**86 * @access public87 * @var string88 */89 public $description = '';90 91 /**92 * @todo: Remove choices93 *94 * @access public95 * @var array96 */97 public $choices = array();98 99 /**100 * @access public101 * @var array102 */103 public $input_attrs = array();104 105 /**106 * @deprecated It is better to just call the json() method107 * @access public108 * @var array109 */110 public $json = array();111 112 /**113 * @access public114 * @var string115 */116 public $type = 'text';117 118 /**119 * Callback.120 *121 * @since 4.0.0122 * @access public123 *124 * @see WP_Customize_Control::active()125 *126 * @var callable Callback is called with one argument, the instance of127 * WP_Customize_Control, and returns bool to indicate whether128 * the control is active (such as it relates to the URL129 * currently being previewed).130 */131 public $active_callback = '';132 133 /**134 * Constructor.135 *136 * Supplied $args override class property defaults.137 *138 * If $args['settings'] is not defined, use the $id as the setting ID.139 *140 * @since 3.4.0141 *142 * @param WP_Customize_Manager $manager Customizer bootstrap instance.143 * @param string $id Control ID.144 * @param array $args Optional. Arguments to override class property defaults.145 */146 public function __construct( $manager, $id, $args = array() ) {147 $keys = array_keys( get_object_vars( $this ) );148 foreach ( $keys as $key ) {149 if ( isset( $args[ $key ] ) ) {150 $this->$key = $args[ $key ];151 }152 }153 154 $this->manager = $manager;155 $this->id = $id;156 if ( empty( $this->active_callback ) ) {157 $this->active_callback = array( $this, 'active_callback' );158 }159 self::$instance_count += 1;160 $this->instance_number = self::$instance_count;161 162 // Process settings.163 if ( empty( $this->settings ) ) {164 $this->settings = $id;165 }166 167 $settings = array();168 if ( is_array( $this->settings ) ) {169 foreach ( $this->settings as $key => $setting ) {170 $settings[ $key ] = $this->manager->get_setting( $setting );171 }172 } else {173 $this->setting = $this->manager->get_setting( $this->settings );174 $settings['default'] = $this->setting;175 }176 $this->settings = $settings;177 }178 179 /**180 * Enqueue control related scripts/styles.181 *182 * @since 3.4.0183 */184 public function enqueue() {}185 186 /**187 * Check whether control is active to current Customizer preview.188 *189 * @since 4.0.0190 * @access public191 *192 * @return bool Whether the control is active to the current preview.193 */194 final public function active() {195 $control = $this;196 $active = call_user_func( $this->active_callback, $this );197 198 /**199 * Filter response of WP_Customize_Control::active().200 *201 * @since 4.0.0202 *203 * @param bool $active Whether the Customizer control is active.204 * @param WP_Customize_Control $control WP_Customize_Control instance.205 */206 $active = apply_filters( 'customize_control_active', $active, $control );207 208 return $active;209 }210 211 /**212 * Default callback used when invoking WP_Customize_Control::active().213 *214 * Subclasses can override this with their specific logic, or they may215 * provide an 'active_callback' argument to the constructor.216 *217 * @since 4.0.0218 * @access public219 *220 * @return true Always true.221 */222 public function active_callback() {223 return true;224 }225 226 /**227 * Fetch a setting's value.228 * Grabs the main setting by default.229 *230 * @since 3.4.0231 *232 * @param string $setting_key233 * @return mixed The requested setting's value, if the setting exists.234 */235 final public function value( $setting_key = 'default' ) {236 if ( isset( $this->settings[ $setting_key ] ) ) {237 return $this->settings[ $setting_key ]->value();238 }239 }240 241 /**242 * Refresh the parameters passed to the JavaScript via JSON.243 *244 * @since 3.4.0245 */246 public function to_json() {247 $this->json['settings'] = array();248 foreach ( $this->settings as $key => $setting ) {249 $this->json['settings'][ $key ] = $setting->id;250 }251 252 $this->json['type'] = $this->type;253 $this->json['priority'] = $this->priority;254 $this->json['active'] = $this->active();255 $this->json['section'] = $this->section;256 $this->json['content'] = $this->get_content();257 $this->json['label'] = $this->label;258 $this->json['description'] = $this->description;259 $this->json['instanceNumber'] = $this->instance_number;260 }261 262 /**263 * Get the data to export to the client via JSON.264 *265 * @since 4.1.0266 *267 * @return array Array of parameters passed to the JavaScript.268 */269 public function json() {270 $this->to_json();271 return $this->json;272 }273 274 /**275 * Check if the theme supports the control and check user capabilities.276 *277 * @since 3.4.0278 *279 * @return bool False if theme doesn't support the control or user doesn't have the required permissions, otherwise true.280 */281 final public function check_capabilities() {282 foreach ( $this->settings as $setting ) {283 if ( ! $setting->check_capabilities() )284 return false;285 }286 287 $section = $this->manager->get_section( $this->section );288 if ( isset( $section ) && ! $section->check_capabilities() )289 return false;290 291 return true;292 }293 294 /**295 * Get the control's content for insertion into the Customizer pane.296 *297 * @since 4.1.0298 *299 * @return string Contents of the control.300 */301 final public function get_content() {302 ob_start();303 $this->maybe_render();304 return trim( ob_get_clean() );305 }306 307 /**308 * Check capabilities and render the control.309 *310 * @since 3.4.0311 * @uses WP_Customize_Control::render()312 */313 final public function maybe_render() {314 if ( ! $this->check_capabilities() )315 return;316 317 /**318 * Fires just before the current Customizer control is rendered.319 *320 * @since 3.4.0321 *322 * @param WP_Customize_Control $this WP_Customize_Control instance.323 */324 do_action( 'customize_render_control', $this );325 326 /**327 * Fires just before a specific Customizer control is rendered.328 *329 * The dynamic portion of the hook name, `$this->id`, refers to330 * the control ID.331 *332 * @since 3.4.0333 *334 * @param WP_Customize_Control $this {@see WP_Customize_Control} instance.335 */336 do_action( 'customize_render_control_' . $this->id, $this );337 338 $this->render();339 }340 341 /**342 * Renders the control wrapper and calls $this->render_content() for the internals.343 *344 * @since 3.4.0345 */346 protected function render() {347 $id = 'customize-control-' . str_replace( array( '[', ']' ), array( '-', '' ), $this->id );348 $class = 'customize-control customize-control-' . $this->type;349 350 ?><li id="<?php echo esc_attr( $id ); ?>" class="<?php echo esc_attr( $class ); ?>">351 <?php $this->render_content(); ?>352 </li><?php353 }354 355 /**356 * Get the data link attribute for a setting.357 *358 * @since 3.4.0359 *360 * @param string $setting_key361 * @return string Data link parameter, if $setting_key is a valid setting, empty string otherwise.362 */363 public function get_link( $setting_key = 'default' ) {364 if ( ! isset( $this->settings[ $setting_key ] ) )365 return '';366 367 return 'data-customize-setting-link="' . esc_attr( $this->settings[ $setting_key ]->id ) . '"';368 }369 370 /**371 * Render the data link attribute for the control's input element.372 *373 * @since 3.4.0374 * @uses WP_Customize_Control::get_link()375 *376 * @param string $setting_key377 */378 public function link( $setting_key = 'default' ) {379 echo $this->get_link( $setting_key );380 }381 382 /**383 * Render the custom attributes for the control's input element.384 *385 * @since 4.0.0386 * @access public387 */388 public function input_attrs() {389 foreach ( $this->input_attrs as $attr => $value ) {390 echo $attr . '="' . esc_attr( $value ) . '" ';391 }392 }393 394 /**395 * Render the control's content.396 *397 * Allows the content to be overriden without having to rewrite the wrapper in $this->render().398 *399 * Supports basic input types `text`, `checkbox`, `textarea`, `radio`, `select` and `dropdown-pages`.400 * Additional input types such as `email`, `url`, `number`, `hidden` and `date` are supported implicitly.401 *402 * Control content can alternately be rendered in JS. See {@see WP_Customize_Control::print_template()}.403 *404 * @since 3.4.0405 */406 protected function render_content() {407 switch( $this->type ) {408 case 'checkbox':409 ?>410 <label>411 <input type="checkbox" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); checked( $this->value() ); ?> />412 <?php echo esc_html( $this->label ); ?>413 <?php if ( ! empty( $this->description ) ) : ?>414 <span class="description customize-control-description"><?php echo $this->description; ?></span>415 <?php endif; ?>416 </label>417 <?php418 break;419 case 'radio':420 if ( empty( $this->choices ) )421 return;422 423 $name = '_customize-radio-' . $this->id;424 425 if ( ! empty( $this->label ) ) : ?>426 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>427 <?php endif;428 if ( ! empty( $this->description ) ) : ?>429 <span class="description customize-control-description"><?php echo $this->description ; ?></span>430 <?php endif;431 432 foreach ( $this->choices as $value => $label ) :433 ?>434 <label>435 <input type="radio" value="<?php echo esc_attr( $value ); ?>" name="<?php echo esc_attr( $name ); ?>" <?php $this->link(); checked( $this->value(), $value ); ?> />436 <?php echo esc_html( $label ); ?><br/>437 </label>438 <?php439 endforeach;440 break;441 case 'select':442 if ( empty( $this->choices ) )443 return;444 445 ?>446 <label>447 <?php if ( ! empty( $this->label ) ) : ?>448 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>449 <?php endif;450 if ( ! empty( $this->description ) ) : ?>451 <span class="description customize-control-description"><?php echo $this->description; ?></span>452 <?php endif; ?>453 454 <select <?php $this->link(); ?>>455 <?php456 foreach ( $this->choices as $value => $label )457 echo '<option value="' . esc_attr( $value ) . '"' . selected( $this->value(), $value, false ) . '>' . $label . '</option>';458 ?>459 </select>460 </label>461 <?php462 break;463 case 'textarea':464 ?>465 <label>466 <?php if ( ! empty( $this->label ) ) : ?>467 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>468 <?php endif;469 if ( ! empty( $this->description ) ) : ?>470 <span class="description customize-control-description"><?php echo $this->description; ?></span>471 <?php endif; ?>472 <textarea rows="5" <?php $this->link(); ?>><?php echo esc_textarea( $this->value() ); ?></textarea>473 </label>474 <?php475 break;476 case 'dropdown-pages':477 ?>478 <label>479 <?php if ( ! empty( $this->label ) ) : ?>480 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>481 <?php endif;482 if ( ! empty( $this->description ) ) : ?>483 <span class="description customize-control-description"><?php echo $this->description; ?></span>484 <?php endif; ?>485 486 <?php $dropdown = wp_dropdown_pages(487 array(488 'name' => '_customize-dropdown-pages-' . $this->id,489 'echo' => 0,490 'show_option_none' => __( '— Select —' ),491 'option_none_value' => '0',492 'selected' => $this->value(),493 )494 );495 496 // Hackily add in the data link parameter.497 $dropdown = str_replace( '<select', '<select ' . $this->get_link(), $dropdown );498 echo $dropdown;499 ?>500 </label>501 <?php502 break;503 default:504 ?>505 <label>506 <?php if ( ! empty( $this->label ) ) : ?>507 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>508 <?php endif;509 if ( ! empty( $this->description ) ) : ?>510 <span class="description customize-control-description"><?php echo $this->description; ?></span>511 <?php endif; ?>512 <input type="<?php echo esc_attr( $this->type ); ?>" <?php $this->input_attrs(); ?> value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); ?> />513 </label>514 <?php515 break;516 }517 }518 519 /**520 * Render the control's JS template.521 *522 * This function is only run for control types that have been registered with523 * {@see WP_Customize_Manager::register_control_type()}.524 *525 * In the future, this will also print the template for the control's container526 * element and be override-able.527 *528 * @since 4.1.0529 */530 final public function print_template() {531 ?>532 <script type="text/html" id="tmpl-customize-control-<?php echo $this->type; ?>-content">533 <?php $this->content_template(); ?>534 </script>535 <?php536 }537 538 /**539 * An Underscore (JS) template for this control's content (but not its container).540 *541 * Class variables for this control class are available in the `data` JS object;542 * export custom variables by overriding {@see WP_Customize_Control::to_json()}.543 *544 * @see WP_Customize_Control::print_template()545 *546 * @since 4.1.0547 */548 protected function content_template() {}549 550 }551 552 /**553 * Customize Color Control class.554 *555 * @since 3.4.0556 *557 * @see WP_Customize_Control558 */559 class WP_Customize_Color_Control extends WP_Customize_Control {560 /**561 * @access public562 * @var string563 */564 public $type = 'color';565 566 /**567 * @access public568 * @var array569 */570 public $statuses;571 572 /**573 * Constructor.574 *575 * @since 3.4.0576 * @uses WP_Customize_Control::__construct()577 *578 * @param WP_Customize_Manager $manager Customizer bootstrap instance.579 * @param string $id Control ID.580 * @param array $args Optional. Arguments to override class property defaults.581 */582 public function __construct( $manager, $id, $args = array() ) {583 $this->statuses = array( '' => __('Default') );584 parent::__construct( $manager, $id, $args );585 }586 587 /**588 * Enqueue scripts/styles for the color picker.589 *590 * @since 3.4.0591 */592 public function enqueue() {593 wp_enqueue_script( 'wp-color-picker' );594 wp_enqueue_style( 'wp-color-picker' );595 }596 597 /**598 * Refresh the parameters passed to the JavaScript via JSON.599 *600 * @since 3.4.0601 * @uses WP_Customize_Control::to_json()602 */603 public function to_json() {604 parent::to_json();605 $this->json['statuses'] = $this->statuses;606 $this->json['defaultValue'] = $this->setting->default;607 }608 609 /**610 * Don't render the control content from PHP, as it's rendered via JS on load.611 *612 * @since 3.4.0613 */614 public function render_content() {}615 616 /**617 * Render a JS template for the content of the color picker control.618 *619 * @since 4.1.0620 */621 public function content_template() {622 ?>623 <# var defaultValue = '';624 if ( data.defaultValue ) {625 if ( '#' !== data.defaultValue.substring( 0, 1 ) ) {626 defaultValue = '#' + data.defaultValue;627 } else {628 defaultValue = data.defaultValue;629 }630 defaultValue = ' data-default-color=' + defaultValue; // Quotes added automatically.631 } #>632 <label>633 <# if ( data.label ) { #>634 <span class="customize-control-title">{{{ data.label }}}</span>635 <# } #>636 <# if ( data.description ) { #>637 <span class="description customize-control-description">{{{ data.description }}}</span>638 <# } #>639 <div class="customize-control-content">640 <input class="color-picker-hex" type="text" maxlength="7" placeholder="<?php esc_attr_e( 'Hex Value' ); ?>" {{ defaultValue }} />641 </div>642 </label>643 <?php644 }645 }646 647 /**648 * Customize Media Control class.649 *650 * @since 4.2.0651 *652 * @see WP_Customize_Control653 */654 class WP_Customize_Media_Control extends WP_Customize_Control {655 /**656 * Control type.657 *658 * @since 4.2.0659 * @access public660 * @var string661 */662 public $type = 'media';663 664 /**665 * Media control mime type.666 *667 * @since 4.2.0668 * @access public669 * @var string670 */671 public $mime_type = '';672 673 /**674 * Button labels.675 *676 * @since 4.2.0677 * @access public678 * @var array679 */680 public $button_labels = array();681 682 /**683 * Constructor.684 *685 * @since 4.1.0686 * @since 4.2.0 Moved from WP_Customize_Upload_Control.687 *688 * @param WP_Customize_Manager $manager Customizer bootstrap instance.689 * @param string $id Control ID.690 * @param array $args Optional. Arguments to override class property defaults.691 */692 public function __construct( $manager, $id, $args = array() ) {693 parent::__construct( $manager, $id, $args );694 695 $this->button_labels = array(696 'select' => __( 'Select File' ),697 'change' => __( 'Change File' ),698 'default' => __( 'Default' ),699 'remove' => __( 'Remove' ),700 'placeholder' => __( 'No file selected' ),701 'frame_title' => __( 'Select File' ),702 'frame_button' => __( 'Choose File' ),703 );704 }705 706 /**707 * Enqueue control related scripts/styles.708 *709 * @since 3.4.0710 * @since 4.2.0 Moved from WP_Customize_Upload_Control.711 */712 public function enqueue() {713 wp_enqueue_media();714 }715 716 /**717 * Refresh the parameters passed to the JavaScript via JSON.718 *719 * @since 3.4.0720 * @since 4.2.0 Moved from WP_Customize_Upload_Control.721 *722 * @see WP_Customize_Control::to_json()723 */724 public function to_json() {725 parent::to_json();726 $this->json['label'] = html_entity_decode( $this->label, ENT_QUOTES, get_bloginfo( 'charset' ) );727 $this->json['mime_type'] = $this->mime_type;728 $this->json['button_labels'] = $this->button_labels;729 $this->json['canUpload'] = current_user_can( 'upload_files' );730 731 $value = $this->value();732 733 if ( is_object( $this->setting ) ) {734 if ( $this->setting->default ) {735 // Fake an attachment model - needs all fields used by template.736 // Note that the default value must be a URL, NOT an attachment ID.737 $type = in_array( substr( $this->setting->default, -3 ), array( 'jpg', 'png', 'gif', 'bmp' ) ) ? 'image' : 'document';738 $default_attachment = array(739 'id' => 1,740 'url' => $this->setting->default,741 'type' => $type,742 'icon' => wp_mime_type_icon( $type ),743 'title' => basename( $this->setting->default ),744 );745 746 if ( 'image' === $type ) {747 $default_attachment['sizes'] = array(748 'full' => array( 'url' => $this->setting->default ),749 );750 }751 752 $this->json['defaultAttachment'] = $default_attachment;753 }754 755 if ( $value && $this->setting->default && $value === $this->setting->default ) {756 // Set the default as the attachment.757 $this->json['attachment'] = $this->json['defaultAttachment'];758 } elseif ( $value ) {759 $this->json['attachment'] = wp_prepare_attachment_for_js( $value );760 }761 }762 }763 764 /**765 * Don't render any content for this control from PHP.766 *767 * @since 3.4.0768 * @since 4.2.0 Moved from WP_Customize_Upload_Control.769 *770 * @see WP_Customize_Media_Control::content_template()771 */772 public function render_content() {}773 774 /**775 * Render a JS template for the content of the media control.776 *777 * @since 4.1.0778 * @since 4.2.0 Moved from WP_Customize_Upload_Control.779 */780 public function content_template() {781 ?>782 <label for="{{ data.settings['default'] }}-button">783 <# if ( data.label ) { #>784 <span class="customize-control-title">{{ data.label }}</span>785 <# } #>786 <# if ( data.description ) { #>787 <span class="description customize-control-description">{{{ data.description }}}</span>788 <# } #>789 </label>790 791 <# if ( data.attachment && data.attachment.id ) { #>792 <div class="current">793 <div class="container">794 <div class="attachment-media-view attachment-media-view-{{ data.attachment.type }} {{ data.attachment.orientation }}">795 <div class="thumbnail thumbnail-{{ data.attachment.type }}">796 <# if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.medium ) { #>797 <img class="attachment-thumb" src="{{ data.attachment.sizes.medium.url }}" draggable="false" />798 <# } else if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.full ) { #>799 <img class="attachment-thumb" src="{{ data.attachment.sizes.full.url }}" draggable="false" />800 <# } else if ( 'audio' === data.attachment.type ) { #>801 <# if ( data.attachment.image && data.attachment.image.src && data.attachment.image.src !== data.attachment.icon ) { #>802 <img src="{{ data.attachment.image.src }}" class="thumbnail" draggable="false" />803 <# } else { #>804 <img src="{{ data.attachment.icon }}" class="attachment-thumb type-icon" draggable="false" />805 <# } #>806 <p class="attachment-meta attachment-meta-title">“{{ data.attachment.title }}”</p>807 <# if ( data.attachment.album || data.attachment.meta.album ) { #>808 <p class="attachment-meta"><em>{{ data.attachment.album || data.attachment.meta.album }}</em></p>809 <# } #>810 <# if ( data.attachment.artist || data.attachment.meta.artist ) { #>811 <p class="attachment-meta">{{ data.attachment.artist || data.attachment.meta.artist }}</p>812 <# } #>813 <audio style="visibility: hidden" controls class="wp-audio-shortcode" width="100%" preload="none">814 <source type="{{ data.attachment.mime }}" src="{{ data.attachment.url }}"/>815 </audio>816 <# } else if ( 'video' === data.attachment.type ) { #>817 <div class="wp-media-wrapper wp-video">818 <video controls="controls" class="wp-video-shortcode" preload="metadata"819 <# if ( data.attachment.image && data.attachment.image.src !== data.attachment.icon ) { #>poster="{{ data.attachment.image.src }}"<# } #>>820 <source type="{{ data.attachment.mime }}" src="{{ data.attachment.url }}"/>821 </video>822 </div>823 <# } else { #>824 <img class="attachment-thumb type-icon icon" src="{{ data.attachment.icon }}" draggable="false" />825 <p class="attachment-title">{{ data.attachment.title }}</p>826 <# } #>827 </div>828 </div>829 </div>830 </div>831 <div class="actions">832 <# if ( data.canUpload ) { #>833 <button type="button" class="button remove-button"><?php echo $this->button_labels['remove']; ?></button>834 <button type="button" class="button upload-button" id="{{ data.settings['default'] }}-button"><?php echo $this->button_labels['change']; ?></button>835 <div style="clear:both"></div>836 <# } #>837 </div>838 <# } else { #>839 <div class="current">840 <div class="container">841 <div class="placeholder">842 <div class="inner">843 <span>844 <?php echo $this->button_labels['placeholder']; ?>845 </span>846 </div>847 </div>848 </div>849 </div>850 <div class="actions">851 <# if ( data.defaultAttachment ) { #>852 <button type="button" class="button default-button"><?php echo $this->button_labels['default']; ?></button>853 <# } #>854 <# if ( data.canUpload ) { #>855 <button type="button" class="button upload-button" id="{{ data.settings['default'] }}-button"><?php echo $this->button_labels['select']; ?></button>856 <# } #>857 <div style="clear:both"></div>858 </div>859 <# } #>860 <?php861 }862 }863 864 /**865 * Customize Upload Control Class.866 *867 * @since 3.4.0868 *869 * @see WP_Customize_Media_Control870 */871 class WP_Customize_Upload_Control extends WP_Customize_Media_Control {872 public $type = 'upload';873 public $mime_type = '';874 public $button_labels = array();875 public $removed = ''; // unused876 public $context; // unused877 public $extensions = array(); // unused878 879 /**880 * Refresh the parameters passed to the JavaScript via JSON.881 *882 * @since 3.4.0883 *884 * @uses WP_Customize_Media_Control::to_json()885 */886 public function to_json() {887 parent::to_json();888 889 $value = $this->value();890 if ( $value ) {891 // Get the attachment model for the existing file.892 $attachment_id = attachment_url_to_postid( $value );893 if ( $attachment_id ) {894 $this->json['attachment'] = wp_prepare_attachment_for_js( $attachment_id );895 }896 }897 }898 }899 900 /**901 * Customize Image Control class.902 *903 * @since 3.4.0904 *905 * @see WP_Customize_Upload_Control906 */907 class WP_Customize_Image_Control extends WP_Customize_Upload_Control {908 public $type = 'image';909 public $mime_type = 'image';910 911 /**912 * Constructor.913 *914 * @since 3.4.0915 * @uses WP_Customize_Upload_Control::__construct()916 *917 * @param WP_Customize_Manager $manager Customizer bootstrap instance.918 * @param string $id Control ID.919 * @param array $args Optional. Arguments to override class property defaults.920 */921 public function __construct( $manager, $id, $args = array() ) {922 parent::__construct( $manager, $id, $args );923 924 $this->button_labels = array(925 'select' => __( 'Select Image' ),926 'change' => __( 'Change Image' ),927 'remove' => __( 'Remove' ),928 'default' => __( 'Default' ),929 'placeholder' => __( 'No image selected' ),930 'frame_title' => __( 'Select Image' ),931 'frame_button' => __( 'Choose Image' ),932 );933 }934 935 /**936 * @since 3.4.2937 * @deprecated 4.1.0938 */939 public function prepare_control() {}940 941 /**942 * @since 3.4.0943 * @deprecated 4.1.0944 *945 * @param string $id946 * @param string $label947 * @param mixed $callback948 */949 public function add_tab( $id, $label, $callback ) {}950 951 /**952 * @since 3.4.0953 * @deprecated 4.1.0954 *955 * @param string $id956 */957 public function remove_tab( $id ) {}958 959 /**960 * @since 3.4.0961 * @deprecated 4.1.0962 *963 * @param string $url964 * @param string $thumbnail_url965 */966 public function print_tab_image( $url, $thumbnail_url = null ) {}967 }968 9 969 10 /** … … 1007 48 } 1008 49 } 1009 1010 /**1011 * Customize Cropped Image Control class.1012 *1013 * @since 4.3.01014 *1015 * @see WP_Customize_Image_Control1016 */1017 class WP_Customize_Cropped_Image_Control extends WP_Customize_Image_Control {1018 1019 /**1020 * Control type.1021 *1022 * @since 4.3.01023 * @access public1024 * @var string1025 */1026 public $type = 'cropped_image';1027 1028 /**1029 * Suggested width for cropped image.1030 *1031 * @since 4.3.01032 * @access public1033 * @var int1034 */1035 public $width = 150;1036 1037 /**1038 * Suggested height for cropped image.1039 *1040 * @since 4.3.01041 * @access public1042 * @var int1043 */1044 public $height = 150;1045 1046 /**1047 * Whether the width is flexible.1048 *1049 * @since 4.3.01050 * @access public1051 * @var bool1052 */1053 public $flex_width = false;1054 1055 /**1056 * Whether the height is flexible.1057 *1058 * @since 4.3.01059 * @access public1060 * @var bool1061 */1062 public $flex_height = false;1063 1064 /**1065 * Enqueue control related scripts/styles.1066 *1067 * @since 4.3.01068 * @access public1069 */1070 public function enqueue() {1071 wp_enqueue_script( 'customize-views' );1072 1073 parent::enqueue();1074 }1075 1076 /**1077 * Refresh the parameters passed to the JavaScript via JSON.1078 *1079 * @since 4.3.01080 * @access public1081 *1082 * @see WP_Customize_Control::to_json()1083 */1084 public function to_json() {1085 parent::to_json();1086 1087 $this->json['width'] = absint( $this->width );1088 $this->json['height'] = absint( $this->height );1089 $this->json['flex_width'] = absint( $this->flex_width );1090 $this->json['flex_height'] = absint( $this->flex_height );1091 }1092 1093 }1094 1095 /**1096 * Customize Site Icon control class.1097 *1098 * Used only for custom functionality in JavaScript.1099 *1100 * @since 4.3.01101 *1102 * @see WP_Customize_Cropped_Image_Control1103 */1104 class WP_Customize_Site_Icon_Control extends WP_Customize_Cropped_Image_Control {1105 1106 /**1107 * Control type.1108 *1109 * @since 4.3.01110 * @access public1111 * @var string1112 */1113 public $type = 'site_icon';1114 1115 /**1116 * Constructor.1117 *1118 * @since 4.3.01119 * @access public1120 *1121 * @param WP_Customize_Manager $manager Customizer bootstrap instance.1122 * @param string $id Control ID.1123 * @param array $args Optional. Arguments to override class property defaults.1124 */1125 public function __construct( $manager, $id, $args = array() ) {1126 parent::__construct( $manager, $id, $args );1127 add_action( 'customize_controls_print_styles', 'wp_site_icon', 99 );1128 }1129 }1130 1131 /**1132 * Customize Header Image Control class.1133 *1134 * @since 3.4.01135 *1136 * @see WP_Customize_Image_Control1137 */1138 class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control {1139 public $type = 'header';1140 public $uploaded_headers;1141 public $default_headers;1142 1143 /**1144 * Constructor.1145 *1146 * @since 3.4.01147 *1148 * @param WP_Customize_Manager $manager Customizer bootstrap instance.1149 */1150 public function __construct( $manager ) {1151 parent::__construct( $manager, 'header_image', array(1152 'label' => __( 'Header Image' ),1153 'settings' => array(1154 'default' => 'header_image',1155 'data' => 'header_image_data',1156 ),1157 'section' => 'header_image',1158 'removed' => 'remove-header',1159 'get_url' => 'get_header_image',1160 ) );1161 1162 }1163 1164 /**1165 * @access public1166 */1167 public function enqueue() {1168 wp_enqueue_media();1169 wp_enqueue_script( 'customize-views' );1170 1171 $this->prepare_control();1172 1173 wp_localize_script( 'customize-views', '_wpCustomizeHeader', array(1174 'data' => array(1175 'width' => absint( get_theme_support( 'custom-header', 'width' ) ),1176 'height' => absint( get_theme_support( 'custom-header', 'height' ) ),1177 'flex-width' => absint( get_theme_support( 'custom-header', 'flex-width' ) ),1178 'flex-height' => absint( get_theme_support( 'custom-header', 'flex-height' ) ),1179 'currentImgSrc' => $this->get_current_image_src(),1180 ),1181 'nonces' => array(1182 'add' => wp_create_nonce( 'header-add' ),1183 'remove' => wp_create_nonce( 'header-remove' ),1184 ),1185 'uploads' => $this->uploaded_headers,1186 'defaults' => $this->default_headers1187 ) );1188 1189 parent::enqueue();1190 }1191 1192 /**1193 *1194 * @global Custom_Image_Header $custom_image_header1195 */1196 public function prepare_control() {1197 global $custom_image_header;1198 if ( empty( $custom_image_header ) ) {1199 return;1200 }1201 1202 // Process default headers and uploaded headers.1203 $custom_image_header->process_default_headers();1204 $this->default_headers = $custom_image_header->get_default_header_images();1205 $this->uploaded_headers = $custom_image_header->get_uploaded_header_images();1206 }1207 1208 /**1209 * @access public1210 */1211 public function print_header_image_template() {1212 ?>1213 <script type="text/template" id="tmpl-header-choice">1214 <# if (data.random) { #>1215 <button type="button" class="button display-options random">1216 <span class="dashicons dashicons-randomize dice"></span>1217 <# if ( data.type === 'uploaded' ) { #>1218 <?php _e( 'Randomize uploaded headers' ); ?>1219 <# } else if ( data.type === 'default' ) { #>1220 <?php _e( 'Randomize suggested headers' ); ?>1221 <# } #>1222 </button>1223 1224 <# } else { #>1225 1226 <# if (data.type === 'uploaded') { #>1227 <button type="button" class="dashicons dashicons-no close"><span class="screen-reader-text"><?php _e( 'Remove image' ); ?></span></button>1228 <# } #>1229 1230 <button type="button" class="choice thumbnail"1231 data-customize-image-value="{{{data.header.url}}}"1232 data-customize-header-image-data="{{JSON.stringify(data.header)}}">1233 <span class="screen-reader-text"><?php _e( 'Set image' ); ?></span>1234 <img src="{{{data.header.thumbnail_url}}}" alt="{{{data.header.alt_text || data.header.description}}}">1235 </button>1236 1237 <# } #>1238 </script>1239 1240 <script type="text/template" id="tmpl-header-current">1241 <# if (data.choice) { #>1242 <# if (data.random) { #>1243 1244 <div class="placeholder">1245 <div class="inner">1246 <span><span class="dashicons dashicons-randomize dice"></span>1247 <# if ( data.type === 'uploaded' ) { #>1248 <?php _e( 'Randomizing uploaded headers' ); ?>1249 <# } else if ( data.type === 'default' ) { #>1250 <?php _e( 'Randomizing suggested headers' ); ?>1251 <# } #>1252 </span>1253 </div>1254 </div>1255 1256 <# } else { #>1257 1258 <img src="{{{data.header.thumbnail_url}}}" alt="{{{data.header.alt_text || data.header.description}}}" tabindex="0"/>1259 1260 <# } #>1261 <# } else { #>1262 1263 <div class="placeholder">1264 <div class="inner">1265 <span>1266 <?php _e( 'No image set' ); ?>1267 </span>1268 </div>1269 </div>1270 1271 <# } #>1272 </script>1273 <?php1274 }1275 1276 /**1277 * @return string|void1278 */1279 public function get_current_image_src() {1280 $src = $this->value();1281 if ( isset( $this->get_url ) ) {1282 $src = call_user_func( $this->get_url, $src );1283 return $src;1284 }1285 }1286 1287 /**1288 * @access public1289 */1290 public function render_content() {1291 $this->print_header_image_template();1292 $visibility = $this->get_current_image_src() ? '' : ' style="display:none" ';1293 $width = absint( get_theme_support( 'custom-header', 'width' ) );1294 $height = absint( get_theme_support( 'custom-header', 'height' ) );1295 ?>1296 <div class="customize-control-content">1297 <p class="customizer-section-intro">1298 <?php1299 if ( $width && $height ) {1300 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 × %s</strong> pixels.' ), $width, $height );1301 } elseif ( $width ) {1302 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 );1303 } else {1304 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 );1305 }1306 ?>1307 </p>1308 <div class="current">1309 <label for="header_image-button">1310 <span class="customize-control-title">1311 <?php _e( 'Current header' ); ?>1312 </span>1313 </label>1314 <div class="container">1315 </div>1316 </div>1317 <div class="actions">1318 <?php if ( current_user_can( 'upload_files' ) ): ?>1319 <button type="button"<?php echo $visibility; ?> class="button remove" aria-label="<?php esc_attr_e( 'Hide header image' ); ?>"><?php _e( 'Hide image' ); ?></button>1320 <button type="button" class="button new" id="header_image-button" aria-label="<?php esc_attr_e( 'Add new header image' ); ?>"><?php _e( 'Add new image' ); ?></button>1321 <div style="clear:both"></div>1322 <?php endif; ?>1323 </div>1324 <div class="choices">1325 <span class="customize-control-title header-previously-uploaded">1326 <?php _ex( 'Previously uploaded', 'custom headers' ); ?>1327 </span>1328 <div class="uploaded">1329 <div class="list">1330 </div>1331 </div>1332 <span class="customize-control-title header-default">1333 <?php _ex( 'Suggested', 'custom headers' ); ?>1334 </span>1335 <div class="default">1336 <div class="list">1337 </div>1338 </div>1339 </div>1340 </div>1341 <?php1342 }1343 }1344 1345 /**1346 * Customize Theme Control class.1347 *1348 * @since 4.2.01349 *1350 * @see WP_Customize_Control1351 */1352 class WP_Customize_Theme_Control extends WP_Customize_Control {1353 1354 /**1355 * Customize control type.1356 *1357 * @since 4.2.01358 * @access public1359 * @var string1360 */1361 public $type = 'theme';1362 1363 /**1364 * Theme object.1365 *1366 * @since 4.2.01367 * @access public1368 * @var WP_Theme1369 */1370 public $theme;1371 1372 /**1373 * Refresh the parameters passed to the JavaScript via JSON.1374 *1375 * @since 4.2.01376 * @access public1377 *1378 * @see WP_Customize_Control::to_json()1379 */1380 public function to_json() {1381 parent::to_json();1382 $this->json['theme'] = $this->theme;1383 }1384 1385 /**1386 * Don't render the control content from PHP, as it's rendered via JS on load.1387 *1388 * @since 4.2.01389 * @access public1390 */1391 public function render_content() {}1392 1393 /**1394 * Render a JS template for theme display.1395 *1396 * @since 4.2.01397 * @access public1398 */1399 public function content_template() {1400 $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );1401 $active_url = esc_url( remove_query_arg( 'theme', $current_url ) );1402 $preview_url = esc_url( add_query_arg( 'theme', '__THEME__', $current_url ) ); // Token because esc_url() strips curly braces.1403 $preview_url = str_replace( '__THEME__', '{{ data.theme.id }}', $preview_url );1404 ?>1405 <# if ( data.theme.isActiveTheme ) { #>1406 <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">1407 <# } else { #>1408 <div class="theme" tabindex="0" data-preview-url="<?php echo esc_attr( $preview_url ); ?>" aria-describedby="{{ data.theme.id }}-action {{ data.theme.id }}-name">1409 <# } #>1410 1411 <# if ( data.theme.screenshot[0] ) { #>1412 <div class="theme-screenshot">1413 <img data-src="{{ data.theme.screenshot[0] }}" alt="" />1414 </div>1415 <# } else { #>1416 <div class="theme-screenshot blank"></div>1417 <# } #>1418 1419 <# if ( data.theme.isActiveTheme ) { #>1420 <span class="more-details" id="{{ data.theme.id }}-action"><?php _e( 'Customize' ); ?></span>1421 <# } else { #>1422 <span class="more-details" id="{{ data.theme.id }}-action"><?php _e( 'Live Preview' ); ?></span>1423 <# } #>1424 1425 <div class="theme-author"><?php printf( __( 'By %s' ), '{{ data.theme.author }}' ); ?></div>1426 1427 <# if ( data.theme.isActiveTheme ) { #>1428 <h3 class="theme-name" id="{{ data.theme.id }}-name">1429 <?php1430 /* translators: %s: theme name */1431 printf( __( '<span>Active:</span> %s' ), '{{{ data.theme.name }}}' );1432 ?>1433 </h3>1434 <# } else { #>1435 <h3 class="theme-name" id="{{ data.theme.id }}-name">{{{ data.theme.name }}}</h3>1436 <div class="theme-actions">1437 <button type="button" class="button theme-details"><?php _e( 'Theme Details' ); ?></button>1438 </div>1439 <# } #>1440 </div>1441 <?php1442 }1443 }1444 1445 /**1446 * Widget Area Customize Control class.1447 *1448 * @since 3.9.01449 *1450 * @see WP_Customize_Control1451 */1452 class WP_Widget_Area_Customize_Control extends WP_Customize_Control {1453 public $type = 'sidebar_widgets';1454 public $sidebar_id;1455 1456 public function to_json() {1457 parent::to_json();1458 $exported_properties = array( 'sidebar_id' );1459 foreach ( $exported_properties as $key ) {1460 $this->json[ $key ] = $this->$key;1461 }1462 }1463 1464 /**1465 * @access public1466 */1467 public function render_content() {1468 $id = 'reorder-widgets-desc-' . str_replace( array( '[', ']' ), array( '-', '' ), $this->id );1469 ?>1470 <button type="button" class="button-secondary add-new-widget" aria-expanded="false" aria-controls="available-widgets">1471 <?php _e( 'Add a Widget' ); ?>1472 </button>1473 <button type="button" class="not-a-button reorder-toggle" aria-label="<?php esc_attr_e( 'Reorder widgets' ); ?>" aria-describedby="<?php echo esc_attr( $id ); ?>">1474 <span class="reorder"><?php _ex( 'Reorder', 'Reorder widgets in Customizer' ); ?></span>1475 <span class="reorder-done"><?php _ex( 'Done', 'Cancel reordering widgets in Customizer' ); ?></span>1476 </button>1477 <p class="screen-reader-text" id="<?php echo esc_attr( $id ); ?>"><?php _e( 'When in reorder mode, additional controls to reorder widgets will be available in the widgets list above.' ); ?></p>1478 <?php1479 }1480 1481 }1482 1483 /**1484 * Widget Form Customize Control class.1485 *1486 * @since 3.9.01487 *1488 * @see WP_Customize_Control1489 */1490 class WP_Widget_Form_Customize_Control extends WP_Customize_Control {1491 public $type = 'widget_form';1492 public $widget_id;1493 public $widget_id_base;1494 public $sidebar_id;1495 public $is_new = false;1496 public $width;1497 public $height;1498 public $is_wide = false;1499 1500 /**1501 * Gather control params for exporting to JavaScript.1502 *1503 * @global array $wp_registered_widgets1504 */1505 public function to_json() {1506 global $wp_registered_widgets;1507 1508 parent::to_json();1509 $exported_properties = array( 'widget_id', 'widget_id_base', 'sidebar_id', 'width', 'height', 'is_wide' );1510 foreach ( $exported_properties as $key ) {1511 $this->json[ $key ] = $this->$key;1512 }1513 1514 // Get the widget_control and widget_content.1515 require_once ABSPATH . '/wp-admin/includes/widgets.php';1516 1517 $widget = $wp_registered_widgets[ $this->widget_id ];1518 if ( ! isset( $widget['params'][0] ) ) {1519 $widget['params'][0] = array();1520 }1521 1522 $args = array(1523 'widget_id' => $widget['id'],1524 'widget_name' => $widget['name'],1525 );1526 1527 $args = wp_list_widget_controls_dynamic_sidebar( array( 0 => $args, 1 => $widget['params'][0] ) );1528 $widget_control_parts = $this->manager->widgets->get_widget_control_parts( $args );1529 1530 $this->json['widget_control'] = $widget_control_parts['control'];1531 $this->json['widget_content'] = $widget_control_parts['content'];1532 }1533 1534 /**1535 * Override render_content to be no-op since content is exported via to_json for deferred embedding.1536 */1537 public function render_content() {}1538 1539 /**1540 * Whether the current widget is rendered on the page.1541 *1542 * @since 4.0.01543 * @access public1544 *1545 * @return bool Whether the widget is rendered.1546 */1547 public function active_callback() {1548 return $this->manager->widgets->is_widget_rendered( $this->widget_id );1549 }1550 }1551 1552 /**1553 * Customize Nav Menu Control Class.1554 *1555 * @since 4.3.01556 */1557 class WP_Customize_Nav_Menu_Control extends WP_Customize_Control {1558 1559 /**1560 * Control type.1561 *1562 * @since 4.3.01563 * @access public1564 * @var string1565 */1566 public $type = 'nav_menu';1567 1568 /**1569 * The nav menu setting.1570 *1571 * @since 4.3.01572 * @access public1573 * @var WP_Customize_Nav_Menu_Setting1574 */1575 public $setting;1576 1577 /**1578 * Don't render the control's content - it uses a JS template instead.1579 *1580 * @since 4.3.01581 * @access public1582 */1583 public function render_content() {}1584 1585 /**1586 * JS/Underscore template for the control UI.1587 *1588 * @since 4.3.01589 * @access public1590 */1591 public function content_template() {1592 ?>1593 <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">1594 <?php _e( 'Add Items' ); ?>1595 </button>1596 <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 }}">1597 <span class="reorder"><?php _ex( 'Reorder', 'Reorder menu items in Customizer' ); ?></span>1598 <span class="reorder-done"><?php _ex( 'Done', 'Cancel reordering menu items in Customizer' ); ?></span>1599 </button>1600 <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>1601 <span class="add-menu-item-loading spinner"></span>1602 <span class="menu-delete-item">1603 <button type="button" class="not-a-button menu-delete">1604 <?php _e( 'Delete menu' ); ?> <span class="screen-reader-text">{{ data.menu_name }}</span>1605 </button>1606 </span>1607 <?php if ( current_theme_supports( 'menus' ) ) : ?>1608 <ul class="menu-settings">1609 <li class="customize-control">1610 <span class="customize-control-title"><?php _e( 'Menu locations' ); ?></span>1611 </li>1612 1613 <?php foreach ( get_registered_nav_menus() as $location => $description ) : ?>1614 <li class="customize-control customize-control-checkbox assigned-menu-location">1615 <label>1616 <input type="checkbox" data-menu-id="{{ data.menu_id }}" data-location-id="<?php echo esc_attr( $location ); ?>" class="menu-location" /> <?php echo $description; ?>1617 <span class="theme-location-set"><?php printf( _x( '(Current: %s)', 'Current menu location' ), '<span class="current-menu-location-name-' . esc_attr( $location ) . '"></span>' ); ?></span>1618 </label>1619 </li>1620 <?php endforeach; ?>1621 1622 </ul>1623 <?php endif;1624 }1625 1626 /**1627 * Return parameters for this control.1628 *1629 * @since 4.3.01630 * @access public1631 *1632 * @return array Exported parameters.1633 */1634 public function json() {1635 $exported = parent::json();1636 $exported['menu_id'] = $this->setting->term_id;1637 1638 return $exported;1639 }1640 }1641 1642 /**1643 * Customize control to represent the name field for a given menu.1644 *1645 * @since 4.3.01646 */1647 class WP_Customize_Nav_Menu_Item_Control extends WP_Customize_Control {1648 1649 /**1650 * Control type.1651 *1652 * @since 4.3.01653 * @access public1654 * @var string1655 */1656 public $type = 'nav_menu_item';1657 1658 /**1659 * The nav menu item setting.1660 *1661 * @since 4.3.01662 * @access public1663 * @var WP_Customize_Nav_Menu_Item_Setting1664 */1665 public $setting;1666 1667 /**1668 * Constructor.1669 *1670 * @since 4.3.01671 * @access public1672 *1673 * @see WP_Customize_Control::__construct()1674 *1675 * @param WP_Customize_Manager $manager Customizer bootstrap instance.1676 * @param string $id The control ID.1677 * @param array $args Optional. Overrides class property defaults.1678 */1679 public function __construct( $manager, $id, $args = array() ) {1680 parent::__construct( $manager, $id, $args );1681 }1682 1683 /**1684 * Don't render the control's content - it's rendered with a JS template.1685 *1686 * @since 4.3.01687 * @access public1688 */1689 public function render_content() {}1690 1691 /**1692 * JS/Underscore template for the control UI.1693 *1694 * @since 4.3.01695 * @access public1696 */1697 public function content_template() {1698 ?>1699 <div class="menu-item-bar">1700 <div class="menu-item-handle">1701 <span class="item-type" aria-hidden="true">{{ data.item_type_label }}</span>1702 <span class="item-title" aria-hidden="true">1703 <span class="spinner"></span>1704 <span class="menu-item-title<# if ( ! data.title ) { #> no-title<# } #>">{{ data.title || wp.customize.Menus.data.l10n.untitled }}</span>1705 </span>1706 <span class="item-controls">1707 <button type="button" class="not-a-button item-edit" aria-expanded="false"><span class="screen-reader-text"><?php1708 /* translators: 1: Title of a menu item, 2: Type of a menu item */1709 printf( __( 'Edit menu item: %1$s (%2$s)' ), '{{ data.title || wp.customize.Menus.data.l10n.untitled }}', '{{ data.item_type_label }}' );1710 ?></span><span class="toggle-indicator" aria-hidden="true"></span></button>1711 <button type="button" class="not-a-button item-delete submitdelete deletion"><span class="screen-reader-text"><?php1712 /* translators: 1: Title of a menu item, 2: Type of a menu item */1713 printf( __( 'Remove Menu Item: %1$s (%2$s)' ), '{{ data.title || wp.customize.Menus.data.l10n.untitled }}', '{{ data.item_type_label }}' );1714 ?></span></button>1715 </span>1716 </div>1717 </div>1718 1719 <div class="menu-item-settings" id="menu-item-settings-{{ data.menu_item_id }}">1720 <# if ( 'custom' === data.item_type ) { #>1721 <p class="field-url description description-thin">1722 <label for="edit-menu-item-url-{{ data.menu_item_id }}">1723 <?php _e( 'URL' ); ?><br />1724 <input class="widefat code edit-menu-item-url" type="text" id="edit-menu-item-url-{{ data.menu_item_id }}" name="menu-item-url" />1725 </label>1726 </p>1727 <# } #>1728 <p class="description description-thin">1729 <label for="edit-menu-item-title-{{ data.menu_item_id }}">1730 <?php _e( 'Navigation Label' ); ?><br />1731 <input type="text" id="edit-menu-item-title-{{ data.menu_item_id }}" class="widefat edit-menu-item-title" name="menu-item-title" />1732 </label>1733 </p>1734 <p class="field-link-target description description-thin">1735 <label for="edit-menu-item-target-{{ data.menu_item_id }}">1736 <input type="checkbox" id="edit-menu-item-target-{{ data.menu_item_id }}" class="edit-menu-item-target" value="_blank" name="menu-item-target" />1737 <?php _e( 'Open link in a new tab' ); ?>1738 </label>1739 </p>1740 <p class="field-attr-title description description-thin">1741 <label for="edit-menu-item-attr-title-{{ data.menu_item_id }}">1742 <?php _e( 'Title Attribute' ); ?><br />1743 <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" />1744 </label>1745 </p>1746 <p class="field-css-classes description description-thin">1747 <label for="edit-menu-item-classes-{{ data.menu_item_id }}">1748 <?php _e( 'CSS Classes' ); ?><br />1749 <input type="text" id="edit-menu-item-classes-{{ data.menu_item_id }}" class="widefat code edit-menu-item-classes" name="menu-item-classes" />1750 </label>1751 </p>1752 <p class="field-xfn description description-thin">1753 <label for="edit-menu-item-xfn-{{ data.menu_item_id }}">1754 <?php _e( 'Link Relationship (XFN)' ); ?><br />1755 <input type="text" id="edit-menu-item-xfn-{{ data.menu_item_id }}" class="widefat code edit-menu-item-xfn" name="menu-item-xfn" />1756 </label>1757 </p>1758 <p class="field-description description description-thin">1759 <label for="edit-menu-item-description-{{ data.menu_item_id }}">1760 <?php _e( 'Description' ); ?><br />1761 <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>1762 <span class="description"><?php _e( 'The description will be displayed in the menu if the current theme supports it.' ); ?></span>1763 </label>1764 </p>1765 1766 <div class="menu-item-actions description-thin submitbox">1767 <# if ( ( 'post_type' === data.item_type || 'taxonomy' === data.item_type ) && '' !== data.original_title ) { #>1768 <p class="link-to-original">1769 <?php printf( __( 'Original: %s' ), '<a class="original-link" href="{{ data.url }}">{{ data.original_title }}</a>' ); ?>1770 </p>1771 <# } #>1772 1773 <button type="button" class="not-a-button item-delete submitdelete deletion"><?php _e( 'Remove' ); ?></button>1774 <span class="spinner"></span>1775 </div>1776 <input type="hidden" name="menu-item-db-id[{{ data.menu_item_id }}]" class="menu-item-data-db-id" value="{{ data.menu_item_id }}" />1777 <input type="hidden" name="menu-item-parent-id[{{ data.menu_item_id }}]" class="menu-item-data-parent-id" value="{{ data.parent }}" />1778 </div><!-- .menu-item-settings-->1779 <ul class="menu-item-transport"></ul>1780 <?php1781 }1782 1783 /**1784 * Return parameters for this control.1785 *1786 * @since 4.3.01787 * @access public1788 *1789 * @return array Exported parameters.1790 */1791 public function json() {1792 $exported = parent::json();1793 $exported['menu_item_id'] = $this->setting->post_id;1794 1795 return $exported;1796 }1797 }1798 1799 /**1800 * Customize Menu Location Control Class.1801 *1802 * This custom control is only needed for JS.1803 *1804 * @since 4.3.01805 *1806 * @see WP_Customize_Control1807 */1808 class WP_Customize_Nav_Menu_Location_Control extends WP_Customize_Control {1809 1810 /**1811 * Control type.1812 *1813 * @since 4.3.01814 * @access public1815 * @var string1816 */1817 public $type = 'nav_menu_location';1818 1819 /**1820 * Location ID.1821 *1822 * @since 4.3.01823 * @access public1824 * @var string1825 */1826 public $location_id = '';1827 1828 /**1829 * Refresh the parameters passed to JavaScript via JSON.1830 *1831 * @since 4.3.01832 * @access public1833 *1834 * @see WP_Customize_Control::to_json()1835 */1836 public function to_json() {1837 parent::to_json();1838 $this->json['locationId'] = $this->location_id;1839 }1840 1841 /**1842 * Render content just like a normal select control.1843 *1844 * @since 4.3.01845 * @access public1846 */1847 public function render_content() {1848 if ( empty( $this->choices ) ) {1849 return;1850 }1851 ?>1852 <label>1853 <?php if ( ! empty( $this->label ) ) : ?>1854 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>1855 <?php endif; ?>1856 1857 <?php if ( ! empty( $this->description ) ) : ?>1858 <span class="description customize-control-description"><?php echo $this->description; ?></span>1859 <?php endif; ?>1860 1861 <select <?php $this->link(); ?>>1862 <?php1863 foreach ( $this->choices as $value => $label ) :1864 echo '<option value="' . esc_attr( $value ) . '"' . selected( $this->value(), $value, false ) . '>' . $label . '</option>';1865 endforeach;1866 ?>1867 </select>1868 </label>1869 <?php1870 }1871 }1872 1873 /**1874 * Customize control to represent the name field for a given menu.1875 *1876 * @since 4.3.01877 *1878 * @see WP_Customize_Control1879 */1880 class WP_Customize_Nav_Menu_Name_Control extends WP_Customize_Control {1881 1882 /**1883 * Type of control, used by JS.1884 *1885 * @since 4.3.01886 * @access public1887 * @var string1888 */1889 public $type = 'nav_menu_name';1890 1891 /**1892 * No-op since we're using JS template.1893 *1894 * @since 4.3.01895 * @access protected1896 */1897 protected function render_content() {}1898 1899 /**1900 * Render the Underscore template for this control.1901 *1902 * @since 4.3.01903 * @access protected1904 */1905 protected function content_template() {1906 ?>1907 <label>1908 <# if ( data.label ) { #>1909 <span class="customize-control-title screen-reader-text">{{ data.label }}</span>1910 <# } #>1911 <input type="text" class="menu-name-field live-update-section-title" />1912 </label>1913 <?php1914 }1915 }1916 1917 /**1918 * Customize control to represent the auto_add field for a given menu.1919 *1920 * @since 4.3.01921 *1922 * @see WP_Customize_Control1923 */1924 class WP_Customize_Nav_Menu_Auto_Add_Control extends WP_Customize_Control {1925 1926 /**1927 * Type of control, used by JS.1928 *1929 * @since 4.3.01930 * @access public1931 * @var string1932 */1933 public $type = 'nav_menu_auto_add';1934 1935 /**1936 * No-op since we're using JS template.1937 *1938 * @since 4.3.01939 * @access protected1940 */1941 protected function render_content() {}1942 1943 /**1944 * Render the Underscore template for this control.1945 *1946 * @since 4.3.01947 * @access protected1948 */1949 protected function content_template() {1950 ?>1951 <span class="customize-control-title"><?php _e( 'Menu options' ); ?></span>1952 <label>1953 <input type="checkbox" class="auto_add" />1954 <?php _e( 'Automatically add new top-level pages to this menu' ); ?>1955 </label>1956 <?php1957 }1958 }1959 1960 /**1961 * Customize control class for new menus.1962 *1963 * @since 4.3.01964 *1965 * @see WP_Customize_Control1966 */1967 class WP_Customize_New_Menu_Control extends WP_Customize_Control {1968 1969 /**1970 * Control type.1971 *1972 * @since 4.3.01973 * @access public1974 * @var string1975 */1976 public $type = 'new_menu';1977 1978 /**1979 * Render the control's content.1980 *1981 * @since 4.3.01982 * @access public1983 */1984 public function render_content() {1985 ?>1986 <button type="button" class="button button-primary" id="create-new-menu-submit"><?php _e( 'Create Menu' ); ?></button>1987 <span class="spinner"></span>1988 <?php1989 }1990 } -
trunk/src/wp-includes/customize/class-wp-customize-color-control.php
r35381 r35389 1 1 <?php 2 2 /** 3 * WordPress Customize Control classes3 * Customize API: WP_Customize_Color_Control class 4 4 * 5 5 * @package WordPress 6 6 * @subpackage Customize 7 * @since 3.4.07 * @since 4.4.0 8 8 */ 9 10 /**11 * Customize Control class.12 *13 * @since 3.4.014 */15 class WP_Customize_Control {16 17 /**18 * Incremented with each new class instantiation, then stored in $instance_number.19 *20 * Used when sorting two instances whose priorities are equal.21 *22 * @since 4.1.023 *24 * @static25 * @access protected26 * @var int27 */28 protected static $instance_count = 0;29 30 /**31 * Order in which this instance was created in relation to other instances.32 *33 * @since 4.1.034 * @access public35 * @var int36 */37 public $instance_number;38 39 /**40 * @access public41 * @var WP_Customize_Manager42 */43 public $manager;44 45 /**46 * @access public47 * @var string48 */49 public $id;50 51 /**52 * All settings tied to the control.53 *54 * @access public55 * @var array56 */57 public $settings;58 59 /**60 * The primary setting for the control (if there is one).61 *62 * @access public63 * @var string64 */65 public $setting = 'default';66 67 /**68 * @access public69 * @var int70 */71 public $priority = 10;72 73 /**74 * @access public75 * @var string76 */77 public $section = '';78 79 /**80 * @access public81 * @var string82 */83 public $label = '';84 85 /**86 * @access public87 * @var string88 */89 public $description = '';90 91 /**92 * @todo: Remove choices93 *94 * @access public95 * @var array96 */97 public $choices = array();98 99 /**100 * @access public101 * @var array102 */103 public $input_attrs = array();104 105 /**106 * @deprecated It is better to just call the json() method107 * @access public108 * @var array109 */110 public $json = array();111 112 /**113 * @access public114 * @var string115 */116 public $type = 'text';117 118 /**119 * Callback.120 *121 * @since 4.0.0122 * @access public123 *124 * @see WP_Customize_Control::active()125 *126 * @var callable Callback is called with one argument, the instance of127 * WP_Customize_Control, and returns bool to indicate whether128 * the control is active (such as it relates to the URL129 * currently being previewed).130 */131 public $active_callback = '';132 133 /**134 * Constructor.135 *136 * Supplied $args override class property defaults.137 *138 * If $args['settings'] is not defined, use the $id as the setting ID.139 *140 * @since 3.4.0141 *142 * @param WP_Customize_Manager $manager Customizer bootstrap instance.143 * @param string $id Control ID.144 * @param array $args Optional. Arguments to override class property defaults.145 */146 public function __construct( $manager, $id, $args = array() ) {147 $keys = array_keys( get_object_vars( $this ) );148 foreach ( $keys as $key ) {149 if ( isset( $args[ $key ] ) ) {150 $this->$key = $args[ $key ];151 }152 }153 154 $this->manager = $manager;155 $this->id = $id;156 if ( empty( $this->active_callback ) ) {157 $this->active_callback = array( $this, 'active_callback' );158 }159 self::$instance_count += 1;160 $this->instance_number = self::$instance_count;161 162 // Process settings.163 if ( empty( $this->settings ) ) {164 $this->settings = $id;165 }166 167 $settings = array();168 if ( is_array( $this->settings ) ) {169 foreach ( $this->settings as $key => $setting ) {170 $settings[ $key ] = $this->manager->get_setting( $setting );171 }172 } else {173 $this->setting = $this->manager->get_setting( $this->settings );174 $settings['default'] = $this->setting;175 }176 $this->settings = $settings;177 }178 179 /**180 * Enqueue control related scripts/styles.181 *182 * @since 3.4.0183 */184 public function enqueue() {}185 186 /**187 * Check whether control is active to current Customizer preview.188 *189 * @since 4.0.0190 * @access public191 *192 * @return bool Whether the control is active to the current preview.193 */194 final public function active() {195 $control = $this;196 $active = call_user_func( $this->active_callback, $this );197 198 /**199 * Filter response of WP_Customize_Control::active().200 *201 * @since 4.0.0202 *203 * @param bool $active Whether the Customizer control is active.204 * @param WP_Customize_Control $control WP_Customize_Control instance.205 */206 $active = apply_filters( 'customize_control_active', $active, $control );207 208 return $active;209 }210 211 /**212 * Default callback used when invoking WP_Customize_Control::active().213 *214 * Subclasses can override this with their specific logic, or they may215 * provide an 'active_callback' argument to the constructor.216 *217 * @since 4.0.0218 * @access public219 *220 * @return true Always true.221 */222 public function active_callback() {223 return true;224 }225 226 /**227 * Fetch a setting's value.228 * Grabs the main setting by default.229 *230 * @since 3.4.0231 *232 * @param string $setting_key233 * @return mixed The requested setting's value, if the setting exists.234 */235 final public function value( $setting_key = 'default' ) {236 if ( isset( $this->settings[ $setting_key ] ) ) {237 return $this->settings[ $setting_key ]->value();238 }239 }240 241 /**242 * Refresh the parameters passed to the JavaScript via JSON.243 *244 * @since 3.4.0245 */246 public function to_json() {247 $this->json['settings'] = array();248 foreach ( $this->settings as $key => $setting ) {249 $this->json['settings'][ $key ] = $setting->id;250 }251 252 $this->json['type'] = $this->type;253 $this->json['priority'] = $this->priority;254 $this->json['active'] = $this->active();255 $this->json['section'] = $this->section;256 $this->json['content'] = $this->get_content();257 $this->json['label'] = $this->label;258 $this->json['description'] = $this->description;259 $this->json['instanceNumber'] = $this->instance_number;260 }261 262 /**263 * Get the data to export to the client via JSON.264 *265 * @since 4.1.0266 *267 * @return array Array of parameters passed to the JavaScript.268 */269 public function json() {270 $this->to_json();271 return $this->json;272 }273 274 /**275 * Check if the theme supports the control and check user capabilities.276 *277 * @since 3.4.0278 *279 * @return bool False if theme doesn't support the control or user doesn't have the required permissions, otherwise true.280 */281 final public function check_capabilities() {282 foreach ( $this->settings as $setting ) {283 if ( ! $setting->check_capabilities() )284 return false;285 }286 287 $section = $this->manager->get_section( $this->section );288 if ( isset( $section ) && ! $section->check_capabilities() )289 return false;290 291 return true;292 }293 294 /**295 * Get the control's content for insertion into the Customizer pane.296 *297 * @since 4.1.0298 *299 * @return string Contents of the control.300 */301 final public function get_content() {302 ob_start();303 $this->maybe_render();304 return trim( ob_get_clean() );305 }306 307 /**308 * Check capabilities and render the control.309 *310 * @since 3.4.0311 * @uses WP_Customize_Control::render()312 */313 final public function maybe_render() {314 if ( ! $this->check_capabilities() )315 return;316 317 /**318 * Fires just before the current Customizer control is rendered.319 *320 * @since 3.4.0321 *322 * @param WP_Customize_Control $this WP_Customize_Control instance.323 */324 do_action( 'customize_render_control', $this );325 326 /**327 * Fires just before a specific Customizer control is rendered.328 *329 * The dynamic portion of the hook name, `$this->id`, refers to330 * the control ID.331 *332 * @since 3.4.0333 *334 * @param WP_Customize_Control $this {@see WP_Customize_Control} instance.335 */336 do_action( 'customize_render_control_' . $this->id, $this );337 338 $this->render();339 }340 341 /**342 * Renders the control wrapper and calls $this->render_content() for the internals.343 *344 * @since 3.4.0345 */346 protected function render() {347 $id = 'customize-control-' . str_replace( array( '[', ']' ), array( '-', '' ), $this->id );348 $class = 'customize-control customize-control-' . $this->type;349 350 ?><li id="<?php echo esc_attr( $id ); ?>" class="<?php echo esc_attr( $class ); ?>">351 <?php $this->render_content(); ?>352 </li><?php353 }354 355 /**356 * Get the data link attribute for a setting.357 *358 * @since 3.4.0359 *360 * @param string $setting_key361 * @return string Data link parameter, if $setting_key is a valid setting, empty string otherwise.362 */363 public function get_link( $setting_key = 'default' ) {364 if ( ! isset( $this->settings[ $setting_key ] ) )365 return '';366 367 return 'data-customize-setting-link="' . esc_attr( $this->settings[ $setting_key ]->id ) . '"';368 }369 370 /**371 * Render the data link attribute for the control's input element.372 *373 * @since 3.4.0374 * @uses WP_Customize_Control::get_link()375 *376 * @param string $setting_key377 */378 public function link( $setting_key = 'default' ) {379 echo $this->get_link( $setting_key );380 }381 382 /**383 * Render the custom attributes for the control's input element.384 *385 * @since 4.0.0386 * @access public387 */388 public function input_attrs() {389 foreach ( $this->input_attrs as $attr => $value ) {390 echo $attr . '="' . esc_attr( $value ) . '" ';391 }392 }393 394 /**395 * Render the control's content.396 *397 * Allows the content to be overriden without having to rewrite the wrapper in $this->render().398 *399 * Supports basic input types `text`, `checkbox`, `textarea`, `radio`, `select` and `dropdown-pages`.400 * Additional input types such as `email`, `url`, `number`, `hidden` and `date` are supported implicitly.401 *402 * Control content can alternately be rendered in JS. See {@see WP_Customize_Control::print_template()}.403 *404 * @since 3.4.0405 */406 protected function render_content() {407 switch( $this->type ) {408 case 'checkbox':409 ?>410 <label>411 <input type="checkbox" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); checked( $this->value() ); ?> />412 <?php echo esc_html( $this->label ); ?>413 <?php if ( ! empty( $this->description ) ) : ?>414 <span class="description customize-control-description"><?php echo $this->description; ?></span>415 <?php endif; ?>416 </label>417 <?php418 break;419 case 'radio':420 if ( empty( $this->choices ) )421 return;422 423 $name = '_customize-radio-' . $this->id;424 425 if ( ! empty( $this->label ) ) : ?>426 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>427 <?php endif;428 if ( ! empty( $this->description ) ) : ?>429 <span class="description customize-control-description"><?php echo $this->description ; ?></span>430 <?php endif;431 432 foreach ( $this->choices as $value => $label ) :433 ?>434 <label>435 <input type="radio" value="<?php echo esc_attr( $value ); ?>" name="<?php echo esc_attr( $name ); ?>" <?php $this->link(); checked( $this->value(), $value ); ?> />436 <?php echo esc_html( $label ); ?><br/>437 </label>438 <?php439 endforeach;440 break;441 case 'select':442 if ( empty( $this->choices ) )443 return;444 445 ?>446 <label>447 <?php if ( ! empty( $this->label ) ) : ?>448 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>449 <?php endif;450 if ( ! empty( $this->description ) ) : ?>451 <span class="description customize-control-description"><?php echo $this->description; ?></span>452 <?php endif; ?>453 454 <select <?php $this->link(); ?>>455 <?php456 foreach ( $this->choices as $value => $label )457 echo '<option value="' . esc_attr( $value ) . '"' . selected( $this->value(), $value, false ) . '>' . $label . '</option>';458 ?>459 </select>460 </label>461 <?php462 break;463 case 'textarea':464 ?>465 <label>466 <?php if ( ! empty( $this->label ) ) : ?>467 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>468 <?php endif;469 if ( ! empty( $this->description ) ) : ?>470 <span class="description customize-control-description"><?php echo $this->description; ?></span>471 <?php endif; ?>472 <textarea rows="5" <?php $this->link(); ?>><?php echo esc_textarea( $this->value() ); ?></textarea>473 </label>474 <?php475 break;476 case 'dropdown-pages':477 ?>478 <label>479 <?php if ( ! empty( $this->label ) ) : ?>480 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>481 <?php endif;482 if ( ! empty( $this->description ) ) : ?>483 <span class="description customize-control-description"><?php echo $this->description; ?></span>484 <?php endif; ?>485 486 <?php $dropdown = wp_dropdown_pages(487 array(488 'name' => '_customize-dropdown-pages-' . $this->id,489 'echo' => 0,490 'show_option_none' => __( '— Select —' ),491 'option_none_value' => '0',492 'selected' => $this->value(),493 )494 );495 496 // Hackily add in the data link parameter.497 $dropdown = str_replace( '<select', '<select ' . $this->get_link(), $dropdown );498 echo $dropdown;499 ?>500 </label>501 <?php502 break;503 default:504 ?>505 <label>506 <?php if ( ! empty( $this->label ) ) : ?>507 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>508 <?php endif;509 if ( ! empty( $this->description ) ) : ?>510 <span class="description customize-control-description"><?php echo $this->description; ?></span>511 <?php endif; ?>512 <input type="<?php echo esc_attr( $this->type ); ?>" <?php $this->input_attrs(); ?> value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); ?> />513 </label>514 <?php515 break;516 }517 }518 519 /**520 * Render the control's JS template.521 *522 * This function is only run for control types that have been registered with523 * {@see WP_Customize_Manager::register_control_type()}.524 *525 * In the future, this will also print the template for the control's container526 * element and be override-able.527 *528 * @since 4.1.0529 */530 final public function print_template() {531 ?>532 <script type="text/html" id="tmpl-customize-control-<?php echo $this->type; ?>-content">533 <?php $this->content_template(); ?>534 </script>535 <?php536 }537 538 /**539 * An Underscore (JS) template for this control's content (but not its container).540 *541 * Class variables for this control class are available in the `data` JS object;542 * export custom variables by overriding {@see WP_Customize_Control::to_json()}.543 *544 * @see WP_Customize_Control::print_template()545 *546 * @since 4.1.0547 */548 protected function content_template() {}549 550 }551 9 552 10 /** … … 644 102 } 645 103 } 646 647 /**648 * Customize Media Control class.649 *650 * @since 4.2.0651 *652 * @see WP_Customize_Control653 */654 class WP_Customize_Media_Control extends WP_Customize_Control {655 /**656 * Control type.657 *658 * @since 4.2.0659 * @access public660 * @var string661 */662 public $type = 'media';663 664 /**665 * Media control mime type.666 *667 * @since 4.2.0668 * @access public669 * @var string670 */671 public $mime_type = '';672 673 /**674 * Button labels.675 *676 * @since 4.2.0677 * @access public678 * @var array679 */680 public $button_labels = array();681 682 /**683 * Constructor.684 *685 * @since 4.1.0686 * @since 4.2.0 Moved from WP_Customize_Upload_Control.687 *688 * @param WP_Customize_Manager $manager Customizer bootstrap instance.689 * @param string $id Control ID.690 * @param array $args Optional. Arguments to override class property defaults.691 */692 public function __construct( $manager, $id, $args = array() ) {693 parent::__construct( $manager, $id, $args );694 695 $this->button_labels = array(696 'select' => __( 'Select File' ),697 'change' => __( 'Change File' ),698 'default' => __( 'Default' ),699 'remove' => __( 'Remove' ),700 'placeholder' => __( 'No file selected' ),701 'frame_title' => __( 'Select File' ),702 'frame_button' => __( 'Choose File' ),703 );704 }705 706 /**707 * Enqueue control related scripts/styles.708 *709 * @since 3.4.0710 * @since 4.2.0 Moved from WP_Customize_Upload_Control.711 */712 public function enqueue() {713 wp_enqueue_media();714 }715 716 /**717 * Refresh the parameters passed to the JavaScript via JSON.718 *719 * @since 3.4.0720 * @since 4.2.0 Moved from WP_Customize_Upload_Control.721 *722 * @see WP_Customize_Control::to_json()723 */724 public function to_json() {725 parent::to_json();726 $this->json['label'] = html_entity_decode( $this->label, ENT_QUOTES, get_bloginfo( 'charset' ) );727 $this->json['mime_type'] = $this->mime_type;728 $this->json['button_labels'] = $this->button_labels;729 $this->json['canUpload'] = current_user_can( 'upload_files' );730 731 $value = $this->value();732 733 if ( is_object( $this->setting ) ) {734 if ( $this->setting->default ) {735 // Fake an attachment model - needs all fields used by template.736 // Note that the default value must be a URL, NOT an attachment ID.737 $type = in_array( substr( $this->setting->default, -3 ), array( 'jpg', 'png', 'gif', 'bmp' ) ) ? 'image' : 'document';738 $default_attachment = array(739 'id' => 1,740 'url' => $this->setting->default,741 'type' => $type,742 'icon' => wp_mime_type_icon( $type ),743 'title' => basename( $this->setting->default ),744 );745 746 if ( 'image' === $type ) {747 $default_attachment['sizes'] = array(748 'full' => array( 'url' => $this->setting->default ),749 );750 }751 752 $this->json['defaultAttachment'] = $default_attachment;753 }754 755 if ( $value && $this->setting->default && $value === $this->setting->default ) {756 // Set the default as the attachment.757 $this->json['attachment'] = $this->json['defaultAttachment'];758 } elseif ( $value ) {759 $this->json['attachment'] = wp_prepare_attachment_for_js( $value );760 }761 }762 }763 764 /**765 * Don't render any content for this control from PHP.766 *767 * @since 3.4.0768 * @since 4.2.0 Moved from WP_Customize_Upload_Control.769 *770 * @see WP_Customize_Media_Control::content_template()771 */772 public function render_content() {}773 774 /**775 * Render a JS template for the content of the media control.776 *777 * @since 4.1.0778 * @since 4.2.0 Moved from WP_Customize_Upload_Control.779 */780 public function content_template() {781 ?>782 <label for="{{ data.settings['default'] }}-button">783 <# if ( data.label ) { #>784 <span class="customize-control-title">{{ data.label }}</span>785 <# } #>786 <# if ( data.description ) { #>787 <span class="description customize-control-description">{{{ data.description }}}</span>788 <# } #>789 </label>790 791 <# if ( data.attachment && data.attachment.id ) { #>792 <div class="current">793 <div class="container">794 <div class="attachment-media-view attachment-media-view-{{ data.attachment.type }} {{ data.attachment.orientation }}">795 <div class="thumbnail thumbnail-{{ data.attachment.type }}">796 <# if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.medium ) { #>797 <img class="attachment-thumb" src="{{ data.attachment.sizes.medium.url }}" draggable="false" />798 <# } else if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.full ) { #>799 <img class="attachment-thumb" src="{{ data.attachment.sizes.full.url }}" draggable="false" />800 <# } else if ( 'audio' === data.attachment.type ) { #>801 <# if ( data.attachment.image && data.attachment.image.src && data.attachment.image.src !== data.attachment.icon ) { #>802 <img src="{{ data.attachment.image.src }}" class="thumbnail" draggable="false" />803 <# } else { #>804 <img src="{{ data.attachment.icon }}" class="attachment-thumb type-icon" draggable="false" />805 <# } #>806 <p class="attachment-meta attachment-meta-title">“{{ data.attachment.title }}”</p>807 <# if ( data.attachment.album || data.attachment.meta.album ) { #>808 <p class="attachment-meta"><em>{{ data.attachment.album || data.attachment.meta.album }}</em></p>809 <# } #>810 <# if ( data.attachment.artist || data.attachment.meta.artist ) { #>811 <p class="attachment-meta">{{ data.attachment.artist || data.attachment.meta.artist }}</p>812 <# } #>813 <audio style="visibility: hidden" controls class="wp-audio-shortcode" width="100%" preload="none">814 <source type="{{ data.attachment.mime }}" src="{{ data.attachment.url }}"/>815 </audio>816 <# } else if ( 'video' === data.attachment.type ) { #>817 <div class="wp-media-wrapper wp-video">818 <video controls="controls" class="wp-video-shortcode" preload="metadata"819 <# if ( data.attachment.image && data.attachment.image.src !== data.attachment.icon ) { #>poster="{{ data.attachment.image.src }}"<# } #>>820 <source type="{{ data.attachment.mime }}" src="{{ data.attachment.url }}"/>821 </video>822 </div>823 <# } else { #>824 <img class="attachment-thumb type-icon icon" src="{{ data.attachment.icon }}" draggable="false" />825 <p class="attachment-title">{{ data.attachment.title }}</p>826 <# } #>827 </div>828 </div>829 </div>830 </div>831 <div class="actions">832 <# if ( data.canUpload ) { #>833 <button type="button" class="button remove-button"><?php echo $this->button_labels['remove']; ?></button>834 <button type="button" class="button upload-button" id="{{ data.settings['default'] }}-button"><?php echo $this->button_labels['change']; ?></button>835 <div style="clear:both"></div>836 <# } #>837 </div>838 <# } else { #>839 <div class="current">840 <div class="container">841 <div class="placeholder">842 <div class="inner">843 <span>844 <?php echo $this->button_labels['placeholder']; ?>845 </span>846 </div>847 </div>848 </div>849 </div>850 <div class="actions">851 <# if ( data.defaultAttachment ) { #>852 <button type="button" class="button default-button"><?php echo $this->button_labels['default']; ?></button>853 <# } #>854 <# if ( data.canUpload ) { #>855 <button type="button" class="button upload-button" id="{{ data.settings['default'] }}-button"><?php echo $this->button_labels['select']; ?></button>856 <# } #>857 <div style="clear:both"></div>858 </div>859 <# } #>860 <?php861 }862 }863 864 /**865 * Customize Upload Control Class.866 *867 * @since 3.4.0868 *869 * @see WP_Customize_Media_Control870 */871 class WP_Customize_Upload_Control extends WP_Customize_Media_Control {872 public $type = 'upload';873 public $mime_type = '';874 public $button_labels = array();875 public $removed = ''; // unused876 public $context; // unused877 public $extensions = array(); // unused878 879 /**880 * Refresh the parameters passed to the JavaScript via JSON.881 *882 * @since 3.4.0883 *884 * @uses WP_Customize_Media_Control::to_json()885 */886 public function to_json() {887 parent::to_json();888 889 $value = $this->value();890 if ( $value ) {891 // Get the attachment model for the existing file.892 $attachment_id = attachment_url_to_postid( $value );893 if ( $attachment_id ) {894 $this->json['attachment'] = wp_prepare_attachment_for_js( $attachment_id );895 }896 }897 }898 }899 900 /**901 * Customize Image Control class.902 *903 * @since 3.4.0904 *905 * @see WP_Customize_Upload_Control906 */907 class WP_Customize_Image_Control extends WP_Customize_Upload_Control {908 public $type = 'image';909 public $mime_type = 'image';910 911 /**912 * Constructor.913 *914 * @since 3.4.0915 * @uses WP_Customize_Upload_Control::__construct()916 *917 * @param WP_Customize_Manager $manager Customizer bootstrap instance.918 * @param string $id Control ID.919 * @param array $args Optional. Arguments to override class property defaults.920 */921 public function __construct( $manager, $id, $args = array() ) {922 parent::__construct( $manager, $id, $args );923 924 $this->button_labels = array(925 'select' => __( 'Select Image' ),926 'change' => __( 'Change Image' ),927 'remove' => __( 'Remove' ),928 'default' => __( 'Default' ),929 'placeholder' => __( 'No image selected' ),930 'frame_title' => __( 'Select Image' ),931 'frame_button' => __( 'Choose Image' ),932 );933 }934 935 /**936 * @since 3.4.2937 * @deprecated 4.1.0938 */939 public function prepare_control() {}940 941 /**942 * @since 3.4.0943 * @deprecated 4.1.0944 *945 * @param string $id946 * @param string $label947 * @param mixed $callback948 */949 public function add_tab( $id, $label, $callback ) {}950 951 /**952 * @since 3.4.0953 * @deprecated 4.1.0954 *955 * @param string $id956 */957 public function remove_tab( $id ) {}958 959 /**960 * @since 3.4.0961 * @deprecated 4.1.0962 *963 * @param string $url964 * @param string $thumbnail_url965 */966 public function print_tab_image( $url, $thumbnail_url = null ) {}967 }968 969 /**970 * Customize Background Image Control class.971 *972 * @since 3.4.0973 *974 * @see WP_Customize_Image_Control975 */976 class WP_Customize_Background_Image_Control extends WP_Customize_Image_Control {977 public $type = 'background';978 979 /**980 * Constructor.981 *982 * @since 3.4.0983 * @uses WP_Customize_Image_Control::__construct()984 *985 * @param WP_Customize_Manager $manager Customizer bootstrap instance.986 */987 public function __construct( $manager ) {988 parent::__construct( $manager, 'background_image', array(989 'label' => __( 'Background Image' ),990 'section' => 'background_image',991 ) );992 }993 994 /**995 * Enqueue control related scripts/styles.996 *997 * @since 4.1.0998 */999 public function enqueue() {1000 parent::enqueue();1001 1002 wp_localize_script( 'customize-controls', '_wpCustomizeBackground', array(1003 'nonces' => array(1004 'add' => wp_create_nonce( 'background-add' ),1005 ),1006 ) );1007 }1008 }1009 1010 /**1011 * Customize Cropped Image Control class.1012 *1013 * @since 4.3.01014 *1015 * @see WP_Customize_Image_Control1016 */1017 class WP_Customize_Cropped_Image_Control extends WP_Customize_Image_Control {1018 1019 /**1020 * Control type.1021 *1022 * @since 4.3.01023 * @access public1024 * @var string1025 */1026 public $type = 'cropped_image';1027 1028 /**1029 * Suggested width for cropped image.1030 *1031 * @since 4.3.01032 * @access public1033 * @var int1034 */1035 public $width = 150;1036 1037 /**1038 * Suggested height for cropped image.1039 *1040 * @since 4.3.01041 * @access public1042 * @var int1043 */1044 public $height = 150;1045 1046 /**1047 * Whether the width is flexible.1048 *1049 * @since 4.3.01050 * @access public1051 * @var bool1052 */1053 public $flex_width = false;1054 1055 /**1056 * Whether the height is flexible.1057 *1058 * @since 4.3.01059 * @access public1060 * @var bool1061 */1062 public $flex_height = false;1063 1064 /**1065 * Enqueue control related scripts/styles.1066 *1067 * @since 4.3.01068 * @access public1069 */1070 public function enqueue() {1071 wp_enqueue_script( 'customize-views' );1072 1073 parent::enqueue();1074 }1075 1076 /**1077 * Refresh the parameters passed to the JavaScript via JSON.1078 *1079 * @since 4.3.01080 * @access public1081 *1082 * @see WP_Customize_Control::to_json()1083 */1084 public function to_json() {1085 parent::to_json();1086 1087 $this->json['width'] = absint( $this->width );1088 $this->json['height'] = absint( $this->height );1089 $this->json['flex_width'] = absint( $this->flex_width );1090 $this->json['flex_height'] = absint( $this->flex_height );1091 }1092 1093 }1094 1095 /**1096 * Customize Site Icon control class.1097 *1098 * Used only for custom functionality in JavaScript.1099 *1100 * @since 4.3.01101 *1102 * @see WP_Customize_Cropped_Image_Control1103 */1104 class WP_Customize_Site_Icon_Control extends WP_Customize_Cropped_Image_Control {1105 1106 /**1107 * Control type.1108 *1109 * @since 4.3.01110 * @access public1111 * @var string1112 */1113 public $type = 'site_icon';1114 1115 /**1116 * Constructor.1117 *1118 * @since 4.3.01119 * @access public1120 *1121 * @param WP_Customize_Manager $manager Customizer bootstrap instance.1122 * @param string $id Control ID.1123 * @param array $args Optional. Arguments to override class property defaults.1124 */1125 public function __construct( $manager, $id, $args = array() ) {1126 parent::__construct( $manager, $id, $args );1127 add_action( 'customize_controls_print_styles', 'wp_site_icon', 99 );1128 }1129 }1130 1131 /**1132 * Customize Header Image Control class.1133 *1134 * @since 3.4.01135 *1136 * @see WP_Customize_Image_Control1137 */1138 class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control {1139 public $type = 'header';1140 public $uploaded_headers;1141 public $default_headers;1142 1143 /**1144 * Constructor.1145 *1146 * @since 3.4.01147 *1148 * @param WP_Customize_Manager $manager Customizer bootstrap instance.1149 */1150 public function __construct( $manager ) {1151 parent::__construct( $manager, 'header_image', array(1152 'label' => __( 'Header Image' ),1153 'settings' => array(1154 'default' => 'header_image',1155 'data' => 'header_image_data',1156 ),1157 'section' => 'header_image',1158 'removed' => 'remove-header',1159 'get_url' => 'get_header_image',1160 ) );1161 1162 }1163 1164 /**1165 * @access public1166 */1167 public function enqueue() {1168 wp_enqueue_media();1169 wp_enqueue_script( 'customize-views' );1170 1171 $this->prepare_control();1172 1173 wp_localize_script( 'customize-views', '_wpCustomizeHeader', array(1174 'data' => array(1175 'width' => absint( get_theme_support( 'custom-header', 'width' ) ),1176 'height' => absint( get_theme_support( 'custom-header', 'height' ) ),1177 'flex-width' => absint( get_theme_support( 'custom-header', 'flex-width' ) ),1178 'flex-height' => absint( get_theme_support( 'custom-header', 'flex-height' ) ),1179 'currentImgSrc' => $this->get_current_image_src(),1180 ),1181 'nonces' => array(1182 'add' => wp_create_nonce( 'header-add' ),1183 'remove' => wp_create_nonce( 'header-remove' ),1184 ),1185 'uploads' => $this->uploaded_headers,1186 'defaults' => $this->default_headers1187 ) );1188 1189 parent::enqueue();1190 }1191 1192 /**1193 *1194 * @global Custom_Image_Header $custom_image_header1195 */1196 public function prepare_control() {1197 global $custom_image_header;1198 if ( empty( $custom_image_header ) ) {1199 return;1200 }1201 1202 // Process default headers and uploaded headers.1203 $custom_image_header->process_default_headers();1204 $this->default_headers = $custom_image_header->get_default_header_images();1205 $this->uploaded_headers = $custom_image_header->get_uploaded_header_images();1206 }1207 1208 /**1209 * @access public1210 */1211 public function print_header_image_template() {1212 ?>1213 <script type="text/template" id="tmpl-header-choice">1214 <# if (data.random) { #>1215 <button type="button" class="button display-options random">1216 <span class="dashicons dashicons-randomize dice"></span>1217 <# if ( data.type === 'uploaded' ) { #>1218 <?php _e( 'Randomize uploaded headers' ); ?>1219 <# } else if ( data.type === 'default' ) { #>1220 <?php _e( 'Randomize suggested headers' ); ?>1221 <# } #>1222 </button>1223 1224 <# } else { #>1225 1226 <# if (data.type === 'uploaded') { #>1227 <button type="button" class="dashicons dashicons-no close"><span class="screen-reader-text"><?php _e( 'Remove image' ); ?></span></button>1228 <# } #>1229 1230 <button type="button" class="choice thumbnail"1231 data-customize-image-value="{{{data.header.url}}}"1232 data-customize-header-image-data="{{JSON.stringify(data.header)}}">1233 <span class="screen-reader-text"><?php _e( 'Set image' ); ?></span>1234 <img src="{{{data.header.thumbnail_url}}}" alt="{{{data.header.alt_text || data.header.description}}}">1235 </button>1236 1237 <# } #>1238 </script>1239 1240 <script type="text/template" id="tmpl-header-current">1241 <# if (data.choice) { #>1242 <# if (data.random) { #>1243 1244 <div class="placeholder">1245 <div class="inner">1246 <span><span class="dashicons dashicons-randomize dice"></span>1247 <# if ( data.type === 'uploaded' ) { #>1248 <?php _e( 'Randomizing uploaded headers' ); ?>1249 <# } else if ( data.type === 'default' ) { #>1250 <?php _e( 'Randomizing suggested headers' ); ?>1251 <# } #>1252 </span>1253 </div>1254 </div>1255 1256 <# } else { #>1257 1258 <img src="{{{data.header.thumbnail_url}}}" alt="{{{data.header.alt_text || data.header.description}}}" tabindex="0"/>1259 1260 <# } #>1261 <# } else { #>1262 1263 <div class="placeholder">1264 <div class="inner">1265 <span>1266 <?php _e( 'No image set' ); ?>1267 </span>1268 </div>1269 </div>1270 1271 <# } #>1272 </script>1273 <?php1274 }1275 1276 /**1277 * @return string|void1278 */1279 public function get_current_image_src() {1280 $src = $this->value();1281 if ( isset( $this->get_url ) ) {1282 $src = call_user_func( $this->get_url, $src );1283 return $src;1284 }1285 }1286 1287 /**1288 * @access public1289 */1290 public function render_content() {1291 $this->print_header_image_template();1292 $visibility = $this->get_current_image_src() ? '' : ' style="display:none" ';1293 $width = absint( get_theme_support( 'custom-header', 'width' ) );1294 $height = absint( get_theme_support( 'custom-header', 'height' ) );1295 ?>1296 <div class="customize-control-content">1297 <p class="customizer-section-intro">1298 <?php1299 if ( $width && $height ) {1300 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 × %s</strong> pixels.' ), $width, $height );1301 } elseif ( $width ) {1302 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 );1303 } else {1304 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 );1305 }1306 ?>1307 </p>1308 <div class="current">1309 <label for="header_image-button">1310 <span class="customize-control-title">1311 <?php _e( 'Current header' ); ?>1312 </span>1313 </label>1314 <div class="container">1315 </div>1316 </div>1317 <div class="actions">1318 <?php if ( current_user_can( 'upload_files' ) ): ?>1319 <button type="button"<?php echo $visibility; ?> class="button remove" aria-label="<?php esc_attr_e( 'Hide header image' ); ?>"><?php _e( 'Hide image' ); ?></button>1320 <button type="button" class="button new" id="header_image-button" aria-label="<?php esc_attr_e( 'Add new header image' ); ?>"><?php _e( 'Add new image' ); ?></button>1321 <div style="clear:both"></div>1322 <?php endif; ?>1323 </div>1324 <div class="choices">1325 <span class="customize-control-title header-previously-uploaded">1326 <?php _ex( 'Previously uploaded', 'custom headers' ); ?>1327 </span>1328 <div class="uploaded">1329 <div class="list">1330 </div>1331 </div>1332 <span class="customize-control-title header-default">1333 <?php _ex( 'Suggested', 'custom headers' ); ?>1334 </span>1335 <div class="default">1336 <div class="list">1337 </div>1338 </div>1339 </div>1340 </div>1341 <?php1342 }1343 }1344 1345 /**1346 * Customize Theme Control class.1347 *1348 * @since 4.2.01349 *1350 * @see WP_Customize_Control1351 */1352 class WP_Customize_Theme_Control extends WP_Customize_Control {1353 1354 /**1355 * Customize control type.1356 *1357 * @since 4.2.01358 * @access public1359 * @var string1360 */1361 public $type = 'theme';1362 1363 /**1364 * Theme object.1365 *1366 * @since 4.2.01367 * @access public1368 * @var WP_Theme1369 */1370 public $theme;1371 1372 /**1373 * Refresh the parameters passed to the JavaScript via JSON.1374 *1375 * @since 4.2.01376 * @access public1377 *1378 * @see WP_Customize_Control::to_json()1379 */1380 public function to_json() {1381 parent::to_json();1382 $this->json['theme'] = $this->theme;1383 }1384 1385 /**1386 * Don't render the control content from PHP, as it's rendered via JS on load.1387 *1388 * @since 4.2.01389 * @access public1390 */1391 public function render_content() {}1392 1393 /**1394 * Render a JS template for theme display.1395 *1396 * @since 4.2.01397 * @access public1398 */1399 public function content_template() {1400 $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );1401 $active_url = esc_url( remove_query_arg( 'theme', $current_url ) );1402 $preview_url = esc_url( add_query_arg( 'theme', '__THEME__', $current_url ) ); // Token because esc_url() strips curly braces.1403 $preview_url = str_replace( '__THEME__', '{{ data.theme.id }}', $preview_url );1404 ?>1405 <# if ( data.theme.isActiveTheme ) { #>1406 <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">1407 <# } else { #>1408 <div class="theme" tabindex="0" data-preview-url="<?php echo esc_attr( $preview_url ); ?>" aria-describedby="{{ data.theme.id }}-action {{ data.theme.id }}-name">1409 <# } #>1410 1411 <# if ( data.theme.screenshot[0] ) { #>1412 <div class="theme-screenshot">1413 <img data-src="{{ data.theme.screenshot[0] }}" alt="" />1414 </div>1415 <# } else { #>1416 <div class="theme-screenshot blank"></div>1417 <# } #>1418 1419 <# if ( data.theme.isActiveTheme ) { #>1420 <span class="more-details" id="{{ data.theme.id }}-action"><?php _e( 'Customize' ); ?></span>1421 <# } else { #>1422 <span class="more-details" id="{{ data.theme.id }}-action"><?php _e( 'Live Preview' ); ?></span>1423 <# } #>1424 1425 <div class="theme-author"><?php printf( __( 'By %s' ), '{{ data.theme.author }}' ); ?></div>1426 1427 <# if ( data.theme.isActiveTheme ) { #>1428 <h3 class="theme-name" id="{{ data.theme.id }}-name">1429 <?php1430 /* translators: %s: theme name */1431 printf( __( '<span>Active:</span> %s' ), '{{{ data.theme.name }}}' );1432 ?>1433 </h3>1434 <# } else { #>1435 <h3 class="theme-name" id="{{ data.theme.id }}-name">{{{ data.theme.name }}}</h3>1436 <div class="theme-actions">1437 <button type="button" class="button theme-details"><?php _e( 'Theme Details' ); ?></button>1438 </div>1439 <# } #>1440 </div>1441 <?php1442 }1443 }1444 1445 /**1446 * Widget Area Customize Control class.1447 *1448 * @since 3.9.01449 *1450 * @see WP_Customize_Control1451 */1452 class WP_Widget_Area_Customize_Control extends WP_Customize_Control {1453 public $type = 'sidebar_widgets';1454 public $sidebar_id;1455 1456 public function to_json() {1457 parent::to_json();1458 $exported_properties = array( 'sidebar_id' );1459 foreach ( $exported_properties as $key ) {1460 $this->json[ $key ] = $this->$key;1461 }1462 }1463 1464 /**1465 * @access public1466 */1467 public function render_content() {1468 $id = 'reorder-widgets-desc-' . str_replace( array( '[', ']' ), array( '-', '' ), $this->id );1469 ?>1470 <button type="button" class="button-secondary add-new-widget" aria-expanded="false" aria-controls="available-widgets">1471 <?php _e( 'Add a Widget' ); ?>1472 </button>1473 <button type="button" class="not-a-button reorder-toggle" aria-label="<?php esc_attr_e( 'Reorder widgets' ); ?>" aria-describedby="<?php echo esc_attr( $id ); ?>">1474 <span class="reorder"><?php _ex( 'Reorder', 'Reorder widgets in Customizer' ); ?></span>1475 <span class="reorder-done"><?php _ex( 'Done', 'Cancel reordering widgets in Customizer' ); ?></span>1476 </button>1477 <p class="screen-reader-text" id="<?php echo esc_attr( $id ); ?>"><?php _e( 'When in reorder mode, additional controls to reorder widgets will be available in the widgets list above.' ); ?></p>1478 <?php1479 }1480 1481 }1482 1483 /**1484 * Widget Form Customize Control class.1485 *1486 * @since 3.9.01487 *1488 * @see WP_Customize_Control1489 */1490 class WP_Widget_Form_Customize_Control extends WP_Customize_Control {1491 public $type = 'widget_form';1492 public $widget_id;1493 public $widget_id_base;1494 public $sidebar_id;1495 public $is_new = false;1496 public $width;1497 public $height;1498 public $is_wide = false;1499 1500 /**1501 * Gather control params for exporting to JavaScript.1502 *1503 * @global array $wp_registered_widgets1504 */1505 public function to_json() {1506 global $wp_registered_widgets;1507 1508 parent::to_json();1509 $exported_properties = array( 'widget_id', 'widget_id_base', 'sidebar_id', 'width', 'height', 'is_wide' );1510 foreach ( $exported_properties as $key ) {1511 $this->json[ $key ] = $this->$key;1512 }1513 1514 // Get the widget_control and widget_content.1515 require_once ABSPATH . '/wp-admin/includes/widgets.php';1516 1517 $widget = $wp_registered_widgets[ $this->widget_id ];1518 if ( ! isset( $widget['params'][0] ) ) {1519 $widget['params'][0] = array();1520 }1521 1522 $args = array(1523 'widget_id' => $widget['id'],1524 'widget_name' => $widget['name'],1525 );1526 1527 $args = wp_list_widget_controls_dynamic_sidebar( array( 0 => $args, 1 => $widget['params'][0] ) );1528 $widget_control_parts = $this->manager->widgets->get_widget_control_parts( $args );1529 1530 $this->json['widget_control'] = $widget_control_parts['control'];1531 $this->json['widget_content'] = $widget_control_parts['content'];1532 }1533 1534 /**1535 * Override render_content to be no-op since content is exported via to_json for deferred embedding.1536 */1537 public function render_content() {}1538 1539 /**1540 * Whether the current widget is rendered on the page.1541 *1542 * @since 4.0.01543 * @access public1544 *1545 * @return bool Whether the widget is rendered.1546 */1547 public function active_callback() {1548 return $this->manager->widgets->is_widget_rendered( $this->widget_id );1549 }1550 }1551 1552 /**1553 * Customize Nav Menu Control Class.1554 *1555 * @since 4.3.01556 */1557 class WP_Customize_Nav_Menu_Control extends WP_Customize_Control {1558 1559 /**1560 * Control type.1561 *1562 * @since 4.3.01563 * @access public1564 * @var string1565 */1566 public $type = 'nav_menu';1567 1568 /**1569 * The nav menu setting.1570 *1571 * @since 4.3.01572 * @access public1573 * @var WP_Customize_Nav_Menu_Setting1574 */1575 public $setting;1576 1577 /**1578 * Don't render the control's content - it uses a JS template instead.1579 *1580 * @since 4.3.01581 * @access public1582 */1583 public function render_content() {}1584 1585 /**1586 * JS/Underscore template for the control UI.1587 *1588 * @since 4.3.01589 * @access public1590 */1591 public function content_template() {1592 ?>1593 <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">1594 <?php _e( 'Add Items' ); ?>1595 </button>1596 <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 }}">1597 <span class="reorder"><?php _ex( 'Reorder', 'Reorder menu items in Customizer' ); ?></span>1598 <span class="reorder-done"><?php _ex( 'Done', 'Cancel reordering menu items in Customizer' ); ?></span>1599 </button>1600 <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>1601 <span class="add-menu-item-loading spinner"></span>1602 <span class="menu-delete-item">1603 <button type="button" class="not-a-button menu-delete">1604 <?php _e( 'Delete menu' ); ?> <span class="screen-reader-text">{{ data.menu_name }}</span>1605 </button>1606 </span>1607 <?php if ( current_theme_supports( 'menus' ) ) : ?>1608 <ul class="menu-settings">1609 <li class="customize-control">1610 <span class="customize-control-title"><?php _e( 'Menu locations' ); ?></span>1611 </li>1612 1613 <?php foreach ( get_registered_nav_menus() as $location => $description ) : ?>1614 <li class="customize-control customize-control-checkbox assigned-menu-location">1615 <label>1616 <input type="checkbox" data-menu-id="{{ data.menu_id }}" data-location-id="<?php echo esc_attr( $location ); ?>" class="menu-location" /> <?php echo $description; ?>1617 <span class="theme-location-set"><?php printf( _x( '(Current: %s)', 'Current menu location' ), '<span class="current-menu-location-name-' . esc_attr( $location ) . '"></span>' ); ?></span>1618 </label>1619 </li>1620 <?php endforeach; ?>1621 1622 </ul>1623 <?php endif;1624 }1625 1626 /**1627 * Return parameters for this control.1628 *1629 * @since 4.3.01630 * @access public1631 *1632 * @return array Exported parameters.1633 */1634 public function json() {1635 $exported = parent::json();1636 $exported['menu_id'] = $this->setting->term_id;1637 1638 return $exported;1639 }1640 }1641 1642 /**1643 * Customize control to represent the name field for a given menu.1644 *1645 * @since 4.3.01646 */1647 class WP_Customize_Nav_Menu_Item_Control extends WP_Customize_Control {1648 1649 /**1650 * Control type.1651 *1652 * @since 4.3.01653 * @access public1654 * @var string1655 */1656 public $type = 'nav_menu_item';1657 1658 /**1659 * The nav menu item setting.1660 *1661 * @since 4.3.01662 * @access public1663 * @var WP_Customize_Nav_Menu_Item_Setting1664 */1665 public $setting;1666 1667 /**1668 * Constructor.1669 *1670 * @since 4.3.01671 * @access public1672 *1673 * @see WP_Customize_Control::__construct()1674 *1675 * @param WP_Customize_Manager $manager Customizer bootstrap instance.1676 * @param string $id The control ID.1677 * @param array $args Optional. Overrides class property defaults.1678 */1679 public function __construct( $manager, $id, $args = array() ) {1680 parent::__construct( $manager, $id, $args );1681 }1682 1683 /**1684 * Don't render the control's content - it's rendered with a JS template.1685 *1686 * @since 4.3.01687 * @access public1688 */1689 public function render_content() {}1690 1691 /**1692 * JS/Underscore template for the control UI.1693 *1694 * @since 4.3.01695 * @access public1696 */1697 public function content_template() {1698 ?>1699 <div class="menu-item-bar">1700 <div class="menu-item-handle">1701 <span class="item-type" aria-hidden="true">{{ data.item_type_label }}</span>1702 <span class="item-title" aria-hidden="true">1703 <span class="spinner"></span>1704 <span class="menu-item-title<# if ( ! data.title ) { #> no-title<# } #>">{{ data.title || wp.customize.Menus.data.l10n.untitled }}</span>1705 </span>1706 <span class="item-controls">1707 <button type="button" class="not-a-button item-edit" aria-expanded="false"><span class="screen-reader-text"><?php1708 /* translators: 1: Title of a menu item, 2: Type of a menu item */1709 printf( __( 'Edit menu item: %1$s (%2$s)' ), '{{ data.title || wp.customize.Menus.data.l10n.untitled }}', '{{ data.item_type_label }}' );1710 ?></span><span class="toggle-indicator" aria-hidden="true"></span></button>1711 <button type="button" class="not-a-button item-delete submitdelete deletion"><span class="screen-reader-text"><?php1712 /* translators: 1: Title of a menu item, 2: Type of a menu item */1713 printf( __( 'Remove Menu Item: %1$s (%2$s)' ), '{{ data.title || wp.customize.Menus.data.l10n.untitled }}', '{{ data.item_type_label }}' );1714 ?></span></button>1715 </span>1716 </div>1717 </div>1718 1719 <div class="menu-item-settings" id="menu-item-settings-{{ data.menu_item_id }}">1720 <# if ( 'custom' === data.item_type ) { #>1721 <p class="field-url description description-thin">1722 <label for="edit-menu-item-url-{{ data.menu_item_id }}">1723 <?php _e( 'URL' ); ?><br />1724 <input class="widefat code edit-menu-item-url" type="text" id="edit-menu-item-url-{{ data.menu_item_id }}" name="menu-item-url" />1725 </label>1726 </p>1727 <# } #>1728 <p class="description description-thin">1729 <label for="edit-menu-item-title-{{ data.menu_item_id }}">1730 <?php _e( 'Navigation Label' ); ?><br />1731 <input type="text" id="edit-menu-item-title-{{ data.menu_item_id }}" class="widefat edit-menu-item-title" name="menu-item-title" />1732 </label>1733 </p>1734 <p class="field-link-target description description-thin">1735 <label for="edit-menu-item-target-{{ data.menu_item_id }}">1736 <input type="checkbox" id="edit-menu-item-target-{{ data.menu_item_id }}" class="edit-menu-item-target" value="_blank" name="menu-item-target" />1737 <?php _e( 'Open link in a new tab' ); ?>1738 </label>1739 </p>1740 <p class="field-attr-title description description-thin">1741 <label for="edit-menu-item-attr-title-{{ data.menu_item_id }}">1742 <?php _e( 'Title Attribute' ); ?><br />1743 <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" />1744 </label>1745 </p>1746 <p class="field-css-classes description description-thin">1747 <label for="edit-menu-item-classes-{{ data.menu_item_id }}">1748 <?php _e( 'CSS Classes' ); ?><br />1749 <input type="text" id="edit-menu-item-classes-{{ data.menu_item_id }}" class="widefat code edit-menu-item-classes" name="menu-item-classes" />1750 </label>1751 </p>1752 <p class="field-xfn description description-thin">1753 <label for="edit-menu-item-xfn-{{ data.menu_item_id }}">1754 <?php _e( 'Link Relationship (XFN)' ); ?><br />1755 <input type="text" id="edit-menu-item-xfn-{{ data.menu_item_id }}" class="widefat code edit-menu-item-xfn" name="menu-item-xfn" />1756 </label>1757 </p>1758 <p class="field-description description description-thin">1759 <label for="edit-menu-item-description-{{ data.menu_item_id }}">1760 <?php _e( 'Description' ); ?><br />1761 <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>1762 <span class="description"><?php _e( 'The description will be displayed in the menu if the current theme supports it.' ); ?></span>1763 </label>1764 </p>1765 1766 <div class="menu-item-actions description-thin submitbox">1767 <# if ( ( 'post_type' === data.item_type || 'taxonomy' === data.item_type ) && '' !== data.original_title ) { #>1768 <p class="link-to-original">1769 <?php printf( __( 'Original: %s' ), '<a class="original-link" href="{{ data.url }}">{{ data.original_title }}</a>' ); ?>1770 </p>1771 <# } #>1772 1773 <button type="button" class="not-a-button item-delete submitdelete deletion"><?php _e( 'Remove' ); ?></button>1774 <span class="spinner"></span>1775 </div>1776 <input type="hidden" name="menu-item-db-id[{{ data.menu_item_id }}]" class="menu-item-data-db-id" value="{{ data.menu_item_id }}" />1777 <input type="hidden" name="menu-item-parent-id[{{ data.menu_item_id }}]" class="menu-item-data-parent-id" value="{{ data.parent }}" />1778 </div><!-- .menu-item-settings-->1779 <ul class="menu-item-transport"></ul>1780 <?php1781 }1782 1783 /**1784 * Return parameters for this control.1785 *1786 * @since 4.3.01787 * @access public1788 *1789 * @return array Exported parameters.1790 */1791 public function json() {1792 $exported = parent::json();1793 $exported['menu_item_id'] = $this->setting->post_id;1794 1795 return $exported;1796 }1797 }1798 1799 /**1800 * Customize Menu Location Control Class.1801 *1802 * This custom control is only needed for JS.1803 *1804 * @since 4.3.01805 *1806 * @see WP_Customize_Control1807 */1808 class WP_Customize_Nav_Menu_Location_Control extends WP_Customize_Control {1809 1810 /**1811 * Control type.1812 *1813 * @since 4.3.01814 * @access public1815 * @var string1816 */1817 public $type = 'nav_menu_location';1818 1819 /**1820 * Location ID.1821 *1822 * @since 4.3.01823 * @access public1824 * @var string1825 */1826 public $location_id = '';1827 1828 /**1829 * Refresh the parameters passed to JavaScript via JSON.1830 *1831 * @since 4.3.01832 * @access public1833 *1834 * @see WP_Customize_Control::to_json()1835 */1836 public function to_json() {1837 parent::to_json();1838 $this->json['locationId'] = $this->location_id;1839 }1840 1841 /**1842 * Render content just like a normal select control.1843 *1844 * @since 4.3.01845 * @access public1846 */1847 public function render_content() {1848 if ( empty( $this->choices ) ) {1849 return;1850 }1851 ?>1852 <label>1853 <?php if ( ! empty( $this->label ) ) : ?>1854 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>1855 <?php endif; ?>1856 1857 <?php if ( ! empty( $this->description ) ) : ?>1858 <span class="description customize-control-description"><?php echo $this->description; ?></span>1859 <?php endif; ?>1860 1861 <select <?php $this->link(); ?>>1862 <?php1863 foreach ( $this->choices as $value => $label ) :1864 echo '<option value="' . esc_attr( $value ) . '"' . selected( $this->value(), $value, false ) . '>' . $label . '</option>';1865 endforeach;1866 ?>1867 </select>1868 </label>1869 <?php1870 }1871 }1872 1873 /**1874 * Customize control to represent the name field for a given menu.1875 *1876 * @since 4.3.01877 *1878 * @see WP_Customize_Control1879 */1880 class WP_Customize_Nav_Menu_Name_Control extends WP_Customize_Control {1881 1882 /**1883 * Type of control, used by JS.1884 *1885 * @since 4.3.01886 * @access public1887 * @var string1888 */1889 public $type = 'nav_menu_name';1890 1891 /**1892 * No-op since we're using JS template.1893 *1894 * @since 4.3.01895 * @access protected1896 */1897 protected function render_content() {}1898 1899 /**1900 * Render the Underscore template for this control.1901 *1902 * @since 4.3.01903 * @access protected1904 */1905 protected function content_template() {1906 ?>1907 <label>1908 <# if ( data.label ) { #>1909 <span class="customize-control-title screen-reader-text">{{ data.label }}</span>1910 <# } #>1911 <input type="text" class="menu-name-field live-update-section-title" />1912 </label>1913 <?php1914 }1915 }1916 1917 /**1918 * Customize control to represent the auto_add field for a given menu.1919 *1920 * @since 4.3.01921 *1922 * @see WP_Customize_Control1923 */1924 class WP_Customize_Nav_Menu_Auto_Add_Control extends WP_Customize_Control {1925 1926 /**1927 * Type of control, used by JS.1928 *1929 * @since 4.3.01930 * @access public1931 * @var string1932 */1933 public $type = 'nav_menu_auto_add';1934 1935 /**1936 * No-op since we're using JS template.1937 *1938 * @since 4.3.01939 * @access protected1940 */1941 protected function render_content() {}1942 1943 /**1944 * Render the Underscore template for this control.1945 *1946 * @since 4.3.01947 * @access protected1948 */1949 protected function content_template() {1950 ?>1951 <span class="customize-control-title"><?php _e( 'Menu options' ); ?></span>1952 <label>1953 <input type="checkbox" class="auto_add" />1954 <?php _e( 'Automatically add new top-level pages to this menu' ); ?>1955 </label>1956 <?php1957 }1958 }1959 1960 /**1961 * Customize control class for new menus.1962 *1963 * @since 4.3.01964 *1965 * @see WP_Customize_Control1966 */1967 class WP_Customize_New_Menu_Control extends WP_Customize_Control {1968 1969 /**1970 * Control type.1971 *1972 * @since 4.3.01973 * @access public1974 * @var string1975 */1976 public $type = 'new_menu';1977 1978 /**1979 * Render the control's content.1980 *1981 * @since 4.3.01982 * @access public1983 */1984 public function render_content() {1985 ?>1986 <button type="button" class="button button-primary" id="create-new-menu-submit"><?php _e( 'Create Menu' ); ?></button>1987 <span class="spinner"></span>1988 <?php1989 }1990 } -
trunk/src/wp-includes/customize/class-wp-customize-cropped-image-control.php
r35381 r35389 1 1 <?php 2 2 /** 3 * WordPress Customize Control classes3 * Customize API: WP_Customize_Cropped_Image_Control class 4 4 * 5 5 * @package WordPress 6 6 * @subpackage Customize 7 * @since 3.4.07 * @since 4.4.0 8 8 */ 9 10 /**11 * Customize Control class.12 *13 * @since 3.4.014 */15 class WP_Customize_Control {16 17 /**18 * Incremented with each new class instantiation, then stored in $instance_number.19 *20 * Used when sorting two instances whose priorities are equal.21 *22 * @since 4.1.023 *24 * @static25 * @access protected26 * @var int27 */28 protected static $instance_count = 0;29 30 /**31 * Order in which this instance was created in relation to other instances.32 *33 * @since 4.1.034 * @access public35 * @var int36 */37 public $instance_number;38 39 /**40 * @access public41 * @var WP_Customize_Manager42 */43 public $manager;44 45 /**46 * @access public47 * @var string48 */49 public $id;50 51 /**52 * All settings tied to the control.53 *54 * @access public55 * @var array56 */57 public $settings;58 59 /**60 * The primary setting for the control (if there is one).61 *62 * @access public63 * @var string64 */65 public $setting = 'default';66 67 /**68 * @access public69 * @var int70 */71 public $priority = 10;72 73 /**74 * @access public75 * @var string76 */77 public $section = '';78 79 /**80 * @access public81 * @var string82 */83 public $label = '';84 85 /**86 * @access public87 * @var string88 */89 public $description = '';90 91 /**92 * @todo: Remove choices93 *94 * @access public95 * @var array96 */97 public $choices = array();98 99 /**100 * @access public101 * @var array102 */103 public $input_attrs = array();104 105 /**106 * @deprecated It is better to just call the json() method107 * @access public108 * @var array109 */110 public $json = array();111 112 /**113 * @access public114 * @var string115 */116 public $type = 'text';117 118 /**119 * Callback.120 *121 * @since 4.0.0122 * @access public123 *124 * @see WP_Customize_Control::active()125 *126 * @var callable Callback is called with one argument, the instance of127 * WP_Customize_Control, and returns bool to indicate whether128 * the control is active (such as it relates to the URL129 * currently being previewed).130 */131 public $active_callback = '';132 133 /**134 * Constructor.135 *136 * Supplied $args override class property defaults.137 *138 * If $args['settings'] is not defined, use the $id as the setting ID.139 *140 * @since 3.4.0141 *142 * @param WP_Customize_Manager $manager Customizer bootstrap instance.143 * @param string $id Control ID.144 * @param array $args Optional. Arguments to override class property defaults.145 */146 public function __construct( $manager, $id, $args = array() ) {147 $keys = array_keys( get_object_vars( $this ) );148 foreach ( $keys as $key ) {149 if ( isset( $args[ $key ] ) ) {150 $this->$key = $args[ $key ];151 }152 }153 154 $this->manager = $manager;155 $this->id = $id;156 if ( empty( $this->active_callback ) ) {157 $this->active_callback = array( $this, 'active_callback' );158 }159 self::$instance_count += 1;160 $this->instance_number = self::$instance_count;161 162 // Process settings.163 if ( empty( $this->settings ) ) {164 $this->settings = $id;165 }166 167 $settings = array();168 if ( is_array( $this->settings ) ) {169 foreach ( $this->settings as $key => $setting ) {170 $settings[ $key ] = $this->manager->get_setting( $setting );171 }172 } else {173 $this->setting = $this->manager->get_setting( $this->settings );174 $settings['default'] = $this->setting;175 }176 $this->settings = $settings;177 }178 179 /**180 * Enqueue control related scripts/styles.181 *182 * @since 3.4.0183 */184 public function enqueue() {}185 186 /**187 * Check whether control is active to current Customizer preview.188 *189 * @since 4.0.0190 * @access public191 *192 * @return bool Whether the control is active to the current preview.193 */194 final public function active() {195 $control = $this;196 $active = call_user_func( $this->active_callback, $this );197 198 /**199 * Filter response of WP_Customize_Control::active().200 *201 * @since 4.0.0202 *203 * @param bool $active Whether the Customizer control is active.204 * @param WP_Customize_Control $control WP_Customize_Control instance.205 */206 $active = apply_filters( 'customize_control_active', $active, $control );207 208 return $active;209 }210 211 /**212 * Default callback used when invoking WP_Customize_Control::active().213 *214 * Subclasses can override this with their specific logic, or they may215 * provide an 'active_callback' argument to the constructor.216 *217 * @since 4.0.0218 * @access public219 *220 * @return true Always true.221 */222 public function active_callback() {223 return true;224 }225 226 /**227 * Fetch a setting's value.228 * Grabs the main setting by default.229 *230 * @since 3.4.0231 *232 * @param string $setting_key233 * @return mixed The requested setting's value, if the setting exists.234 */235 final public function value( $setting_key = 'default' ) {236 if ( isset( $this->settings[ $setting_key ] ) ) {237 return $this->settings[ $setting_key ]->value();238 }239 }240 241 /**242 * Refresh the parameters passed to the JavaScript via JSON.243 *244 * @since 3.4.0245 */246 public function to_json() {247 $this->json['settings'] = array();248 foreach ( $this->settings as $key => $setting ) {249 $this->json['settings'][ $key ] = $setting->id;250 }251 252 $this->json['type'] = $this->type;253 $this->json['priority'] = $this->priority;254 $this->json['active'] = $this->active();255 $this->json['section'] = $this->section;256 $this->json['content'] = $this->get_content();257 $this->json['label'] = $this->label;258 $this->json['description'] = $this->description;259 $this->json['instanceNumber'] = $this->instance_number;260 }261 262 /**263 * Get the data to export to the client via JSON.264 *265 * @since 4.1.0266 *267 * @return array Array of parameters passed to the JavaScript.268 */269 public function json() {270 $this->to_json();271 return $this->json;272 }273 274 /**275 * Check if the theme supports the control and check user capabilities.276 *277 * @since 3.4.0278 *279 * @return bool False if theme doesn't support the control or user doesn't have the required permissions, otherwise true.280 */281 final public function check_capabilities() {282 foreach ( $this->settings as $setting ) {283 if ( ! $setting->check_capabilities() )284 return false;285 }286 287 $section = $this->manager->get_section( $this->section );288 if ( isset( $section ) && ! $section->check_capabilities() )289 return false;290 291 return true;292 }293 294 /**295 * Get the control's content for insertion into the Customizer pane.296 *297 * @since 4.1.0298 *299 * @return string Contents of the control.300 */301 final public function get_content() {302 ob_start();303 $this->maybe_render();304 return trim( ob_get_clean() );305 }306 307 /**308 * Check capabilities and render the control.309 *310 * @since 3.4.0311 * @uses WP_Customize_Control::render()312 */313 final public function maybe_render() {314 if ( ! $this->check_capabilities() )315 return;316 317 /**318 * Fires just before the current Customizer control is rendered.319 *320 * @since 3.4.0321 *322 * @param WP_Customize_Control $this WP_Customize_Control instance.323 */324 do_action( 'customize_render_control', $this );325 326 /**327 * Fires just before a specific Customizer control is rendered.328 *329 * The dynamic portion of the hook name, `$this->id`, refers to330 * the control ID.331 *332 * @since 3.4.0333 *334 * @param WP_Customize_Control $this {@see WP_Customize_Control} instance.335 */336 do_action( 'customize_render_control_' . $this->id, $this );337 338 $this->render();339 }340 341 /**342<