|
1
|
|
|
<?php |
|
|
|
|
|
|
2
|
|
|
/** |
|
3
|
|
|
* Earnings / Sales Stats |
|
4
|
|
|
* |
|
5
|
|
|
* @package Give |
|
6
|
|
|
* @subpackage Classes/Stats |
|
7
|
|
|
* @copyright Copyright (c) 2016, WordImpress |
|
8
|
|
|
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License |
|
9
|
|
|
* @since 1.0 |
|
10
|
|
|
*/ |
|
11
|
|
|
|
|
12
|
|
|
// Exit if accessed directly |
|
13
|
|
|
if ( ! defined( 'ABSPATH' ) ) { |
|
14
|
|
|
exit; |
|
15
|
|
|
} |
|
16
|
|
|
|
|
17
|
|
|
/** |
|
18
|
|
|
* Give_Stats Class |
|
19
|
|
|
* |
|
20
|
|
|
* This class is for retrieving stats for earnings and sales |
|
21
|
|
|
* |
|
22
|
|
|
* Stats can be retrieved for date ranges and pre-defined periods |
|
23
|
|
|
* |
|
24
|
|
|
* @since 1.0 |
|
25
|
|
|
*/ |
|
26
|
|
|
class Give_Payment_Stats extends Give_Stats { |
|
27
|
|
|
|
|
28
|
|
|
|
|
29
|
|
|
/** |
|
30
|
|
|
* Retrieve sale stats |
|
31
|
|
|
* |
|
32
|
|
|
* @access public |
|
33
|
|
|
* @since 1.0 |
|
34
|
|
|
* |
|
35
|
|
|
* @param $form_id INT The donation form to retrieve stats for. If false, gets stats for all forms |
|
36
|
|
|
* @param $start_date string|bool The starting date for which we'd like to filter our sale stats. If false, we'll use the default start date of `this_month` |
|
37
|
|
|
* @param $end_date string|bool The end date for which we'd like to filter our sale stats. If false, we'll use the default end date of `this_month` |
|
38
|
|
|
* @param $status string|array The sale status(es) to count. Only valid when retrieving global stats |
|
39
|
|
|
* |
|
40
|
|
|
* @return float|int Total amount of donations based on the passed arguments. |
|
41
|
|
|
*/ |
|
42
|
2 |
|
public function get_sales( $form_id = 0, $start_date = false, $end_date = false, $status = 'publish' ) { |
|
43
|
|
|
|
|
44
|
2 |
|
$this->setup_dates( $start_date, $end_date ); |
|
45
|
|
|
|
|
46
|
|
|
// Make sure start date is valid |
|
47
|
2 |
|
if ( is_wp_error( $this->start_date ) ) { |
|
48
|
|
|
return $this->start_date; |
|
49
|
|
|
} |
|
50
|
|
|
|
|
51
|
|
|
// Make sure end date is valid |
|
52
|
2 |
|
if ( is_wp_error( $this->end_date ) ) { |
|
53
|
|
|
return $this->end_date; |
|
54
|
|
|
} |
|
55
|
|
|
|
|
56
|
2 |
|
if ( empty( $form_id ) ) { |
|
57
|
|
|
|
|
58
|
|
|
// Global sale stats |
|
59
|
2 |
|
add_filter( 'give_count_payments_where', array( $this, 'count_where' ) ); |
|
60
|
|
|
|
|
61
|
2 |
|
if ( is_array( $status ) ) { |
|
62
|
|
|
$count = 0; |
|
63
|
|
|
foreach ( $status as $payment_status ) { |
|
64
|
|
|
$count += give_count_payments()->$payment_status; |
|
65
|
|
|
} |
|
66
|
|
|
} else { |
|
67
|
2 |
|
$count = give_count_payments()->$status; |
|
68
|
|
|
} |
|
69
|
|
|
|
|
70
|
2 |
|
remove_filter( 'give_count_payments_where', array( $this, 'count_where' ) ); |
|
71
|
|
|
|
|
72
|
2 |
|
} else { |
|
73
|
|
|
|
|
74
|
|
|
$this->timestamp = false; |
|
75
|
|
|
|
|
76
|
|
|
// Product specific stats |
|
77
|
|
|
global $give_logs; |
|
|
|
|
|
|
78
|
|
|
|
|
79
|
|
|
add_filter( 'posts_where', array( $this, 'payments_where' ) ); |
|
80
|
|
|
|
|
81
|
|
|
$count = $give_logs->get_log_count( $form_id, 'sale' ); |
|
82
|
|
|
|
|
83
|
|
|
remove_filter( 'posts_where', array( $this, 'payments_where' ) ); |
|
84
|
|
|
|
|
85
|
|
|
} |
|
86
|
|
|
|
|
87
|
2 |
|
return $count; |
|
88
|
|
|
|
|
89
|
|
|
} |
|
90
|
|
|
|
|
91
|
|
|
|
|
92
|
|
|
/** |
|
93
|
|
|
* Retrieve earning stats |
|
94
|
|
|
* |
|
95
|
|
|
* @access public |
|
96
|
|
|
* @since 1.0 |
|
97
|
|
|
* |
|
98
|
|
|
* @param $form_id INT The donation form to retrieve stats for. If false, gets stats for all forms |
|
99
|
|
|
* @param $start_date string|bool The starting date for which we'd like to filter our donation earnings stats. If false, we'll use the default start date of `this_month` |
|
100
|
|
|
* @param $end_date string|bool The end date for which we'd like to filter our sale stats. If false, we'll use the default end date of `this_month` |
|
101
|
|
|
* @param $gateway_id string|bool The gateway to get earnings for such as 'paypal' or 'stripe' |
|
102
|
|
|
* |
|
103
|
|
|
* @return float|int Total amount of donations based on the passed arguments. |
|
104
|
|
|
*/ |
|
105
|
2 |
|
public function get_earnings( $form_id = 0, $start_date = false, $end_date = false, $gateway_id = false ) { |
|
106
|
|
|
|
|
107
|
2 |
|
global $wpdb; |
|
|
|
|
|
|
108
|
|
|
|
|
109
|
2 |
|
$this->setup_dates( $start_date, $end_date ); |
|
110
|
|
|
|
|
111
|
|
|
// Make sure start date is valid |
|
112
|
2 |
|
if ( is_wp_error( $this->start_date ) ) { |
|
113
|
|
|
return $this->start_date; |
|
114
|
|
|
} |
|
115
|
|
|
|
|
116
|
|
|
// Make sure end date is valid |
|
117
|
2 |
|
if ( is_wp_error( $this->end_date ) ) { |
|
118
|
|
|
return $this->end_date; |
|
119
|
|
|
} |
|
120
|
|
|
|
|
121
|
2 |
|
add_filter( 'posts_where', array( $this, 'payments_where' ) ); |
|
122
|
|
|
|
|
123
|
2 |
|
if ( empty( $form_id ) ) { |
|
124
|
|
|
|
|
125
|
|
|
// Global earning stats |
|
126
|
|
|
$args = array( |
|
127
|
2 |
|
'post_type' => 'give_payment', |
|
128
|
2 |
|
'nopaging' => true, |
|
129
|
2 |
|
'post_status' => array( 'publish' ), |
|
130
|
2 |
|
'fields' => 'ids', |
|
131
|
2 |
|
'update_post_term_cache' => false, |
|
132
|
2 |
|
'suppress_filters' => false, |
|
133
|
2 |
|
'start_date' => $this->start_date, |
|
134
|
|
|
// These dates are not valid query args, but they are used for cache keys |
|
135
|
2 |
|
'end_date' => $this->end_date, |
|
136
|
2 |
|
'give_transient_type' => 'give_earnings', |
|
137
|
|
|
// This is not a valid query arg, but is used for cache keying |
|
138
|
2 |
|
); |
|
139
|
|
|
|
|
140
|
|
|
//Filter by Gateway ID meta_key |
|
141
|
2 |
|
if ( $gateway_id !== false ) { |
|
142
|
|
|
$args['meta_key'] = '_give_payment_gateway'; |
|
143
|
|
|
$args['meta_value'] = $gateway_id; |
|
144
|
|
|
} |
|
145
|
|
|
|
|
146
|
2 |
|
$args = apply_filters( 'give_stats_earnings_args', $args ); |
|
147
|
2 |
|
$key = 'give_stats_' . substr( md5( serialize( $args ) ), 0, 15 ); |
|
148
|
2 |
|
$earnings = get_transient( $key ); |
|
149
|
|
|
|
|
150
|
2 |
|
if ( false === $earnings ) { |
|
151
|
2 |
|
$sales = get_posts( $args ); |
|
152
|
2 |
|
$earnings = 0; |
|
153
|
2 |
|
if ( $sales ) { |
|
154
|
2 |
|
$sales = implode( ',', array_map('intval', $sales ) ); |
|
155
|
2 |
|
$earnings += $wpdb->get_var( "SELECT SUM(meta_value) FROM $wpdb->postmeta WHERE meta_key = '_give_payment_total' AND post_id IN({$sales})" ); |
|
156
|
2 |
|
} |
|
157
|
|
|
// Cache the results for one hour |
|
158
|
2 |
|
set_transient( $key, $earnings, HOUR_IN_SECONDS ); |
|
159
|
2 |
|
} |
|
160
|
|
|
|
|
161
|
2 |
|
} else { |
|
162
|
|
|
|
|
163
|
|
|
// Donation form specific earning stats |
|
164
|
|
|
global $give_logs, $wpdb; |
|
|
|
|
|
|
165
|
|
|
|
|
166
|
|
|
$args = array( |
|
167
|
|
|
'post_parent' => $form_id, |
|
168
|
|
|
'nopaging' => true, |
|
169
|
|
|
'log_type' => 'sale', |
|
170
|
|
|
'fields' => 'ids', |
|
171
|
|
|
'suppress_filters' => false, |
|
172
|
|
|
'start_date' => $this->start_date, |
|
173
|
|
|
// These dates are not valid query args, but they are used for cache keys |
|
174
|
|
|
'end_date' => $this->end_date, |
|
175
|
|
|
'give_transient_type' => 'give_earnings', |
|
176
|
|
|
// This is not a valid query arg, but is used for cache keying |
|
177
|
|
|
); |
|
178
|
|
|
$args = apply_filters( 'give_stats_earnings_args', $args ); |
|
179
|
|
|
$key = 'give_stats_' . substr( md5( serialize( $args ) ), 0, 15 ); |
|
180
|
|
|
//Set transient for faster stats |
|
181
|
|
|
$earnings = get_transient( $key ); |
|
182
|
|
|
|
|
183
|
|
|
if ( false === $earnings ) { |
|
184
|
|
|
|
|
185
|
|
|
$this->timestamp = false; |
|
186
|
|
|
$log_ids = $give_logs->get_connected_logs( $args, 'sale' ); |
|
187
|
|
|
$earnings = 0; |
|
188
|
|
|
|
|
189
|
|
|
if ( $log_ids ) { |
|
190
|
|
|
$log_ids = implode( ',', array_map('intval', $log_ids ) ); |
|
191
|
|
|
$payment_ids = $wpdb->get_col( "SELECT meta_value FROM $wpdb->postmeta WHERE meta_key='_give_log_payment_id' AND post_id IN ($log_ids);" ); |
|
192
|
|
|
|
|
193
|
|
|
foreach ( $payment_ids as $payment_id ) { |
|
194
|
|
|
$earnings += give_get_payment_amount( $payment_id ); |
|
195
|
|
|
} |
|
196
|
|
|
|
|
197
|
|
|
} |
|
198
|
|
|
|
|
199
|
|
|
// Cache the results for one hour |
|
200
|
|
|
set_transient( $key, $earnings, 60 * 60 ); |
|
201
|
|
|
} |
|
202
|
|
|
} |
|
203
|
|
|
|
|
204
|
|
|
//remove our filter |
|
205
|
2 |
|
remove_filter( 'posts_where', array( $this, 'payments_where' ) ); |
|
206
|
|
|
|
|
207
|
|
|
//return earnings |
|
208
|
2 |
|
return round( $earnings, give_currency_decimal_filter() ); |
|
209
|
|
|
|
|
210
|
|
|
} |
|
211
|
|
|
|
|
212
|
|
|
/** |
|
213
|
|
|
* Get the best selling Forms |
|
214
|
|
|
* |
|
215
|
|
|
* @access public |
|
216
|
|
|
* @since 1.0 |
|
217
|
|
|
* |
|
218
|
|
|
* @param $number int The number of results to retrieve with the default set to 10. |
|
219
|
|
|
* |
|
220
|
|
|
* @return array |
|
221
|
|
|
*/ |
|
222
|
1 |
|
public function get_best_selling( $number = 10 ) { |
|
223
|
|
|
|
|
224
|
1 |
|
global $wpdb; |
|
|
|
|
|
|
225
|
|
|
|
|
226
|
1 |
|
$give_forms = $wpdb->get_results( $wpdb->prepare( |
|
227
|
|
|
"SELECT post_id as form_id, max(meta_value) as sales |
|
228
|
1 |
|
FROM $wpdb->postmeta WHERE meta_key='_give_form_sales' AND meta_value > 0 |
|
229
|
|
|
GROUP BY meta_value+0 |
|
230
|
1 |
|
DESC LIMIT %d;", $number |
|
231
|
1 |
|
) ); |
|
232
|
|
|
|
|
233
|
1 |
|
return $give_forms; |
|
234
|
|
|
} |
|
235
|
|
|
|
|
236
|
|
|
} |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.