5

I have this function hardcoded into content-single-product.php (WooCommerce) and it works to show 3 random products from categories ID 64 and 72:

$args = array(
    'post_type'      => 'product',
    'post_status'    => 'publish',
    'posts_per_page' => '3',
    'orderby'        => 'rand',
    'tax_query'      => array(
        'relation' => 'AND',
        array(
            'taxonomy' => 'product_cat',
            'field'    => 'term_id',
            'terms'    => array( 64, 72 ),
        ),
    ),
);

$loop = new WP_Query( $args );

while ( $loop->have_posts() ) : $loop->the_post();
    global $product;

Now, instead of hardcoding the category ID, I added a custom field to the product MyCustomField and wrote 64,72 in it. Then I tried to modify the above code to be populated dynamically:

$MyCustomField = get_post_meta($post->ID, 'MyCustomField', true);

$args = array(
    'post_type'      => 'product',
    'post_status'    => 'publish',
    'posts_per_page' => '3',
    'orderby'        => 'rand',
    'tax_query'      => array(
        'relation' => 'AND',
        array(
            'taxonomy' => 'product_cat',
            'field'    => 'term_id',
            'terms'    => array( $MyCustomField ),
        ),
    ),
);

$loop = new WP_Query( $args );

while ( $loop->have_posts() ) : $loop->the_post();
    global $product;

Unfortunately, this doesn't work correctly:

'terms' => array( $MyCustomField )

because it only displays products from the first category (ID 64), and not from both, as I want.

I'm a newbie programmer so what did I do wrong? Thanks!

7

I suspect the problem is coming from $MyCustomField which you enter as such in:

'terms' => array( $MyCustomField ),

The query consider it as only one value: '64,72', a string.

So try:

$MyCustomFieldValues = array_map( 'intval', explode( ',', $MyCustomField ) );

This will also ensure your values are integers.

Then:

'terms' => $MyCustomFieldValues,
  • Read carefully other answers which are also interesting... – ClemC Oct 4 '16 at 13:16
  • 1
    Yes, I have, and will plan to use all input, including checking for an empty custom field, as sMyles suggested. You guys have been of great help! – Alex Oct 4 '16 at 13:25
4

From the WordPress codex:

relation (string) - The logical relationship between each inner taxonomy array when there is more than one. Possible values are 'AND', 'OR'. Do not use with a single inner taxonomy array.

Few other things too, you should be saving the values to the custom meta as an array, WordPress will automatically serialize that value:

Using update_post_meta will automatically serialize any array you pass it:

update_post_meta( $post_id, 'MyCustomField', array( 64, 72 ) );

Then you can just unserialize it when pulling the value:

$MyCustomField = maybe_unserialize( get_post_meta( $post->ID, 'MyCustomField', TRUE ) );

You should probably also check to make sure you have a value before making the WP_Query call

if( ! empty( $MyCustomField ) ){

    $args = array(
        'post_type'      => 'product',
        'post_status'    => 'publish',
        'posts_per_page' => '3',
        'orderby'        => 'rand',
        'tax_query'      => array(
            array(
                'taxonomy' => 'product_cat',
                'field'    => 'term_id',
                'terms'    => $MyCustomField,
            ),
        ),
    );

}

If your plan is to add these values through the WP Admin interface (meaning you want to input a CSV), then you should use @ClemC approach, and use explode, with array_map to convert to integers

2

If you are passing in the text (string) "64,72" to a function that expects an array of integers, then you need to translate that incoming string into an integer array. Try adding this statement before your $args = statement:

$MyCustomField = array_map('intval', explode(',', $MyCustomField));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.