index of
/
home
/
thefkyzp
/
public_html
/
wp-content
/
plugins
/
forminator
/
library
/
fields
/
File: /home/thefkyzp/public_html/wp-content/plugins/forminator/library/fields/date.php
<?php /** * The Forminator_Date class. * * @package Forminator */ if ( ! defined( 'ABSPATH' ) ) { die(); } /** * Class Forminator_Date * * @since 1.0 */ class Forminator_Date extends Forminator_Field { /** * Name * * @var string */ public $name = ''; /** * Slug * * @var string */ public $slug = 'date'; /** * Position * * @var int */ public $position = 12; /** * Type * * @var string */ public $type = 'date'; /** * Options * * @var string */ public $options = array(); /** * Category * * @var string */ public $category = 'standard'; /** * Icon * * @var string */ public $icon = 'sui-icon-calendar'; /** * Forminator_Date constructor. * * @since 1.0 */ public function __construct() { parent::__construct(); $this->name = esc_html__( 'Datepicker', 'forminator' ); } /** * Field defaults * * @since 1.0 * @return array */ public function defaults() { return array( 'field_type' => 'picker', 'date_format' => 'mm/dd/yy', 'default_date' => 'none', 'field_label' => esc_html__( 'Date', 'forminator' ), 'placeholder' => esc_html__( 'Choose Date', 'forminator' ), 'icon' => 'true', 'day_label' => esc_html__( 'Day', 'forminator' ), 'day_placeholder' => esc_html__( 'E.g. 01', 'forminator' ), 'month_label' => esc_html__( 'Month', 'forminator' ), 'month_placeholder' => esc_html__( 'E.g. 01', 'forminator' ), 'year_label' => esc_html__( 'Year', 'forminator' ), 'year_placeholder' => esc_html__( 'E.g. 2000', 'forminator' ), 'restrict_message' => esc_html__( 'Please select one of the available dates.', 'forminator' ), ); } /** * Autofill Setting * * @since 1.0.5 * * @param array $settings Settings. * * @return array */ public function autofill_settings( $settings = array() ) { $providers = apply_filters( 'forminator_field_' . $this->slug . '_autofill', array(), $this->slug ); // TODO: support for multiple field date. $autofill_settings = array( 'date' => array( 'values' => forminator_build_autofill_providers( $providers ), ), ); return $autofill_settings; } /** * Field front-end markup * * @since 1.0 * * @param array $field Field. * @param Forminator_Render_Form $views_obj Forminator_Render_Form object. * @param array $draft_value Draft value. * * @return mixed */ public function markup( $field, $views_obj, $draft_value = null ) { $settings = $views_obj->model->settings; $this->field = $field; $html = ''; $design = $this->get_form_style( $settings ); $name = self::get_property( 'element_id', $field ); $required = self::get_property( 'required', $field, false ); $placeholder = $this->sanitize_value( self::get_property( 'placeholder', $field ) ); $label = $this->sanitize_value( self::get_property( 'field_label', $field ) ); $description = self::get_property( 'description', $field ); $type = trim( self::get_property( 'field_type', $field ) ); $has_icon = self::get_property( 'icon', $field, false, 'bool' ); $has_icon = filter_var( $has_icon, FILTER_VALIDATE_BOOLEAN ); $date_format = esc_html( self::get_property( 'date_format', $field, 'm/d/Y' ) ); $start_date_type = self::get_property( 'start-date', $field, '' ); $end_date_type = self::get_property( 'end-date', $field, '' ); $start_of_week = self::get_property( 'start_of_week', $field, get_option( 'start_of_week' ) ); $disabled_dates = self::get_property( 'disabled-dates', $field, array() ); $disabled_range = self::get_property( 'disable-date-range', $field, array() ); $id = self::get_field_id( $name ); $describedby = esc_attr( $id . '-description' ); if ( false !== strpos( $date_format, '-' ) ) { $sep = '-'; } elseif ( false !== strpos( $date_format, '.' ) ) { $sep = '.'; } else { $sep = '/'; } $formats = explode( $sep, $date_format ); $min_year = esc_html( self::get_property( 'min_year', $field, gmdate( 'Y' ) - 100 ) ); $max_year = esc_html( self::get_property( 'max_year', $field, gmdate( 'Y' ) + 100 ) ); $prefill = false; $is_prefil_valid = false; // Check if Pre-fill parameter used. if ( $this->has_prefill( $field ) ) { // We have pre-fill parameter, use its value or $value. $prefill = $this->get_prefill( $field, $prefill ); } $parsed_date = self::parse_date( $prefill, $date_format ); if ( $parsed_date && $this->check_date( $parsed_date['month'], $parsed_date['day'], $parsed_date['year'] ) ) { $is_prefil_valid = true; } if ( 'picker' === $type ) { $html .= '<div class="forminator-field">'; } if ( 'picker' === $type ) { $restrict = array(); $restrict_type = self::get_property( 'howto-restrict', $field ); if ( 'week' === $restrict_type ) { $days = forminator_week_days(); $i = 0; foreach ( $days as $k => $day ) { if ( ! self::get_property( $k, $field ) ) { $restrict[] = $i; } ++$i; } } elseif ( 'custom' === $restrict_type ) { $dates = self::get_property( 'date_multiple', $field ); $default_value = ''; $default_date = esc_html( self::get_property( 'default_date', $field, false ) ); if ( ! empty( $dates ) ) { foreach ( $dates as $k => $date ) { $restrict[] = $date['value']; } } if ( 'custom' === $default_date ) { $default_date_value = esc_html( self::get_property( 'date', $field, '' ) ); $default_value = $default_date_value; } } $default_value = ''; $default_date = self::get_property( 'default_date', $field, false ); if ( 'today' === $default_date ) { $datepicker_format = $this->normalize_date_format( $date_format ); $default_value = current_time( $datepicker_format ); } if ( 'custom' === $default_date ) { $default_date_value = self::get_property( 'date', $field, '' ); $default_value = $default_date_value; } if ( $is_prefil_valid ) { $default_value = $prefill; } $past_dates = self::get_property( 'past_dates', $field ); $past_dates = '' !== $default_value && 'disable' === $past_dates ? 'disable' : 'enable'; $start_date = ''; $end_date = ''; $start_date_field = ''; $end_date_field = ''; $start_offset = ''; $end_offset = ''; if ( ! empty( $start_date_type ) ) { if ( 'specific' === $start_date_type ) { $start_date = self::get_property( 'start-specific-date', $field, '' ); } else { $start_offset_operator = self::get_property( 'start-offset-operator', $field, '+' ); $start_offset_value = self::get_property( 'start-offset-value', $field, '0' ); $start_offset_duration = self::get_property( 'start-offset-duration', $field, 'days' ); if ( 'today' === $start_date_type ) { $start_date = date_i18n( 'Y-m-d', strtotime( $start_offset_operator . $start_offset_value . ' ' . $start_offset_duration, current_time( 'U' ) ) ); // phpcs:ignore WordPress.DateTime.CurrentTimeTimestamp.Requested -- We are using the current timestamp based on the site's timezone. } else { $start_date_field = $start_date_type; $start_offset = $start_offset_operator . '_' . $start_offset_value . '_' . $start_offset_duration; } } } if ( ! empty( $end_date_type ) ) { if ( 'specific' === $end_date_type ) { $end_date = self::get_property( 'end-specific-date', $field, '' ); } else { $end_offset_operator = self::get_property( 'end-offset-operator', $field, '+' ); $end_offset_value = self::get_property( 'end-offset-value', $field, '0' ); $end_offset_duration = self::get_property( 'end-offset-duration', $field, 'days' ); if ( 'today' === $end_date_type ) { $end_date = date_i18n( 'Y-m-d', strtotime( $end_offset_operator . $end_offset_value . ' ' . $end_offset_duration, current_time( 'U' ) ) ); // phpcs:ignore WordPress.DateTime.CurrentTimeTimestamp.Requested -- We are using the current timestamp based on the site's timezone. } else { $end_date_field = $end_date_type; $end_offset = $end_offset_operator . '_' . $end_offset_value . '_' . $end_offset_duration; } } } $icon_markup = array( '<div class="forminator-input-with-icon">', '</div>', 'calendar', ); if ( ! empty( $start_date ) ) { $min_year = gmdate( 'Y', strtotime( $start_date ) ); } if ( ! empty( $end_date ) ) { $max_year = gmdate( 'Y', strtotime( $end_date ) ); } if ( isset( $draft_value['value'] ) ) { $default_value = $draft_value['value']; } $html .= self::create_input( array( 'autocomplete' => 'off', 'type' => 'text', 'size' => 1, 'name' => $name, 'value' => $default_value, 'placeholder' => $placeholder, 'id' => self::get_field_id( $name . '-picker' ), 'class' => 'forminator-input forminator-datepicker', 'data-required' => $required, 'data-format' => $date_format, 'data-restrict-type' => $restrict_type, 'data-restrict' => implode( ',', $restrict ), 'data-start-year' => $min_year, 'data-end-year' => $max_year, 'data-past-dates' => $past_dates, 'data-start-of-week' => $start_of_week, 'data-start-date' => $start_date, 'data-end-date' => $end_date, 'data-start-field' => $start_date_field, 'data-end-field' => $end_date_field, 'data-start-offset' => $start_offset, 'data-end-offset' => $end_offset, 'data-disable-date' => implode( ',', $disabled_dates ), 'data-disable-range' => implode( ',', $disabled_range ), ), $label, $description, $required, $design, $has_icon ? $icon_markup : '' ); } elseif ( 'select' === $type ) { if ( ! empty( $label ) ) { $html .= self::get_field_label( $label, 'forminator-field-' . $name, $required ); // Mark day, month and year required markup as false. $required = false; } $default_date = esc_html( self::get_property( 'default_date', $field, false ) ); $default_date_value = esc_html( self::get_property( 'date', $field, '' ) ); if ( $is_prefil_valid ) { $default_value = $prefill; } if ( isset( $draft_value['value'] ) ) { $parsed_date = $draft_value['value']; $day = $parsed_date['day']; $month = $parsed_date['month']; $year = $parsed_date['year']; } elseif ( $is_prefil_valid ) { $day = $parsed_date['day']; $month = $parsed_date['month']; $year = $parsed_date['year']; } elseif ( 'today' === $default_date ) { list( $day, $month, $year ) = explode( ' ', current_time( 'j n Y' ) ); } elseif ( 'custom' === $default_date && ! empty( $default_date_value ) ) { if ( empty( strtotime( $default_date_value ) ) ) { if ( false !== strpos( $date_format, '-' ) || false !== strpos( $date_format, '.' ) ) { $default_date_value = str_replace( array( '.', '-' ), '/', $default_date_value ); } elseif ( false !== strpos( $date_format, '/' ) ) { $default_date_value = str_replace( '/', '-', $default_date_value ); } } $day = gmdate( 'j', strtotime( $default_date_value ) ); $month = gmdate( 'n', strtotime( $default_date_value ) ); $year = gmdate( 'Y', strtotime( $default_date_value ) ); } else { $day = ''; $month = ''; $max_selected_year = esc_html( self::get_property( 'max_year', $field ) ); if ( $max_selected_year ) { $year = ''; } else { $year = gmdate( 'Y' ); } } // START: Row. $html .= '<div class="forminator-date-select">'; $html .= '<div class="forminator-row" data-multiple="true">'; foreach ( $formats as $format ) { switch ( $format ) { case 'dd': $day_id = self::get_subfield_id( $name, '-day' ); $html .= '<div id="' . $day_id . '" class="forminator-col">'; $html .= '<div class="forminator-field">'; $day_data = array( 'name' => $day_id, 'id' => self::get_field_id( $settings['form_id'] . '__field--' . $day_id ), 'class' => 'forminator-select2', 'data-format' => $date_format, 'data-parent' => $name, ); if ( ! empty( $description ) ) { $day_data['aria-describedby'] = $describedby; } if ( $required ) { $label = self::get_property( 'day_label', $field ); if ( ! empty( $label ) ) { $html .= sprintf( '<label for="%s" class="forminator-label">%s %s</label>', $day_data['id'], $this->sanitize_value( $label ), '<span class="forminator-required">*</span>' ); } $html .= self::create_select( $day_data, false, $this->get_day(), $day ); } else { $html .= self::create_select( $day_data, $this->sanitize_value( self::get_property( 'day_label', $field ) ), $this->get_day(), $day ); } $html .= '</div>'; $html .= '</div>'; break; case 'mm': $month_id = self::get_subfield_id( $name, '-month' ); $html .= '<div id="' . $month_id . '" class="forminator-col">'; $html .= '<div class="forminator-field">'; $month_data = array( 'name' => $month_id, 'id' => self::get_field_id( $settings['form_id'] . '__field--' . $month_id ), 'class' => 'forminator-select2', 'data-format' => $date_format, 'data-parent' => $name, ); if ( ! empty( $description ) ) { $month_data['aria-describedby'] = $describedby; } if ( $required ) { $label = self::get_property( 'month_label', $field ); if ( ! empty( $label ) ) { $html .= sprintf( '<label for="%s" class="forminator-label">%s %s</label>', $month_data['id'], $this->sanitize_value( $label ), '<span class="forminator-required">*</span>' ); } $html .= self::create_select( $month_data, false, $this->get_months(), $month ); } else { $html .= self::create_select( $month_data, $this->sanitize_value( self::get_property( 'month_label', $field ) ), $this->get_months(), $month ); } $html .= '</div>'; $html .= '</div>'; break; case 'yy': $year_id = self::get_subfield_id( $name, '-year' ); $html .= '<div id="' . $year_id . '" class="forminator-col">'; $html .= '<div class="forminator-field">'; $year_data = array( 'name' => $year_id, 'id' => self::get_field_id( $settings['form_id'] . '__field--' . $year_id ), 'class' => 'forminator-select2', 'data-format' => $date_format, 'data-parent' => $name, ); if ( ! empty( $description ) ) { $year_data['aria-describedby'] = $describedby; } if ( $required ) { $label = self::get_property( 'year_label', $field ); if ( ! empty( $label ) ) { $html .= sprintf( '<label for="%s" class="forminator-label">%s %s</label>', $year_data['id'], $this->sanitize_value( $label ), '<span class="forminator-required">*</span>' ); } $html .= self::create_select( $year_data, false, $this->get_years( $min_year, $max_year ), $year ); } else { $html .= self::create_select( $year_data, $this->sanitize_value( self::get_property( 'year_label', $field ) ), $this->get_years( $min_year, $max_year ), $year ); } $html .= '</div>'; $html .= '</div>'; break; default: break; } } $html .= '</div>'; // END: Row. $html .= '</div>'; $html .= self::get_description( $description, $id ); } elseif ( 'input' === $type ) { $day_value = ''; $month_value = ''; $year_value = ''; if ( isset( $draft_value['value'] ) ) { $parsed_date = $draft_value['value']; $day_value = $parsed_date['day']; $month_value = $parsed_date['month']; $year_value = $parsed_date['year']; } elseif ( $is_prefil_valid ) { $day_value = $parsed_date['day']; $month_value = $parsed_date['month']; $year_value = $parsed_date['year']; } $html .= self::get_field_label( $label, 'forminator-field-' . $name, $required ); // START: Row. $html .= '<div class="forminator-date-input">'; $html .= '<div class="forminator-row" data-multiple="true">'; foreach ( $formats as $format ) { switch ( $format ) { case 'dd': $day = self::get_subfield_id( $name, '-day' ); $html .= '<div id="' . $day . '" class="forminator-col">'; $html .= '<div class="forminator-field">'; $day_data = array( 'type' => 'number', 'min' => 1, 'max' => 31, 'name' => $day, 'value' => esc_attr( $day_value ), 'placeholder' => $this->sanitize_value( self::get_property( 'day_placeholder', $field ) ), 'id' => self::get_field_id( $day ), 'class' => 'forminator-input', 'data-field' => 'day', 'data-format' => $date_format, 'data-parent' => $name, ); if ( ! empty( $description ) ) { $day_data['aria-describedby'] = $describedby; } if ( $required ) { $label = self::get_property( 'day_label', $field ); if ( ! empty( $label ) ) { $html .= sprintf( '<label for="%s" class="forminator-label">%s %s</label>', $day_data['id'], $this->sanitize_value( $label ), '<span class="forminator-required">*</span>' ); } $html .= self::create_input( $day_data, false, '', $required, $design ); } else { $html .= self::create_input( $day_data, $this->sanitize_value( self::get_property( 'day_label', $field ) ), '', $required, $design ); } $html .= '</div>'; $html .= '</div>'; break; case 'mm': $month = self::get_subfield_id( $name, '-month' ); $html .= '<div id="' . $month . '" class="forminator-col">'; $html .= '<div class="forminator-field">'; $month_data = array( 'type' => 'number', 'min' => 1, 'max' => 12, 'name' => $month, 'value' => esc_attr( $month_value ), 'placeholder' => $this->sanitize_value( self::get_property( 'month_placeholder', $field ) ), 'id' => self::get_field_id( $month ), 'class' => 'forminator-input', 'data-field' => 'month', 'data-format' => $date_format, 'data-parent' => $name, ); if ( ! empty( $description ) ) { $month_data['aria-describedby'] = $describedby; } if ( $required ) { $label = self::get_property( 'month_label', $field ); if ( ! empty( $label ) ) { $html .= sprintf( '<label for="%s" class="forminator-label">%s %s</label>', $month_data['id'], $this->sanitize_value( $label ), '<span class="forminator-required">*</span>' ); } $html .= self::create_input( $month_data, false, '', $required, $design ); } else { $html .= self::create_input( $month_data, $this->sanitize_value( self::get_property( 'month_label', $field ) ), '', $required, $design ); } $html .= '</div>'; $html .= '</div>'; break; case 'yy': $year = self::get_subfield_id( $name, '-year' ); $html .= '<div id="' . $year . '" class="forminator-col">'; $html .= '<div class="forminator-field">'; $year_data = array( 'type' => 'number', 'min' => 1, 'name' => $year, 'placeholder' => $this->sanitize_value( self::get_property( 'year_placeholder', $field ) ), 'id' => self::get_field_id( $year ), 'class' => 'forminator-input', 'data-field' => 'year', 'value' => esc_attr( $year_value ), 'data-format' => $date_format, 'data-parent' => $name, ); if ( ! empty( $description ) ) { $year_data['aria-describedby'] = $describedby; } if ( $required ) { $label = self::get_property( 'year_label', $field ); if ( ! empty( $label ) ) { $html .= sprintf( '<label for="%s" class="forminator-label">%s %s</label>', $year_data['id'], $this->sanitize_value( $label ), '<span class="forminator-required">*</span>' ); } $html .= self::create_input( $year_data, false, '', $required, $design ); } else { $html .= self::create_input( $year_data, $this->sanitize_value( self::get_property( 'year_label', $field ) ), '', $required, $design ); } $html .= '</div>'; $html .= '</div>'; break; default: break; } } $html .= '</div>'; // END: Row. $html .= '</div>'; $html .= self::get_description( $description, $id ); } if ( 'picker' === $type ) { $html .= '</div>'; } return apply_filters( 'forminator_field_date_markup', $html, $field, $this ); } /** * Return modified date format * * @since 1.7.0.1 * * @param string $date_format Date format. * * @return string */ public function normalize_date_format( $date_format ) { $date_format = str_replace( 'dd', 'd', $date_format ); $date_format = str_replace( 'mm', 'm', $date_format ); $date_format = str_replace( 'yy', 'Y', $date_format ); return $date_format; } /** * Return all years between two dates * * @since 1.0 * * @param string $min_year Minimum year. * @param string $max_year Maximum year. * * @return array */ public function get_years( $min_year = '', $max_year = '' ) { $array = array(); $year = intval( gmdate( 'Y' ) ); $end = empty( $min_year ) ? $year - 100 : intval( $min_year ) - 1; $start = empty( $max_year ) ? $year + 100 : intval( $max_year ); for ( $i = $start; $i > $end; $i-- ) { $array[] = array( 'label' => $i, 'value' => $i, ); } array_unshift( $array, array( 'label' => esc_html__( 'Select Year', 'forminator' ), 'value' => '', ) ); return apply_filters( 'forminator_field_date_get_years', $array, $min_year, $max_year, $year, $start, $end, $this ); } /** * Return monts * * @since 1.0 * @return array */ public function get_months() { $array = array(); for ( $i = 1; $i < 13; $i++ ) { $array[] = array( 'label' => $i, 'value' => $i, ); } array_unshift( $array, array( 'label' => esc_html__( 'Select month', 'forminator' ), 'value' => '', ) ); return apply_filters( 'forminator_field_date_get_months', $array, $this ); } /** * Return days * * @since 1.0 * @return array */ public function get_day() { $array = array(); for ( $i = 1; $i < 32; $i++ ) { $array[] = array( 'label' => $i, 'value' => $i, ); } array_unshift( $array, array( 'label' => esc_html__( 'Select day', 'forminator' ), 'value' => '', ) ); return apply_filters( 'forminator_field_date_get_day', $array, $this ); } /** * Parse date * * @since 1.0 * * @param string|array $date - the date to be parsed. * @param string $format - the data format. * * @return array */ public static function parse_date( $date, $format = 'yy-mm-dd' ) { $date_info = array( 'year' => 0, 'month' => 0, 'day' => 0, ); $position = substr( $format, 0, 8 ); if ( is_array( $date ) ) { switch ( $position ) { case 'mm/dd/yy': case 'mm-dd-yy': case 'mm.dd.yy': $date_info['month'] = isset( $date['month'] ) ? $date['month'] : 0; $date_info['day'] = isset( $date['day'] ) ? $date['day'] : 0; $date_info['year'] = isset( $date['year'] ) ? $date['year'] : 0; break; case 'dd/mm/yy': case 'dd-mm-yy': case 'dd.mm.yy': $date_info['day'] = isset( $date['day'] ) ? $date['day'] : 0; $date_info['month'] = isset( $date['month'] ) ? $date['month'] : 0; $date_info['year'] = isset( $date['year'] ) ? $date['year'] : 0; break; case 'yy-mm-dd': case 'yy/mm/dd': case 'yy.mm.dd': $date_info['year'] = isset( $date['year'] ) ? $date['year'] : 0; $date_info['month'] = isset( $date['month'] ) ? $date['month'] : 0; $date_info['day'] = isset( $date['day'] ) ? $date['day'] : 0; break; default: break; } return apply_filters( 'forminator_field_date_parse_dates', $date_info, $date, $format ); } $date = preg_replace( '|[/\.]|', '-', $date ); if ( 'mm/dd/yy' === $position || 'mm-dd-yy' === $position || 'mm.dd.yy' === $position ) { if ( preg_match( '/^(\d{1,2})-(\d{1,2})-(\d{1,4})$/', $date, $matches ) ) { $date_info['month'] = $matches[1]; $date_info['day'] = $matches[2]; $date_info['year'] = $matches[3]; } } elseif ( 'dd/mm/yy' === $position || 'dd-mm-yy' === $position || 'dd.mm.yy' === $position ) { if ( preg_match( '/^(\d{1,2})-(\d{1,2})-(\d{1,4})$/', $date, $matches ) ) { $date_info['day'] = $matches[1]; $date_info['month'] = $matches[2]; $date_info['year'] = $matches[3]; } } elseif ( 'yy-mm-dd' === $position || 'yy/mm/dd' === $position || 'yy.mm.dd' === $position ) { if ( preg_match( '/^(\d{1,4})-(\d{1,2})-(\d{1,2})$/', $date, $matches ) ) { $date_info['year'] = $matches[1]; $date_info['month'] = $matches[2]; $date_info['day'] = $matches[3]; } } return apply_filters( 'forminator_field_date_parse_dates', $date_info, $date, $format ); } /** * Check data * * @since 1.0 * * @param int $month - the month. * @param int $day - the day. * @param int $year - the year. * * @return bool */ public function check_date( $month, $day, $year ) { if ( empty( $month ) || ! is_numeric( $month ) || empty( $day ) || ! is_numeric( $day ) || empty( $year ) || ! is_numeric( $year ) || 4 !== strlen( $year ) ) { return false; } return checkdate( $month, $day, $year ); } /** * Return field inline validation rules * * @since 1.0 * @return string */ public function get_validation_rules() { $field = $this->field; $id = self::get_property( 'element_id', $field ); $type = trim( self::get_property( 'field_type', $field ) ); $date_format = self::get_property( 'date_format', $field ); $rules = ''; if ( 'picker' === $type ) { $rules .= '"' . $this->get_id( $field ) . '": {' . "\n"; if ( $this->is_required( $field ) ) { $rules .= '"required": true,'; } $rules .= '"dateformat": "' . $date_format . '",'; $rules .= '},' . "\n"; } elseif ( $this->is_required( $field ) ) { $rules .= '"' . $this->get_id( $field ) . '-day": "required",'; $rules .= '"' . $this->get_id( $field ) . '-month": "required",'; $rules .= '"' . $this->get_id( $field ) . '-year": "required",'; } return apply_filters( 'forminator_field_date_validation_rules', $rules, $id, $field ); } /** * Return field inline validation errors * * @since 1.0 * @return string */ public function get_validation_messages() { $field = $this->field; $type = trim( self::get_property( 'field_type', $field ) ); $date_format = self::get_property( 'date_format', $field ); $required_validation_message = self::get_property( 'required_message', $field, '' ); $month_label = self::get_property( 'month_label', $field, '' ); $day_label = self::get_property( 'day_label', $field, '' ); $year_label = self::get_property( 'year_label', $field, '' ); if ( empty( $required_validation_message ) ) { if ( 'picker' === $type ) { $required_validation_message = esc_html__( 'This field is required.', 'forminator' ); } else { $required_validation_message = ' ' . esc_html__( 'field is required.', 'forminator' ); } } $messages = ''; if ( 'picker' === $type ) { $messages = '"' . $this->get_id( $field ) . '": {' . "\n"; if ( $this->is_required( $field ) ) { $required_validation_message = apply_filters( 'forminator_field_date_required_validation_message', $required_validation_message, $field, $type, $date_format, $this ); $messages .= '"required": "' . forminator_addcslashes( $required_validation_message ) . '",' . "\n"; } $format_validation_message = apply_filters( 'forminator_field_date_format_validation_message', esc_html__( 'Not valid date', 'forminator' ), $field, $type, $date_format, $this ); $messages .= '"dateformat": "' . forminator_addcslashes( $format_validation_message ) . '",' . "\n"; $messages .= '},' . "\n"; } elseif ( $this->is_required( $field ) ) { $day_validation_message = apply_filters( 'forminator_field_date_day_validation_message', $required_validation_message, $field, $type, $date_format, $this ); $messages = '"' . $this->get_id( $field ) . '-day": "<strong>' . $day_label . '</strong> ' . forminator_addcslashes( $day_validation_message ) . '",' . "\n"; $month_validation_message = apply_filters( 'forminator_field_date_month_validation_message', $required_validation_message, $field, $type, $date_format, $this ); $messages .= '"' . $this->get_id( $field ) . '-month": "<strong>' . $month_label . '</strong> ' . forminator_addcslashes( $month_validation_message ) . '",' . "\n"; $year_validation_message = apply_filters( 'forminator_field_date_year_validation_message', $required_validation_message, $field, $type, $date_format, $this ); $messages .= '"' . $this->get_id( $field ) . '-year": "<strong>' . $year_label . '</strong> ' . forminator_addcslashes( $year_validation_message ) . '",' . "\n"; } return apply_filters( 'forminator_field_date_validation_message', $messages, $field, $type, $date_format, $this ); } /** * Field back-end validation * * @since 1.0 * * @param array $field Field. * @param array|string $data Data. */ public function validate( $field, $data ) { $id = self::get_property( 'element_id', $field ); $start_date_type = self::get_property( 'start-date', $field, '' ); $end_date_type = self::get_property( 'end-date', $field, '' ); $date_type = self::get_property( 'field_type', $field, 'picker' ); $disabled_dates = self::get_property( 'disabled-dates', $field, array() ); $disabled_range = self::get_property( 'disable-date-range', $field, array() ); $restrict_type = self::get_property( 'howto-restrict', $field ); if ( $this->is_required( $field ) ) { $required_validation_message = self::get_property( 'required_message', $field, esc_html__( 'This field is required. Please enter a valid date.', 'forminator' ) ); if ( empty( $data ) ) { $this->validation_message[ $id ] = apply_filters( 'forminator_field_date_required_field_validation_message', $required_validation_message, $id, $data, $this ); return; } elseif ( 'picker' !== $date_type ) { $month = $data['month']; $day = $data['day']; $year = $data['year']; if ( empty( $month ) ) { $month_id = $id . '-month'; $this->validation_message[ $month_id ] = apply_filters( 'forminator_field_date_required_field_validation_message', esc_html__( 'Month field is required.', 'forminator' ), $month_id, $data, $this ); } if ( empty( $day ) ) { $day_id = $id . '-day'; $this->validation_message[ $day_id ] = apply_filters( 'forminator_field_date_required_field_validation_message', esc_html__( 'Day field is required.', 'forminator' ), $day_id, $data, $this ); } if ( empty( $year ) ) { $year_id = $id . '-year'; $this->validation_message[ $year_id ] = apply_filters( 'forminator_field_date_required_field_validation_message', esc_html__( 'Year field is required.', 'forminator' ), $year_id, $data, $this ); } } } if ( empty( $data ) ) { return; } if ( isset( $data['year'] ) && isset( $data['day'] ) && isset( $data['month'] ) && empty( $data['year'] ) && empty( $data['day'] ) && empty( $data['month'] ) ) { return; } // Always! (we dont have validate flag on builder) validate date_format. $date_format = self::get_property( 'date_format', $field ); $date = self::parse_date( $data, $date_format ); $month = $date['month']; $day = $date['day']; $year = $date['year']; // strtotime does not recognize all of our date formats so we need to convert all dates to 1 accepted format before processing. if ( 'Y-m-d' !== datepicker_default_format( $date_format ) && ! is_array( $data ) ) { $format_date = date_create_from_format( datepicker_default_format( $date_format ), $data ); if ( $format_date ) { $data = date_format( $format_date, 'Y-m-d' ); } else { $this->validation_message[ $id ] = apply_filters( 'forminator_field_date_valid_date_validation_message', esc_html__( 'Please enter a valid date.', 'forminator' ), $id, $data, $date_format, $this ); return; } } if ( 'select' !== $date_type && ! $this->check_date( $date['month'], $date['day'], $date['year'] ) ) { $year_id = $id . '-year'; if ( strlen( $date['year'] ) !== 4 && 'picker' !== $date_type ) { $this->validation_message[ $year_id ] = apply_filters( 'forminator_field_date_valid_year_validation_message', esc_html__( 'Year field is invalid.', 'forminator' ), $year_id, $data, $date_format, $this ); } else { $this->validation_message[ $id ] = apply_filters( 'forminator_field_date_valid_date_validation_message', esc_html__( 'Please enter a valid date.', 'forminator' ), $id, $data, $date_format, $this ); } } else { if ( 'select' === $date_type ) { // For year limits. $min_year = self::get_property( 'min_year', $field, gmdate( 'Y' ) - 100 ); $max_year = self::get_property( 'max_year', $field, gmdate( 'Y' ) + 100 ); $year = intval( $date['year'] ); if ( ! empty( $min_year ) && ! empty( $max_year ) ) { if ( $year < $min_year || $year > $max_year ) { $this->validation_message[ $id ] = apply_filters( 'forminator_field_date_valid_maxmin_year_validation_message', esc_html__( 'Please select a valid year.', 'forminator' ) ); } } else { if ( ! empty( $min_year ) ) { if ( $year < $min_year ) { $this->validation_message[ $id ] = apply_filters( 'forminator_field_date_valid_maxmin_year_validation_message', esc_html__( 'Please select a valid year.', 'forminator' ) ); } } if ( ! empty( $max_year ) ) { if ( $year > $max_year ) { $this->validation_message[ $id ] = apply_filters( 'forminator_field_date_valid_maxmin_year_validation_message', esc_html__( 'Please select a valid year.', 'forminator' ) ); } } } /* * For empty day or month. * We are allowing year to be filled because it defaults to current year. * In front-action.php (get_fields_info), we will remove the date submission data if only year has value coz its the default value. */ if ( ( ! empty( $date['month'] ) || ! empty( $date['day'] ) ) && ! $this->check_date( $date['month'], $date['day'], $date['year'] ) ) { if ( empty( $month ) ) { $month_id = $id . '-month'; $this->validation_message[ $month_id ] = apply_filters( 'forminator_field_date_required_field_validation_message', esc_html__( 'Month field is invalid.', 'forminator' ), $month_id, $data, $this ); } if ( empty( $day ) ) { $day_id = $id . '-day'; $this->validation_message[ $day_id ] = apply_filters( 'forminator_field_date_required_field_validation_message', esc_html__( 'Day field is invalid.', 'forminator' ), $day_id, $data, $this ); } if ( empty( $year ) ) { $year_id = $id . '-year'; $this->validation_message[ $year_id ] = apply_filters( 'forminator_field_date_required_field_validation_message', esc_html__( 'Year field is invalid.', 'forminator' ), $year_id, $data, $this ); } } } if ( 'picker' === $date_type ) { $custom_form = forminator_get_model_from_id( Forminator_Front_Action::$module_id ); $selected_date = preg_replace( '/(\d+)\D+(\d+)\D+(\d+)/', '$1/$2/$3', $data ); if ( 'week' === $restrict_type ) { $restrict = array(); $days = forminator_week_days(); foreach ( $days as $k => $day ) { if ( ! self::get_property( $k, $field ) ) { $restrict[] = $k; } } if ( ! empty( $restrict ) ) { $current_day = gmdate( 'l', strtotime( $selected_date ) ); if ( in_array( strtolower( $current_day ), $restrict, true ) ) { $this->validation_message[ $id ] = apply_filters( 'forminator_field_date_valid_between_date_validation_message', self::get_property( 'restrict_message', $field, esc_html__( 'Please select one of the available dates.', 'forminator' ) ) ); } } } if ( ! empty( $start_date_type ) ) { if ( 'specific' === $start_date_type ) { $start_date = self::get_property( 'start-specific-date', $field, '' ); } else { $start_offset_operator = self::get_property( 'start-offset-operator', $field, '+' ); $start_offset_value = self::get_property( 'start-offset-value', $field, '0' ); $start_offset_duration = self::get_property( 'start-offset-duration', $field, 'days' ); if ( 'today' === $start_date_type ) { $start_date = date_i18n( 'Y-m-d', strtotime( $start_offset_operator . $start_offset_value . ' ' . $start_offset_duration, current_time( 'U' ) ) ); // phpcs:ignore WordPress.DateTime.CurrentTimeTimestamp.Requested -- We are using the current timestamp based on the site's timezone. } else { $start_date_value = isset( Forminator_CForm_Front_Action::$prepared_data[ $start_date_type ] ) ? Forminator_CForm_Front_Action::$prepared_data[ $start_date_type ] : ''; $start_date = ''; if ( ! empty( $start_date_value ) ) { $start_date_field = $custom_form->get_field( $start_date_type, true ); $start_date_format = self::get_property( 'date_format', $start_date_field ); $start_date_format = date_create_from_format( datepicker_default_format( $start_date_format ), $start_date_value ); $start_date_value = date_format( $start_date_format, 'Y-m-d' ); $start_date = date_i18n( 'Y-m-d', strtotime( $start_date_value . ' ' . $start_offset_operator . $start_offset_value . ' ' . $start_offset_duration ) ); } } } if ( ! empty( $start_date ) && strtotime( $selected_date ) < strtotime( $start_date ) ) { $this->validation_message[ $id ] = apply_filters( 'forminator_field_date_valid_between_date_validation_message', self::get_property( 'restrict_message', $field, esc_html__( 'Please select one of the available dates.', 'forminator' ) ) ); } } if ( ! empty( $end_date_type ) ) { if ( 'specific' === $end_date_type ) { $end_date = self::get_property( 'end-specific-date', $field, '' ); } else { $end_offset_operator = self::get_property( 'end-offset-operator', $field, '+' ); $end_offset_value = self::get_property( 'end-offset-value', $field, '0' ); $end_offset_duration = self::get_property( 'end-offset-duration', $field, 'days' ); if ( 'today' === $end_date_type ) { $end_date = date_i18n( 'Y-m-d', strtotime( $end_offset_operator . $end_offset_value . ' ' . $end_offset_duration, current_time( 'U' ) ) ); // phpcs:ignore WordPress.DateTime.CurrentTimeTimestamp.Requested -- We are using the current timestamp based on the site's timezone. } else { $end_date_value = isset( Forminator_CForm_Front_Action::$prepared_data[ $end_date_type ] ) ? Forminator_CForm_Front_Action::$prepared_data[ $end_date_type ] : ''; $end_date = ''; if ( ! empty( $end_date_value ) ) { $end_date_field = $custom_form->get_field( $end_date_type, true ); $end_date_format = self::get_property( 'date_format', $end_date_field ); $end_date_format = date_create_from_format( datepicker_default_format( $end_date_format ), $end_date_value ); $end_date_value = date_format( $end_date_format, 'Y-m-d' ); $end_date = date_i18n( 'Y-m-d', strtotime( $end_date_value . ' ' . $end_offset_operator . $end_offset_value . ' ' . $end_offset_duration ) ); } } } if ( ! empty( $end_date ) && strtotime( $selected_date ) > strtotime( $end_date ) ) { $this->validation_message[ $id ] = apply_filters( 'forminator_field_date_valid_between_date_validation_message', self::get_property( 'restrict_message', $field, esc_html__( 'Please select one of the available dates.', 'forminator' ) ) ); } } // Change selected date format to the disabled-date format which is m/d/Y. $selected_date_format = date_create_from_format( 'Y/m/d', $selected_date ); $formatted_selected_date = date_format( $selected_date_format, 'm/d/Y' ); if ( ! empty( $disabled_dates ) && in_array( $formatted_selected_date, $disabled_dates, true ) ) { $this->validation_message[ $id ] = apply_filters( 'forminator_field_date_valid_disabled_validation_message', self::get_property( 'restrict_message', $field, esc_html__( 'Please select one of the available dates.', 'forminator' ) ) ); } if ( ! empty( $disabled_range ) ) { $has_range = true; foreach ( $disabled_range as $range ) { $range_arr = array_map( 'trim', explode( '-', $range ) ); if ( ! empty( $range_arr ) ) { $start_date = isset( $range_arr[0] ) ? $range_arr[0] : ''; $end_date = isset( $range_arr[1] ) ? $range_arr[1] : ''; if ( strtotime( $selected_date ) >= strtotime( $start_date ) && strtotime( $selected_date ) <= strtotime( $end_date ) ) { $has_range = false; continue; } } } if ( ! $has_range ) { $this->validation_message[ $id ] = apply_filters( 'forminator_field_date_valid_disabled_validation_message', self::get_property( 'restrict_message', $field, esc_html__( 'Please select one of the available dates.', 'forminator' ) ) ); } } } } } /** * Sanitize data * * @since 1.0.2 * * @param array $field Field. * @param array|string $data - the data to be sanitized. * * @return array|string $data - the data after sanitization */ public function sanitize( $field, $data ) { $original_data = $data; // Sanitize. if ( is_array( $data ) ) { $data = forminator_sanitize_array_field( $data ); } else { $data = forminator_sanitize_field( $data ); } return apply_filters( 'forminator_field_date_sanitize', $data, $field, $original_data ); } /** * Convert condition date to timestamp * * @param string $conditions_date Date from conditions. * @return string|false Timestamp */ public static function prepare_condition_date( $conditions_date ) { if ( is_numeric( $conditions_date ) ) { // Timestamp is in milliseconds. $compare_to = $conditions_date / 1000; } else { // Backward compatibility. $compare_to = strtotime( $conditions_date ); } return $compare_to; } }