On my site, I intend to display the total number of posts and comments on the site, as well as the total number of purchases made from my site.
The codes I wrote are as follows:
//copy to functions.php
// Total Comment
function site_total_comment_count() {
$num_comm = get_comment_count();
$num_comm = $num_comm['total_comments'];
echo $num_comm ;}
add_shortcode('total_comment_count', 'site_total_comment_count');
// Total Completed Orders
function total_completed_Orders() {
$query = new WC_Order_Query( array(
'limit' => 99999,
'status' => array( 'completed' ),
'return' => 'ids',
) );
$orders = $query->get_orders();
return count( $orders ); }
// Copy to the desired page
<h2> All Orders:
<?php echo total_completed_Orders(); ?>
</h2>
<h2> All Comments:
<?php echo site_total_comment_count(); ?>
</h2>
<h2> All Posts:
<?php
echo $wpdb->get_var("SELECT COUNT(ID) FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish'");
?>
</h2>
These codes work fine individually, but when I put all three on the target page, the stats show wrong.
Can you write me a code that shows the correct statistics of these three items from my site?
You can create a custom shortcode.
Try out this in your functions.php file:
add_shortcode('custom_shortcode', 'kb_get_details');
function kb_get_details()
{
//For total post.
global $wpdb;
$total_post = $wpdb->get_var("SELECT COUNT(ID) FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish'");
//For total comments.
$num_comm = get_comment_count();
$total_cmt = $num_comm['total_comments'];
//For total orders.
$query = new WC_Order_Query(array(
'limit' => 99999,
'status' => array('completed'),
'return' => 'ids',
));
$orders = $query->get_orders();
$total_orders = count($orders);
?>
<h2>All Posts : <?php esc_html_e($total_post); ?></h2>
<h2>All Comments: <?php esc_html_e($total_cmt); ?></h2>
<h2>All Orders : <?php esc_html_e($total_orders); ?></h2>
<?php
}
After that, this shortcode can be directly add it to your target page from the backend. You can also add it to any custom template by the use of do_shortcode('[custom_shortcode]');
Related
Ok, so I know how to echo meta_key value for a post:
<?php
$meta_print_value=get_post_meta(get_the_ID(),'_heart_this',true);
echo($meta_print_value);
?>
I also know how to echo a TOTAL amount of posts with this specific meta_key:
<?php $query = new WP_Query( array( 'meta_key' => '_heart_this' ) )
echo $query->found_posts; ?>
What I need, is the TOTAL amount of posts for this meta_key for a post author.
I know I need to add get_the_author() somewhere in the above code to show the total amount of posts for the post author only, but struggling for a while now.
Any help would be appreciated.
Use Author Parameters in WP_Query(). You can use author id/name/multiple authors. For your case, the query should look like this:
<?php
$query = new WP_Query(
array(
'author' => get_the_author_meta( 'ID' );
'meta_key' => '_heart_this',
),
);
echo $query->found_posts; ?>
Is it possible to count the amount of the same meta_keys for the same post_id.
I have a page with the post_id 44 and every time a user submits something on this page a new database rule is added with the meta_key "post_rating_0".
There are over 30 rules now for this page and I want to count them.
For other pages the same thing.
Is this possible?
Code so far:
global $post;
$query_args = array(
'post_type' => 'page',
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_key' => 'post_rating_0'
// 'fields' => 'SUM(amount_to_paid)',
);
$sum = 0;
$query = new WP_Query($query_args);
if ( $query->have_posts() ) {
while( $query->have_posts() ) {
$query->the_post();
// do the processing for each post
$sum = $sum + intval(get_post_meta(get_the_id(),'post_rating_0', true ));
}
}
echo $sum ;
This is what I got so far... But what this does is echo the value of "2" what is very logic. It searches for posts with the meta_key "post_rating_0", counts them and that are 2 posts.
What I'm trying to do is count the amount of meta_keys "post_rating_0" are in one page.
This modified code will give you an array with all post_id and the corresponding amount of your specific meta:
$meta_arr = array();
$query = new WP_Query($query_args);
if ( $query->have_posts() ) {
while( $query->have_posts() ) {
$query->the_post();
$post_id = get_the_id();
$meta_arr[$post_id] = intval(get_post_meta($post_id, 'post_rating_0', false));
}
}
print_r($meta_arr);
Did some more research and with some modifications I managed to got it working. This is the final code:
$pagina_id_test = get_the_id();
// retrieve all meta_values with key 'post_rating_0' from database
$reviews_posts = $wpdb->get_results("
SELECT meta_value FROM " . $wpdb->prefix . "postmeta
WHERE meta_key = 'post_rating_0'
AND post_id = $pagina_id_test", ARRAY_A);
// define reviews array
$reviews_count = array();
// iterate through meta_values, count the occurence of each review
foreach ($reviews_posts as $reviews_post) {
if (isset($reviews_count[$reviews_post['meta_value']])) {
$reviews_count[$reviews_post['meta_value']] = $reviews_count[$reviews_post['meta_value']] + 1;
} else {
$reviews_count[$reviews_post['meta_value']] = 1;
}
}
// echo results
$aantal_reviews = 0;
foreach ($reviews_count as $review) {
$aantal_reviews++;
}
echo $aantal_reviews;
global $wpdb;
global $post;
$post_id = $post->ID;
$c = $wpdb->get_row("SELECT COUNT(*) as NBR FROM {$wpdb->postmeta}
WHERE post_id={$post_id} AND meta_key='post_rating_0' AND
(SELECT ID FROM {$wpdb->posts} WHERE ID={$post_id} AND post_type='page') IS NOT NULL");
echo $c->NBR;
Select count of post where post_type is page and meta_key='post_rating_0'
So I have done a bunch of looking around the web and couldn't find a solution for this...
Basically what I am trying to do is display a product loop of all the products the user has purchased in the store just like displaying normal products.
If you still don't understand maybe this will help you get what I mean..
Here is the example product loop on the WooCommerce documentation...
<ul class="products">
<?php
$args = array(
'post_type' => 'product',
'posts_per_page' => 12
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
woocommerce_get_template_part( 'content', 'product' );
endwhile;
} else {
echo __( 'No products found' );
}
wp_reset_postdata();
?>
</ul><!--/.products-->
So what if I wanted to display basically this same exact product loop however filter it out so that it only displays products that the user has already purchased.
I honestly do not know where to go with this one and I am sure there are others that have done research on this in the past so maybe this will help out a bunch of people!
Thanks in advance!
There are at least two different approaches you can take to solve this problem.
The first is to get the product from each post, and then get the product ID from each product and then use an if statement to filter using wc_customer_bought_product or woocommerce_customer_bought_product (if you are using old WooCommerece).
The second is to pass the correct arguments to filter the WP_Query to only include orders purchased by a user and then filter products only in those orders. More information on the second approach is available at Get All User Orders and Products bought by user in WooCommerce based shop (archive.org).
An example of the first approach is something like
<!-- code started -->
<ul class="products">
<?php
$user_id = get_current_user_id();
$current_user= wp_get_current_user();
$customer_email = $current_user->email;
$args = array(
'post_type' => 'product',
'posts_per_page' => 12
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post(); $_product = get_product( $loop->post->ID );
if (wc_customer_bought_product($customer_email, $user_id,$_product->id)){
woocommerce_get_template_part( 'content', 'product' );
}
endwhile;
} else {
echo __( 'No products found' );
}
wp_reset_postdata();
?>
</ul><!--/.products-->
Kudos to Appleman1234 for providing two answers, both of which will work.
ApppleMan1234's first answer that he provided an example for is to loop through all products and then filter them by calling wc_customer_bought_product(). This certainly will work. If you have n products then you are going to make n+1 database queries.
His second suggestion is a link to a post written by Brajesh Singh who, on June 2, 2013, published a solution on fusedpress.com. The original post is no longer available. I found a cached copy at Google.
Brajesh Singh's solution queries the user's orders, then queries the order details, and last queries the product id in the order item's metadata. This solution then is always only 3 queries. Unless your shop only has 1 or 2 products, this solution is far better.
Here is a slightly edited version of Brajesh Singh's code.
/**
* Get all Products Successfully Ordered by the user
* #return bool|array false if no products otherwise array of product ids
*/
function so28362162_get_all_products_ordered_by_user() {
$orders = so28362162_get_all_user_orders(get_current_user_id(), 'completed');
if(empty($orders)) {
return false;
}
$order_list = '(' . join(',', $orders) . ')';//let us make a list for query
//so, we have all the orders made by this user that were completed.
//we need to find the products in these orders and make sure they are downloadable.
global $wpdb;
$query_select_order_items = "SELECT order_item_id as id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id IN {$order_list}";
$query_select_product_ids = "SELECT meta_value as product_id FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_key=%s AND order_item_id IN ($query_select_order_items)";
$products = $wpdb->get_col($wpdb->prepare($query_select_product_ids, '_product_id'));
return $products;
}
/**
* Returns all the orders made by the user
* #param int $user_id
* #param string $status (completed|processing|canceled|on-hold etc)
* #return array of order ids
*/
function so28362162_get_all_user_orders($user_id, $status = 'completed') {
if(!$user_id) {
return false;
}
$args = array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => $user_id,
'post_type' => 'shop_order',
'post_status' => 'publish',
'tax_query' => array(
array(
'taxonomy' => 'shop_order_status',
'field' => 'slug',
'terms' => $status
)
)
);
$posts = get_posts($args);
//get the post ids as order ids
return wp_list_pluck($posts, 'ID');
}
Combining that with a product loop from the question, plus a non-deprecated wc_get_template_part() and an addition of posts_per_page=-1 gives us
<ul class="products">
<?php
$args = array(
'post_type' => 'product',
'post__in' => so28362162_get_all_products_ordered_by_user(),
'posts_per_page' => -1
);
$loop = new WP_Query($args);
if($loop->have_posts()) {
while($loop->have_posts()) : $loop->the_post();
wc_get_template_part('content', 'product');
endwhile;
}
else {
echo __('No products found');
}
wp_reset_postdata();
?>
</ul><!--/.products-->
Not sure if this helps you out at all, but there is a plugin developed by WooThemes to support purchase history.
Running a voting system on my site that lets users vote on posts with the standard up/down type thing.
I'm trying to run a query on author pages to get the total number of 'votes' that author has attributed to them over all the posts they've made.
Small problem is that when the author has zero votes it displays the total number of votes from the meta_key value for every author on the site.
Code:-
<?php
function author_rating_total() {
$user_id = get_the_author_meta( 'ID' );
$query = array (
'author' => $user_id,
'suppress_filters' => 'true', //lets skip some unnessecery sql queries
'posts_per_page' => -1
);
$queryObject = new WP_Query($query); while($queryObject->have_posts()) : $queryObject->the_post();
$post_ratings_data = get_post_custom(get_the_id());
$post_ratings_score = intval($post_ratings_data['votecount'][0]);
$ratings_array[] = $post_ratings_score;
endwhile;
$ratings_sum = array_sum($ratings_array);
if ($ratings_sum > 0) {
$ratings_sum = '' . $ratings_sum;
}
echo $ratings_sum;
wp_reset_query();
}
?>
<?php
echo author_rating_total();
?>
How do I return the value 0 instead of the total number of that meta_key?
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...