Ask your WordPress questions! Pay money and get answers fast! (more info)

query post, meta value in_array(meta_key) WordPress

  • SOLVED

'automobiles' is a duplicateable custom field.

For example, the output of
print_r(get_post_meta( $post->ID, 'automobiles', true ));
for the post 'post of test' is
Array
(
[0] => Array
(
[select] => value1
)

[1] => Array
(
[select] => value2
)

[2] => Array
(
[select] => value3
)

[3] => Array
(
[select] => value4
)

[4] => Array
(
[select] => value5
)

)



I want to display all custom post types 'professeur' which have 'value3' as 'automobiles'.

I use

$args = array(
'numberposts' => -1,
'post_type' => 'professeur',
'meta_query' => array (
array (
'key' => 'automobiles',
'value' => 'value3',
'compare' => 'IN'
)
) );

$new_query = new WP_Query( $args );

if($new_query->have_posts()) : while($new_query->have_posts()) : $new_query->the_post();
the_title();echo '<br>';
endwhile;endif;

but that doesn't work...

Answers (3)

2014-05-09

Dbranes answers:

You should in general use an array:


'value' => array( 'value3' )


when the compare method is "IN".

Did you try that?

<strong>Update:</strong>

You can try the following:


$args = array(
'posts_per_page' => -1,
'post_type' => 'professeur',
'meta_key' => 'automobiles',
);

$new_query = new WP_Query( $args );

if( $new_query->have_posts() ):
while($new_query->have_posts()) : $new_query->the_post();

the_title();

$meta = get_post_meta( get_the_ID(), 'automobiles', true );
foreach( $meta as $k => $v ):
if( isset( $v['select'] ) && 'value3' === $v['select'] ):
echo '<br /> Meta: yes this post contains a "select" with "value3"';
endif;
endforeach;

echo '<hr />';

endwhile;
endif;


<strong>Another idea:</strong>

You modify the <em>save_post </em> hook of the github snippet to save the select values (or others) into a single custom fields, that can be filtered via <em>meta_query</em> of<em> WP_Query()</em>.

You can for example collect the <em>name</em>, <em>select</em> or <em>url</em> of the repeatable fields, so we can introduce new (multiple) custom fields:

automobiles_name,
automobiles_select,
automobiles_url


Let's collect for example the <em>automobiles_select</em> values, modified by the user.

We then have to modify the <em>save_post</em> action callback, with a single <em>delete_post_meta()</em> before the for loop and place the <em>add_post_meta()</em> inside the for loop:



...cut...

//---------------------------------------------------------------
// Delete our new (multiple) custom field for the 'select' part
//
delete_post_meta( $post_id, 'automobiles_select' );
//---------------------------------------------------------------

for ( $i = 0; $i < $count; $i++ ) {
if ( $names[$i] != '' ) :
$new[$i]['name'] = stripslashes( strip_tags( $names[$i] ) );

if ( in_array( $selects[$i], $options ) )
$new[$i]['select'] = $selects[$i];
else
$new[$i]['select'] = '';

if ( $urls[$i] == 'http://' )
$new[$i]['url'] = '';
else
$new[$i]['url'] = stripslashes( $urls[$i] ); // and however you want to sanitize

//---------------------------------------------------------------
// Add our new (multiple) custom field for the 'select' part
//
add_post_meta( $post_id, 'automobiles_select', $new[$i]['select'] );
//---------------------------------------------------------------

endif;

}

...cut...



Then you can filter the <em>automobiles_select</em> values with <em>WP_Query( $args )</em>, where:


$args = array(
'posts_per_page' => -1,
'post_type' => 'professeur',
'meta_query' => array (
array (
'key' => 'automobiles_select',
'value' => array( 'value1','value2' ),
'compare' => 'IN',
),
),
);


ps: Just let me know if we need to adjust it more.


Sébastien | French WordpressDesigner comments:

Thx Dbranes, I just tried... and that doesn't work


Dbranes comments:

ok, so by "duplicated meta value",

you mean you add for example the "automobile" custom field x times, but with different values:

automobiles value1
automobiles value2
automobiles value3
...


or is it serialized array in the meta value?


Sébastien | French WordpressDesigner comments:

i use this method : [[LINK href="https://gist.github.com/helenhousandi/1593065"]]https://gist.github.com/helenhousandi/1593065[[/LINK]]


Dbranes comments:

ok, I see the problem, it saves a single meta key <strong>repeatable_fields</strong> with a meta value that is a <strong>serialized array</strong>.


Dbranes comments:

It looks like you replaced <em>repeatable_fields</em> with <em>automobiles</em>, so you can try this in your loop:


$meta = get_post_meta( get_the_ID(), 'automobiles', true );
foreach( $meta as $k => $v ){
if( isset( $v['select'] ) && 'value3' === $v['select'] ){
echo 'yes I found it';
}
}


to find 'value3' items.

ps: maybe we need to modify this a little bit, you just let me know


Sébastien | French WordpressDesigner comments:

Yes I know this code :)
I search a way with query_post


Dbranes comments:

Then the idea is to construct the loop as in the updated answer.


Dbranes comments:

Another option/idea would be to modify the <em>save_post</em> hook of the github snippet to save the <em>select</em> values (or others) into a single custom fields, that can be filtered via <em>meta_query</em> of <em>WP_Query()</em>.


Sébastien | French WordpressDesigner comments:

absolutely ! I thought about this way !
The field is duplicatable, one post can have multiple values for "automobiles".
For example "automobiles can have the value "value3" AND "value4".

I need a loop like this, for example :
$args = array(
'numberposts' => -1,
'post_type' => 'professeur',
'meta_query' => array (
array (
'key' => 'my new custom field',
'value' => 'value3, value 4'
)
) );

$new_query = new WP_Query( $args );


For you, what is the best way ?

Could you write the code please ?


Dbranes comments:

Please check out the updated answer above.


Dbranes comments:

Hi, did the github code snippet rewrite work for you?


Sébastien | French WordpressDesigner comments:

could you paste the complete code please, i will try


Dbranes comments:

It's listed in my updated answer under "Another idea:".

You just need to add these two lines (that are specially marked) to the github code snippet, that's it.

Then the WP_Query args are listed there as well.

I hope this works for you, I tested it on my install and it worked.

2014-05-09

Kyle answers:

Querying meta field arrays is only 'partially' supported. May be better of using an SQL query

global $wpdb;
$posts=$wpdb->get_results("SELECT * FROM `wp_posts` WHERE post_type='professeur' AND post_status ='publish' AND ID
IN(SELECT post_id FROM `wp_postmeta` WHERE meta_key='automobiles' AND meta_value IN 'value3' ORDER BY RAND()");


Sébastien | French WordpressDesigner comments:

"partially" supported... but supported ?
Is it possible with a query post ?


Kyle comments:

It is supported but buggy, what you are doing is the correct way, and should work.

Have you considered doing a simply top level if statement inside the loop?

if($new_query->have_posts() ) : while($new_query->have_posts()) : $new_query->the_post();
global $post;
$cf = get_post_meta($post->ID,'automobiles',true);
if( $cf[1] == 'value3' ) {
the_title();echo '<br>';
}
endwhile;endif;


Sébastien | French WordpressDesigner comments:

yes I have.
your request write an error message :-/


Sébastien | French WordpressDesigner comments:


<blockquote>
WordPress database error: [You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''value3' ORDER BY RAND()' at line 2]
SELECT * FROM `wp_posts` WHERE post_type='professeur' AND post_status ='publish' AND ID IN(SELECT post_id FROM `wp_postmeta` WHERE meta_key='automobiles' AND meta_value IN 'value3' ORDER BY RAND()</blockquote>

2014-05-09

John Cotton answers:

Array meta values are serialized (ie converted to a string) when stored in the database, so there is not direct way (nor will there ever be until MySQL is rewritten - there are too many permutations) to query that data as data.

However, if you want to avoid the (smallish, if your data set is small) performance hit of testing the value in the query posts loop, you could make use of the LIKE compare value for meta data (ie a string match).

But your serialized array would have to be consistent for it to work.

Let me know if you want me to show some code.