Wordpress query to display most commented articles over X days - php

I'm creating a wordpress widget to display the most commented articles over the last 4 days.
I have this so far
global $wpdb;
global $pagepost;
function filter_where( $where = '' ) {
// posts in the last 4 days
$where .= " AND post_date > '" . date('Y-m-d', strtotime('-4 days')) . "'";
return $where;
}
add_filter( 'posts_where', 'filter_where' );
$the_query = new WP_Query( 'posts_per_page=4;orderby=comment_count' );
remove_filter( 'posts_where', 'filter_where' );
?>
<ul>
<?php while ( $the_query->have_posts() ) : $the_query->the_post();
echo "<li>";
echo "<a href='".get_permalink()."' class='linkTitle'>";
echo get_the_title();
echo "</a>";
woo_post_meta();
echo "<div class='fix'>";
echo "</li>";
endwhile;
echo "</ul>";
wp_reset_postdata();
Which from what I can find on the wordpress site should return the articles from the last 4 days ordered by comment_count
but it's just showing me my last 4 articles, I'm sure I'm doing something very obviously wrong here but I can't get it
I want the 4 articles with the most comments where the article was posted in the last 4 days.
someone please save what little hair I have left

Thanks to #swapnesh I found the answer.
My query wasn't correct, it should have been like this
$the_query = new WP_Query(array( 'posts_per_page' => 4, 'orderby' => 'comment_count', 'order'=> 'DESC' ));

$querystr = "
SELECT $wpdb->posts.* FROM $wpdb->posts WHERE 1=1 AND $wpdb->posts.post_status = 'publish' AND $wpdb->posts.post_type = 'post' ORDER BY $wpdb->posts.comment_count DESC
";
Use this custom query
$pageposts = $wpdb->get_results($querystr, OBJECT);
echo''; print_r($pageposts); echo'';

Related

WordPress query: Group posts by year DESC, then posts by month ASC within each group

I'm trying to set up a WordPress query and loop such that events are grouped by year in descending order, with a heading for each year, and then ordered by month in ascending order for each year group, like so:
2020
Jan 1, 2020
Feb 1, 2020
Mar 1, 2020
2019
Jan 1, 2019
Feb 1, 2019
Mar 1, 2019
I have found some helpful threads here that point in the right direction, such as this one, which uses a direct SQL query to get the posts by year, and then runs the usual loop on WP_Query to group and sort the posts within each group. In my case, however, instead of using post_date, I have a custom field (using Advanced Custom Fields) for event_end_date that should define the order of the posts and group definitions.
The SQL query in the linked example is
$sql = "SELECT DISTINCT(YEAR(`post_date`)) as years FROM $posts WHERE post_type = 'testimonials' ORDER BY years DESC"; //Get all post year list by DESC
$result = $wpdb->get_results($sql);
foreach($result as $rs) {
echo '<h2>'.$rs->years.'</h2>';
$args = array(
'post_type' => 'event',
'post_per_page'=> -1,
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'DESC',
'date_query' => array(array(
'year'=> $rs->years,
),),
);
$loop = new WP_Query($args);
if($loop->have_posts()) {
while($loop->have_posts()) : $loop->the_post();
echo ''.get_the_date().'';
endwhile;
}
}
And I'm not quite sure how to modify it such that I can query the event_end_date custom field, and form the year groups, within which I can then list posts sorted by month ASC.
I'm assuming that I need to use a manual SQL query here in that a typical WP_Query would not allow for sorting in two different ways, as I've described? I can easily output the events into groups with headings for each year, but only in one set order, i.e. ASC or DESC. Thanks for any assistance here, and please let me know if this is unclear in any way.
If you are using the Advanced Custom Fields' "Date Picker", here is how you sort by the posts' custom field a WP_Query:
<?php
$year = '';
$args = array(
'posts_per_page' => -1,
'meta_key' => 'event_end_date',
'orderby' => 'meta_value_num',
'order' => 'DESC',
);
$the_query = new WP_Query( $args );
?>
<?php if ( $the_query->have_posts() ) : ?>
<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
<?php
// create the date variables
$event_date_string = get_field('event_end_date');
$event_date = DateTime::createFromFormat('Ymd', $event_date_string);
$event_year = $event_date->format('Y');
// add header for each year
if ($year != $event_year) :
echo '<div><b>' . $event_year . '</b></div>';
$year = $event_year;
endif;
// echo out current post
echo '<div>' . $event_date . ': ' . get_the_title() . '</div>';
?>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php endif; ?>
Explanation:
Create a $year variable to keep track of the current year
Get all posts with a WP_Query and sort by 'event_end_date' in DESC order
Loop through posts and get the event year for each post which we use to update the $year variable
More information here:
https://www.advancedcustomfields.com/resources/date-picker/

[sql]wordpress custom post_type get overriden

I am having problems with my custom post type (quote) for my wordpress theme WPF. The version on github has the custom post type in functions.php, but I have moved that to a plugin (wpf quote). I also added a custom widget.
The problem:
My main query doesnt include the custom post type "quote" (wish is fine, this is intended). The quote post type can be reached by going to: [domain]/quote/. This works fine and on this page the widget also works fine. But it goes wrong on a none-quote page (like on the homepage). The widget show the "content" and 2 meta values. The 2 meta values are not showing on a none-quote page.
I looked at the query and so I added echo '<pre>'; print_r($GLOBALS['wp_query']->request); echo '</pre>'; to my plugin.
On a quote-page:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'quote' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 5
On a none-quote-page:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 5
The only difference is wp_posts.post_type = 'quote' versus wp_posts.post_type = 'post'.
So the first one (quote) is the right one. I dont understand why it's changing back to post on a none-quote page. This is my widget() function within my WP_Widget-child:
<?php
public function widget($args, $instance) {
extract($args, EXTR_SKIP);
$title = empty($instance['title']) ? '' : apply_filters('widget_title', $instance['title']);
$read_more = $instance['read_more'];
echo $before_widget;
if (!empty($title)) echo $before_title . $title . $after_title;;
$quotes = get_posts(array('numberposts' => 1, 'orderby' => 'rand', 'post_type' => 'quote'));
if (count($quotes) > 0) {
foreach($quotes as $post) {
echo '<pre>'; print_r($quotes); echo '</pre>';
setup_postdata($post);
// print the quote
wpf_quote_print();
}
if (!empty($read_more)) {
printf('<p>%s</p>', esc_url(home_url()) . '/quote/', __('Read more quotes', 'wpf_quote'));
}
} else {
echo '<p>' . __('There are no quotes yet', 'wpf_quote') . '</p>';
}
echo $after_widget;
}
?>
The function that's being called within the foreach is:
<?php
function wpf_quote_print() {
// get the meta value's
$quote_meta = get_post_custom();
// first check if 'source_is_url' and 'quote_source' are not empty and prints the source as url. Else print source within parentheses.
if (!empty($quote_meta['source_is_url'][0]) and !empty($quote_meta['quote_source'][0])) {
$cite = '<cite>' . $quote_meta['person'][0] . '</cite>';
} else {
$cite = '<cite>' . $quote_meta['person'][0];
if (!empty($quote_meta['quote_source'][0])) $cite .= ' (' . $quote_meta['quote_source'][0] . ')';
$cite .= '</cite>';
}
// print the html
echo '<blockquote>' . get_the_content() . $cite . '</blockquote>';
}
?>
So why does wp change my query while I explicitly tell it to retrieve post with the type of quote? I think if I solve this then it will solve the problem I have now with not getting any meta values.
If it's easier I can fork my current work on github (I am gona fork it anyways to WPF when it's fixed).
I fixed this by using a new WP_Query instead of get_posts(). Still dont know why it's not doing what I want with get_posts(). Later today I will place the hole thing on github WPF.

wp_reset_query() wordpress - unable to reset the last query

I am trying to run two querys on a page.
The first shows the results of the custom user search
and the second is just supposed to display the more recent records with a few custom params hard coded into the query.
The problem i have is that when the custom search is run both queries are affected and the results are updated in both places.
I have tried placing these wp_reset_postdata();
wp_reset_query(); all over the place but all to no available.
Does anyone have any ideas?
This is my first query
$args = array('post_type' => 'vacancy', 'post_status' => 'publish' ) );
add_filter( 'posts_where', 'posts_where_title', 10, 2 );
function posts_where_title( $where, &$wp_query ) {
global $wpdb;
$where .= ' AND (' . $wpdb->posts . '.post_title LIKE \'%' . esc_sql( like_escape( $_POST['post_title'] ) ) . '%\'';
$where .= ' OR ' . $wpdb->posts . '.post_content LIKE \'%' . esc_sql( like_escape( $_POST['post_title'] ) ) . '%\')';
return $where;
}
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post();
//display results ?>
<?php $i++; endwhile; endif;
wp_reset_postdata();
wp_reset_query();?>
This is my second query...
$args = array( 'post_type' => 'vacancy', 'posts_per_page' => 10 );
query_posts( "_vacancy_ends>=".date("Y-m-d")."&_vacancy_starts<=".date("Y-m-d")."&order=DESC" );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
//display results
endwhile;
wp_reset_postdata();
wp_reset_query();
Your problem is this line:
query_posts( "_vacancy_ends>=".date("Y-m-d")."&_vacancy_starts<=".date("Y-m-d")."&order=DESC" );
query_posts affects the main loop, and just about every other loop that runs in that given page request. There are very few circumstances when it would be considered good practice to use it over WP_Query or even get_posts as you're affecting a LOT of the global variables Wordpress uses to populate information about what is being viewed.
Personally, I don't typically use the query method on WP_Query, but perhaps it might help in this scenario. Try changing your second query to something like this:
$args = array( 'post_type' => 'vacancy', 'posts_per_page' => 10 );
$loop = new WP_Query( $args );
$loop->query( "_vacancy_ends>=".date("Y-m-d")."&_vacancy_starts<=".date("Y-m-d")."&order=DESC" );
while ( $loop->have_posts() ) : $loop->the_post();
//display results
endwhile;
wp_reset_postdata();
wp_reset_query();
This localizes your query to a single instance of WP_Query, rather than affecting everything globally. It's untested, but let me know if this helps.
One more thing:
add_filter( 'posts_where', 'posts_where_title', 10, 2 );
function posts_where_title( $where, &$wp_query ) {
global $wpdb;
$where .= ' AND (' . $wpdb->posts . '.post_title LIKE \'%' . esc_sql( like_escape( $_POST['post_title'] ) ) . '%\'';
$where .= ' OR ' . $wpdb->posts . '.post_content LIKE \'%' . esc_sql( like_escape( $_POST['post_title'] ) ) . '%\')';
return $where;
}
Bear in mind that this filter will run on EVERY query you set after your call to add_filter. You might want to consider removing your filter at the point where more queries after it do not require the filter to run:
remove_filter( 'posts_where', 'posts_where_title');

How do I Split Up A Wordpress Query?

Ive been looking all over web i even tried to hire freelancer for help on this but had no luck. While searching i found this how to get popular posts fro selected categories in wordpress? & http://www.queness.com/code-snippet/6546/how-to-display-most-popular-posts-from-a-specific-category-in-wordpress and thats basically what i want but i want the information i get from it split up so i can rank the post.
<?php
$args=array(
'cat' => 3, // this is category ID
'orderby' => 'comment_count',
'order' => 'DESC',
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 6, // how much post you want to display
'caller_get_posts'=> 1
);
$my_query = null;
$my_query = new WP_Query($args);
if( $my_query->have_posts() ) { ?>
<ul>
<?php while ($my_query->have_posts()) : $my_query->the_post(); ?>
<li><?php the_title(); ?></li>
<?php endwhile; ?>
</ul>
<?php }
wp_reset_query(); ?>
With that code it gets the most popular post by comments and what i want to do is basically take the results and add a rank to it like example below.
#1 - post 1
#2 - post 2
#3 - post 3
#4 - post 4
#5 - post5 last post
thanks in advance for any help
May be this idea will help you.
Use get_comments_number( $post_id ) function
To get number of comment and then do a if else loop for displaying rank.
$num_comments = get_comments_number(); // get_comments_number returns only a numeric value
if ( comments_open() ) {
if ( $num_comments == 0 ) {
$rating= 0 ;
} elseif ( $num_comments > 1 ) {
$rating= 1 ;
} else {
$rating= 0 ;
}
}
Thanks
By your current question I understand the following:
You want to query from the WP database posts that have the most comments.
You want to display to visitors a ranking for those received posts. The ranking is determined by the amount of comments post has.
So your result could be:
1 Post A (comment count 500)
2 Post B (Comment count 499)
3 Post Z (Comment count 200)
This is how I would do it:
<?php
function get_popular_posts()
{
$sql="SELECT comment_count, guid AS link_to_post, post_title
FROM wp_posts
WHERE post_status = "publish" AND post_type = "post"
ORDER BY comment_count DESC
LIMIT 5"
return $wpdb->get_results($sql, OBJECT)
}
$post_objects = get_popular_posts();
$i = 1;
foreach($post_objects as $object)
{
echo 'Post: ' . $i . '#' . ' ' . $post_title . ' ' . $link_to_post . ' ' . $comment_count;
$i++;
}
?>
Haven't tested the code. But it should take five "top posts" from the database. Left in the comment_count for explanatory reasons.

Wordpress: previous_post_link / next_post_link by alphabetical order?

I'm developing a wordpress website with custom posts which are ordered alphabetically in the loop.
<!-- THE ARGS -->
<?php global $query_string;
$args = wp_parse_args($query_string);
$args = array(
'post_type' => 'custom_post',
'orderby' => 'title',
'order' => 'ASC',
'posts_per_page' => -1,
); ?>
<!-- THE LOOP -->
<?php $wp_query = new WP_Query( $args ); ?>
<?php while ($wp_query->have_posts()) : $wp_query->the_post(); ?>
<?php endwhile; ?>
<?php wp_reset_query(); ?>
Nothing fancy there, just a normal loop.
When I open a post, in its page I have the usual previous_post_link and next_post_link so I can navigate through posts. However, this is done by chronological order of the posts, and I wish to do so by the same alphabetical order as I used in the loop, of course. Any help on this matter would be very appreciated.
Thanks in advance!
It looks like this plug-in does what you're after, e.g.:
<ul class="pager">
<?php previous_post_link_plus( array('order_by' => 'post_title') ); ?>
<?php next_post_link_plus( array('order_by' => 'post_title') ); ?>
</ul>
You can do this by using filters in the get_adjacent_post function.
In your functions.php file, add:
function mytheme_previous_post_orderby_name($orderby){
return "ORDER BY p.post_title DESC LIMIT 1";
}
function mytheme_previous_post_where_name(){
global $post, $wpdb;
return $wpdb->prepare( "WHERE p.post_title < %s AND p.post_type = %s AND ( p.post_status = 'publish' OR p.post_status = 'private' )", $post->post_title, $post->post_type );
}
function mytheme_next_post_orderby_name($orderby){
return "ORDER BY p.post_title ASC LIMIT 1";
}
function mytheme_next_post_where_name(){
global $post, $wpdb;
return $wpdb->prepare( "WHERE p.post_title > %s AND p.post_type = %s AND ( p.post_status = 'publish' OR p.post_status = 'private' )", $post->post_title, $post->post_type );
}
Then in your single.php page add the filters before you call the previous/next posts link functions:
add_filter('get_previous_post_sort', 'mytheme_previous_post_orderby_name', 10, 1);
add_filter('get_next_post_sort', 'mytheme_next_post_orderby_name', 10, 1);
add_filter('get_previous_post_where', 'mytheme_previous_post_where_name', 10);
add_filter('get_next_post_where', 'mytheme_next_post_where_name', 10);
the_post_navigation();
remove_filter('get_previous_post_sort', 'mytheme_previous_post_orderby_name', 10);
remove_filter('get_next_post_sort', 'mytheme_next_post_orderby_name', 10);
remove_filter('get_previous_post_where', 'mytheme_previous_post_where_name', 10);
remove_filter('get_next_post_where', 'mytheme_next_post_where_name', 10);
If you want to check for your specific post_type, you can add an if around the adding filter section:
if($post->post_type == 'my_custom_post_type'){
add_filter(...);
the_post_navigation();
remove_filter(...);
}
or, you can just use a post_type specific single.php file!
This worked great for me, but there may be some limitations if you are planning on combining this with posts in the same term...

Categories