Count posts that include the current users email in a meta field - php

I was hoping someone could please assist with my below code. I have a field called pds_project_manager and it contains the email address of my users assigned to projects(posts), I am wanting to count the number of posts that have the field with the current users email in it. The below code works, but if there is more than just the current users email address in the field pds_project_manager it ignores it and does note count it. The field will often have multiple email addresses in it.
$current_user = wp_get_current_user();
$display_name = $current_user->display_name;
$args_pm = array(//number of posts by pm
'posts_per_page' => -1,
'post_type' => 'project',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'status',
'value' => '1'
),
array(
'key' => 'pds_project_manager',
'value' => $current_user->user_email,
)
)
);
$posts_pm = get_posts($args_pm);
$pm_count = count($posts_pm);//number of posts by pm
echo "$display_name's Active Projects: $pm_count";

Assuming that you have a serialized array represented as a string and stored in Database for your pds_project_manager field, use LIKE in your query like this:
...
array(
'key' => 'pds_project_manager',
'value' => $current_user->user_email,
'compare' => 'LIKE'
)
...
There is a good article why not to use LIKE or not to store serialized data in Database, in case you want to know alternatives: https://wordpress.stackexchange.com/questions/16709/meta-query-with-meta-values-as-serialize-arrays

Related

WordPress How to sort by a custom meta key using a key inside it?

On my WordPress site, each user has a custom meta key named 'user_details' which is an array and has the following structure:
$user_details = array('age'=>10,'gender'=>'male');
in the following example, how can I sort users in an ASC order according to each user 'age'?
<?php
//get all users above 10 years
$args = array(
'meta_query' => array(
'meta_key' => array(
'key' => 'user_details',
'value' => '',
'type' => 'CHAR',
'compare' => '!=',
),
),
'orderby' => array( 'meta_key' => 'ASC' ),
);
$users = get_users( $args );
?>
SO, the line
array( 'meta_key' => 'ASC' ) does not sort the retrieved users according to 'age', how can I sort the retrieved users according to the age?
Thanks.
Power,
there are 2 options:
1) IF you store an array into the user meta VALUE (not the key) as you appear to have done, THEN you will have to query the records and then sort the array retrieved AFTER the query - lookup php array sorting functions.
2) AN alternative is to store the user details more cleanly in separate meta records eg:
meta-key: user-age
meta-key: user-gender
THEN you can query and sort at the same time.
If you look at how the data is stored in phpmyadmin and try to write a MYSQL query to extract that data, you will gain a better appreciation of the situation.

Only get pages where a field matches one of a set of values

I'm trying to create a storelocator in wordpress where I use zipcodes to filter for distance. I then create I string with all zipcodes that are within range and make a string with all those zipcodes separated by comma's. This works fine and returns something like this:
5062,5063,5061,4163,5060,5059,5056,5076,5066,5070,5071,5074,5268,5034,5035,5037,5027,5033,5032,5031,5030,5029,5028,5038,5039,5036,5049,5048,5047,5046,5045,5044,5043,5042,5041,5040,5026,5025,5010,5009,5008,5007,5006,5005,5004,5003,5002,5001,5000,5011,5012,5013,5024,5023,5022,5021,5020,5019,5018,5017,5016,5015,5014,5296
Now I want to get posts where the zipcode CONTAINS one of these values. I figured something like this would work:
$query_adresses = array (
'order' => 'ASC',
'cat' => $_GET["cat"],
'post_type'=> 'adressen',
'posts_per_page' => '-1',
'meta_query' => array(
array(
'key' => 'postcode',
'value' => array($final_target_zips),
'compare' => 'IN',
)
)
);
Sadly it doesn't work and just returns all posts that match the other arguments. Keep in mind that zipcodes in the posts consist of the numbers but also have two letters attached to them like: 5021GH. Only the numbers need to be checked though. I hope someone can help me out.

Querying sanatized data with meta_query in Wordpress

After Googeling this for a while, I've found that this should work ref., but I don't seem to get it running.
On the backend I have a custom field on commments for setting a list of userIDs of who liked it. It is stored sanatized in the DB this way:
a:2:{i:0;s:1:"1";i:1;s:1:"2";}
which translates into
Array (
[0] => 1
[1] => 2
)
A pretty straight forward flat array where the values 1 and 2 are the user IDs of two likes. Now, I want to query comments liked by userID 1
$args = array(
'status' => 'approve',
'post_status' => 'publish',
'meta_query' => array(
array(
'key' => 'liked_by',
'value' => array(1),
'compare' => 'IN',
'type' => 'numeric'
)
)
);
// The Query
$comments_query = new WP_Comment_Query;
$comments = $comments_query->query( $args );
And I get no comments in return, why is that?
Here is the query generated:
SELECT * FROM wp_comments JOIN wp_posts ON wp_posts.ID = wp_comments.comment_post_ID INNER JOIN wp_commentmeta ON ( wp_comments.comment_ID = wp_commentmeta.comment_id ) WHERE ( comment_approved = '1' ) AND wp_posts.post_status = 'publish' AND (
( wp_commentmeta.meta_key = 'liked_by' AND CAST(wp_commentmeta.meta_value AS SIGNED) IN ('1') )
) GROUP BY wp_comments.comment_ID ORDER BY comment_date_gmt DESC
I wanted to do this over serialized data even though I cited an URL that said
don't store array of ids in one row instead loop through ids array and
normalize your likes data manually Don't serialize data into a
database field.
This is because I used ACF and added an Users field, which used serialized data. I solved my problem by avoiding ACF and just using the comment meta API.
// UserID 1 likes commentID 9
add_comment_meta(9, 'like', 1, false);
// Get comments liked by userID 1
$args = array(
'status' => 'approve',
'post_status' => 'publish',
'meta_query' => array(
array(
'key' => 'like',
'value' => 1,
'compare' => '=',
'type' => 'numeric'
)
)
);
// The Query
$comments_query = new WP_Comment_Query;
$comments = $comments_query->query( $args );
// Surprise, it's commentID 9
Notice how I use add_comment_meta with unique=false for every like instead of serializing an array into the database, making it unavailable for queries.

filter custom post type archive page using meta_query with multiple arrays using acf relationship field

As the title suggests I'm trying to filter a custom post type archive page using meta_query with multiple arrays using an acf relationship field.
This is what I have so far using the documentation and tutorials at acf. Both the keywords filter and the project_ref filter work independently if I use 'relation' => 'AND' but only keywords works using 'OR' and never together. Also, project_ref is a post id.
// functions.php
$meta_query = $query->get('meta_query');
// allow the url to alter the query
if( !empty($_GET['keywords']) OR !empty($_GET['project_ref']) )
{
$keywords = explode(',', $_GET['keywords']);
$projects = $_GET['project_ref'];
// Add our meta query to the original meta queries
$meta_query[] = array(
'relation' => 'OR',
array(
'key' => 'keywords',
'value' => $keywords,
'compare' => 'LIKE'
),
array(
'key' => 'project_ref',
'value' => $projects,
'compare' => 'LIKE'
)
);
}
So if my url is website.com/customposttype/?keywords=one,two&project_ref=684 the posts filter by the keywords but not the project_ref post id. I also get an error Warning: trim() expects parameter 1 to be string, array given in .../wp-includes/meta.php on line 1400.
Any help would be greatly appreciated. I feel like I'm close but I definitely seem to be missing something.
Thanks in advance.
It looks like you could be using the wrong compare value for your keywords portion of the query.
As per the WP_Query codex entry:
value (string|array) - Custom field value. It can be an array only
when compare is 'IN', 'NOT IN', 'BETWEEN', or 'NOT BETWEEN'. You don't
have to specify a value when using the 'EXISTS' or 'NOT EXISTS'
comparisons in WordPress 3.9 and up.
As your error is indicating you're passing an array. In SQL when you want to check for the existance of a number of required values you would use the IN compare option.
So your code would be:
// functions.php
$meta_query = $query->get('meta_query');
// allow the url to alter the query
if( !empty($_GET['keywords']) OR !empty($_GET['project_ref']) )
{
$keywords = explode(',', $_GET['keywords']);
$projects = $_GET['project_ref'];
// Add our meta query to the original meta queries
$meta_query[] = array(
'relation' => 'OR',
array(
'key' => 'keywords',
'value' => $keywords,
'compare' => 'IN'
),
array(
'key' => 'project_ref',
'value' => $projects,
'compare' => 'LIKE'
)
);
}

Wordpress Query by Custom Field with date type

I want to create a query where all posts should be displayed where the custom field "expiration_date' is larger than the date from today.
Short form: if the expiration date of the post is reached, it should no longer displayed in the query
I tried with this snippet:
<?php
$today = date("Y-m-d");
$args= array(
'tag' => 'Pinnwand',
'meta_query' => array(
'key' => 'expiration_date',
'type' => 'DATE',
'value' => $today,
'compare' => '>'
)
);
$my_query = new WP_Query($args); ?>
the expiration date is in the format (2014-10-04) for example.
But I tried also the format "Ymd" on both sides, change the compare type, or set the type as "NUMERIC" and nothing helps. The result is, that the post will always be displayed.
It would be great if somebody could help me!
Okay I found the mistake!
The correct query needs one more array(). I don't know exactly why, but in other cases the query couldn't work with it. So here is the code
$args= array(
'tag' => 'Pinnwand',
'meta_query' => array(
array(
'key' => 'expiration',
'type' => 'DATE',
'value' => $today,
'compare' => '>'
),
),
);
$my_query = new WP_Query($args); ?>
You could do a two-query exclusion. First query finds all the posts you want to exclude, then loop through those and store the post IDs in an array, then call second query excluding them using 'post__not_in' with the ID array as the argument.
I would use the $wpdb object for this because it's very efficient.
For reference material:
http://codex.wordpress.org/Class_Reference/WP_Query and
http://codex.wordpress.org/Class_Reference/wpdb
This chunk of code SHOULD do what you're trying to do or get you close to it, and I kept your tag part of the query in there too.
// first query to find exclusions
$today = date("Y-m-d");
$exclusions = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE expiration_date < ".$today);
if ( $exclusions ) {
foreach ( $exclusions as $exclusion ) {
$excludeIDs[] = $exclusion->ID;
}
}
// second query using exclusion array
$args= array(
'tag' => 'Pinnwand',
'post__not_in' => $excludeIDs,
);
$my_query = new WP_Query($args);
You can do it simpler, as stated on http://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters:
$args= array(
'tag' => 'Pinnwand',
'meta_key' => 'expiration',
'meta_type' => 'DATE',
'meta_value' => $today,
'meta_compare' => '>'
);

Categories