'Hide specific WooCommerce products based on product category for users under the age of 18

I want to hide specific products, based on product category for users under the age of 18.

So if the user is not logged in, or if logged in but under the age of 18 years old (date of birth will be set during check out), these products should be hidden on WooCommerce shop and archive pages.

Via code I found online, and trial and error, this is my code attempt:

add_filter( 'woocommerce_product_categories_hide_empty', 'hide_empty_categories' );
function hide_empty_categories( $hide_empty ) {
    if ( is_user_logged_in() ) {
        $current_user = wp_get_current_user();
        $age = (int) $current_user->user_age;
        if ( $age < 18 ) {
            $hide_empty = true;
        }
    }
    return $hide_empty;
}

Unfortunately without the desired result. Any advice?


To add the birthday field, I use:

function new_add_custom_checkbox_fields() {
    $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
    $chosen_shipping = $chosen_methods[0]; 

    if ($chosen_shipping != 'free_shipping:2'){
        add_filter('woocommerce_checkout_fields', function($fields) {
            $fields['billing']['billing_date_intervention'] = [
                'label'     => __('date du jour', 'textdomain'),
                'required'  => true,
                'type'      => 'text',
                'default' => date("d/m/Y"),
                'class'     => ['wooccm-required-field'],
                'priority'  => 125
            ];
            $fields['billing']['billing_date_naissance'] = [
                'label'     => __('date de naissance', 'textdomain'),
                'required'  => true,
                'type'      => 'date',
                'class'     => ['wooccm-required-field'],
                'id'        => 'date_of_birth',
                'priority'  => 70
            ];

            return $fields;
        });

    }
}
add_action('woocommerce_billing_fields', 'new_add_custom_checkbox_fields');

/**
 * Ajout et mise à jour des champs dans la base de donnée
 */
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
    if ( ! empty( $_POST['billing_date_intervention'] ) ) {
        add_post_meta( $order_id, '_billing_date_intervention', sanitize_text_field( $_POST['billing_date_intervention'] ) );
    }
    if ( ! empty( $_POST['billing_date_naissance'] ) ) {
        add_post_meta( $order_id, '_billing_date_naissance', sanitize_text_field( $_POST['billing_date_naissance'] ) );
    }
}


Solution 1:[1]

If you want to determine the age, it is first and foremost important to make a field available in WooCommerce, so that a user can enter his date of birth

An important note is that you should save data as user_meta and not as post_meta

So to add and save the field, use:

// Display billing birthdate field to checkout and my account addresses
function filter_woocommerce_billing_fields( $fields ) {
    $fields['billing_birthdate'] = array(
        'type'        => 'date',
        'label'       => __( 'Birthdate', 'woocommerce' ),
        'class'       => array( 'form-row-wide' ),
        'priority'    => 25,
        'required'    => true,
        'clear'       => true,
    );

    return $fields;
}
add_filter( 'woocommerce_billing_fields', 'filter_woocommerce_billing_fields', 10, 1 );

// Save/update user data from custom field value
function action_woocommerce_checkout_update_customer( $customer, $data ) {  
    // Isset
    if ( isset( $_POST['billing_birthdate'] ) ) {
        $customer->update_meta_data( 'billing_birthdate', sanitize_text_field( $_POST['billing_birthdate'] ) );
    }
}
add_action( 'woocommerce_checkout_update_customer', 'action_woocommerce_checkout_update_customer', 10, 2 );

To hide the desired products, belonging to certain categories in frontend, based on age. You can then use the woocommerce_product_query_tax_query hook.

So you get:

function filter_woocommerce_product_query_tax_query( $tax_query, $query ) {
    // The desired product category slug(s)
    $categories = array( 'categorie-1', 'categorie-2' );

    // Initialize
    $flag = true;

    // Logged in (not logged in, hide products by default)
    if ( is_user_logged_in() ) {
        // Get user ID
        $user_id = get_current_user_id();

        // Get meta
        $billing_birthdate = get_user_meta( $user_id, 'billing_birthdate', true );

        // NOT empty (when empty, hide products by default)
        if ( ! empty( $billing_birthdate ) ) {
            // Older than 18
            if ( time() > strtotime ( '+18 years', strtotime( $billing_birthdate ) ) ) {
                $flag = false;
            } 
        }
    }

    // When true
    if ( $flag ) {
        $tax_query[] = array(
            'taxonomy'  => 'product_cat',
            'field'     => 'slug',
            'terms'     => $categories,
            'operator'  => 'NOT IN'
        );
    }

    return $tax_query;
}
add_filter( 'woocommerce_product_query_tax_query', 'filter_woocommerce_product_query_tax_query', 10, 2 );

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1