How to Sort WooCommerce products by ACF value?

Viewed 1490

How is it possible to sort WooCommerce products by Advanced Custom Field values?

I've added some custom fields to the back-end and front-end of the website. The front-end implementation in my functions.php looks like so:

add_action( 'woocommerce_before_add_to_cart_form', 'tmy_eventbooking', 20 );

function tmy_eventbooking() {
    if( !empty( get_field('datum') ) ) { // if your custom field is not empty…
        echo '<p class="acf-info">Findet statt am: <span>' . get_field('datum') . '</span></p>';
    }
        if( !empty( get_field('datum_ende') ) ) { // if your custom field is not empty…
        echo '<p class="acf-info">Bis: <span>' . get_field('datum_ende') . '</span></p>';
    }
        if( !empty( get_field('veranstaltungsort') ) ) { // if your custom field is not empty…
        echo '<p class="acf-info">Ort: <span>' . get_field('veranstaltungsort') . '</span></p>';
    }
    return;
}

This works fine.

Now I would like to be able to sort products by these ACF fields (type date and text).

If a user clicks for example on a 'date' button or selects a location from a dropdown menu, all events get sorted accordingly. Events are regular WooCommerce service products.

What is a good way to approach this?

1 Answers

You need to use two filter hooks to perform custom sorting in the archive page based on ACF.

Use woocommerce_catalog_orderby filter hooks to add custom date and location options.

// Add these date and location sorting options on the frontend.
function add_new_custom_postmeta_orderby( $sortby ) {
    $sortby['date']     = __( 'Sort by date', 'woocommerce' );
    $sortby['location'] = __( 'Sort by location', 'woocommerce' );
    return $sortby;
}
add_filter( 'woocommerce_catalog_orderby', 'add_new_custom_postmeta_orderby' );

Use woocommerce_get_catalog_ordering_args filter hook to modified orderby and order based on option you choosed

function add_custom_postmeta_ordering_args( $sort_args ) {
    $orderby_value = isset( $_GET['orderby'] ) ? wc_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
    switch( $orderby_value ) {
        case 'date':
            $sort_args['orderby']  = 'meta_value_num';
            $sort_args['order']    = 'desc';
            $sort_args['meta_key'] = 'date';
            break;

        case 'location':
            $sort_args['orderby']  = 'meta_value';
            $sort_args['order']    = 'asc';
            $sort_args['meta_key'] = 'location';
            break;
    }
    return $sort_args;
}
add_filter( 'woocommerce_get_catalog_ordering_args', 'add_custom_postmeta_ordering_args' );

USEFUL LINKS

Related