Get all comments on a post by an array of users - wordpress

I'm trying to get all the comments from a post by an array of users.
This is what I'd like to be able to do:
$user_ids = array(10, 22, 41, 80);
$post_id = 57;
$args = array (
'number' => -1,
'user_id' => $user_ids,
'post_id' => $post_id,
'status' => 'approve',
'order' => 'DESC'
);
$comments = get_comments( $args );
Now obviously this doesn't work, but that's what I'd like to do. Is there any other way to achieve this? Maybe using a custom select?

I've built a WPDB query based on the query method of WP_Comment_Query class. And doing the sanitization based on this forum post.
global $wpdb;
// Sanitize
$post = '1148';
$post = absint($post);
// Sanitize
$a = '2'; // User One
$b = '3'; // User Two
$user_ids = array_map( 'absint', array( $a, $b ) );
$user_ids = implode( ', ', $user_ids );
$query = "SELECT * FROM $wpdb->comments
WHERE comment_post_ID = $post
AND user_id IN ($user_ids)
AND comment_approved = 1
ORDER BY comment_date DESC";
$comments = $wpdb->get_results( $query );

A simple SELECT query would do:
$query = "SELECT * FROM $wpdb->comments
WHERE comment_post_ID = %d
AND comment_approved = 1
AND user_id IN %s
ORDER BY comment_date DESC"; // get only approved comment and sort by date
$comments = $wpdb->get_results($wpdb->prepare(
$query,
intval($post_id),
'('.implode(',', array_map('intval', $user_ids)).')'
)); // use prepare to prevent SQL injection
Hope this helps.

We can use the OR condition in MySQL to do this.
If I was to write the query we want using the values you provided it could be done something like this:
SELECT * FROM comments WHERE comment_post_ID='57' AND (user_id='10' OR user_id='22' OR user_id='41' OR user_id='80')
Now, we can make this dynamic and processable by PHP:
// The User IDs and Post ID (make sure you are escaping these properly).
$user_ids = array(10, 22, 41, 80);
$post_id = 57;
foreach($user_ids as $uid){ $user_ids_string .= " OR user_id='$uid'"; } // Loop through each user and append their ID to the query segment.
$user_ids_string = substr($use, 4); // Remove the unnecessary first " OR "
$query = mysql_query("SELECT * FROM comments WHERE comment_post_ID='$post_id' AND ($user_ids_string)"); // Create the final MySQL Query.
while($row = mysql_fetch_array($query)){
// Do something with each $row[].
}
Before you use this, make sure you're connected to the WordPress database properly before using this and that all the tables and fields I've listed are correct for your installation first.

paste this code in functions.php
function users_comment( $postid = null , $users = array() ){
if( ! empty( $users ) && $postid ){
foreach ($users as $user) {
$args = array (
'number' => '',
'user_id' => $user,
'post_id' => $postid,
'status' => 'approve',
'order' => 'DESC'
);
$comments[] = get_comments( $args );
}
return $comments;
}else{
return 'Please provide a user id and postid';
}
}
use this function anywhere you want by calling it required parameters user ids and post id.
print_r( users_comment(1,array(1,4,3)) );

only single user to get post:
$args = array(
'status' => 'approve',
'number' => '-1',
'post_id' => 57,
'user_id' => 1,
'order' => 'DESC'
);
$comments = get_comments($args);
foreach($comments as $comment) :
echo($comment->comment_author . '<br />' . $comment->comment_content);
endforeach;
?>
For multiple user get comment using post id:
$args = array( 'user_id' => 0 );
add_filter( 'comments_clauses', 'custom_comments_clauses');
$comments = get_comments( $args );
remove_filter( 'comments_clauses', 'custom_comments_clauses');
function custom_comments_clauses( $clauses ){
$clauses['where'] = str_replace( 'user_id = 0',
'user_id IN (1, 2, 3)',
$clauses['where'] );
return $clauses;
}
https://wordpress.stackexchange.com/questions/105010/get-comments-only-for-certain-specific-users-in-template-file

As Brasofilo already provided you the custom query to get the comments but it will fetch all the comments while they were trashed
$user_ids = array(10, 22, 41, 80);
$post_id = 57;
global $wpdb;
$comments=$wpdb->get_results("SELECT * FROM `wp_comments` WHERE
`comment_post_ID` =$post_id AND `user_id` IN (".join(',',$user_ids)")
AND `comment_approved` ='1' ORDER BY `comment_date` DESC");

Related

How to call posts from this functions code?

I have a piece of code for displaying related posts by the post tag, but I don't know how to call posts in theme,
so I have this code which I have to put in my theme functions file:
function exe_get_related_posts_by_common_terms( $post_id, $number_posts = 0, $taxonomy = 'post_tag', $post_type = 'post' ) {
global $wpdb;
$post_id = (int) $post_id;
$number_posts = (int) $number_posts;
$limit = $number_posts > 0 ? ' LIMIT ' . $number_posts : '';
$related_posts_records = $wpdb->get_results(
$wpdb->prepare(
"SELECT tr.object_id, count( tr.term_taxonomy_id ) AS common_tax_count
FROM {$wpdb->term_relationships} AS tr
INNER JOIN {$wpdb->term_relationships} AS tr2 ON tr.term_taxonomy_id = tr2.term_taxonomy_id
INNER JOIN {$wpdb->term_taxonomy} as tt ON tt.term_taxonomy_id = tr2.term_taxonomy_id
INNER JOIN {$wpdb->posts} as p ON p.ID = tr.object_id
WHERE
tr2.object_id = %d
AND tt.taxonomy = %s
AND p.post_type = %s
GROUP BY tr.object_id
HAVING tr.object_id != %d
ORDER BY common_tax_count DESC" . $limit,
$post_id, $taxonomy, $post_type, $post_id
)
);
if ( count( $related_posts_records ) === 0 )
return false;
$related_posts = array();
foreach( $related_posts_records as $record )
$related_posts[] = array(
'post_id' => (int) $record->object_id,
'common_tax_count' => $record->common_tax_count
);
return $related_posts;
}
and now I want to call 10 posts from the above code in my single.php that can show post title and post thumbnail with the link to every post.
try something like that:
$query = new WP_Query(array(
'post_status' => 'publish',
'post_type' => 'your-posttype', // or 'any'
'tag_slug__in' => 'your-tag',
'order' => 'DESC',
'posts_per_page' => 10
));
Then you will get latest 10 posts
This function is very useful, people continually looking for ways to get related posts
What this function does:
The code you are using is a working function that is returning an array of posts related to current post depending on common terms.
How this function works:
You can call the function from your single.php file and as input you have to provide 4 info. The current post ID, the number of related posts to return, the post_term to filter the related posts (post_tag) and at last the post_type.
Example function call: exe_get_related_posts_by_common_terms(get_the_ID(), 10, 'post_tag', 'post')
The above example will return 10 post ids as array based on current post ID and the tag
- Returning the post array and loop through ID's
Now we only need a custom wp_query in order to loop through the array and format the output.
Example wp_query:
$args = array(
'post_type' => 'post',
'post__in' => $related_post
);
// The Query
$related_query = new WP_Query( $args );
Result:
Full working example returning the post titles in an unordered list:
<?php
$cpid = get_the_ID(); // get current post id
$related_posts = exe_get_related_posts_by_common_terms($cpid, 10, 'post_tag', 'post');
$posts_array = array_column($related_posts, 'post_id'); // new single dimension array with the ID's
$args = array(
'post_type' => 'post',
'post__in' => $posts_array
);
// The Query
$related_query = new WP_Query( $args );
if ($related_query->have_posts()) : ?>
<ul>
<?php while ($related_query->have_posts()) : $related_query->the_post(); ?>
<li><?php the_title(); ?></li>
<?php endwhile; ?>
</ul>
<?php endif; ?>
You can now set the look and fill as you like

Wordpress: The Events Calendar, ACF: TEC Filter Bar Filter Based on ACF Relationship Field

I've been struggling a bit with this. I have one custom post type that I created called "pt_initiatives" and one that The Event Calendar created called "tribe_events". With Advanced Custom Fields, I added a relationship field to both post types which is also bi-directional. The relationship field is called "bi_initiatives-events".
I have The Events Calendar Pro with the Filter Bar add on. I am trying to create a filter that shows the pt_initiatives posts as options in a multi-checkbox filter. (There are only 9 of these posts). I have that part working so far. I am a bit lost on how to update the list of events when one of these pt_initiatives are chosen.
I've been playing with the wpdb queries with no success. I'm not sure how to tell it to look at tribe_events posts to find which has posts in common. I've been scouring the internet and haven't come across anything too helpful and The Event Calendar folks don't seem too keen on helping since this is considered "Customization". However, they offer the ability to add filters as a feature... They have a very vague page on how to do this but I personally did not find it too helpful.
I am not too familiar with writing wpdb queries, hence you can see me adding a post loop to achieve the same thing. At least, I think it's the same output as some examples I came across.
Thanks in advance!
class Tribe__Events__Filterbar__Filters__Initiative extends Tribe__Events__Filterbar__Filter {
public $type = 'checkbox';
public function get_admin_form() {
$title = $this->get_title_field();
$type = $this->get_multichoice_type_field();
return $title.$type;
}
protected function get_values() {
/** #var wpdb $wpdb */
global $wpdb;
// get initiative IDs associated with published posts
// $initiative_ids = $wpdb->get_col(
// $wpdb->prepare(
// "SELECT DISTINCT m.meta_value
// FROM {$wpdb->postmeta} m
// INNER JOIN {$wpdb->posts} p
// ON p.ID=m.post_id
// WHERE p.post_type=%s,
// AND p.post_status='publish'
// AND m.meta_key='bi_initiatives-events'
// AND m.meta_value > 0", $post_type
// )
// );
$initiative_ids = array();
// WP_Query arguments
$args = array(
'post_type' => array( 'pt_initiatives' ),
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'bi_initiatives-events',
// 'value' => '',
'compare' => 'EXISTS'
)
)
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
$initiative_ids[] = get_the_ID();
}
}
wp_reset_postdata();
array_filter( $initiative_ids );
if ( empty( $initiative_ids ) ) {
return array();
}
/**
* Filter Total Initiatives in Filter Bar
* Use this with caution, this will load initiatives on the front-end, may be slow
* The base limit is 200 for safety reasons
*
*
* #parm int 200 posts per page limit
* #parm array $initiative_ids ids of initiatives attached to events
*/
$limit = apply_filters( 'tribe_events_filter_bar_pt_initiatives_limit', 200, $initiative_ids );
$initiatives = get_posts( array(
'post_type' => 'pt_initiatives',
'posts_per_page' => $limit,
'suppress_filters' => false,
'post__in' => $initiative_ids,
'post_status' => 'publish',
'orderby' => 'title',
'order' => 'ASC',
) );
$initiatives_array = array();
foreach ( $initiatives as $initiative => $value ) {
$initiatives_array[] = array(
'name' => $value->post_title,
'value' => $value->ID,
);
}
return $initiatives_array;
}
protected function setup_join_clause() {
add_filter( 'posts_join', array( 'Tribe__Events__Query', 'posts_join' ), 10, 2 );
global $wpdb;
$this->joinClause .= " LEFT JOIN {$wpdb->postmeta} AS initiatives_filter ON ({$wpdb->posts}.ID = initiatives_filter.post_id AND initiatives_filter.meta_key = 'bi_initiatives-events')";
}
protected function setup_where_clause() {
if ( is_array( $this->currentValue ) ) {
$initiative_ids = implode( ',', array_map( 'intval', $this->currentValue ) );
} else {
$initiative_ids = esc_attr( $this->currentValue );
}
$this->whereClause = " AND initiatives_filter.meta_value IN ($initiative_ids) ";
}
}
new Tribe__Events__Filterbar__Filters__Initiative( __( 'Initiatives', 'tribe-events-filter-view' ), 'initiatives_filter' );

How do I search ACF (Advanced Custom Fields) data with the conditional logic?

All,
I'm running a search with Wordpress and it's returning ACF data. The problem, is that for fields that are hidden with conditional logic, they are still returning in the search results.
Does anyone happen to know how to exclude fields that are hidden? Or, does anyone know those items are declared as hidden in the database? I can't seem to find anything that ties a field to another in the wp_postmeta.
EDIT: added some code by request
<?php
error_reporting(0);
global $query_string;
$query_args = explode("&", $query_string);
$search_query = array();
foreach($query_args as $key => $string) {
$query_split = explode("=", $string);
$search_query[$query_split[0]] = urldecode($query_split[1]);
}
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
$search = new WP_Query(
$search_query,
array(
'post_type' => 'page',
'post_status'=>'publish',
'post__in' => array(),
//'posts_per_page' => -1,
'paged' => $paged
)
);
$resultArray = array();
if (have_posts()){
while(have_posts()): the_post();
//places the WP post meta data into an array
$array = get_post_meta($post->ID);
//Flattens the array into one-dimensonal
$result = call_user_func_array('array_merge', $array);
//changes the search term to all lower case
$searchword = strtolower($search_query['s']);
//Searches the $result array for the $searchword and saves all occurances into $matches array
$matches = array_filter($result, function($var) use ($searchword) { return preg_match("/\b$searchword\b/i", strip_tags($var)); });
//Grab the first value of the $matches array since we won't always know the key
$first_value = reset($matches);
if(!empty($first_value)){
array_push($resultArray,
array(
'id'=>$post->ID,
'match' =>strip_tags($first_value)
)
);
}
endwhile;
}
$total_results = count($resultArray);
?>

List authors that have written certain number of posts in category/tags in Wordpress

I'm struggling to get the list of authors on the category page. I need to list the authors who have written at least 5 articles in that category.
I need something like this in tags also.
Any idea how to do this in wordpress?
Its only possible with a custom SQL query so here is a simple function which should return an array with user id's of users with at least $n posts in the current term archive, which means it should work in categories, tags and custom taxonomies
function get_authors_with($num = 5){
global $wpdb;
$term_slug = get_query_var( 'term' );
$taxonomyName = get_query_var( 'taxonomy' );
$current_term = get_term_by( 'slug', $term_slug, $taxonomyName );
$sub_q = $wpdb->prepare("SELECT * FROM $wpdb->posts
INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)
INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
WHERE ($wpdb->term_taxonomy.term_id = %s
AND $wpdb->term_taxonomy.taxonomy = '%s'
AND $wpdb->posts.post_type = 'post'
AND $wpdb->posts.post_status = 'publish')",
$current_term->term_id,
$taxonomyName
);
$sql = $wpdb->prepare("SELECT $wpdb->posts.post_author, FROM (%s)
GROUP BY $wpdb->posts.post_author
HAVING count(*) > %s",
$sub_q,
$num
);
return $wpdb->get_results($sql);
}
Try this.
function list_author_in_this_cat ($with) {
if (is_category()) {
$current_category = get_query_var('cat');
$args = array(
'numberposts' => -1,
'category' => $current_category,
'orderby' => 'author',
'order' => 'ASC'
);
} else {
$tag_id = get_query_var('tag_id');
$args = array(
'numberposts' => -1,
'tag__in' => $tag_id,
'orderby' => 'author',
'order' => 'ASC'
);
}
$cat_posts = get_posts($args);
$author_id_array = array();
$user_posts = array();
foreach( $cat_posts as $cat_post ):
$user_posts[$cat_post->post_author][] = $cat_post->ID;
endforeach;
foreach( $user_posts as $key => $user_post ):
$user_post = array_unique($user_post);
$count_user_posts[$key] = count($user_post);
if ($count_user_posts[$key] >= $with) {
$author_id_array[] = $key;
}
endforeach;
return $author_id_array; }
In your theme files, place this code wherever you want the list of authors to be displayed:
if (is_category() || is_tag()) {
$at_least = 5; // at least 5 articles in current category or tags
$author_array = list_author_in_this_cat ($at_least);
foreach (array_slice($author_array, 0, 4) as $author) : // limit 4 results
$name = get_userdata($author)->display_name;
$link = get_userdata($author)->user_login;
echo "<a href='/author/".$link."'>".$name."</a>\n";
endforeach;
}
Add the following code to your theme's function.php
function get_authors_in_category ( $category_id, $min_posts ) {
$posts = get_posts( array( 'numberposts' => 1000, 'category' => $category_id ) );
$author_count = array();
foreach ($posts as $post) {
if( array_key_exists( get_the_author_meta( 'display_name', $post->post_author ), $author_count ) ) {
$author_count[get_the_author_meta( 'display_name', $post->post_author )]++;
} else { $author_count[get_the_author_meta( 'display_name', $post->post_author )] = 1; }
}
$authors = array();
foreach ( $author_count as $author_name => $count ) {
if ( $min_posts <= $count ) {
$authors[] = $author_name;
}
return $authors;
}
This function as you can see returns an array of authors who have a minimum number of posts in a category. Category ID has to be passed, this can be obtained using the wordpress function get_cat_ID.
You can call this function from any where in the theme and display the authors as you wish.
Note: This is a more resource intensive than the custom SQL functions. Also this function might have some errors, I typed it here and didn't test it.
I did some simple coding with query post method.,
<?php
$cur_cat_id = get_cat_id(single_cat_title("",false));
$posts=query_posts("cat=$cur_cat_id&order=ASC");
foreach($posts as $post){
$number_of_posts = number_format_i18n(get_the_author_posts($post->post_author));
if($number_of_posts>5)
{
echo the_author_meta('user_nicename',$post->post_author)."(".number_format_i18n(get_the_author_posts($post->post_author)).")<br>";
}
}
?>
I think this may help you to resolve your problem.

How to get Posts Greater Than X (ID) using get_posts

$args = array('numberposts' => 10, 'tag' => 'my-tag', 'ID' => 555');
$posts = get_posts($args);
I want to bring only 10 records from an specific tag and that the ID is less than a number. Is there any way to do this with the get_posts arguments? How can I specify Greater Than, Less Than or Not Like in the arguments array?
Thanks...
A nice solution if you want to get the posts with an ID lower than X:
$post_ids = range(1, 555);
$args = array('numberposts' => 10,
'tag' => 'my-tag',
'post__in' => $post_ids');
$posts = get_posts($args);
props to girlieworks here: https://wordpress.org/support/topic/wp_query-how-to-get-posts-with-and-id-lower-than?replies=7#post-8203891
You need to get the IDs first, and then add those IDs to wp_query.
global $wpdb;
$post_ids = [];
// Get all the IDs you want to choose from
$sql = $wpdb->prepare(
"
SELECT ID
FROM $wpdb->posts
WHERE ID > %d
", 555 );
$results = $wpdb->get_results( $sql );
// Convert the IDs from row objects to an array of IDs
foreach ( $results as $row ) {
array_push( $post_ids, $row->ID );
}
// Set up your query
$custom_args = array(
'posts_per_page' => 10,
'tag' => 'my-tag',
'post__in' => $post_ids
);
// Do the query
$custom_query = new WP_Query( $custom_args );
// the loop
if( $custom_query->have_posts() ) :
while( $custom_query->have_posts() ) : $custom_query->the_post();
echo get_the_title() . '<br>';
endwhile;
endif;
You could use the posts_where filter to alter the SQL query to restrict the results to posts with ID lower (or greater) than a certain number:
$args = [
'tag' => 'my-tag',
'posts_per_page' => 10,
// Required: posts_where is not triggered without setting suppress_filters to false.
'suppress_filters' => false,
];
$max_id = 155;
$filter_handler = function( $where ) use ( $max_id ) {
global $wpdb;
return $where . $wpdb->prepare( " AND {$wpdb->posts}.ID < %d", $max_id );
};
add_filter( 'posts_where', $filter_handler );
$posts = get_posts( $args );
remove_filter( 'posts_where', $filter_handler );
You would have to query all of them, and inside the query-loop check if the id is greater or less than the number of your choice.
As for as I know the query itself can't handle such requests.
This is the fastest, most efficient and most reliable way (at least compared to the craziness of passing thousands of integers into SQL):
$compId = 555;
$filterWhere = function(string $where, \WP_Query $query) use (&$compId): string {
$where .= " AND `ID` > $compId";
return $where;
};
add_filter('posts_where', $filterWhere, 10, 2);
$posts = get_posts([
'posts_per_page' => 20,
'suppress_filters' => false,
]);
remove_filter('posts_where', $filterWhere);
I like Web-Entwickler's idea, but using in the opposite direction (as it is in the question). It's even futureproof if you set up the latest known ID and using the not_in method. So my solution is if you want 555+:
$args['post__not_in'] = range(1, 555);
And if you want 1-555:
$args['post__in'] = range(1, 555);

Resources