PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.3.2
GiveWP – Donation Plugin and Fundraising Platform v4.3.2
4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / src / API / Endpoints / Reports / Endpoint.php
give / src / API / Endpoints / Reports Last commit date
AverageDonation.php 4 years ago DonationsVsIncome.php 4 years ago Endpoint.php 1 year ago FormPerformance.php 4 years ago Income.php 4 years ago IncomeBreakdown.php 4 years ago PaymentMethods.php 4 years ago PaymentStatuses.php 4 years ago RecentDonations.php 4 years ago TopDonors.php 4 years ago TotalDonors.php 4 years ago TotalIncome.php 4 years ago TotalRefunds.php 4 years ago
Endpoint.php
450 lines
1 <?php
2
3 /**
4 * Reports base endpoint
5 *
6 * @package Give
7 */
8
9 namespace Give\API\Endpoints\Reports;
10
11 use DateInterval;
12 use DateTime;
13 use Give\API\RestRoute;
14 use Give_Cache;
15 use Give_Payment;
16 use WP_Error;
17 use WP_REST_Request;
18 use WP_REST_Response;
19
20 abstract class Endpoint implements RestRoute
21 {
22 /**
23 * @since 2.6.1
24 * @var WP_REST_Request
25 */
26 protected $request;
27
28 /**
29 * @var DateTime
30 */
31 protected $startDate;
32
33 /**
34 * @var DateTime
35 */
36 protected $endDate;
37
38 /**
39 * @var DateInterval
40 */
41 protected $dateDiff;
42
43 /**
44 * @var string
45 */
46 protected $endpoint;
47
48 /**
49 * @var boolean
50 */
51 protected $testMode;
52
53 /**
54 * @var string
55 */
56 protected $currency;
57
58 /**
59 * @var array
60 */
61 protected $schema;
62
63 /**
64 * @inheritDoc
65 */
66 public function registerRoute()
67 {
68 register_rest_route(
69 'give-api/v2',
70 '/reports/' . $this->endpoint,
71 [
72 // Here we register the readable endpoint
73 [
74 'methods' => 'GET',
75 'callback' => [$this, 'handleRequest'],
76 'permission_callback' => [$this, 'permissionsCheck'],
77 'args' => [
78 'start' => [
79 'type' => 'string',
80 'required' => true,
81 'validate_callback' => [$this, 'validateDate'],
82 'sanitize_callback' => [$this, 'sanitizeDate'],
83 ],
84 'end' => [
85 'type' => 'string',
86 'required' => true,
87 'validate_callback' => [$this, 'validateDate'],
88 'sanitize_callback' => [$this, 'sanitizeDate'],
89 ],
90 'currency' => [
91 'type' => 'string',
92 'required' => true,
93 'validate_callback' => [$this, 'validateCurrency'],
94 ],
95 'testMode' => [
96 'type' => 'boolean',
97 'required' => true,
98 'sanitize_callback' => [$this, 'sanitizeTestMode'],
99 ],
100 ],
101 ],
102 // Register our schema callback.
103 'schema' => [$this, 'getReportSchema'],
104 ]
105 );
106 }
107
108 /**
109 * Handle rest request.
110 *
111 * @since 2.6.1
112 *
113 * @param WP_REST_Request $request
114 *
115 * @return WP_REST_Response
116 */
117 public function handleRequest($request)
118 {
119 // Check if a cached version exists
120 $cached_report = $this->getCachedReport($request);
121 if ($cached_report !== null) {
122 // Bail and return the cached version
123 return new WP_REST_Response($cached_report);
124 }
125
126 $this->setupProperties($request);
127
128 $responseData = [
129 'status' => $this->getGiveStatus(),
130 'data' => $this->getReport($request),
131 ];
132
133 $this->cacheReport($request, $responseData);
134
135 return new WP_REST_Response($responseData);
136 }
137
138 /**
139 * Setup properties
140 *
141 * @since 2.6.1
142 *
143 * @param WP_REST_Request $request
144 */
145 private function setupProperties($request)
146 {
147 $this->request = $request;
148 $this->startDate = date_create($request->get_param('start'));
149 $this->endDate = date_create($request->get_param('end'));
150 $this->currency = $request->get_param('currency');
151 $this->testMode = $request->get_param('testMode');
152 $this->dateDiff = date_diff($this->startDate, $this->endDate);
153 }
154
155 public function validateDate($param, $request, $key)
156 {
157 // Check that date is valid, and formatted YYYY-MM-DD
158 $exploded = explode('-', $param);
159 $valid = checkdate($exploded[1], $exploded[2], $exploded[0]);
160
161 // If checking end date, check that it is after start date
162 if ($key === 'end') {
163 $start = date_create($request->get_param('start'));
164 $end = date_create($request->get_param('end'));
165 $valid = $start <= $end ? $valid : false;
166 }
167
168 return $valid;
169 }
170
171 /**
172 * @since 2.9.0 Restrict appended time to only the end date.
173 * @since 2.6.1
174 */
175 public function sanitizeDate($param, $request, $key)
176 {
177 // Return Date object from parameter
178 $exploded = explode('-', $param);
179
180 $sanitizedDate = "{$exploded[0]}-{$exploded[1]}-{$exploded[2]}";
181
182 if ('end' === $key) {
183 /**
184 * For the end date manually specify an end time.
185 */
186 $sanitizedDate .= ' 24:00:00';
187 }
188
189 return $sanitizedDate;
190 }
191
192 /**
193 * Validate currency string
194 * Check if currency code provided to REST APi is valid
195 *
196 * @param string $param Currency parameter provided in REST API request
197 * @param WP_REST_Request $request REST API Request object
198 * @param string $key REST API Request key being validated (in this case currency)
199 *
200 * @return bool
201 */
202 public function validateCurrency($param, $request, $key)
203 {
204 return in_array($param, array_keys(give_get_currencies_list()));
205 }
206
207 /**
208 * Sanitize test mode parameter
209 * Uses filter_var to cast string to variable
210 *
211 * @param string $param Validated test mode parameter provided in REST API request
212 * @param WP_REST_Request $request REST API Request object
213 * @param string $key REST API Request key being validated (in this case test mode)
214 */
215 public function sanitizeTestMode($param, $request, $key)
216 {
217 return filter_var($param, FILTER_VALIDATE_BOOLEAN);
218 }
219
220 /**
221 * Check permissions
222 *
223 * @since 3.22.2 change permissions to view_give_reports
224 *
225 * @param WP_REST_Request $request Current request.
226 *
227 * @return bool|WP_Error
228 */
229 public function permissionsCheck($request)
230 {
231 if ( ! current_user_can('view_give_reports')) {
232 return new WP_Error(
233 'rest_forbidden',
234 esc_html__('You cannot view the reports resource.', 'give'),
235 ['status' => $this->authorizationStatusCode()]
236 );
237 }
238
239 return true;
240 }
241
242 /**
243 * Get report callback
244 *
245 * @param WP_REST_Request $request Current request.
246 *
247 * @return array
248 */
249 public function getReport($request)
250 {
251 return [
252 'data' => [
253 'labels' => ['a', 'b', 'c'],
254 'data' => ['1', '4', '3'],
255 ],
256 ];
257 }
258
259 /**
260 * Get our sample schema for a report
261 */
262 public function getReportSchema()
263 {
264 if ($this->schema) {
265 // Since WordPress 5.3, the schema can be cached in the $schema property.
266 return $this->schema;
267 }
268
269 $this->schema = [
270 // This tells the spec of JSON Schema we are using which is draft 4.
271 '$schema' => 'http://json-schema.org/draft-04/schema#',
272 // The title property marks the identity of the resource.
273 'title' => 'report',
274 'type' => 'object',
275 // In JSON Schema you can specify object properties in the properties attribute.
276 'properties' => [
277 'data' => [
278 'description' => esc_html__('The data for the report.', 'give'),
279 'type' => 'object',
280 ],
281 ],
282 ];
283
284 return $this->schema;
285 }
286
287 // Sets up the proper HTTP status code for authorization.
288 public function authorizationStatusCode()
289 {
290 $status = 401;
291 if (is_user_logged_in()) {
292 $status = 403;
293 }
294
295 return $status;
296 }
297
298 /**
299 * Get cached report
300 *
301 * @param WP_REST_Request $request Current request.
302 *
303 * @return mixed
304 */
305 public function getCachedReport($request)
306 {
307 $cache_key = Give_Cache::get_key("api_get_report_{$this->endpoint}", $request->get_params());
308
309 $cached = Give_Cache::get_db_query($cache_key);
310
311 if ($cached) {
312 return $cached;
313 }
314
315 return null;
316 }
317
318 /**
319 * Cache report
320 *
321 * @param WP_REST_Request $request Current request.
322 * @param array $report
323 *
324 * @return bool
325 */
326 public function cacheReport($request, $report)
327 {
328 $cache_key = Give_Cache::get_key("api_get_report_{$this->endpoint}", $request->get_params());
329
330 return Give_Cache::set_db_query($cache_key, $report);
331 }
332
333 /**
334 * Cache report
335 *
336 * @param array $args Query arguments.
337 * @param Give_Payment[] $payments Payments.
338 *
339 * @return bool
340 */
341 private function cachePayments($args, $payments)
342 {
343 $cache_key = Give_Cache::get_key('api_report_payments', $args);
344
345 return Give_Cache::set_db_query($cache_key, $payments);
346 }
347
348 /**
349 * Get cached report
350 *
351 * @param array $args Query arguments.
352 *
353 * @return mixed
354 */
355 private function getCachedPayments($args)
356 {
357 $cache_key = Give_Cache::get_key('api_report_payments', $args);
358
359 $cached = Give_Cache::get_db_query($cache_key);
360
361 if ($cached) {
362 return $cached;
363 }
364
365 return null;
366 }
367
368 /**
369 * Get payment.
370 *
371 * @param string $startStr
372 * @param string $endStr
373 * @param string $orderBy
374 * @param int $number
375 *
376 * @return mixed
377 */
378 public function getPayments($startStr, $endStr, $orderBy = 'date', $number = -1)
379 {
380 $gatewayObjects = give_get_payment_gateways();
381 $paymentModeKeyCompare = '!=';
382
383 if ($this->testMode === false) {
384 unset($gatewayObjects['manual']);
385 $paymentModeKeyCompare = '=';
386 }
387
388 $gateway = array_keys($gatewayObjects);
389
390 $args = [
391 'post_status' => [
392 'publish',
393 'give_subscription',
394 ],
395 'number' => $number,
396 'paged' => 1,
397 'orderby' => $orderBy,
398 'order' => 'DESC',
399 'start_date' => strtotime($startStr),
400 'end_date' => strtotime($endStr),
401 'gateway' => $gateway,
402 'meta_query' => [
403 [
404 'key' => '_give_payment_currency',
405 'value' => $this->currency,
406 'compare' => '=',
407 ],
408 [
409 'key' => '_give_payment_mode',
410 'value' => 'live',
411 'compare' => $paymentModeKeyCompare,
412 ],
413 ],
414 ];
415
416 // Check if a cached payments exists
417 $cached_payments = $this->getCachedPayments($args);
418
419 if ($cached_payments !== null) {
420 // Bail and return the cached payments
421 return $cached_payments;
422 }
423
424 $payments = new \Give_Payments_Query($args);
425 $payments = $payments->get_payments();
426
427 // Cache the report data
428 $this->cachePayments($args, $payments);
429
430 return $payments;
431 }
432
433 public function getGiveStatus()
434 {
435 $donations = get_posts(
436 [
437 'post_type' => ['give_payment'],
438 'post_status' => 'publish',
439 'numberposts' => 1,
440 ]
441 );
442
443 if (count($donations) > 0) {
444 return 'donations_found';
445 }
446
447 return 'no_donations_found';
448 }
449 }
450