wp/wp-includes/customize/class-wp-customize-date-time-control.php
changeset 7 cf61fcea0001
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
       
     1 <?php
       
     2 /**
       
     3  * Customize API: WP_Customize_Date_Time_Control class
       
     4  *
       
     5  * @package WordPress
       
     6  * @subpackage Customize
       
     7  * @since 4.9.0
       
     8  */
       
     9 
       
    10 /**
       
    11  * Customize Date Time Control class.
       
    12  *
       
    13  * @since 4.9.0
       
    14  *
       
    15  * @see WP_Customize_Control
       
    16  */
       
    17 class WP_Customize_Date_Time_Control extends WP_Customize_Control {
       
    18 
       
    19 	/**
       
    20 	 * Customize control type.
       
    21 	 *
       
    22 	 * @since 4.9.0
       
    23 	 * @var string
       
    24 	 */
       
    25 	public $type = 'date_time';
       
    26 
       
    27 	/**
       
    28 	 * Minimum Year.
       
    29 	 *
       
    30 	 * @since 4.9.0
       
    31 	 * @var integer
       
    32 	 */
       
    33 	public $min_year = 1000;
       
    34 
       
    35 	/**
       
    36 	 * Maximum Year.
       
    37 	 *
       
    38 	 * @since 4.9.0
       
    39 	 * @var integer
       
    40 	 */
       
    41 	public $max_year = 9999;
       
    42 
       
    43 	/**
       
    44 	 * Allow past date, if set to false user can only select future date.
       
    45 	 *
       
    46 	 * @since 4.9.0
       
    47 	 * @var boolean
       
    48 	 */
       
    49 	public $allow_past_date = true;
       
    50 
       
    51 	/**
       
    52 	 * Whether hours, minutes, and meridian should be shown.
       
    53 	 *
       
    54 	 * @since 4.9.0
       
    55 	 * @var boolean
       
    56 	 */
       
    57 	public $include_time = true;
       
    58 
       
    59 	/**
       
    60 	 * If set to false the control will appear in 24 hour format,
       
    61 	 * the value will still be saved in Y-m-d H:i:s format.
       
    62 	 *
       
    63 	 * @since 4.9.0
       
    64 	 * @var boolean
       
    65 	 */
       
    66 	public $twelve_hour_format = true;
       
    67 
       
    68 	/**
       
    69 	 * Don't render the control's content - it's rendered with a JS template.
       
    70 	 *
       
    71 	 * @since 4.9.0
       
    72 	 */
       
    73 	public function render_content() {}
       
    74 
       
    75 	/**
       
    76 	 * Export data to JS.
       
    77 	 *
       
    78 	 * @since 4.9.0
       
    79 	 * @return array
       
    80 	 */
       
    81 	public function json() {
       
    82 		$data = parent::json();
       
    83 
       
    84 		$data['maxYear'] = intval( $this->max_year );
       
    85 		$data['minYear'] = intval( $this->min_year );
       
    86 		$data['allowPastDate'] = (bool) $this->allow_past_date;
       
    87 		$data['twelveHourFormat'] = (bool) $this->twelve_hour_format;
       
    88 		$data['includeTime'] = (bool) $this->include_time;
       
    89 
       
    90 		return $data;
       
    91 	}
       
    92 
       
    93 	/**
       
    94 	 * Renders a JS template for the content of date time control.
       
    95 	 *
       
    96 	 * @since 4.9.0
       
    97 	 */
       
    98 	public function content_template() {
       
    99 		$data = array_merge( $this->json(), $this->get_month_choices() );
       
   100 		$timezone_info = $this->get_timezone_info();
       
   101 
       
   102 		$date_format = get_option( 'date_format' );
       
   103 		$date_format = preg_replace( '/(?<!\\\\)[Yyo]/', '%1$s', $date_format );
       
   104 		$date_format = preg_replace( '/(?<!\\\\)[FmMn]/', '%2$s', $date_format );
       
   105 		$date_format = preg_replace( '/(?<!\\\\)[jd]/', '%3$s', $date_format );
       
   106 
       
   107 		// Fallback to ISO date format if year, month, or day are missing from the date format.
       
   108 		if ( 1 !== substr_count( $date_format, '%1$s' ) || 1 !== substr_count( $date_format, '%2$s' ) || 1 !== substr_count( $date_format, '%3$s' ) ) {
       
   109 			$date_format = '%1$s-%2$s-%3$s';
       
   110 		}
       
   111 		?>
       
   112 
       
   113 		<# _.defaults( data, <?php echo wp_json_encode( $data ); ?> ); #>
       
   114 		<# var idPrefix = _.uniqueId( 'el' ) + '-'; #>
       
   115 
       
   116 		<# if ( data.label ) { #>
       
   117 			<span class="customize-control-title">
       
   118 				{{ data.label }}
       
   119 			</span>
       
   120 		<# } #>
       
   121 		<div class="customize-control-notifications-container"></div>
       
   122 		<# if ( data.description ) { #>
       
   123 			<span class="description customize-control-description">{{ data.description }}</span>
       
   124 		<# } #>
       
   125 		<div class="date-time-fields {{ data.includeTime ? 'includes-time' : '' }}">
       
   126 			<fieldset class="day-row">
       
   127 				<legend class="title-day {{ ! data.includeTime ? 'screen-reader-text' : '' }}"><?php esc_html_e( 'Date' ); ?></legend>
       
   128 				<div class="day-fields clear">
       
   129 					<?php ob_start(); ?>
       
   130 					<label for="{{ idPrefix }}date-time-month" class="screen-reader-text"><?php esc_html_e( 'Month' ); ?></label>
       
   131 					<select id="{{ idPrefix }}date-time-month" class="date-input month" data-component="month">
       
   132 						<# _.each( data.month_choices, function( choice ) {
       
   133 							if ( _.isObject( choice ) && ! _.isUndefined( choice.text ) && ! _.isUndefined( choice.value ) ) {
       
   134 								text = choice.text;
       
   135 								value = choice.value;
       
   136 							}
       
   137 							#>
       
   138 							<option value="{{ value }}" >
       
   139 								{{ text }}
       
   140 							</option>
       
   141 						<# } ); #>
       
   142 					</select>
       
   143 					<?php $month_field = trim( ob_get_clean() ); ?>
       
   144 
       
   145 					<?php ob_start(); ?>
       
   146 					<label for="{{ idPrefix }}date-time-day" class="screen-reader-text"><?php esc_html_e( 'Day' ); ?></label>
       
   147 					<input id="{{ idPrefix }}date-time-day" type="number" size="2" autocomplete="off" class="date-input day" data-component="day" min="1" max="31" />
       
   148 					<?php $day_field = trim( ob_get_clean() ); ?>
       
   149 
       
   150 					<?php ob_start(); ?>
       
   151 					<label for="{{ idPrefix }}date-time-year" class="screen-reader-text"><?php esc_html_e( 'Year' ); ?></label>
       
   152 					<input id="{{ idPrefix }}date-time-year" type="number" size="4" autocomplete="off" class="date-input year" data-component="year" min="{{ data.minYear }}" max="{{ data.maxYear }}">
       
   153 					<?php $year_field = trim( ob_get_clean() ); ?>
       
   154 
       
   155 					<?php printf( $date_format, $year_field, $month_field, $day_field ); ?>
       
   156 				</div>
       
   157 			</fieldset>
       
   158 			<# if ( data.includeTime ) { #>
       
   159 				<fieldset class="time-row clear">
       
   160 					<legend class="title-time"><?php esc_html_e( 'Time' ); ?></legend>
       
   161 					<div class="time-fields clear">
       
   162 						<label for="{{ idPrefix }}date-time-hour" class="screen-reader-text"><?php esc_html_e( 'Hour' ); ?></label>
       
   163 						<# var maxHour = data.twelveHourFormat ? 12 : 23; #>
       
   164 						<# var minHour = data.twelveHourFormat ? 1 : 0; #>
       
   165 						<input id="{{ idPrefix }}date-time-hour" type="number" size="2" autocomplete="off" class="date-input hour" data-component="hour" min="{{ minHour }}" max="{{ maxHour }}">
       
   166 						:
       
   167 						<label for="{{ idPrefix }}date-time-minute" class="screen-reader-text"><?php esc_html_e( 'Minute' ); ?></label>
       
   168 						<input id="{{ idPrefix }}date-time-minute" type="number" size="2" autocomplete="off" class="date-input minute" data-component="minute" min="0" max="59">
       
   169 						<# if ( data.twelveHourFormat ) { #>
       
   170 							<label for="{{ idPrefix }}date-time-meridian" class="screen-reader-text"><?php esc_html_e( 'Meridian' ); ?></label>
       
   171 							<select id="{{ idPrefix }}date-time-meridian" class="date-input meridian" data-component="meridian">
       
   172 								<option value="am"><?php esc_html_e( 'AM' ); ?></option>
       
   173 								<option value="pm"><?php esc_html_e( 'PM' ); ?></option>
       
   174 							</select>
       
   175 						<# } #>
       
   176 						<abbr class="date-timezone" aria-label="<?php esc_attr_e( 'Timezone' ); ?>" title="<?php echo esc_attr( $timezone_info['description'] ); ?>"><?php echo esc_html( $timezone_info['abbr'] ); ?></abbr>
       
   177 					</div>
       
   178 				</fieldset>
       
   179 			<# } #>
       
   180 		</div>
       
   181 		<?php
       
   182 	}
       
   183 
       
   184 	/**
       
   185 	 * Generate options for the month Select.
       
   186 	 *
       
   187 	 * Based on touch_time().
       
   188 	 *
       
   189 	 * @since 4.9.0
       
   190 	 * @see touch_time()
       
   191 	 *
       
   192 	 * @return array
       
   193 	 */
       
   194 	public function get_month_choices() {
       
   195 		global $wp_locale;
       
   196 		$months = array();
       
   197 		for ( $i = 1; $i < 13; $i++ ) {
       
   198 			$month_text = $wp_locale->get_month_abbrev( $wp_locale->get_month( $i ) );
       
   199 
       
   200 			/* translators: 1: month number (01, 02, etc.), 2: month abbreviation */
       
   201 			$months[ $i ]['text'] = sprintf( __( '%1$s-%2$s' ), $i, $month_text );
       
   202 			$months[ $i ]['value'] = $i;
       
   203 		}
       
   204 		return array(
       
   205 			'month_choices' => $months,
       
   206 		);
       
   207 	}
       
   208 
       
   209 	/**
       
   210 	 * Get timezone info.
       
   211 	 *
       
   212 	 * @since 4.9.0
       
   213 	 *
       
   214 	 * @return array abbr and description.
       
   215 	 */
       
   216 	public function get_timezone_info() {
       
   217 		$tz_string = get_option( 'timezone_string' );
       
   218 		$timezone_info = array();
       
   219 
       
   220 		if ( $tz_string ) {
       
   221 			try {
       
   222 				$tz = new DateTimezone( $tz_string );
       
   223 			} catch ( Exception $e ) {
       
   224 				$tz = '';
       
   225 			}
       
   226 
       
   227 			if ( $tz ) {
       
   228 				$now = new DateTime( 'now', $tz );
       
   229 				$formatted_gmt_offset = sprintf( 'UTC%s', $this->format_gmt_offset( $tz->getOffset( $now ) / 3600 ) );
       
   230 				$tz_name = str_replace( '_', ' ', $tz->getName() );
       
   231 				$timezone_info['abbr'] = $now->format( 'T' );
       
   232 
       
   233 				/* translators: 1: timezone name, 2: timezone abbreviation, 3: gmt offset  */
       
   234 				$timezone_info['description'] = sprintf( __( 'Timezone is %1$s (%2$s), currently %3$s.' ), $tz_name, $timezone_info['abbr'], $formatted_gmt_offset );
       
   235 			} else {
       
   236 				$timezone_info['description'] = '';
       
   237 			}
       
   238 		} else {
       
   239 			$formatted_gmt_offset = $this->format_gmt_offset( intval( get_option( 'gmt_offset', 0 ) ) );
       
   240 			$timezone_info['abbr'] = sprintf( 'UTC%s', $formatted_gmt_offset );
       
   241 
       
   242 			/* translators: %s: UTC offset  */
       
   243 			$timezone_info['description'] = sprintf( __( 'Timezone is %s.' ), $timezone_info['abbr'] );
       
   244 		}
       
   245 
       
   246 		return $timezone_info;
       
   247 	}
       
   248 
       
   249 	/**
       
   250 	 * Format GMT Offset.
       
   251 	 *
       
   252 	 * @since 4.9.0
       
   253 	 * @see wp_timezone_choice()
       
   254 	 *
       
   255 	 * @param float $offset Offset in hours.
       
   256 	 * @return string Formatted offset.
       
   257 	 */
       
   258 	public function format_gmt_offset( $offset ) {
       
   259 		if ( 0 <= $offset ) {
       
   260 			$formatted_offset = '+' . (string) $offset;
       
   261 		} else {
       
   262 			$formatted_offset = (string) $offset;
       
   263 		}
       
   264 		$formatted_offset = str_replace(
       
   265 			array( '.25', '.5', '.75' ),
       
   266 			array( ':15', ':30', ':45' ),
       
   267 			$formatted_offset
       
   268 		);
       
   269 		return $formatted_offset;
       
   270 	}
       
   271 }