wordpressadvanced-custom-fieldspost-metameta-key

wordpress $query->set to sort archive product pages, by *manipulated* ACF meta key value


I am trying to use the pre_get_posts action hook to sort products by ACF field for archive product pages.

The ACF field is a string, that contains characters and numeric value

My solution: to add missing leading zero's so that '040' < '180' will hold.

The following code is NOT working. What am I missing?

function sort_batteries_by_amper( $query ) {
        if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'product' ) {
            $query->set('orderby', 'meta_value');    
            $query->set('meta_key', 'MY_KEY');    
            $query->set('order', 'ASC'); 
            $value = get_ah_value($query, 'MY_KEY'); // add leading zero's to int values < 100
            $query->set( 'meta_value', $value );
        }
        return $query;
    }

    add_action('pre_get_posts', 'sort_batteries_by_amper');


Solution

  • The following is a complete solution that works

    add_action( 'woocommerce_product_query', 'ah_product_query' );
    function ah_product_query( $q ) {
        if ( ! is_admin() ) { 
            $acffieldname = 'ACF_KEY_1';
            if ($q->queried_object->term_id == 320 || $q->queried_object->term_id == 321)
                $scffieldname = 'ACF_KEY_2';
    
            $value = get_ah_value($q, $acffieldname );
            $q->set( 'meta_query', array(
                array(
                    'key'     => $acffieldname,
                    'compare' => '>',
                    'value'   => intval($value), 
                    'type'    => 'numeric',
                )
            ) );
            $q->set('orderby', 'meta_value');    
            $q->set( 'order', 'ASC' ); 
        }
    }
    
    function get_ah_value($query, $s){
        if (!isset($query->query['p'])) return '';
        $str = get_field($s, $query->query['p']);
        if (empty($str)) return '';
        preg_match_all('/[0-9]+/', $str, $matches);
        $n = $matches[0][0];
        $s = intval($n) < 100 ? '0'.$n : $n;
        return $s;
    }