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;
}
?>