Use placeholders and $wpdb->prepare(); found interpolated variable $now - wordpress

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?

Related

Get ACF repeater field values from all posts, sorted by a sub-field

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'];
}

How to use global $wpdb query to run SQL query and echoing the result

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

Remove author id from query

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

Wordpress Query Get all values for a key when match a value for another key

The following query can get all values for a custom field key. collected from: http://goo.gl/94qw3
function get_meta_values( $key = '', $type = 'post', $status = 'publish' ) {
global $wpdb;
if( empty( $key ) )
return;
$r = $wpdb->get_col( $wpdb->prepare( "
SELECT pm.meta_value FROM {$wpdb->postmeta} pm
LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
WHERE pm.meta_key = '%s'
AND p.post_status = '%s'
AND p.post_type = '%s'
", $key, $status, $type ) );
return $r;
}
$my_var = get_meta_values( 'YOURKEY' );
I want to get all values for a key of "custom field B"
when match a value '2010' for a key of "custom field A".
Example:
I have 2 keys (2 costom Fields)
-------------------------
Movie Yr | Artist
---------------------------
2000 | Artist One
2008 | Artist Two
2012 | Artist Three
| Artist Four
| Artist Five
---------------------------
With the above query I can get the following list.
---------
Movie Yr
---------
2000
2008
2012
---------
Now after I select value '2010' of the field "Movie Yr", I want to get a list of Artists. Not all artists but only those who are related with '2010'. Something like
---------
Artist
---------
Artist Two
Artist Four
Artist Five
---------
if i get you right here, insted of taking all the values you want to add another filter.
am i right?
if so - all you need is edit the SQL you get and add the filter you want.
this is your sql now:
SELECT pm.meta_value FROM {$wpdb->postmeta} pm LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id WHERE pm.meta_key = '%s' AND p.post_status = '%s' AND p.post_type = '%s'
the %s is taking it's content from the variables that comes after:
$key, $status, $type
in that order.
in your case all you need to do is add the extra to the SQL query.
i would be happy to help you if you could just say what you want to do... your explanation is quite a mess.

Wordpress Custom Query String

I have a meta field called date & I need to query all records where that timestamp is equal to or less than today...
<?php
$time = time();
$querystr = "
SELECT wposts.*
FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta
WHERE wpostmeta.meta_key = 'date'
AND wpostmeta.meta_value <= $time
";
$pageposts = $wpdb->get_results($querystr, OBJECT);
?>
You could try something like this :
$today = date('Y-m-d');
$querystr = "
SELECT *
FROM wp_posts, wp_postmeta
WHERE wp_posts.ID = wp_postmeta.post_id
AND wp_postmeta.meta_key = 'date'
AND wp_posts.post_status = 'publish'
AND wp_posts.post_type = 'post'
AND STR_TO_DATE(wp_postmeta.meta_value, '%Y/%m/%d') <= '$today'
ORDER BY STR_TO_DATE(wp_postmeta.meta_value, '%Y/%m/%d') ASC
";
$custom_loop = $wpdb->get_results($querystr, OBJECT);
In the last two lines of the que query, you have to specify the format of your date (in your custom field "date"). For example if your custom "date" field has a dd/mm/YYYY format you would use :
AND STR_TO_DATE(wp_postmeta.meta_value, '%d/%m/%Y') <= '$today'
ORDER BY STR_TO_DATE(wp_postmeta.meta_value, '%d/%m/%Y') ASC
The $today date has to be Y-m-d because it's the default time format, used for the comparison by mysql.

Resources