How to see if a post exists based on a meta value - php

Is there any way to see if a post exists by a meta value?
For instance, lets say I want to see if another post has a unique meta value of "pictureID", and if so do something else.
Is there a way I could write that clause in php?
Thank you

if you dont know the post id then
you can use custom wordpress query to check post meta according to key like
global $wpdb;
$wpdb->get_results( "select * from $wpdb->postmeta where meta_key = 'pictureID' " );
And then you can get all results with post id and then get that post data.
Hope this helps ;)

You can use a standard WP_Query to return posts by meta_key using the meta_query argument and EXISTS compare type.
// query for all posts with the pictureID meta key set
$args = array(
'post_type' => 'post', // or your_custom_post_type
'meta_query' => array(
array(
'key' => 'pictureID',
'compare' => 'EXISTS',
),
),
}
// create a custom query
$my_query = new WP_Query( $args );
// loop over your query, creating a custom The Loop
if ( $my_query->have_posts() ): while ( $my_query->have_posts() ): $my_query->the_post();
// $post is now posts that have a pictureId meta value
endwhile; endif;
// reset $post
wp_reset_postdata();
If you want to quickly grab a random post_id that has this meta_key set you can go to the database directly (bypassing caching, etc).
global $wpdb;
// SQL statement to fetch the post_id using a meta_key and a published post
$sql = <<<SQL
SELECT post_id
FROM {$wpdb->postmeta} pm
JOIN {$wpdb->posts} p
ON p.ID = pm.post_id
AND post_status = 'publish'
AND post_type = 'post'
WHERE meta_key = 'pictureID'
AND meta_value != ''
AND post_id != %d
ORDER BY RAND()
LIMIT 1
SQL;
// exclude the current post by replacing %d with the current ID
$sql = $wpdb->prepare( $sql, $post->ID );
// use get_var() to return the post_id
$post_id = $wpdb->get_var( $sql );

first try to get meta value for post get_post_meta()
$postMetaValue=get_post_meta($postId,"meta_key",true);
if($postMetaValue=='pictureID')
{
//do as you want
}

Related

SQL Fetching Woocommerce Product Thumbnail From DB

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>";
}

using $wpdb to get custom post type with term array

I'm trying to get the ranking the number of meta_key at specific custom post type.
But I'm not great at SQL so therefor not great with using $wpdb.
For example, if I write something like this,
<?php
$tarms = array( ‘sweet, sour’ );
echo get_count_ranking( $tarms );
?>
Then I would like to display rankings from comment("custom post of reply") of "custom post of fluits" with "term of sweet" and "term of sour" in order of "meta_key of count".
Here is my code:
function get_count_ranking( $tarms ){
global $wpdb;
$counts = $wpdb->get_results( $wpdb->prepare( "
SELECT p.post_author AS user_id, sum(m.meta_value) AS SumUser
FROM $wpdb->posts AS p, $wpdb->postmeta AS m
WHERE p.ID = m.post_ID
AND p.ID IN (
SELECT tr.object_id
FROM $wpdb->term_relationships AS tr, $wpdb->posts AS p, $wpdb->term_taxonomy AS tt
WHERE p.post_type = 'reply'
AND tt.term_id = %s
AND p.id = tr.object_id
AND tr.term_taxonomy_id = tt.term_taxonomy_id
)
AND p.post_status = 'publish'
AND m.meta_key = 'count'
GROUP BY p.post_author
ORDER BY m.meta_value DESC LIMIT 10
", $tarms ) );
$result = '';
foreach ( $counts as $count ) {
$result .= '<li><img>'.get_avatar($count->user_id, 30).'<span></span></li>';
}
return $result;
}
I am sorry that my English is so bad.
So I attach that image for your reference.
Thanks.
enter image description here
--
Updated code:
function get_count_ranking( $tarms ){
$customPostArg = array(
'posts_per_page' => 5,
'post_type' => 'fluits',
'tax_query' => array(
array(
'taxonomy' => 'taste-tag',
'field' => 'slug',
'terms' => $tarms
)
)
);
$array_with_post_ids = get_posts($customPostArg);
$argsp = array(
'post__in' => $array_with_post_ids
);
$commentsp = get_comments( $argsp );
$needed_data_array = array();
foreach ($comments as $key => $comment) {
$ranking = get_comment_meta($comment->ID, 'count', $return_single_value = true);
$author_id = $comment->user_id;
// make sure we have an author id
if($author_id) {
$needed_data_array[$author_id][] = $ranking;
}
}
}
$tarms = array( ‘sweet, sour’ );
echo get_count_ranking( $tarms );
I would not use $wpdb for this.
Also, it looks like you save rankings to a POST meta field, I would use a comment meta field.
Please NOTE, i'm not going to help you write everything, but here are
some pointers how I would accomplish this.
Register the custom post types with comment capability.
Extend the add comment to include a ranking setter. Save this ranking data in a comment_meta field. Now the comment and ranking meta are linked. When you remove the comment, the ranking meta data is also removed from the DB.
Now post comments and rankings are saved.
Collecting data
WP has a get_comments() function, this function accepts many arguments. Sadly, I miss an argument to get comments from posts with a certain taxonomy. So we have to collect all the posts first:
Collect all the posts with 'sweet' and/or 'sour' taxonomy, use get_posts().
Build an array with post id's.
Use get_comments() to get all comments connected to the posts.
Example:
$args = array(
'post__in' => $array_with_post_ids,
);
$comments = get_comments( $args );
Now you have all the comments you need for creating overviews, I would loop (iterate) through them and build an array with author_names and their rankings.
Example:
$needed_data_array = array();
foreach ($comments as $key => $comment) {
$ranking = get_comment_meta($comment->ID, 'ranking_meta_key', $return_single_value = true);
$author_id = $comment->user_id;
// make sure we have an author id
if($author_id) {
$needed_data_array[$author_id][] = $ranking;
}
}
//
// Now the $needed_data_array holds all authors
// and their post rankings, you can count them
// to get ranking totals for each comment-author.
//

Custom WP_Query order by post_meta and (author) user_meta

I am having an issue that i couldn't find on google and elsewhere.
To put problem in the context.
I am making a wordpress site where user can put their tutor listing for giving a tutorials, and i am implementing the system of evaluation of the tutors them self and their listening.
So I have tutor_listing post type and each tutor_listing has a 'post_score' meta value, and each tutor (user who puts his tutorials) has user_meta value called 'user_points'.
So I need a WP_Query that will get from the database all published tutor_listing but sorted by (post_score + user_points). Just to emphasis 'post_score' is a post_meta of the post_type tutor_listing and 'user_points' is user_meta of author of that post (tutor_listing).
Also i need that value to show in the loop.
I can get all the tutor_listing by
$args = array(
'post_type' => 'job_listing',
'post_status' => 'publish'
);
$query = new WP_Query( $args );
I can get the result from the custom wordpress sql query like this:
SELECT p1.ID, p1.post_author, p1.post_title, p1.post_date, (um1.meta_value + pm1.meta_value) AS total_score
FROM $wpdb->posts p1
JOIN $wpdb->users u1 ON (p1.post_author = u1.ID)
JOIN $wpdb->usermeta um1 ON (um1.user_id = u1.ID)
JOIN $wpdb->postmeta pm1 ON (pm1.post_id = p1.ID)
WHERE p1.post_type = 'tutor_listing'
AND p1.post_status = 'publish'
AND um1.meta_key = 'user_points'
AND pm1.meta_key = 'post_score'";
Can WP_Query provide such a functionality?
I need WP_Query to use its all extra functionality like pagination ect.
Or is there a way i could all the result done with the my custom sql give to WP_Query object?
Thank you

Get user id from wp_usermeta table

I have stored the certain term ids in wp_usermeta table.
i want to get the user id where the term id match with the user meta key 'location' value.
i have tried it with below query but it is doing nothing.
global $wpdb;
$term = get_queried_object();
$query = $wpdb->get_results("SELECT user_id FROM wp_usermeta WHERE meta_key='location' AND meta_value LIKE %s",'%'.$term->term_id.'%');
try this, you are not passing the value correctly
$query = $wpdb->get_results("SELECT user_id FROM wp_usermeta WHERE
meta_key='location' AND meta_value LIKE '%s,%".$term->term_id."%'");
Is there any reason for using a sql query? i think this will do what you want exactly :
$user_query = new WP_User_Query( array( 'meta_key' => 'location', 'meta_value' => 'ANY' ) );
foreach ($user_query as $user) {
$user->ID; // the the user id
}
I have figured it out. Here is my solution. if someone needed.
$term = get_queried_object();
$wpdb->get_results($wpdb->prepare("SELECT user_id FROM $wpdb->usermeta WHERE meta_key='location' AND $wpdb->usermeta.meta_value LIKE %s", '%' . $term->term_id . '%'));

Ordering Wordpress posts by most recent comment

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

Categories