/**
* WooCommerce date of birth field with age validation
* Insert this code into the functions.php of your theme or into a plugin
*/
// 1. add date of birth field to checkout
add_action('woocommerce_after_checkout_billing_form', 'add_birthdate_checkout_field');
function add_birthdate_checkout_field($checkout) {
echo '<div id="birthdate_checkout_field"><h3>' . __('Geburtsdatum') . '</h3>';
woocommerce_form_field('billing_birthdate', array(
'type' => 'date',
'class' => array('form-row-wide'),
'label' => __('Geburtsdatum *'),
'placeholder' => __('TT.MM.JJJJ'),
'required' => true,
'custom_attributes' => array(
'max' => date('Y-m-d') // Maximaldatum ist heute
)
), $checkout->get_value('billing_birthdate'));
echo '</div>';
}
// 2. validate date of birth field (age must be at least 18 years)
add_action('woocommerce_checkout_process', 'validate_birthdate_checkout_field');
function validate_birthdate_checkout_field() {
if (!$_POST['billing_birthdate']) {
wc_add_notice(__('Bitte geben Sie Ihr Geburtsdatum an.'), 'error');
return;
}
$birthdate = sanitize_text_field($_POST['billing_birthdate']);
$birth_timestamp = strtotime($birthdate);
if (!$birth_timestamp) {
wc_add_notice(__('Bitte geben Sie ein gültiges Geburtsdatum an.'), 'error');
return;
}
// Calculate age
$today = new DateTime();
$birth = new DateTime($birthdate);
$age = $today->diff($birth)->y;
if ($age < 18) {
wc_add_notice(__('Sie müssen mindestens 18 Jahre alt sein, um eine Bestellung aufgeben zu können.'), 'error');
}
// Additional validation: Date of birth must not be in the future
if ($birth > $today) {
wc_add_notice(__('Das Geburtsdatum darf nicht in der Zukunft liegen.'), 'error');
}
}
// 3. save date of birth in the order
add_action('woocommerce_checkout_update_order_meta', 'save_birthdate_checkout_field');
function save_birthdate_checkout_field($order_id) {
if (!empty($_POST['billing_birthdate'])) {
$birthdate = sanitize_text_field($_POST['billing_birthdate']);
update_post_meta($order_id, 'billing_birthdate', $birthdate);
// Auch im Benutzerprofil speichern, wenn Benutzer eingeloggt ist
$user_id = get_current_user_id();
if ($user_id) {
update_user_meta($user_id, 'billing_birthdate', $birthdate);
}
}
}
// 4. display date of birth in the order details (Admin)
add_action('woocommerce_admin_order_data_after_billing_address', 'display_birthdate_in_admin_order_meta', 10, 1);
function display_birthdate_in_admin_order_meta($order) {
$birthdate = get_post_meta($order->get_id(), 'billing_birthdate', true);
if ($birthdate) {
$formatted_date = date('d.m.Y', strtotime($birthdate));
echo '<p><strong>' . __('Geburtsdatum') . ':</strong> ' . $formatted_date . '</p>';
}
}
// 5. add date of birth field to user account
add_action('woocommerce_edit_account_form', 'add_birthdate_to_account_form');
function add_birthdate_to_account_form() {
$user_id = get_current_user_id();
$birthdate = get_user_meta($user_id, 'billing_birthdate', true);
?>
<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
<label for="billing_birthdate"><?php _e('Geburtsdatum'); ?> <span class="required">*</span></label>
<input type="date" class="woocommerce-Input woocommerce-Input--text input-text"
name="billing_birthdate" id="billing_birthdate"
value="<?php echo esc_attr($birthdate); ?>"
max="<?php echo date('Y-m-d'); ?>" required />
</p>
<?php
}
// 6. validate and save date of birth from account form
add_action('woocommerce_save_account_details', 'save_birthdate_account_details', 10, 1);
function save_birthdate_account_details($user_id) {
if (isset($_POST['billing_birthdate'])) {
$birthdate = sanitize_text_field($_POST['billing_birthdate']);
// Validation
if (empty($birthdate)) {
wc_add_notice(__('Bitte geben Sie Ihr Geburtsdatum an.'), 'error');
return;
}
$birth_timestamp = strtotime($birthdate);
if (!$birth_timestamp) {
wc_add_notice(__('Bitte geben Sie ein gültiges Geburtsdatum an.'), 'error');
return;
}
// Age validation
$today = new DateTime();
$birth = new DateTime($birthdate);
$age = $today->diff($birth)->y;
if ($age < 18) {
wc_add_notice(__('Sie müssen mindestens 18 Jahre alt sein.'), 'error');
return;
}
if ($birth > $today) {
wc_add_notice(__('Das Geburtsdatum darf nicht in der Zukunft liegen.'), 'error');
return;
}
// Save if validation successful
update_user_meta($user_id, 'billing_birthdate', $birthdate);
}
}
// 7. display date of birth in account details (readonly)
add_action('woocommerce_account_dashboard', 'display_birthdate_in_account_dashboard');
function display_birthdate_in_account_dashboard() {
$user_id = get_current_user_id();
$birthdate = get_user_meta($user_id, 'billing_birthdate', true);
if ($birthdate) {
$formatted_date = date('d.m.Y', strtotime($birthdate));
echo '<p><strong>' . __('Ihr Geburtsdatum') . ':</strong> ' . $formatted_date . '</p>';
}
}
// 8. add CSS for better display
add_action('wp_head', 'birthdate_checkout_styles');
function birthdate_checkout_styles() {
?>
<style>
#birthdate_checkout_field {
margin: 20px 0;
padding: 15px;
border: 1px solid #ddd;
border-radius: 4px;
background-color: #f9f9f9;
}
#birthdate_checkout_field h3 {
margin-top: 0;
color: #333;
font-size: 18px;
}
#billing_birthdate {
width: 100%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 16px;
}
.woocommerce-error {
background-color: #e74c3c;
color: white;
padding: 10px;
border-radius: 4px;
margin: 10px 0;
}
</style>
<?php
}
// 9. add JavaScript for better UX
add_action('wp_footer', 'birthdate_checkout_scripts');
function birthdate_checkout_scripts() {
if (is_checkout() || is_account_page()) {
?>
<script>
jQuery(document).ready(function($) {
// Automatic age calculation and warning
$('#billing_birthdate').on('change', function() {
var birthdate = new Date($(this).val());
var today = new Date();
var age = today.getFullYear() - birthdate.getFullYear();
var m = today.getMonth() - birthdate.getMonth();
if (m < 0 || (m === 0 && today.getDate() < birthdate.getDate())) {
age--;
}
// Show warning if under 18
$('.age-warning').remove();
if (age < 18 && age >= 0) {
$(this).after('<div class="age-warning" style="color: red; font-weight: bold; margin-top: 5px;">Sie müssen mindestens 18 Jahre alt sein, um bestellen zu können.</div>');
}
});
});
</script>
<?php
}
}
// 10. display date of birth in e-mail notifications
add_action('woocommerce_email_customer_details', 'add_birthdate_to_emails', 25, 4);
function add_birthdate_to_emails($order, $sent_to_admin, $plain_text, $email) {
$birthdate = get_post_meta($order->get_id(), 'billing_birthdate', true);
if ($birthdate) {
$formatted_date = date('d.m.Y', strtotime($birthdate));
if ($plain_text) {
echo "\nGeburtsdatum: " . $formatted_date . "\n";
} else {
echo '<p><strong>Geburtsdatum:</strong> ' . $formatted_date . '</p>';
}
}
}
// 11. request date of birth for existing users at first checkout
add_action('woocommerce_checkout_init', 'populate_birthdate_for_existing_users');
function populate_birthdate_for_existing_users($checkout) {
if (is_user_logged_in()) {
$user_id = get_current_user_id();
$birthdate = get_user_meta($user_id, 'billing_birthdate', true);
if ($birthdate) {
$checkout->checkout_fields['billing']['billing_birthdate']['default'] = $birthdate;
}
}
}