I have posts where the author is assigned as Co-Author. If i want to show them on my author page, they are not listed. Because of this condition in the query:
AND (wp_posts.post_author = 53)
How can i remove it? Or is there any better solution?
public static function pre_get_posts($query)
{
if ($query->is_author() && $query->is_main_query()):
$author = (get_query_var('author_name')) ? get_user_by('slug', get_query_var('author_name')) : get_userdata(get_query_var('author'));
$authorPostIDs = self::getAuthorsPostIDs($author->ID);
$coAuthorPostIDs = self::getCoAuthorsPostsIDs($author->ID);
$postIDs = array_unique(
array_merge($coAuthorPostIDs, $authorPostIDs), SORT_REGULAR
);
$query->set('post__in', $postIDs);
$query->set('post_status', 'publish');
endif;
}
My full query:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts
WHERE 1=1
AND wp_posts.ID IN (349956,327745)
AND (wp_posts.post_author = 53)
AND wp_posts.post_type = 'post'
AND ((wp_posts.post_status = 'publish'))
ORDER BY wp_posts.post_date DESC
LIMIT 0, 10
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 have an ACF repeater field (publications) with 2 sub-fields.
title and year.
I need to select from the database all titles from all posts matching a condition (let’s say all titles which include ‘search-term’) but I need the result sorted by the year (the 2nd sub-field).
This is the query I use to fetch the titles.
function get_search_results(): array
{
global $wpdb;
$sql = "SELECT pm.meta_value title, pm.post_id post
FROM {$wpdb->posts} p
JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
WHERE p.post_status = 'publish'
AND pm.meta_key LIKE 'publication_%_title'
AND pm.meta_value LIKE '%search-term%';";
return $wpdb->get_results($sql, ARRAY_A);
}
How can I sort the results by the year?
This is the solution I came up with.
Only 2 SQL queries.
function get_search_results(): array
{
global $wpdb;
// Get publication titles.
$sql = "SELECT pm.meta_key, pm.meta_value title, pm.post_id researcher
FROM {$wpdb->posts} p
JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
WHERE p.post_status = 'publish'
AND pm.meta_key LIKE 'publication_%_title'
AND pm.meta_value LIKE '%search-term%';";
$titles = $wpdb->get_results($sql, ARRAY_A);
// Get list of post IDs.
$researcher_ids = implode(', ', array_unique(array_column($titles, 'researcher')));
// Get publication years.
$sql = "SELECT REPLACE(pm.meta_key,'_year','_title') AS meta_key, pm.meta_value year, pm.post_id researcher
FROM {$wpdb->posts} p
JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
WHERE p.post_status = 'publish'
AND pm.meta_key LIKE 'publication_list_%_year'
AND pm.post_id IN ($researcher_ids);";
$years_raw = $wpdb->get_results($sql, ARRAY_A);
$years = [];
// Reformat the publication years.
foreach ($years_raw as $year) {
$years[$year['researcher'] . '__' . $year['meta_key']] = $year['year'];
}
// Add the year field to each title.
foreach ($titles as &$title) {
$title['year'] = $years[$title['researcher'] . '__' . $title['meta_key']];
}
// Sort the array by the inner year value.
usort($titles, 'sortByInnerYear');
return $titles;
}
function sortByInnerYear($a, $b): int
{
return $b['year'] <=> $a['year'];
}
I am trying to count the total events using the following SQL query. I am using global $wpdb to echo the results and to store them into a variable.
global $wpdb;
$current_d_t = strtotime(date("y-m-d"));
$sql = "SELECT COUNT(post.ID) as eventCountUpcoming FROM wp_posts AS post LEFT JOIN wp_postmeta AS meta ON post.ID = meta.post_id WHERE post.post_type = 'ajde_events' AND meta.meta_key = 'evcal_erow' AND meta.meta_value > $current_d_t AND post.post_status = 'publish' GROUP BY post.ID";
$result = $wpdb->get_results($sql, ARRAY_A);
$result_more = $result->fetch_assoc();
$countEvent = $result_more['eventCountUpcoming'];
getting this error
Call to a member function fetch_assoc() on an array
Tried for each loop too, using the following code,
foreach ($result as $result_more){
$countEvent = $result_more['eventCountUpcoming'];
}
but getting this error:
$result = $wpdb->get_results($sql, ARRAY_A); returns an array of results.
In order to echo the results, try looping the array:
$result = $wpdb->get_results($sql, ARRAY_A);
foreach ($result as $res){
var_dump($result);
}
If you're just looking for one variable as the result. You can try using $wpdb->get_var()
global $wpdb;
$current_d_t = strtotime(date("y-m-d"));
$sql = "SELECT COUNT(post.ID) as eventCountUpcoming
FROM {$wpdb->posts} AS post LEFT JOIN {$wpdb->postmeta} AS meta
ON post.ID = meta.post_id
WHERE post.post_type = 'ajde_events'
AND meta.meta_key = 'evcal_erow'
AND meta.meta_value
> {$current_d_t}
AND post.post_status = 'publish';"
$result = $wpdb->get_var($sql);
Then $result should be your count.
Groupby shouldn't be necessary if you're just counting Post ID's
I have a problem with placeholders in $wpdb->get_results. With the code below I have all the results correctly but I have an error when I use the code sniffer
$now = current_time('mysql', true);
$allPosts = $wpdb->get_results("
SELECT DISTINCT
YEAR(post_date_gmt) AS `year`,
MONTH(post_date_gmt) AS `month`,
MAX(post_date_gmt) AS last_mod,
count(ID) AS posts
FROM
$wpdb->posts
WHERE
post_date_gmt < '$now'
AND post_status = 'publish'
AND post_type = 'post'
GROUP BY
YEAR(post_date_gmt),
MONTH(post_date_gmt)
ORDER BY
post_date_gmt DESC
");
I tried to change with %s and $now in the end but no results are shown
$allPosts = $wpdb->get_results("
SELECT DISTINCT
YEAR(post_date_gmt) AS `year`,
MONTH(post_date_gmt) AS `month`,
MAX(post_date_gmt) AS last_mod,
count(ID) AS posts
FROM
$wpdb->posts
WHERE
post_date_gmt < %s
AND post_status = 'publish'
AND post_type = 'post'
GROUP BY
YEAR(post_date_gmt),
MONTH(post_date_gmt)
ORDER BY
post_date_gmt DESC
", $now);
I know I can resolve it by omitted post_date_gmt < %s but I'd like to know how I can resolve it with post_date_gmt < %s?
I'm hoping somebody can help me, I've got a woocommerce install that 504 errors when adding a product with six attributes to the cart. There is one 'catchall' variation set up for the product. I have disabled all plugins and reverted to the storefront theme and still experience the same issue, it appears to be directly related to a very slow SQL query that is being run.
The query appears to be selecting the post ID where the meta values for the attribute match the selected attributes which in this case is suboptimal as there are 70k entries in the post_meta table and hundreds in the post table. This query does not complete in a reasonable timeframe and is called more than once so kills off the SQL server. Personally I was able to rewrite the query to be much faster in mysql workbench but I can't figure out where it's being generated. The query is as follows:
SELECT wp_posts.ID FROM wp_posts LEFT JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) LEFT JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id AND mt1.meta_key = 'attribute_pa_workbee-size-drive' ) LEFT JOIN wp_postmeta AS mt2 ON ( wp_posts.ID = mt2.post_id ) LEFT JOIN wp_postmeta AS mt3 ON (wp_posts.ID = mt3.post_id AND mt3.meta_key = 'attribute_pa_extrusion-colour' ) LEFT JOIN wp_postmeta AS mt4 ON ( wp_posts.ID = mt4.post_id ) LEFT JOIN wp_postmeta AS mt5 ON (wp_posts.ID = mt5.post_id AND mt5.meta_key = 'attribute_pa_router' ) LEFT JOIN wp_postmeta AS mt6 ON ( wp_posts.ID = mt6.post_id ) LEFT JOIN wp_postmeta AS mt7 ON (wp_posts.ID = mt7.post_id AND mt7.meta_key = 'attribute_pa_dust-shoe' ) LEFT JOIN wp_postmeta AS mt8 ON ( wp_posts.ID = mt8.post_id ) LEFT JOIN wp_postmeta AS mt9 ON (wp_posts.ID = mt9.post_id AND mt9.meta_key = 'attribute_pa_cam-software' ) LEFT JOIN wp_postmeta AS mt10 ON ( wp_posts.ID = mt10.post_id ) LEFT JOIN wp_postmeta AS mt11 ON (wp_posts.ID = mt11.post_id AND mt11.meta_key = 'attribute_pa_connectivity' ) WHERE 1=1 AND wp_posts.post_parent = 2603 AND (
(
( wp_postmeta.meta_key = 'attribute_pa_workbee-size-drive' AND wp_postmeta.meta_value IN ('','') )
OR
mt1.post_id IS NULL
)
AND
(
( mt2.meta_key = 'attribute_pa_extrusion-colour' AND mt2.meta_value IN ('','') )
OR
mt3.post_id IS NULL
)
AND
(
( mt4.meta_key = 'attribute_pa_router' AND mt4.meta_value IN ('','') )
OR
mt5.post_id IS NULL
)
AND
(
( mt6.meta_key = 'attribute_pa_dust-shoe' AND mt6.meta_value IN ('','') )
OR
mt7.post_id IS NULL
)
AND
(
( mt8.meta_key = 'attribute_pa_cam-software' AND mt8.meta_value IN ('','') )
OR
mt9.post_id IS NULL
)
AND
(
( mt10.meta_key = 'attribute_pa_connectivity' AND mt10.meta_value IN ('','') )
OR
mt11.post_id IS NULL
)
) AND wp_posts.post_type = 'product_variation' AND ((wp_posts.post_status = 'publish')) GROUP BY wp_posts.ID ORDER BY wp_posts.menu_order ASC LIMIT 0, 1