get( 'Version' ) ); } add_action( 'wp_enqueue_scripts', 'your_theme_enqueue_styles' ); // force meta boxes panel in gutenberg editor to be full natual height add_action('admin_head', function() { echo ''; }); // 4. Remove the Comments link from the Admin Sidebar menu add_action('admin_menu', 'disable_comment_admin_menu'); function disable_comment_admin_menu() { remove_menu_page('edit-comments.php'); } // Change gravity form error message from h2 to span add_filter( 'gform_validation_message', 'change_message', 10, 2 ); function change_message( $message, $form ) { return "There was a problem with your submission. Please review the fields below."; } // Change gravity form required legend text add_filter( 'gform_required_legend', function( $legend, $form ) { return 'An asterisk (*) indicates a required field.'; }, 10, 2 ); // force AJAX on all GForms add_filter( 'gform_form_args', 'setup_form_args' ); function setup_form_args( $form_args ) { $form_args['ajax'] = true; return $form_args; } /** * Gravity Forms Date Field Validation * * ACCESSIBILITY FEATURES: * - Server-side validation with descriptive error messages. * - Client-side real-time feedback with aria-live announcements. * - Error messages clearly identify which field has the problem. * - End date min attribute updates dynamically when start date changes. */ // ───────────────────────────────────────────────────────────── // CONFIGURATION // ───────────────────────────────────────────────────────────── define( 'GF_DATE_FORM_ID', 5 ); // Form ID define( 'GF_START_DATE_FIELD_ID', 8 ); // Start Date field ID define( 'GF_END_DATE_FIELD_ID', 9 ); // End Date field ID // ───────────────────────────────────────────────────────────── /** * Parse a yyyy-mm-dd or yyyy/mm/dd string into a DateTime object. * Returns false if the string is empty or does not match either format. * * @param string $raw * @return DateTime|false */ function gf_parse_ymd( $raw ) { if ( empty( $raw ) ) { return false; } // Normalise: replace slash separator with dash so one format string handles both. $normalised = str_replace( '/', '-', trim( $raw ) ); // Reject anything that is not exactly yyyy-mm-dd after normalisation. if ( ! preg_match( '/^\d{4}-\d{2}-\d{2}$/', $normalised ) ) { return false; } $date = DateTime::createFromFormat( 'Y-m-d', $normalised ); // createFromFormat can return a date even when the values overflow // (e.g. month 13). Verify the parsed values match the input. if ( ! $date ) { return false; } $date->setTime( 0, 0, 0 ); // Guard against overflow dates (e.g. 2026-13-01 parsing as 2027-01-01). if ( $date->format( 'Y-m-d' ) !== $normalised ) { return false; } return $date; } /** * SERVER-SIDE VALIDATION * Runs on form submission. Catches bad dates even if JS is bypassed. */ add_filter( 'gform_validation', 'gf_validate_date_range' ); function gf_validate_date_range( $validation_result ) { $form = $validation_result['form']; if ( (int) $form['id'] !== GF_DATE_FORM_ID ) { return $validation_result; } $start_raw = isset( $_POST[ 'input_' . GF_START_DATE_FIELD_ID ] ) ? sanitize_text_field( $_POST[ 'input_' . GF_START_DATE_FIELD_ID ] ) : ''; $end_raw = isset( $_POST[ 'input_' . GF_END_DATE_FIELD_ID ] ) ? sanitize_text_field( $_POST[ 'input_' . GF_END_DATE_FIELD_ID ] ) : ''; $start_date = gf_parse_ymd( $start_raw ); $end_date = gf_parse_ymd( $end_raw ); $today = new DateTime( 'today midnight' ); foreach ( $form['fields'] as &$field ) { // ── Start Date ───────────────────────────────────────────────────── if ( (int) $field->id === GF_START_DATE_FIELD_ID ) { if ( ! $start_date ) { $field->failed_validation = true; $field->validation_message = 'Please enter a valid start date.'; $validation_result['is_valid'] = false; } elseif ( $start_date < $today ) { $field->failed_validation = true; $field->validation_message = 'Start date must be today or a future date.'; $validation_result['is_valid'] = false; } } // ── End Date ─────────────────────────────────────────────────────── if ( (int) $field->id === GF_END_DATE_FIELD_ID ) { if ( ! $end_date ) { $field->failed_validation = true; $field->validation_message = 'Please enter a valid end date.'; $validation_result['is_valid'] = false; } elseif ( $start_date && $end_date < $start_date ) { $field->failed_validation = true; $field->validation_message = 'End date must be on or after the start date (' . $start_date->format( 'Y-m-d' ) . ').'; $validation_result['is_valid'] = false; } elseif ( ! $start_date && $end_date < $today ) { $field->failed_validation = true; $field->validation_message = 'End date must be today or a future date.'; $validation_result['is_valid'] = false; } } } $validation_result['form'] = $form; return $validation_result; } /** * CLIENT-SIDE VALIDATION * - Locks start date min to today. * - Updates end date min whenever start date changes. * - Shows accessible inline errors on change and blur. * - Handles both yyyy-mm-dd and yyyy/mm/dd field values. */ add_action( 'wp_footer', 'gf_date_range_scripts' ); function gf_date_range_scripts() { if ( ! class_exists( 'GFForms' ) ) { return; } ?>