File "FrmProFieldTime.php"
Full path: /home/bud/public_html/swamp/Response/cgi-bin/wp-admin/wp-content/plugins/formidable-pro/classes/models/fields/FrmProFieldTime.php
File size: 15.67 KB
MIME-type: text/x-php
Charset: utf-8
<?php
if ( ! defined( 'ABSPATH' ) ) {
die( 'You are not allowed to call this page directly.' );
}
/**
* @since 3.0
*/
class FrmProFieldTime extends FrmFieldType {
/**
* @var string
* @since 3.0
*/
protected $type = 'time';
/**
* Fix WCAG errors when multiple dropdowns for the time field.
*
* @var bool
* @since 3.06.01
*/
protected $has_for_label = false;
public function show_on_form_builder( $name = '' ) {
$field = FrmFieldsHelper::setup_edit_vars( $this->field );
$field['value'] = $field['default_value'];
$field_name = $this->html_name( $name );
$html_id = $this->html_id();
$this->show_time_field( compact( 'field', 'html_id', 'field_name' ) );
}
protected function field_settings_for_type() {
$settings = array(
'autopopulate' => true,
'size' => true,
'unique' => true,
'read_only' => true,
'invalid' => true,
);
FrmProFieldsHelper::fill_default_field_display( $settings );
return $settings;
}
protected function extra_field_opts() {
return array(
'start_time' => '00:00',
'end_time' => '23:30',
'clock' => 12,
'single_time' => 0,
'step' => 30,
);
}
/**
* @since 4.0
* @param array $args - Includes 'field', 'display', and 'values'
*/
public function show_primary_options( $args ) {
$field = $args['field'];
include( FrmProAppHelper::plugin_path() . '/classes/views/frmpro-fields/back-end/clock-settings.php' );
$this->auto_width_setting( $args );
parent::show_primary_options( $args );
}
/**
* @since 4.0
*/
public function default_value_to_string( &$default_value ) {
if ( is_array( $default_value ) ) {
$this->time_array_to_string( $default_value );
}
}
protected function fill_default_atts( &$atts ) {
$defaults = array(
'format' => $this->get_time_format_for_field(),
);
$atts = wp_parse_args( $atts, $defaults );
}
public function prepare_front_field( $values, $atts ) {
$values['options'] = $this->get_options( $values );
$values['value'] = $this->prepare_field_value( $values['value'], $atts );
return $values;
}
public function prepare_field_value( $value, $atts ) {
return $this->get_display_value( $value, $atts );
}
public function get_options( $values ) {
if ( empty( $values ) ) {
// use a text field for conditional logic
return parent::get_options( $values );
}
$this->prepare_time_settings( $values );
$options = array();
$this->get_single_time_field_options( $values, $options );
$use_single_dropdown = FrmField::is_option_true( $values, 'single_time' );
if ( ! $use_single_dropdown ) {
$this->get_multiple_time_field_options( $values, $options );
}
return $options;
}
public function front_field_input( $args, $shortcode_atts ) {
ob_start();
$this->show_time_field(
array(
'html_id' => $args['html_id'],
'field_name' => $args['field_name'],
)
);
$input_html = ob_get_contents();
ob_end_clean();
return $input_html;
}
private function show_time_field( $values ) {
if ( isset( $values['field'] ) ) {
$field = $values['field'];
} else {
$field = $this->field;
$values['field'] = $field;
}
$values['field_value'] = $field['value'];
$this->set_field_column( 'options', $field['options'] );
$hidden = $this->maybe_include_hidden_values( $values );
$this->maybe_format_time( $values['field_value'] );
$labeled_by = 'aria-labelledby="' . esc_attr( $values['html_id'] ) . '_label" ';
if ( isset( $field['options']['H'] ) ) {
$this->time_string_to_array( $values['field_value'] );
$this->time_string_to_array( $values['field']['default_value'] );
$html = '<div class="frm_time_wrap"><span dir="ltr">' . "\r\n";
$values['combo_name'] = 'H';
$html .= $this->get_select_box( $values ) . "\r\n";
$html .= '<span class="frm_time_sep">:</span>' . "\r\n";
$values['combo_name'] = 'm';
$html .= $this->get_select_box( $values ) . "\r\n";
$html .= '</span>' . "\r\n";
if ( isset( $field['options']['A'] ) ) {
$values['combo_name'] = 'A';
$html .= $this->get_select_box( $values ) . "\r\n";
}
$html = str_replace( '<select ', '<select ' . $labeled_by, $html );
$html .= '</div>';
} else {
$this->time_array_to_string( $values['field_value'] );
$html = $this->get_select_box( $values );
$html = str_replace( '<select ', '<select ' . $labeled_by, $html );
}
echo $hidden . $html;
}
/**
* If the value was in a hidden field on a previous page,
* it may still be in the database format
*
* @since 3.02.01
*/
private function maybe_format_time( &$time ) {
if ( ! is_array( $time ) && ! strpos( $time, ' ' ) ) {
$time = $this->get_display_value(
$time,
array(
'format' => $this->get_time_format_for_field(),
)
);
}
}
/**
* Add extra classes on front-end input
*
* @since 3.01.04
*/
protected function get_input_class() {
$class = '';
$is_separate = $this->get_field_column( 'options' );
$combo_name = FrmField::get_option( $this->field, 'combo_name' );
if ( isset( $is_separate['H'] ) || ! empty( $combo_name ) ) {
$class = 'auto_width frm_time_select';
}
return $class;
}
protected function show_readonly_hidden() {
return true;
}
public function validate( $args ) {
$errors = array();
if ( is_array( $args['value'] ) ) {
$this->time_array_to_string( $args['value'] );
FrmEntriesHelper::set_posted_value( $this->field, $args['value'], $args );
}
$is_required = FrmField::is_required( (array) $this->field );
$is_empty = ! is_array( $args['value'] ) && trim( $args['value'] ) == '';
if ( $is_required && $is_empty ) {
$errors[ 'field' . $args['id'] ] = FrmFieldsHelper::get_error_msg( $this->field, 'blank' );
} elseif ( ! $is_empty && ! $this->in_time_range( $args['value'] ) ) {
$errors[ 'field' . $args['id'] ] = FrmFieldsHelper::get_error_msg( $this->field, 'invalid' );
}
return $errors;
}
private function in_time_range( $time ) {
$values = $this->field->field_options;
$this->fill_start_end_times( $values );
$time = FrmProAppHelper::format_time( $time );
return $time >= $values['start_time'] && $time <= $values['end_time'];
}
private function prepare_time_settings( &$values ) {
$this->fill_start_end_times( $values );
$values['start_time_str'] = $values['start_time'];
$values['end_time_str'] = $values['end_time'];
$this->split_time_setting( $values['start_time'] );
$this->split_time_setting( $values['end_time'] );
$this->step_in_minutes( $values['step'] );
$this->set_step( $values['step'] );
$values['hour_step'] = floor( $values['step'] / 60 );
if ( ! $values['hour_step'] ) {
$values['hour_step'] = 1;
}
if ( $values['end_time'][0] < $values['start_time'][0] ) {
$values['end_time'][0] += 12;
}
}
private function fill_start_end_times( &$values ) {
$values['clock'] = isset( $values['clock'] ) ? $values['clock'] : 12;
$values['start_time'] = isset( $values['start_time'] ) ? $values['start_time'] : '';
$values['end_time'] = isset( $values['end_time'] ) ? $values['end_time'] : '';
$this->format_time( '00:00', $values['start_time'] );
$this->format_time( '23:59', $values['end_time'] );
}
public function is_not_unique( $value, $entry_id ) {
$used = false;
$value = FrmProAppHelper::format_time( $value );
if ( FrmProEntryMetaHelper::value_exists( $this->get_field_column('id'), $value, false ) ) {
$first_date_field = FrmProFormsHelper::has_field( 'date', $this->get_field_column('form_id') );
if ( $first_date_field ) {
$values = array(
'time_field' => 'field_' . $this->field->field_key,
'date_field' => 'field_' . $first_date_field->field_key,
'time_key' => $this->field->id,
'date_key' => $first_date_field->id,
'date' => sanitize_text_field( $_POST['item_meta'][ $first_date_field->id ] ), //TODO: repeat name
'time' => $value,
'entry_id' => $entry_id,
);
$not_allowed = array();
$this->get_disallowed_times( $values, $not_allowed );
if ( ! empty( $not_allowed ) ) {
$used = true;
}
} else {
$used = true;
}
}
return $used;
}
/**
* Prepare the global time field JS information
*
* @since 3.0
*
* @param array $values
*/
protected function load_field_scripts( $values ) {
if ( $this->field['unique'] && $this->field['single_time'] && isset( $values['html_id'] ) ) {
global $frm_vars;
if ( ! isset( $frm_vars['timepicker_loaded'] ) || ! is_array( $frm_vars['timepicker_loaded'] ) ) {
$frm_vars['timepicker_loaded'] = array();
}
if ( ! isset( $frm_vars['timepicker_loaded'][ $values['html_id'] ] ) ) {
$frm_vars['timepicker_loaded'][ $values['html_id'] ] = true;
}
}
}
public function get_disallowed_times( $values, &$remove ) {
$values['date'] = FrmProAppHelper::maybe_convert_to_db_date( $values['date'], 'Y-m-d' );
$remove = apply_filters( 'frm_allowed_times', $remove, $values );
array_walk_recursive( $remove, 'FrmProAppHelper::format_time_by_reference' );
$values['date_entries'] = $this->get_entry_ids_for_date( $values );
if ( empty( $values['date_entries'] ) ) {
return;
}
$used_times = $this->get_used_times_for_entries( $values );
if ( empty( $used_times ) ) {
return;
}
$number_allowed = apply_filters( 'frm_allowed_time_count', 1, $values['time_key'], $values['date_key'] );
$count = array();
foreach ( $used_times as $used ) {
if ( isset( $remove[ $used ] ) ) {
continue;
}
if ( ! isset( $count[ $used ] ) ) {
$count[ $used ] = 0;
}
$count[ $used ]++;
if ( (int) $count[ $used ] >= $number_allowed ) {
$remove[ $used ] = $used;
}
}
}
private function get_entry_ids_for_date( $values ) {
$query = array( 'meta_value' => $values['date'] );
FrmProEntryMeta::add_field_to_query( $values['date_key'], $query );
return FrmEntryMeta::getEntryIds( $query );
}
private function get_used_times_for_entries( $values ) {
$query = array( 'it.item_id' => $values['date_entries'] );
FrmProEntryMeta::add_field_to_query( $values['time_key'], $query );
if ( $values['entry_id'] ) {
$query['it.item_id !'] = $values['entry_id'];
}
if ( isset( $values['time'] ) && ! empty( $values['time'] ) ) {
$query['meta_value'] = $values['time'];
}
global $wpdb;
$select = $wpdb->prefix . 'frm_item_metas it';
if ( ! is_numeric( $values['time_key'] ) ) {
$select .= ' LEFT JOIN ' . $wpdb->prefix . 'frm_fields fi ON (it.field_id = fi.id)';
}
$used_times = FrmDb::get_col( $select, $query, 'meta_value' );
return $used_times;
}
private function split_time_setting( &$time ) {
$separator = ':';
$time = FrmProAppHelper::format_time( $time );
$time = explode( $separator, $time );
}
private function step_in_minutes( &$step ) {
$separator = ':';
$step = explode( $separator, $step );
$step = ( isset( $step[1] ) ) ? ( ( $step[0] * 60 ) + $step[1] ) : ( $step[0] );
if ( empty( $step ) ) {
// force an hour step if none was defined to prevent infinite loop
$step = 60;
}
}
private function get_single_time_field_options( $values, &$options ) {
$time = strtotime( $values['start_time_str'] );
$end_time = strtotime( $values['end_time_str'] );
$format = ( $values['clock'] == 24 ) ? 'H:i' : 'g:i A';
$this->set_step( $values['step'] );
$values['step'] = max( $values['step'] * 60, 60 ); //switch minutes to seconds
$options[] = '';
while ( $time <= $end_time ) {
$options[] = gmdate( $format, $time );
$time += $values['step'];
}
}
/**
* @since 4.04.04
*/
private function set_step( &$step ) {
if ( ! is_numeric( $step ) ) {
$step = 30;
}
}
private function get_multiple_time_field_options( $values, &$options ) {
$all_times = $options;
$options['H'] = array( '' );
$options['m'] = array( '' );
$this->get_hours( $all_times, $options );
$this->get_minutes( $all_times, $options );
if ( $values['clock'] != 24 ) {
$options['A'] = array( 'AM', 'PM' );
}
}
/**
* Get the hour options for a three-dropdown time field
*
* @since 3.0
*
* @param array $all_times
* @param array $options
*/
private function get_hours( $all_times, &$options ) {
foreach ( $all_times as $time ) {
if ( $time == '' ) {
$options['H'][] = '';
continue;
}
$colon_position = strpos( $time, ':' );
if ( $colon_position !== false ) {
$hour = substr( $time, 0, $colon_position );
$options['H'][] = $hour;
}
}
unset( $time );
$options['H'] = array_unique( $options['H'] );
}
/**
* Get the minute options for a three-dropdown time field
*
* @since 3.0
*
* @param array $all_times
* @param array $options
*/
private function get_minutes( $all_times, &$options ) {
foreach ( $all_times as $time ) {
if ( $time == '' ) {
$options['m'][] = '';
continue;
}
$colon_position = strpos( $time, ':' );
if ( $colon_position !== false ) {
$minute = substr( $time, $colon_position + 1 );
if ( strpos( $minute, 'M' ) ) {
// AM/PM is included, so strip it off
$minute = str_replace( array( ' AM', ' PM' ), '', $minute );
}
$options['m'][] = $minute;
}
}
unset( $time );
$options['m'] = array_unique( $options['m'] );
sort( $options['m'] );
}
/**
* Format the start and end time
*
* @since 3.0
*
* @param string $default
* @param string $time
*/
private function format_time( $default, &$time ) {
if ( strlen( $time ) === 4 && substr( $time, 1, 1 ) === ':' ) {
$time = '0' . $time;
} elseif ( ! preg_match( '/^(?:2[0-3]|[01][0-9]):[0-5][0-9]$/', $time ) || strlen( $time ) !== 5 || $time === '' ) {
$time = $default;
}
}
public function set_value_before_save( $value ) {
$this->default_value_to_string( $value );
return FrmProAppHelper::format_time( $value, 'H:i' );
}
protected function prepare_display_value( $value, $atts ) {
if ( empty( $value ) ) {
return $value;
}
if ( is_array( $value ) && isset( $value['H'] ) ) {
$this->time_array_to_string( $value );
} elseif ( ! is_array( $value ) && strpos( $value, ',' ) ) {
$value = explode( ',', $value );
}
return FrmProFieldsHelper::format_values_in_array( $value, $atts['format'], array( 'FrmProAppHelper', 'format_time' ) );
}
public function time_array_to_string( &$value ) {
if ( $this->is_time_empty( $value ) ) {
$value = '';
} elseif ( is_array( $value ) ) {
$new_value = $value['H'] . ':' . $value['m'];
$new_value .= ( isset( $value['A'] ) ? ' ' . $value['A'] : '' );
$value = $new_value;
}
}
private function time_string_to_array( &$value ) {
$defaults = array( 'H' => '', 'm' => '', 'A' => '' );
if ( is_array( $value ) ) {
$value = wp_parse_args( $value, $defaults );
} elseif ( is_string( $value ) && strpos( $value, ':' ) !== false ) {
$h = explode( ':', $value );
$m = explode( ' ', $h[1] );
$value = array(
'H' => reset( $h ),
'm' => reset( $m ),
'A' => isset( $m[1] ) ? $m[1] : '',
);
} else {
$value = $defaults;
}
}
public function is_time_empty( $value ) {
$empty_string = ! is_array( $value ) && $value == '';
$empty_array = is_array( $value ) && ( $value['H'] == '' || $value['m'] == '' );
return $empty_string || $empty_array;
}
protected function prepare_import_value( $value, $atts ) {
return FrmProAppHelper::format_time( $value );
}
/**
* @since 3.02.01
*/
public function get_time_format_for_field( $field = array() ) {
if ( empty( $field ) ) {
$field = $this->field;
}
$time_format = FrmField::get_option( $field, 'clock', 12 );
return $this->get_time_format_for_setting( $time_format );
}
/**
* @since 3.02.01
*/
public function get_time_format_for_setting( $time_format ) {
return ( $time_format == 12 ) ? 'g:i A' : 'H:i';
}
/**
* @since 4.0.04
*/
public function sanitize_value( &$value ) {
FrmAppHelper::sanitize_value( 'sanitize_text_field', $value );
}
}