I am trying to get ordering working in wp_query, but posts are still being ordered with default settings (just tag__in is working). SQL query for posts looks like this:
string(379) "SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (81) ) 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 wp_posts.post_date DESC LIMIT 0, 3"
Here is code snippet:
remove_all_filters('posts_orderby');
$tag = get_term_by('name', 'title_post', 'post_tag');
$args=array(
'order'=>'ID',
'orderby'=>'ASC',
'tag__in' => $tag,
'posts_per_page'=>3, // Number of related posts to display.
'caller_get_posts'=>1
);
$my_query = new wp_query( $args );
var_dump($my_query->request);
Thanks!
I have checked your code you have to pass wrong arguments.
Can you please check below code?
Wrong
'order'=>'ID',
'orderby'=>'ASC',
Right
'order'=>'ASC',
'orderby'=>'ID',
Ok, I switched order and orderby ...
So, correct arguments are 'orderby'=>'ID','order'=>'ASC',
Related
I have 2 SQL queries as below:
$results2 = $wpdb->get_results("SELECT * FROM `wp_posts` WHERE id IN (".implode(",", $product_ids).")");
$getprice = $wpdb->get_results("SELECT * FROM `wp_postmeta` WHERE meta_key='_regular_price' AND post_id IN (".implode(",", $product_ids).")");
I have combined them as below query:
$yeni = $wpdb->get_results("SELECT wp_posts.id, wp_posts.post_title, wp_postmeta.meta_value
FROM wp_posts
INNER JOIN wp_postmeta ON wp_posts.id = wp_postmeta.post_id
WHERE meta_key = '_regular_price'
WHERE wp_posts.id IN (".implode(",", $product_ids).")");
After combining the queries, it's giving an empty result. I can't find the issue with the updated query.
Try this sql.
I have replace this WHERE meta_key = '_regular_price'
$yeni = $wpdb->get_results("SELECT wp_posts.id, wp_posts.post_title, wp_postmeta.meta_value FROM wp_posts INNER JOIN wp_postmeta ON wp_posts.id = wp_postmeta.post_id WHERE wp_posts.id IN (".implode(",", $product_ids).") and wp_postmeta.meta_key = '_regular_price'");
I don't understand why you don't use the native Wordpress features via OOP procedure.
Your simple query, it can be translated like this:
<?php
$loop = new WP_Query(
array(
'post_type' => 'page', // post type: page, post, attachment etc..
'post__in' => $productIds, // array[]
)
);
// after that, you can use a standard wordpress loop
if($loop->have_posts()) {
while($loop->have_posts()) {
: $loop->the_post();
the_title();
print "<br>";
// access to meta key _regular_price
print get_post_meta(get_the_ID(), '_regular_price', true);
}
}
This is the right way.
Cheers
Class reference here: https://developer.wordpress.org/reference/classes/wp_query/
I've been searching through the past two days to find out where exactly could the Woocommerce products thumbnails (images) texts and URL's are stored inside the database tables, but still cannot figure this out!
I'm in a situation where I must use SQL queries to move the products data into another tables, and I have to implement the process from my phpmyadmin panel.
I already searched the wp_posts and wp_postmeta tables, wp_posts contains a guide column for the url to the product which post_type like 'product%', So far I know that in general the post stores it's thumbnalis link inside one of the posts with a type of attachment , while I need the posts with a post_type of product or like so.
Hope I can find some answers here, Thanks.
You can use the Wordpress WP_Query to get the thumbnail image of product.
$args = array(
'post_type' => 'product', //post type of product
'posts_per_page' => -1
);
$query= new WP_Query( $args );
while ( $query->have_posts() ) : $query->the_post();
global $product;
//woocommerce_get_product_thumbnail is use to get the product thumbnail link
echo '<br />' . woocommerce_get_product_thumbnail().' '.get_the_title().'';
endwhile;
wp_reset_query();
Solution 2- using the custom query as you mention in query.
//Using custom query get the details from wp_postmeta and wp_posts
//_wp_attached_file - meta key for image
$querystr = "SELECT p.*, pm2.meta_value as product_image FROM wp_posts p LEFT JOIN
wp_postmeta pm ON (
pm.post_id = p.id
AND pm.meta_value IS NOT NULL
AND pm.meta_key = '_thumbnail_id'
)
LEFT JOIN wp_postmeta pm2 ON (pm.meta_value = pm2.post_id AND pm2.meta_key = '_wp_attached_file'
AND pm2.meta_value IS NOT NULL) WHERE p.post_status='publish' AND p.post_type='product'
ORDER BY p.post_date DESC";
$upload_dir = wp_upload_dir();
//get wp_upload url
$wp_upload_url = $upload_dir['baseurl'];
$pageposts = $wpdb->get_results($querystr, OBJECT);
foreach ($pageposts as $post){
echo "<br /><a href='".$post->guid."'><img src='". $wp_upload_url.'/'.$post->product_image."'>".$post->post_title."</a>";
}
I need to run this query every time my client uploads a product, so how do I run this query within Wordpress? I want to tie it to an action in the functions.php
UPDATE wp_postmeta
JOIN wp_posts ON wp_posts.id = wp_postmeta.post_id
SET wp_postmeta.meta_value = 'no'
WHERE (wp_posts.post_title = '4x6' AND wp_postmeta.meta_key = '_virtual')
Add this code in your functions.php:
function on_product_publish( $new_status, $old_status, $post ) {
global $post;
if ( 'publish' !== $new_status or 'publish' === $old_status ) return;
$wpdb->query("UPDATE wp_postmeta
JOIN wp_posts ON wp_posts.id = wp_postmeta.post_id
SET wp_postmeta.meta_value = 'no'
WHERE (wp_posts.post_title = '4x6' AND wp_postmeta.meta_key = '_virtual')");
}
add_action( 'transition_post_status', 'on_product_publish', 10, 3 );
First of all I am working on a theme created by another developer and I am having a few problems understanding at all how theme works or what dev did. So, I am need to increment search display results from 10 to 25. Using a DEBUG plugin I am able to see the query being executed from WP:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts
WHERE 1=1
AND (((wp_posts.post_title LIKE '%noticias%')
OR (wp_posts.post_content LIKE '%noticias%')))
AND wp_posts.post_type IN ('post', 'page', 'attachment', 'esp-publicitarios', 'opinion', 'especiales', 'portadadeldia', 'clasificados', 'anunciantes', 'logos')
AND (wp_posts.post_status = 'publish'
OR wp_posts.post_author = 4
AND wp_posts.post_status = 'private')
ORDER BY wp_posts.post_date DESC
LIMIT 0, 10
What I want to change is the LIMIT from 10 to 25 so I tried to add this at functions.php file at the end:
function change_wp_search_size($query)
{
if ($query->is_search)
$query->query_vars['posts_per_page'] = 25; // Change 25 to the number of posts you would like to show
return $query; // Return our modified query variables
}
add_filter('pre_get_posts', 'change_wp_search_size'); // Hook our custom function onto the request filter
But didn't work since I still getting 10 results. I have tried also set posts_per_page in search.php file as follow:
// Just below get_header() call
$wp_query->set('posts_per_page', 25);
And again, same result just 10 items for display. It's possible to extends|increment the max amount of items shown in search query results? any clue or advice?
I don't know the answer to your problem, but the query as it stands seems a bit illogical to me.
Something like this seems more plausible...
SELECT SQL_CALC_FOUND_ROWS p.ID
FROM wp_posts p
WHERE 1=1
AND (
p.post_title LIKE '%noticias%'
OR
p.post_content LIKE '%noticias%'
)
AND p.post_type IN ( 'post', 'page', 'attachment', 'esp-publicitarios'
, 'opinion', 'especiales', 'portadadeldia'
, 'clasificados', 'anunciantes', 'logos')
AND (
p.post_status = 'publish'
OR (
p.post_author = 4
AND
p.post_status = 'private'
)
)
ORDER
BY p.post_date DESC
LIMIT 0, 10
I'm wanting to order Wordpress posts by the most recent comment. To the best of my knowledge this isn't possible using the WP_Query object, and would require a custom $wpdb query, which I can easily write. However, I then don't know how to setup the loop to run off this object.
Can anyone help?
Assign
select wp_posts.*, max(comment_date) as max_comment_date
from $wpdb->posts wp_posts
right join $wpdb->comments
on id = comment_post_id
group by ID
order by max_comment_date desc
limit 10
to some variable $query. You can fiddle around with the 10 or the query itself. (I'm no SQL optimization ninja.) Then your code will look something like
<?php
$results = $wpdb->get_results($query) or die('!');
foreach ($results as $result):
?>
[insert template here]
<?php endforeach ?>
This pattern is covered in more depth by the Codex.
I used a simpler, portion of a native WP in function. hope it helps and some one can continue to develop. Here is a simplified version that shows the title & excerpt of the post along with the comment content & author from the latest commented posts using get_comments.
$args = array(
'status' => 'approve',
'number' => 6,
'order' => 'DESC'
);
$comments = get_comments($args);
foreach($comments as $comment) : $count++;
$post_args = array(
'post_type' => 'post',
'p' => $comment->comment_post_ID,
'posts_per_page' => 1
);
$posts = get_posts($post_args);
foreach($posts as $post) : setup_postdata($post);
the_title();
the_excerpt();
endforeach;
echo $comment->comment_content;
echo $comment->comment_author;
endforeach;
OK guys,
A lot of great answers here, but obviously nobody's taken the time to test them.
Hao Lian gets the credit for the first best original answer, but unfortunately his code doesn't show posts without comments.
Captain Keytar is on the right track, but his code will display every single post and attachment as a separate result.
Here is a modified version of Captain Keytar but it limits the results to the type 'post'.. that has been published (to avoid getting drafts!!)
select wp_posts.*,
coalesce(
(
select max(comment_date)
from $wpdb->comments wpc
where wpc.comment_post_id = wp_posts.id
),
wp_posts.post_date
) as mcomment_date
from $wpdb->posts wp_posts
where post_type = 'post'
and post_status = 'publish'
order by mcomment_date desc
limit 10
This is an old question, but I had the same issue and found a much cleaner way to do this, so I'm posting it here in case it helps anyone.
If you use the posts_clauses filter you can then just modify the main query and still use The Loop and all the regular loop functions.
function intercept_query_clauses( $pieces ) {
global $wpdb;
$pieces['fields'] = "wp_posts.*,
(
select max(comment_date)
from " . $wpdb->comments ." wpc
where wpc.comment_post_id = wp_posts.id AND wpc.comment_approved = 1
) as mcomment_date";
$pieces['orderby'] = "mcomment_date desc";
return $pieces;
}
add_filter( 'posts_clauses', 'intercept_query_clauses', 20, 1 );
Note that I changed the sql slightly for my own purposes, but the general concept is the same.
As an addendum to Hao Lian's answer, if you use the following query:
select wp_posts.*,
coalesce(
(
select max(comment_date)
from $wpdb->comments wpc
where wpc.comment_post_id = wp_posts.id
),
wp_posts.post_date
) as mcomment_date
from $wpdb->posts wp_posts
order by mcomment_date desc
limit 10
This mixes in posts that don't have comments yet, and sorts them by post_date and max(comment_date).
Code suggested by Hao Lian works perfect except for the fact that we should add the following WHERE clause to avoid pulling POST with comment_count = 0, this situation is caused by spam comments.
The WHERE clause to add is as follows:
WHERE comment_approved = '1' AND comment_type = '' AND post_password = ''
Complete code after adding the where clause shoud look like following:
select wp_posts.*, max(comment_date) as comment_date
from wp_posts
right join wp_comments on id = comment_post_id
WHERE comment_approved = '1' AND comment_type = '' AND post_password = ''
group by ID
order by comment_date desc
limit 6
This can be done by combining WP_Comment_Query with WP_Query, like this:
// For performance, limit the number of queried comments,
// but make it be something big enough to account for "duplicate" posts.
$comments_query = new WP_Comment_Query;
$comments = $comments_query->query( array( 'number' => '100' ) );
if ( $comments ) {
foreach ( $comments as $comment ) {
// You'll want to convert the dates from string to integer so you can sort them out later
$comment_utf = strtotime($comment->comment_date);
// Build an array of post IDs with the date of the last published comment
$latest_comments[$comment->comment_post_ID] = $comment_utf;
}}
// Sort the array by date
arsort($latest_comments); foreach ($latest_comments as $key => $value) { $posts_ordered[] = $key; }
// The nice thing is that WP_Query will remove duplicates by default
$args = array ( 'posts_per_page' => '10', 'post__in' => $posts_ordered, 'orderby' => 'post__in');
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
// Do your stuff (add the template or whatever)
// If you want to add the comment itself, use this:
$comments = get_comments(array('number' => '1', 'post_id' => $post->ID));
foreach($comments as $comment) :
echo $comment->comment_content;
endforeach;
// That's about it
}}
wp_reset_postdata();
I'm thinking that adding in the max function will screw up your results. MySQL isn't going to pull the max from each one. It's going to pull the max from the full set. This is the query that'll get you your results:
select wp_posts.*, comment_date
from $wpdb->posts wp_posts
right join $wpdb->comments
on id = comment_post_id
group by ID
order by comment_date desc
limit 10
After that, if you want to follow WP convention, use this, and then you can use the functions that most of your templates are using (based on the loop):
$results = $wpdb->get_results($query) or die('!');
foreach ($results as $post):
setup_postdata($post);
Get 3 newest comments for custom post type 'question' regardless of approvement:
global $wpdb;
$results = $wpdb->get_results(
"
SELECT wp_posts.ID, MAX(comment_date) AS max_comment_date
FROM wp_posts
RIGHT JOIN wp_comments
ON id = comment_post_id
WHERE wp_posts.post_type = 'question'
AND wp_posts.post_status = 'publish'
GROUP BY ID
ORDER BY max_comment_date DESC
LIMIT 3
"
);
foreach ($results as $result) {
$posts_arr[] = $result->ID;
}
$args = array(
'post_type' => 'question',
'post__in' => $posts_arr,
'orderby' => 'post__in',
);
$the_query = new WP_Query( $args );
Using Lucian's BEAUTIFUL solution, I needed to alter/filter the existing WP_Query to sort posts by the latest comment. Here's the code, tested & works perfectly:
$comments_query = new WP_Comment_Query;
$comments = $comments_query->query( array( 'number' => '100' ) );
if ( $comments ) {
foreach ( $comments as $comment ) {
$comment_utf = strtotime($comment->comment_date);
$latest_comments[$comment->comment_post_ID] = $comment_utf;
}
// Sort the array by date
arsort( $latest_comments );
foreach( $latest_comments as $key => $value ) {
$posts_ordered[] = $key;
}
$query->set( 'post__in', $posts_ordered );
$query->set( 'orderby', 'post__in' );
}