Wordpress latest Posts AND comments feed? - sql

I'm trying to write a custom SQL query that will create a list of the most recent Posts AND comments and I'm having trouble visualizing how i can do this.
I can pull the latest comments by date DESC and i can pull the latest posts by date DESC but how do I make a feed / query to show them both?
Here is my comment SQL
SELECT comment_id, comment_content, comment_date
FROM wp_comments
WHERE comment_author = 'admin'
ORDER BY comment_date DESC
Edit: more clear:
Sorry, I should have been a little more clear. I want to have a list like this based on what date they occurred:
Wordpress post
wordpress post
wordpress comment
wordpress post
wordpress comment
So if someone comments on a 4 month old post, it will still show up at the top of this 'feed'

To get a list based solely on the most recent timestamp from two tables, you need to use a UNION:
SELECT wc.comment_date AS dt
FROM WP_COMMENTS wc
UNION ALL
SELECT wp.post_date AS dt
FROM WP_POSTS wp
ORDER BY dt
...where dt is the column alias for the column that holds the date value for records in either table.
Use UNION ALL - because data is from two different tables, there's no change of duplicates to filter out. But that means you have to get the other columns you want from either table to line up based on data and data type...

I think your best bet (and to avoid using custom SQL) would be to grab the latest X posts and X comments, loop over each and build an array to merge the two into one 'most recent' data set;
$comments = get_comments('number=X');
$posts = get_posts('posts_per_page=X');
$most_recent = array();
foreach ($comments as $comment)
$most_recent[strtotime($comment->comment_date_gmt)] = $comment;
foreach ($posts as $post)
$most_recent[strtotime($post->post_date_gmt)] = $post;
unset($comments, $posts);
krsort($most_recent);
$most_recent = array_slice($most_recent, 0, X);
foreach ($most_recent as $post_or_comment) {
$is_post = isset($post_or_comment->post_date_gmt);
// output comments and posts
}
It ain't too pretty, but it should do it.

No special mySql necessary, just use the query_posts loop and the get_comments function in the loop.
<?php query_posts('posts_per_page=10'); while (have_posts()) : the_post(); ?>
<div>
<a href="<?php the_permalink() ?>" title="Permanent Link to <?php the_title_attribute(); ?>"<?php the_title_attribute(); ?></a>
<?php echo the_title(); ?>
<?php
$comments = get_comments();
foreach($comments as $comm) :
echo($comm->comment_author);
echo($comm->comment_content);
endforeach;
?>
</div>
<?php endwhile; ?>

Related

WooCommerce products shortcode order by sku list

Is there a way to modify the WooCommerce Products shortcode to order by a list of product sku's?
A search engine send a Post to the page with a list of sku's. The page should display the Products in the same order the http post is.
Example php and mysql select (the code like this worked in my old shop system where I can use SQL syntax):
$_POST['skus'] = "51,57,34,12,111";
$skus = $_POST['skus'];
select * from products where sku in ('$skus') order by FIELD(sku,'$skus);
How can I do an "orderby" like the example with products shortcode from woocommerce or is there a better way to do that with woocommerce?
Thanks for every answer.
With the help from Gavin and the code from https://wordpress.stackexchange.com/a/67830/43362
I found this solution:
function wpse67823_orderby_post_in($orderby, $query){
//Remove it so it doesn't effect future queries
remove_filter(current_filter(), __FUNCTION__);
$post__in = $_POST['skus'];
$post__in = str_replace(',','\',\'',$post__in);
return "FIELD(CAST(mt2.meta_value AS CHAR), '$post__in' )";
}
//Add filter and perform query
add_filter('posts_orderby','wpse67823_orderby_post_in',10,2);
echo do_shortcode('[products skus="'.$skus.'" orderby="sku"]');
remove_filter('posts_orderby','wpse67823_orderby_post_in',10,2);

How to use YII's createCommand to also return total items?

Let's say I do a simple query:
$products =
Yii::app()->db->createCommand()->setFetchMode(PDO::FETCH_OBJ)
->select('*')
->from('products')
->limit(9)
->queryAll();
Let's say there are 500 products in the database. Is there a way I can get YII to automatically return the total number (count) of products if the "limit" was included? Perhaps return an object like this:
$products->products = array( ... products ... )
$products->totalProducts = 500;
The problem is, if LIMIT is included, it will return items, and the count will therefore be 9. I want a solution whereby it will return the 9 items, but also the count of say 200 items if there were 200 items.
Why not an easy:
$сount = Yii::app()->db->createCommand('select count(*) from table')->queryScalar();
echo $count;
You'll either have to run two queries (a count(*) query without the limit and then the limited query) or you can send you can retrieve your products using CSqlDataProvider and let it do it for you. But it generally takes two queries.
Note: one of the nifty features in Yii 1.1.13 is that you can send your query builder command in to the CSqlDataProvider if you're going to be using a dataprovider. More information at on this pull request that fixed it. That way, you can both use the power of query builder while also being able to shift your data into a dataprovider. Previously you had to build your SQL statement manually or grab the queryText of the command.
Yii::app()->db->createCommand('select count(*) from tbl_table')->queryScalar();
Try to use execute() instead of query() because execute returns rows count.
example:
$rowCount = $command->execute();
You could try using COUNT like this:
$dbCommand = Yii::app()->db->createCommand("
SELECT COUNT(*) as count FROM `products`");
$data = $dbCommand->queryAll();
Hope that helps!
EDIT: You might find this useful too: CDataProvider
Try this -
$sql = Yii::app()->db->createCommand('select * from tbl_table')->queryAll(); //It's return the Array
echo count($sql); //Now using count() method we can count the array.

how to create criteria with join in yii

I have to tables, one is profile and the other is rating.
rating has a field profileid which is primary key to profile.id and a field with rating values. Now I want to find the field with highest rating and display the corresponding profile. Since I'm new to YII framework I'm having troubles with it. Please help me getting out of it. What I'm doing is described below.
$topRage=new CDbCriteria();
$topRage->select="*";
$topRage->alias="t1";
$topRage->order="rateing DESC";
$topRage->join="JOIN `ratings` ON `profile`.`id` = `t1`.`profileId`";
$topRage->limit="1";
Try this :
join='JOIN profile ON profile.id = t1.profileId';
If you are doing this: Ratings::model()->findAll($topRage) , then ratings table is already being queried, so you need to join with profile table.
Edit:
for echo you'll need to do this:
$echo "Rating id: ".$rating->id."|&nbspProfile Id: ".$rating->profile->id."|&nbspProfile Name: ".$rating->profile->name."|&nbspRating: ".$rating->ratingvalue;
Don't forget to pass $rating from the controller though.
You could also use find($topRage) instead of the findAll($topRage) and remove the limit, but that 's just another way of doing the same thing.
just query without join .
$topRage=new CDbCriteria();
$topRage->select="*";
$topRage->alias="t1";
$topRage->order="rateing DESC";
$topRage->limit="1";
$rating=Ratings::model()->findAll($topRage);
$profile=Profile::model()->findByPk($rating->profileId);

How to Write a SQL Query to Display list of most used tags in the last 30 days in Wordpress website

I am looking for a way to display the most used tags over the last 30 days on my Baseball blog, built on Wordpress. I am no coder, but I have come up with this mashup to display a list of the most used 28 tags (preference to fit my theme). I cannot, for the life of me, figure out how to limit the tags to the most used in the last 30 days.
Here is what I have:
<ul id="footer-tags">
<?php
global $wpdb;
$term_ids = $wpdb->get_col("
SELECT DISTINCT term_taxonomy_id FROM $wpdb->term_relationships
INNER JOIN $wpdb->posts ON $wpdb->posts.ID = object_id
WHERE DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= $wpdb->posts.post_date");
if(count($term_ids) > 0){
$tags = get_tags(array(
'orderby' => 'count',
'order' => 'DESC',
'number' => 28,
'include' => $term_ids,
));
foreach ( (array) $tags as $tag ) {
echo '<li>' . $tag->name . '</li>';
}
}
?>
</ul>
The website is slightly less than ~4 weeks old, so to test, I changed INTERVAL 30 DAY to INTERVAL 3 DAY and the tags being returned seem random and some haven't been used in 2+ weeks and have only been used a single time. As well, only 8 tags are being displayed, when more have been used.
To check that the correct number of days have been queried, I did the following:
Completely deleted all items in the trash for posts and pages, I don't have any custom post types.
Did the same with drafts.
Ran a query in phpmyadmin to delete all post revisions - DELETE FROM wp_posts WHERE post_type = "revision";
Ran a query in phpmyadmin to check if the results are the posts from the last 3 days - SELECT * from wp_posts WHERE DATE_SUB(CURDATE(), INTERVAL 3 DAY) <= post_date
The results from the phpmyadmin query were, in fact, the posts from the last 3 days, but the front-end display did not change.
UPDATE
Here are some screen shots. Maybe the screenshots can help find where my code is wrong.
Blog Post with Category and Tags
wp_posts table with the post ID of above post
wp_terms table with the term_id of the tags used
wp_term_taxonomy with the tags' term_id as term_taxonomy_id
wp_term_relationships with term_taxonomy_id assigned to post as object_id
UPDATE 2
I think I figured out the problem, but do not know how to fix it.
The SQL query gets the term_taxonomy_id, not the actual tag ID and get_tag_link uses term_id
UPDATE 3
I have recently created a plugin to display the most popular recently used tags - https://wordpress.org/plugins/recent-popular-tags/
The PHP variables you are inserting in your SQL string are the PHP objects that can be used to access WordPress tables from within PHP; whereas you are after the names of the tables and columns for accessing the data from within SQL.
You want instead:
"SELECT DISTINCT term_taxonomy_id FROM wp_term_relationships
INNER JOIN wp_posts ON wp_posts.ID = wp_term_relationships.object_id
WHERE DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= wp_posts.post_date"
As an aside: should you ever need to insert the value of a PHP variable into a SQL statement, be very careful to escape it first in order to prevent any malicious code from being injected.
The problem was that the SQL query code was getting the term_taxonomy_id, not the actual tag ID.
I added an additional INNER JOIN using the term_taxonomy table to get the term_id. This seems to work, but if a mod can improve this, please do!
<ul id="footer-tags">
<?php $wpdb->show_errors(); ?>
<?php
global $wpdb;
$term_ids = $wpdb->get_col("
SELECT term_id FROM $wpdb->term_taxonomy
INNER JOIN $wpdb->term_relationships ON $wpdb->term_taxonomy.term_taxonomy_id=$wpdb->term_relationships.term_taxonomy_id
INNER JOIN $wpdb->posts ON $wpdb->posts.ID = $wpdb->term_relationships.object_id
WHERE DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= $wpdb->posts.post_date");
if(count($term_ids) > 0){
$tags = get_tags(array(
'orderby' => 'count',
'order' => 'DESC',
'number' => 28,
'include' => $term_ids,
));
foreach ( (array) $tags as $tag ) {
echo '<li>' . $tag->name . '</li>';
}
}
?>
</ul>
UPDATE
I have recently created a plugin to display the most popular recently used tags - https://wordpress.org/plugins/recent-popular-tags/

Yii order by another table CActiveDataProvider

I am a bit stumped on this. Basically I have two tables:
Page:
id
name
Points:
id-
pageid
points
I am looking to get the records from the Page table, and sort it by the amount of points it has in the Points table (the points field)
Currently I have:
$dataProvider=new CActiveDataProvider('Page',array(
'criteria'=>array(
'condition'=>"active = 1 AND userid IN (".$ids.")",
'order'=>"???",
),
'pagination'=>array(
'pageSize'=>30,
),
));
I just don't know how to sort it by the Points table value for the relevant record
I have set up a relation for the Page/Points tables like so:
(in the Page model)
'pagepoints' => array(self::HAS_ONE, 'Points', 'pageid'),
Thanks
You need to do two things:
Add the pagepoints relation to the with part of the query criteria
Reference the column you want to sort by in the order part of the criteria
I 've marked the lines where this happens in the code below:
$dataProvider = new CActiveDataProvider('Page', array(
'criteria'=>array(
'with' => array('pagepoints'), // #1
'condition' => 'active = 1 AND userid IN ('.$ids.')',
'order' => 'pagepoints.points', // #2
),
'pagination'=>array(
'pageSize'=>30,
),
));
What you need to know to understand how this works is that when Yii builds the SQL query (which is a LEFT OUTER JOIN to the Points table), it uses the name you gave to the relation in the Page model (you give the definition for this, it's pagepoints) to alias the joined table. In other words, the query looks like:
SELECT ... FROM Page ... LEFT OUTER JOIN `Points` `pagepoints` ...
It follows that the correct specification for the sort order is pagepoints.points: pagepoints is the table alias, and points is the column in that table.
Try the following
$dataProvider=new CActiveDataProvider('Page',array(
'criteria'=>array(
'with'=>array('pagepoints'),
'condition'=>"active = 1 AND userid IN (".$ids.")",
'order'=>"t.points DESC",
),
'pagination'=>array(
'pageSize'=>30,
),
));
this is the sql you want to generate:
select * from page inner join points
on page.id = points.page_id order by
points.points desc