I want to calculate the sum of a meta-value after Views has run the wp-query.
I have a paginated view.
I have created a working shortcode.
The problem is that the shortcode returns the sum based on the posts in the current page in the paginated view. I want the sum of all posts found in the query.
I need the sum to update when the user changes the filter inputs.
Is there another views API filter for this?
I am currently using "get_view_query_results( $view_id )"
In the image you can see a sum in the table footer. The sum is only for the posts on the current page not for all pages.
This is the code for my current shortcode:
//sum post meta after view query
function calc_meta_sum_function($atts) {
$view_id = $atts['viewid'];
$wpcf_field = $atts['wpcf'];
$sum = 0;
$filtered_posts = get_view_query_results( $view_id );
foreach ( $filtered_posts as $filtered_post ) {
$sum = $sum + get_post_meta( $filtered_post->ID, $wpcf_field, true );
}
return $sum;
}
add_shortcode('calc-meta-sum', 'calc_meta_sum_function');
This is how I apply the shortcode in the view:
Inside table footer (tfoot) [calc-meta-sum viewid='10073' wpcf='wpcf-invoice-tot']
[wpv-layout-start]
[wpv-items-found]
<!-- wpv-loop-start -->
<table width="100%" class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>[wpv-heading name="types-field-book-invoice-paid-date"]Datum[/wpv-heading]</th>
<th class="text-right">[wpv-heading name="post-id"]Nr[/wpv-heading]</th>
<th class="text-right">[wpv-heading name="types-field-invoice-net"]Netto[/wpv-heading]</th>
<th class="text-right">[wpv-heading name="types-field-invoice-vat"]Moms[/wpv-heading]</th>
<th class="text-right">[wpv-heading name="types-field-invoice-tot"]Total[/wpv-heading]</th>
</tr>
</thead>
<tfoot>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<th class="text-right">[calc-meta-sum viewid='10073' wpcf='wpcf-invoice-tot']</th>
</tr>
</tfoot>
<tbody class="wpv-loop js-wpv-loop">
<wpv-loop>
<tr>
[wpv-conditional if="( $(wpcf-book-invoice-paid-date) gt '0' )"][wpv-post-body view_template="Loop item in Transactions"][/wpv-conditional]
</tr>
</wpv-loop>
</tbody>
</table>
<!-- wpv-loop-end -->
[wpv-post-body view_template="pagination" raw="true"]
[/wpv-items-found]
[wpv-no-items-found]
<strong>[wpml-string context="wpv-views"]No items found[/wpml-string]</strong>
[/wpv-no-items-found]
[wpv-layout-end]
Dear Tina,
Please try to modify your PHP codes as below:
function calc_meta_sum_function($atts) {
$view_id = $atts['viewid'];
$wpcf_field = $atts['wpcf'];
$sum = 0;
add_filter('wpv_filter_wpv_get_view_settings', 'test_func', 10, 2);
$filtered_posts = get_view_query_results( $view_id, null, null, array('limit'=>-1) );
foreach ( $filtered_posts as $filtered_post ) {
$sum = $sum + (int)get_post_meta( $filtered_post->ID, $wpcf_field, true );
}
remove_filter('wpv_filter_wpv_get_view_settings', 'test_func', 10);
return $sum;
}
add_shortcode('calc-meta-sum', 'calc_meta_sum_function');
function test_func($settings, $view_id){
if($view_id == 10073){
$settings['pagination']['type'] = 'disabled';
}
return $settings;
}
Thank you for your reply.
I have some questions.
Please explain the parameters for get view query results. Is limit required? Doesn't it follow the settings of the view? What are "null", "null"?
get_view_query_results( $view_id, null, null, array('limit'=>-1) );
Regarding test_func(). if($view_id == 10073) makes my shortcode static. Is there a way to keep it dynamic?
Q1) Is limit required?
Yes, in your case, you are going to ignore the view's pagination settings, it is required to setup the parameter "limit" to -1
Q2)Doesn't it follow the settings of the view?
As I mentioned above, it will ignore the view's pagination settings
Q3) What are "null", "null"?
Those are parameter of function "get_view_query_results":
$post_in = null
$current_user_in = null
Q4) Regarding test_func(). if($view_id == 10073) makes my shortcode static. Is there a way to keep it dynamic?
The var "$view_id" is a dynamic variable, you can change the number to any value you want. it is the specific view's ID.
Thank you for helping me understand.
(I still don't get the how the test_func() is dynamic when the code says if view id == fixed number)
I solved it by creating another view that calls all posts and responds to the same filter url parameters. I placed this in a separate table row outside of the other view so it remains constant.