最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

custom post types - meta_query Where the key value is stored as an array

programmeradmin3浏览0评论

I am having difficulty getting this function to work. What I have going on is that information about a specific clothing items is created in an "Attire" custom post type. I did this because many classes share similar clothing items so it is easier to create 1 clothing item and then assign it to different classes. The custom fields for attired are stored like this:

   [9] => Array
    (
        [attire-id] => 5680
        [cat] => Leotard
        [gender] => girl
        [assign-classes] => Array
            (
                [0] => 5576
                [1] => 5577
            )

        [attire-name] => Lilac Skirt Eurotard 10127
    )

The 'assign-classes' is storing the IDs of different classes that require that particular attire item. When the class appears on the webpage, I want to do a custom query to only retrieve the clothing items that have the classes ID stored in that 'assign-classes'.

This is the function that is not working.

 function get_class_attire($id){
    $all_attire = array();
    $args = array(
        'post_type'     => 'attire',
        'meta_query'=>array(
            array(
                'key'       => 'assign-classes',
                'value'     => $id,
                'compare'   => 'IN'
                ),
        ),
        'numberposts'   => -1,
    );
    $the_query = get_posts($args);

    foreach ( $the_query as $post ) : setup_postdata( $post );
        $this_attire = array(
            'attire-id' => $post->ID,
            'cat' => get_post_meta($post->ID, 'attire-category', true),
            'gender' => get_post_meta($post->ID, 'gender', true),
            'assign-classes' => get_post_meta($post->ID, 'assign-classes', true),
            'attire-name' => get_the_title($post->ID)
        );
        array_push($all_attire, $this_attire);
    endforeach;
    wp_reset_postdata();
    return $all_attire;
}

I feel like the problem is that when it goes to check, it just sees Array for all of the 'assign-classes' values and then returns nothing. I'm not sure how to get it to look at the values in the array to do the comparison.

I am having difficulty getting this function to work. What I have going on is that information about a specific clothing items is created in an "Attire" custom post type. I did this because many classes share similar clothing items so it is easier to create 1 clothing item and then assign it to different classes. The custom fields for attired are stored like this:

   [9] => Array
    (
        [attire-id] => 5680
        [cat] => Leotard
        [gender] => girl
        [assign-classes] => Array
            (
                [0] => 5576
                [1] => 5577
            )

        [attire-name] => Lilac Skirt Eurotard 10127
    )

The 'assign-classes' is storing the IDs of different classes that require that particular attire item. When the class appears on the webpage, I want to do a custom query to only retrieve the clothing items that have the classes ID stored in that 'assign-classes'.

This is the function that is not working.

 function get_class_attire($id){
    $all_attire = array();
    $args = array(
        'post_type'     => 'attire',
        'meta_query'=>array(
            array(
                'key'       => 'assign-classes',
                'value'     => $id,
                'compare'   => 'IN'
                ),
        ),
        'numberposts'   => -1,
    );
    $the_query = get_posts($args);

    foreach ( $the_query as $post ) : setup_postdata( $post );
        $this_attire = array(
            'attire-id' => $post->ID,
            'cat' => get_post_meta($post->ID, 'attire-category', true),
            'gender' => get_post_meta($post->ID, 'gender', true),
            'assign-classes' => get_post_meta($post->ID, 'assign-classes', true),
            'attire-name' => get_the_title($post->ID)
        );
        array_push($all_attire, $this_attire);
    endforeach;
    wp_reset_postdata();
    return $all_attire;
}

I feel like the problem is that when it goes to check, it just sees Array for all of the 'assign-classes' values and then returns nothing. I'm not sure how to get it to look at the values in the array to do the comparison.

Share Improve this question asked Apr 16, 2020 at 13:00 KevinKevin 275 bronze badges 7
  • How is the field populated? Do you have your own meta box, or are you using a plugin? Querying meta values sorted as an array really doesn't work very well, especially if you're querying inside a sub-array. You'd have a much easier time if you stored classes as its own meta key, with multiple entries. – Jacob Peattie Commented Apr 16, 2020 at 13:09
  • Thanks Jacob. In the "Attire" post type all the classes are displayed as checkbox options. The user checks the classes that will use that particular attire item. The values stored are the IDs of all of the checked classes. I went with this direction because one attire item might be used by only 2 classes while another 23. It can vary considerably. What do you mean exactly by "own meta key, with multiple entries?" – Kevin Commented Apr 16, 2020 at 13:16
  • 1 You can store the same meta key multiple times with different values by using add_post_meta() instead of update_post_meta(). So my question is do you control the code that is saving the checkboxes, or is a plugin doing it? – Jacob Peattie Commented Apr 16, 2020 at 13:17
  • Ah, now I got ya. I control it. I built the plugin. I'm not using ACF or anything else. So you're saying I could make a loop and do add_post_meta() for any boxes that are checked. Is that the gist? – Kevin Commented Apr 16, 2020 at 13:20
  • Right. You'll just need to delete all values when saving, before adding values, rather than updating them, to make sure you're not just adding values every time the post is saved. – Jacob Peattie Commented Apr 16, 2020 at 13:22
 |  Show 2 more comments

1 Answer 1

Reset to default 0

Thanks to the help of @JacobPeattie the problem was how the data was being saved. So instead of:

    if(isset($_POST['assign-classes'])) {            
        update_post_meta( $post->ID, 'assign-classes', $_POST['assign-classes'] );
    }

It is now:

delete_post_meta($post->ID, "assign-classes");
    for($i = 0; $i < count($_POST['assign-classes-all']); $i++){
        add_post_meta( $post->ID, 'assign-classes', $_POST['assign-classes-all'][$i], false );
    }

Only thing that was weird is that at first I tried a foreach loop which would not iterate more than one time. However, a for loop would.

发布评论

评论列表(0)

  1. 暂无评论