I'm struggling with a wp_query and i need your help.
I have 3 custom fields called "Agenda_day", "Agenda_month", "Agenda_year", representing the day, month and year of an event.
I want to order the results of my query by day, then month, and finally year, ascendingly.
Here is my query :
$query_agenda = new WP_Query(
array(
'posts_per_page' => 8,
'cat' => 4,
'meta_query' =>
array(
'relation' => 'AND',
'day' => array('key' => 'Agenda_day', 'compare' => 'EXISTS'),
'month' => array('key' => 'Agenda_month', 'compare' => 'EXISTS'),
'year' => array('key' => 'Agenda_year', 'compare' => 'EXISTS')
),
'orderby' => array('day' => 'ASC', 'month' => 'ASC', 'year' => 'ASC')
)
);
And this does not work ... can you explain me why and show me how to fix it ?
Thank you !
EDIT
Here is the executed query (results are returned but not well ordered)
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) INNER JOIN wp_postmeta AS mt1 ON ( wp_posts.ID = mt1.post_id ) INNER JOIN wp_postmeta AS mt2 ON ( wp_posts.ID = mt2.post_id ) WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (4) ) AND ( wp_postmeta.meta_key = 'Agenda_jour' AND mt1.meta_key = 'Agenda_mois' AND mt2.meta_key = 'Agenda_annee' ) AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY CAST(wp_postmeta.meta_value AS CHAR) ASC, CAST(mt1.meta_value AS CHAR) ASC, CAST(mt2.meta_value AS CHAR) ASC LIMIT 0, 8
https://codex.wordpress.org/Class_Reference/WP_Query
https://codex.wordpress.org/Class_Reference/WP_Meta_Query
please check above both links you will get your answer and your orderby arguments which you are passing it's wrong
Problem solved !
i was dealing with different formats in the custom fields : some days and months were on 1 character ("6") and others on two ("06"), so the system couldn't sort it well
second point is, as i'm dealing with dates, i have to reorder the "orderby" instruction from "day, month, year" to "year, month, day"
Related
I am trying to fetch another table column by WP_Query but it does not work.
Note: I can easily do this by $wpdb->get_results( 'custom_sql' ) but I want to do it by WP_Query
My code
function join_my_query( $join, $wp_query ) {
global $wpdb;
if ( $wp_query->get( 'custom_logic' ) === true ) {
$join .= " LEFT JOIN $wpdb->postmeta as pm ON $wpdb->posts.ID = pm.post_id ";
}
return $join;
}
add_filter( 'posts_join', 'join_my_query', 10, 2 );
$query = new WP_Query(
array(
'custom_logic' => true,
'post_type' => 'post',
)
);
It's giving me SQL like below, which does not select any column from the joined table!
Generated SQL
SELECT
SQL_CALC_FOUND_ROWS wp_posts.ID
FROM
wp_posts
LEFT JOIN wp_postmeta as pm ON wp_posts.ID = pm.post_id
WHERE
1 = 1
AND (
(
wp_posts.post_type = 'post'
AND (
wp_posts.post_status = 'publish'
OR wp_posts.post_status = 'future'
OR wp_posts.post_status = 'draft'
OR wp_posts.post_status = 'pending'
)
)
)
ORDER BY
wp_posts.post_date DESC
LIMIT
0, 10
It does not select any column from my joined table. I have use var_dump($query->posts[0]) which return a WP_Post object and it has no column from my joined table. How I can get columns from my joined table with WP_Query like below
My Goal
$post = $query->posts[0];
$post->meta_key; // from my joined table, not work
$post->pm->meta_key; // pm is alias used in join, still not work
According to your expected result, the posts_join filter is not required. You can do this with the posts_clauses filter easily!
add_filter( 'posts_clauses', 'modify_post_clauses_callback' , 10, 2 );
function modify_post_clauses_callback( $clauses, $wp_query ) {
if ( $wp_query->get( 'custom_logic' ) === true ) {
global $wpdb;
$clauses['fields'] = $clauses['fields'] . ', pm.meta_key';
$clauses['join'] = "LEFT JOIN {$wpdb->postmeta} as pm ON {$wpdb->posts}.ID = pm.post_id";
}
return $clauses;
}
$query = new WP_Query(
array(
'custom_logic' => true,
'post_type' => 'post',
)
);
$post = $query->posts[0];
$post->meta_key;
I'm using 's' parameter to generate Wp_query to search a particular string into content.
My problem is when this string have a white space.
My $args conf:
$argsPaged = array(
// Get the "resources_network" post type.
'post_type' => 'resources_network',
'posts_per_page' => $per_page,
'paged' => $start,
'post_status' => 'publish',
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'rnet_category',
'field' => 'term_id',
'terms' => array( $categoryid )
)
),
's' => esc_attr($texttosearch)
);
$wpq = new WP_Query( $argsPaged );
For example, when $texttosearch = "E-LEARNING 6" , query result is:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (72) ) AND (((wp_posts.post_title LIKE '%E-LEARNING%') OR (wp_posts.post_excerpt LIKE '%E-LEARNING%') OR (wp_posts.post_content LIKE '%E-LEARNING%')) AND ((wp_posts.post_title LIKE '%6%') OR (wp_posts.post_excerpt LIKE '%6%') OR (wp_posts.post_content LIKE '%6%'))) AND wp_posts.post_type = 'resources_network' AND ((wp_posts.post_status = 'publish')) GROUP BY wp_posts.ID ORDER BY (CASE WHEN wp_posts.post_title LIKE '%E-LEARNING 6%' THEN 1 WHEN wp_posts.post_title LIKE '%E-LEARNING%' AND wp_posts.post_title LIKE '%6%' THEN 2 WHEN wp_posts.post_title LIKE '%E-LEARNING%' OR wp_posts.post_title LIKE '%6%' THEN 3 WHEN wp_posts.post_excerpt LIKE '%E-LEARNING 6%' THEN 4 WHEN wp_posts.post_content LIKE '%E-LEARNING 6%' THEN 5 ELSE 6 END), wp_posts.post_date DESC LIMIT 0, 3
I replaced genered strings like this "{5a92e13925a303d097056a5017e22dfb76290b661a9b5cf9d34f0c78e887b4d4}" for "%" .
Problem is it separate "E-LEARNING" from "6" when it search into title and i don't know why.
Some configuration parameters to fix this? I can't find solution anywhere
Thank you
I'm using ACF pro and need to query posts that have some special ACF fields certain value.
But also I need to get posts that have ANY year, but the date should be between today and + 30 days from today. I cannot use static month number because then if post is made in day 1 it would not find it enough in advance.
Here is my initial query that is not working. It works if only get certain year and month, but that only gets posts from that date.
//$date_month_advance_month = ... month number of today + 30 days
//$date_month_advance_day= ... day number of today + 30 days
// args
$args = array(
'post_type' => 'my_post_type',
'posts_per_page'=> -1,
'meta_key' => 'status',
'meta_value' => 'accepted',
'date_query' => array(
'compare' => 'BETWEEN',
array(
'month' => $date_today_month,
'day' => $date_today_day,
),
array(
'month' => $date_month_advance_month,
'day' => $date_month_advance_day,
),
),
);
You could create a custom query. I made one quickly, tested for the date but not the custom field status as i don't have it. Replace my_post_type with your post type name.
global $wpdb;
$query = "
SELECT * FROM {$wpdb->posts} as p
LEFT JOIN {$wpdb->postmeta} as pm
ON pm.post_id = p.ID
WHERE p.post_type = 'my_post_type'
AND pm.meta_key = 'status'
AND pm.meta_value = 'accepted'
AND REPLACE(SUBSTRING(p.post_date, 6, 10), '-', '') BETWEEN %s AND %s
GROUP BY p.ID
";
// Should replace 0301 and 0331 by variables (date('mO1') and date('m31') for example), I let you handle this.
$prepared_query = $wpdb->prepare($query, array('0301', '0331'));
$result = $wpdb->get_results($prepared_query);
foreach($result as $r) {
$cs_post = get_post($r->ID);
echo '<p>';
echo get_the_title($cs_post->ID) .'<br>';
echo get_the_date('Y-m-d', $cs_post->ID) .'<br>';
echo '</p>';
}
Not sure if it's the proper way but it works.
How can I combine the result of the tax_query and meta_query?
ex:
tax_query results to:
Post1, Post2.
and meta_query results to:
Post3.
I want to combine the results of the 2 queries.
Here is my partial code:
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'tax1',
'field' => 'term_id',
'terms' => array(1,2,3),
),
array(
'taxonomy' => 'tax2',
'field' => 'term_id',
'terms' => array(1,2,3),
),
),
'meta_query' => array(
array(
'key' => 'meta1',
'value' => '1',
'compare' => '=',
),
),
The same question was asked here but wasn't answered. So I'm re-opening it.
Thanks!
It sounds like you are wanting it to act like an 'OR' where a post that matches either the tax_query or meta_query is returned.
Unfortunately, that's not possible using WP_Query.
You'll either need to write a custom database call, or just query them separately and do your checking on the PHP end (that's ok if you know you'll have a relatively small number of results, but be warned this won't necessarily scale to a huge site).
The only way to achieve a query like that is creating a custom query to the db using the $wpdb global and SQL statements. I think it would be something like this:
global $wpdb;
$querystr =
"
SELECT * FROM $wpdb->posts
LEFT JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)
LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy as term_taxonomy1 ON($wpdb->term_relationships.term_taxonomy_id = term_taxonomy1.term_taxonomy_id)
LEFT JOIN $wpdb->term_taxonomy as term_taxonomy2 ON($wpdb->term_relationships.term_taxonomy_id = term_taxonomy2.term_taxonomy_id)
LEFT JOIN $wpdb->terms as tax1_term1 ON(term_taxonomy1.term_id = tax1_term1.term_id)
LEFT JOIN $wpdb->terms as tax1_term2 ON(term_taxonomy1.term_id = tax1_term2.term_id)
LEFT JOIN $wpdb->terms as tax1_term3 ON(term_taxonomy1.term_id = tax1_term3.term_id)
LEFT JOIN $wpdb->terms as tax2_term1 ON(term_taxonomy2.term_id = tax2_term1.term_id)
LEFT JOIN $wpdb->terms as tax2_term2 ON(term_taxonomy2.term_id = tax2_term2.term_id)
LEFT JOIN $wpdb->terms as tax2_term3 ON(term_taxonomy2.term_id = tax2_term3.term_id)
WHERE
(
(
(term_taxonomy1.taxonomy = 'tax1')
AND
(tax1_term1.term_id = 1 AND tax1_term2.term_id = 2 AND tax1_term3.term_id = 3)
)
OR
(
(term_taxonomy2.taxonomy = 'tax2')
AND
(tax2_term1.term_id = 1 AND tax2_term2.term_id = 2 AND tax2_term3.term_id = 3)
)
)
OR
(
$wpdb->postmeta.meta_key = 'meta1' AND $wpdb->postmeta.meta_value = '1'
)
ORDER BY $wpdb->postmeta.meta_value ASC
"
$pageposts = $wpdb->get_results($querystr, OBJECT);
Then you could iterate over $pageposts as with a WP_Query loop.
I need to get posts by custom category id, sort by custom field value and with another custom field if this field exists. I think I need to use custom selection query. Look at my query: The problem is that this query returns the same post 5 times... In admin panel I made 20 posts per page. Maybe someone have their own solution ? Thanks.
$wp_query->request = "SELECT * FROM $wpdb->posts
LEFT JOIN $wpdb->postmeta ON($wpdb->posts.ID = $wpdb->postmeta.post_id)
LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
LEFT JOIN $wpdb->terms ON($wpdb->terms.term_id = $wpdb->term_taxonomy.term_id)
WHERE $wpdb->terms.slug = 'categoryname'
AND $wpdb->term_taxonomy.taxonomy = 'category'
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_type = 'post'
ORDER BY $wpdb->posts.post_date DESC";
$pageposts = $wpdb->get_results($wp_query->request, OBJECT);
$customSelect = new WP_Query(array(
'post_type' => 'post',
'posts_per_page' => 10,
'taxonomy' => 'category',
'order' => 'DESC',
'meta_key' => 'your custom field',
'orderby' => 'meta_value'
This is probably way off what your trying to achieve, the only bit I can't get my head round is how to test if meta key exists using a variable or something.
Anyways good luck
Why you use "$wp_query->request", this variable is for retrieving last query result, not to set new one...
just try
$my_custom_sql = "SELECT * FROM $wpdb->posts
LEFT JOIN $wpdb->postmeta ON($wpdb->posts.ID = $wpdb->postmeta.post_id)
LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
LEFT JOIN $wpdb->terms ON($wpdb->terms.term_id = $wpdb->term_taxonomy.term_id)
WHERE $wpdb->terms.slug = 'categoryname'
AND $wpdb->term_taxonomy.taxonomy = 'category'
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_type = 'post'
ORDER BY $wpdb->posts.post_date DESC";
$pageposts = $wpdb->get_results($my_custom_sql, OBJECT);
Try this-
get_results(
"
SELECT * FROM $wpdb->posts
LEFT JOIN $wpdb->term_relationships ON
($wpdb->posts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON
($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
WHERE $wpdb->posts.post_status = 'publish'
AND $wpdb->term_taxonomy.taxonomy = 'category'
AND $wpdb->term_taxonomy.term_id = 3
ORDER BY post_date ASC
"
); ?>