This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Give API |
||
4 | * |
||
5 | * A front-facing JSON/XML API that makes it possible to query donation data. |
||
6 | * |
||
7 | * @package Give |
||
8 | * @subpackage Classes/API |
||
9 | * @copyright Copyright (c) 2016, WordImpress |
||
10 | * @license https://opensource.org/licenses/gpl-license GNU Public License |
||
11 | * @since 1.1 |
||
12 | */ |
||
13 | |||
14 | // Exit if accessed directly. |
||
15 | if ( ! defined( 'ABSPATH' ) ) { |
||
16 | exit; |
||
17 | } |
||
18 | |||
19 | /** |
||
20 | * Give_API Class |
||
21 | * |
||
22 | * Renders API returns as a JSON/XML array |
||
23 | * |
||
24 | * @since 1.1 |
||
25 | */ |
||
26 | class Give_API { |
||
27 | |||
28 | /** |
||
29 | * Latest API Version |
||
30 | */ |
||
31 | const VERSION = 1; |
||
32 | |||
33 | /** |
||
34 | * Pretty Print? |
||
35 | * |
||
36 | * @var bool |
||
37 | * @access private |
||
38 | * @since 1.1 |
||
39 | */ |
||
40 | private $pretty_print = false; |
||
41 | |||
42 | /** |
||
43 | * Log API requests? |
||
44 | * |
||
45 | * @var bool |
||
46 | * @access public |
||
47 | * @since 1.1 |
||
48 | */ |
||
49 | public $log_requests = true; |
||
50 | |||
51 | /** |
||
52 | * Is this a valid request? |
||
53 | * |
||
54 | * @var bool |
||
55 | * @access private |
||
56 | * @since 1.1 |
||
57 | */ |
||
58 | private $is_valid_request = false; |
||
59 | |||
60 | /** |
||
61 | * User ID Performing the API Request |
||
62 | * |
||
63 | * @var int |
||
64 | * @access public |
||
65 | * @since 1.1 |
||
66 | */ |
||
67 | public $user_id = 0; |
||
68 | |||
69 | /** |
||
70 | * Instance of Give Stats class |
||
71 | * |
||
72 | * @var object |
||
73 | * @access private |
||
74 | * @since 1.1 |
||
75 | */ |
||
76 | private $stats; |
||
77 | |||
78 | /** |
||
79 | * Response data to return |
||
80 | * |
||
81 | * @var array |
||
82 | * @access private |
||
83 | * @since 1.1 |
||
84 | */ |
||
85 | private $data = array(); |
||
86 | |||
87 | /** |
||
88 | * Whether or not to override api key validation. |
||
89 | * |
||
90 | * @var bool |
||
91 | * @access public |
||
92 | * @since 1.1 |
||
93 | */ |
||
94 | public $override = true; |
||
95 | |||
96 | /** |
||
97 | * Version of the API queried |
||
98 | * |
||
99 | * @var string |
||
100 | * @access public |
||
101 | * @since 1.1 |
||
102 | */ |
||
103 | private $queried_version; |
||
104 | |||
105 | /** |
||
106 | * All versions of the API |
||
107 | * |
||
108 | * @var array |
||
109 | * @access protected |
||
110 | * @since 1.1 |
||
111 | */ |
||
112 | protected $versions = array(); |
||
113 | |||
114 | /** |
||
115 | * Queried endpoint |
||
116 | * |
||
117 | * @var string |
||
118 | * @access private |
||
119 | * @since 1.1 |
||
120 | */ |
||
121 | private $endpoint; |
||
122 | |||
123 | /** |
||
124 | * Endpoints routes |
||
125 | * |
||
126 | * @var object |
||
127 | * @access private |
||
128 | * @since 1.1 |
||
129 | */ |
||
130 | private $routes; |
||
131 | |||
132 | /** |
||
133 | * Setup the Give API |
||
134 | * |
||
135 | * @since 1.1 |
||
136 | 13 | * @access public |
|
137 | */ |
||
138 | 13 | public function __construct() { |
|
139 | 13 | ||
140 | $this->versions = array( |
||
141 | 'v1' => 'GIVE_API_V1', |
||
142 | 13 | ); |
|
143 | 13 | ||
144 | 13 | foreach ( $this->get_versions() as $version => $class ) { |
|
145 | require_once GIVE_PLUGIN_DIR . 'includes/api/class-give-api-' . $version . '.php'; |
||
146 | 13 | } |
|
147 | 13 | ||
148 | 13 | add_action( 'init', array( $this, 'add_endpoint' ) ); |
|
149 | 13 | add_action( 'wp', array( $this, 'process_query' ), - 1 ); |
|
150 | 13 | add_filter( 'query_vars', array( $this, 'query_vars' ) ); |
|
151 | 13 | add_action( 'show_user_profile', array( $this, 'user_key_field' ) ); |
|
152 | 13 | add_action( 'edit_user_profile', array( $this, 'user_key_field' ) ); |
|
153 | 13 | add_action( 'personal_options_update', array( $this, 'generate_api_key' ) ); |
|
154 | add_action( 'edit_user_profile_update', array( $this, 'generate_api_key' ) ); |
||
155 | add_action( 'give_process_api_key', array( $this, 'process_api_key' ) ); |
||
156 | 13 | ||
157 | // Setup a backwards compatibility check for user API Keys |
||
158 | add_filter( 'get_user_metadata', array( $this, 'api_key_backwards_compat' ), 10, 4 ); |
||
159 | 13 | ||
160 | // Determine if JSON_PRETTY_PRINT is available |
||
161 | $this->pretty_print = defined( 'JSON_PRETTY_PRINT' ) ? JSON_PRETTY_PRINT : null; |
||
0 ignored issues
–
show
|
|||
162 | 13 | ||
163 | // Allow API request logging to be turned off |
||
164 | $this->log_requests = apply_filters( 'give_api_log_requests', $this->log_requests ); |
||
165 | 13 | ||
166 | // Setup Give_Payment_Stats instance |
||
167 | 13 | $this->stats = new Give_Payment_Stats(); |
|
168 | |||
169 | } |
||
170 | |||
171 | /** |
||
172 | * There are certain responsibility of this function: |
||
173 | * 1. handle backward compatibility for deprecated functions |
||
174 | * |
||
175 | * @since 2.0 |
||
176 | * |
||
177 | * @param $name |
||
178 | 11 | * @param $arguments |
|
179 | 11 | * |
|
180 | 11 | * @return mixed |
|
181 | */ |
||
182 | public function __call( $name, $arguments ) { |
||
183 | $deprecated_function_arr = array( |
||
184 | 'get_customers', |
||
185 | ); |
||
186 | |||
187 | if ( in_array( $name, $deprecated_function_arr, true ) ) { |
||
188 | switch ( $name ) { |
||
189 | case 'get_customers': |
||
190 | $args = ! empty( $arguments[0] ) ? $arguments[0] : array(); |
||
191 | |||
192 | 4 | return $this->get_donors( $args ); |
|
193 | } |
||
194 | 4 | } |
|
195 | 4 | } |
|
196 | 4 | ||
197 | 4 | /** |
|
198 | 4 | * Registers a new rewrite endpoint for accessing the API |
|
199 | 4 | * |
|
200 | 4 | * @access public |
|
201 | 4 | * |
|
202 | 4 | * @since 1.1 |
|
203 | 4 | */ |
|
204 | 4 | public function add_endpoint() { |
|
205 | 4 | add_rewrite_endpoint( 'give-api', EP_ALL ); |
|
206 | 4 | } |
|
207 | 4 | ||
208 | /** |
||
209 | 4 | * Registers query vars for API access |
|
210 | * |
||
211 | * @access public |
||
212 | * @since 1.1 |
||
213 | * |
||
214 | * @param array $vars Query vars |
||
215 | * |
||
216 | * @return string[] $vars New query vars |
||
217 | */ |
||
218 | public function query_vars( $vars ) { |
||
219 | 13 | ||
220 | 13 | $vars[] = 'token'; |
|
221 | $vars[] = 'key'; |
||
222 | $vars[] = 'query'; |
||
223 | $vars[] = 'type'; |
||
224 | $vars[] = 'form'; |
||
225 | $vars[] = 'number'; |
||
226 | $vars[] = 'date'; |
||
227 | $vars[] = 'startdate'; |
||
228 | $vars[] = 'enddate'; |
||
229 | $vars[] = 'donor'; |
||
230 | $vars[] = 'format'; |
||
231 | $vars[] = 'id'; |
||
232 | $vars[] = 'purchasekey'; |
||
233 | $vars[] = 'email'; |
||
234 | |||
235 | return $vars; |
||
236 | } |
||
237 | |||
238 | /** |
||
239 | * Retrieve the API versions |
||
240 | * |
||
241 | 1 | * @access public |
|
242 | * @since 1.1 |
||
243 | 1 | * @return array |
|
244 | */ |
||
245 | 1 | public function get_versions() { |
|
246 | 1 | return $this->versions; |
|
247 | 1 | } |
|
248 | |||
249 | /** |
||
250 | * Retrieve the API version that was queried |
||
251 | 1 | * |
|
252 | * @access public |
||
253 | * @since 1.1 |
||
254 | * @return string |
||
255 | */ |
||
256 | public function get_queried_version() { |
||
257 | return $this->queried_version; |
||
258 | } |
||
259 | |||
260 | /** |
||
261 | * Retrieves the default version of the API to use |
||
262 | * |
||
263 | * @access public |
||
264 | * @since 1.1 |
||
265 | * @return string |
||
266 | */ |
||
267 | public function get_default_version() { |
||
268 | |||
269 | $version = get_option( 'give_default_api_version' ); |
||
270 | |||
271 | if ( defined( 'GIVE_API_VERSION' ) ) { |
||
272 | $version = GIVE_API_VERSION; |
||
273 | } elseif ( ! $version ) { |
||
274 | $version = 'v1'; |
||
275 | } |
||
276 | |||
277 | return $version; |
||
278 | } |
||
279 | |||
280 | /** |
||
281 | * Sets the version of the API that was queried. |
||
282 | * |
||
283 | * Falls back to the default version if no version is specified |
||
284 | * |
||
285 | * @access private |
||
286 | * @since 1.1 |
||
287 | */ |
||
288 | private function set_queried_version() { |
||
289 | |||
290 | global $wp_query; |
||
291 | |||
292 | $version = $wp_query->query_vars['give-api']; |
||
293 | |||
294 | if ( strpos( $version, '/' ) ) { |
||
295 | |||
296 | $version = explode( '/', $version ); |
||
297 | $version = strtolower( $version[0] ); |
||
298 | |||
299 | $wp_query->query_vars['give-api'] = str_replace( $version . '/', '', $wp_query->query_vars['give-api'] ); |
||
300 | |||
301 | if ( array_key_exists( $version, $this->versions ) ) { |
||
302 | |||
303 | $this->queried_version = $version; |
||
304 | |||
305 | } else { |
||
306 | |||
307 | $this->is_valid_request = false; |
||
308 | $this->invalid_version(); |
||
309 | } |
||
310 | } else { |
||
311 | |||
312 | $this->queried_version = $this->get_default_version(); |
||
313 | |||
314 | } |
||
315 | |||
316 | } |
||
317 | |||
318 | /** |
||
319 | * Validate the API request |
||
320 | * |
||
321 | * Checks for the user's public key and token against the secret key. |
||
322 | * |
||
323 | * @access private |
||
324 | * @global object $wp_query WordPress Query |
||
325 | * @uses Give_API::get_user() |
||
326 | * @uses Give_API::invalid_key() |
||
327 | * @uses Give_API::invalid_auth() |
||
328 | * @since 1.1 |
||
329 | * @return bool |
||
330 | */ |
||
331 | private function validate_request() { |
||
332 | global $wp_query; |
||
333 | |||
334 | $this->override = false; |
||
335 | |||
336 | // Make sure we have both user and api key |
||
337 | if ( ! empty( $wp_query->query_vars['give-api'] ) && ( $wp_query->query_vars['give-api'] !== 'forms' || ! empty( $wp_query->query_vars['token'] ) ) ) { |
||
0 ignored issues
–
show
|
|||
338 | |||
339 | if ( empty( $wp_query->query_vars['token'] ) || empty( $wp_query->query_vars['key'] ) ) { |
||
340 | $this->missing_auth(); |
||
341 | |||
342 | return false; |
||
343 | } |
||
344 | |||
345 | // Retrieve the user by public API key and ensure they exist |
||
346 | if ( ! ( $user = $this->get_user( $wp_query->query_vars['key'] ) ) ) { |
||
347 | |||
348 | $this->invalid_key(); |
||
349 | |||
350 | return false; |
||
351 | |||
352 | } else { |
||
353 | 1 | ||
354 | 1 | $token = urldecode( $wp_query->query_vars['token'] ); |
|
355 | $secret = $this->get_user_secret_key( $user ); |
||
0 ignored issues
–
show
$user is of type boolean , but the function expects a integer .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
356 | 1 | $public = urldecode( $wp_query->query_vars['key'] ); |
|
357 | |||
358 | if ( hash_equals( md5( $secret . $public ), $token ) ) { |
||
359 | $this->is_valid_request = true; |
||
360 | 1 | } else { |
|
361 | $this->invalid_auth(); |
||
362 | |||
363 | return false; |
||
364 | 1 | } |
|
0 ignored issues
–
show
|
|||
365 | |||
366 | 1 | } |
|
367 | 1 | } elseif ( ! empty( $wp_query->query_vars['give-api'] ) && $wp_query->query_vars['give-api'] === 'forms' ) { |
|
0 ignored issues
–
show
|
|||
368 | 1 | $this->is_valid_request = true; |
|
369 | 1 | $wp_query->set( 'key', 'public' ); |
|
370 | } |
||
371 | 1 | } |
|
372 | 1 | ||
373 | /** |
||
374 | 1 | * Retrieve the user ID based on the public key provided |
|
375 | * |
||
376 | * @access public |
||
377 | * @since 1.1 |
||
378 | * @global WPDB $wpdb Used to query the database using the WordPress |
||
379 | * Database API |
||
380 | 11 | * |
|
381 | 2 | * @param string $key Public Key |
|
382 | * |
||
383 | 2 | * @return bool if user ID is found, false otherwise |
|
384 | */ |
||
385 | public function get_user( $key = '' ) { |
||
386 | global $wpdb, $wp_query; |
||
387 | 2 | ||
388 | 2 | if ( empty( $key ) ) { |
|
389 | $key = urldecode( $wp_query->query_vars['key'] ); |
||
390 | 2 | } |
|
391 | 2 | ||
392 | 2 | if ( empty( $key ) ) { |
|
393 | 2 | return false; |
|
394 | } |
||
395 | 11 | ||
396 | $user = Give_Cache::get( md5( 'give_api_user_' . $key ), true ); |
||
397 | |||
398 | 11 | if ( false === $user ) { |
|
399 | 2 | $user = $wpdb->get_var( $wpdb->prepare( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = %s LIMIT 1", $key ) ); |
|
0 ignored issues
–
show
|
|||
400 | Give_Cache::set( md5( 'give_api_user_' . $key ), $user, DAY_IN_SECONDS, true ); |
||
401 | 2 | } |
|
402 | |||
403 | if ( $user != null ) { |
||
404 | $this->user_id = $user; |
||
405 | 2 | ||
406 | 2 | return $user; |
|
407 | } |
||
408 | 2 | ||
409 | 2 | return false; |
|
410 | 2 | } |
|
411 | 11 | ||
412 | /** |
||
413 | 2 | * Get user public key. |
|
414 | * |
||
415 | * @param int $user_id |
||
416 | * |
||
417 | * @return mixed|null|string |
||
418 | */ |
||
419 | View Code Duplication | public function get_user_public_key( $user_id = 0 ) { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
420 | global $wpdb; |
||
421 | |||
422 | if ( empty( $user_id ) ) { |
||
423 | return ''; |
||
424 | } |
||
425 | |||
426 | $cache_key = md5( 'give_api_user_public_key' . $user_id ); |
||
427 | $user_public_key = Give_Cache::get( $cache_key, true ); |
||
428 | |||
429 | if ( empty( $user_public_key ) ) { |
||
430 | $user_public_key = $wpdb->get_var( $wpdb->prepare( "SELECT meta_key FROM $wpdb->usermeta WHERE meta_value = 'give_user_public_key' AND user_id = %d", $user_id ) ); |
||
0 ignored issues
–
show
|
|||
431 | Give_Cache::set( $cache_key, $user_public_key, HOUR_IN_SECONDS, true ); |
||
432 | } |
||
433 | |||
434 | return $user_public_key; |
||
435 | } |
||
436 | |||
437 | /** |
||
438 | * Get user secret key. |
||
439 | * |
||
440 | * @param int $user_id |
||
441 | * |
||
442 | * @return mixed|null|string |
||
443 | */ |
||
444 | View Code Duplication | public function get_user_secret_key( $user_id = 0 ) { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
445 | global $wpdb; |
||
446 | |||
447 | if ( empty( $user_id ) ) { |
||
448 | return ''; |
||
449 | } |
||
450 | |||
451 | $cache_key = md5( 'give_api_user_secret_key' . $user_id ); |
||
452 | $user_secret_key = Give_Cache::get( $cache_key, true ); |
||
453 | |||
454 | if ( empty( $user_secret_key ) ) { |
||
455 | $user_secret_key = $wpdb->get_var( $wpdb->prepare( "SELECT meta_key FROM $wpdb->usermeta WHERE meta_value = 'give_user_secret_key' AND user_id = %d", $user_id ) ); |
||
0 ignored issues
–
show
|
|||
456 | Give_Cache::set( $cache_key, $user_secret_key, HOUR_IN_SECONDS, true ); |
||
457 | } |
||
458 | |||
459 | return $user_secret_key; |
||
460 | } |
||
461 | |||
462 | /** |
||
463 | * Displays a missing authentication error if all the parameters are not met. |
||
464 | * provided |
||
465 | * |
||
466 | * @access private |
||
467 | * @uses Give_API::output() |
||
468 | * @since 1.1 |
||
469 | */ |
||
470 | View Code Duplication | private function missing_auth() { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
471 | $error = array(); |
||
472 | $error['error'] = __( 'You must specify both a token and API key.', 'give' ); |
||
473 | |||
474 | $this->data = $error; |
||
475 | $this->output( 401 ); |
||
476 | } |
||
477 | |||
478 | /** |
||
479 | * Displays an authentication failed error if the user failed to provide valid |
||
480 | * credentials |
||
481 | * |
||
482 | * @access private |
||
483 | * @since 1.1 |
||
484 | * @uses Give_API::output() |
||
485 | * @return void |
||
486 | */ |
||
487 | View Code Duplication | private function invalid_auth() { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
488 | $error = array(); |
||
489 | $error['error'] = __( 'Your request could not be authenticated.', 'give' ); |
||
490 | 3 | ||
491 | $this->data = $error; |
||
492 | 3 | $this->output( 403 ); |
|
493 | } |
||
494 | |||
495 | 3 | /** |
|
496 | * Displays an invalid API key error if the API key provided couldn't be |
||
497 | * validated |
||
498 | 3 | * |
|
499 | 3 | * @access private |
|
500 | * @since 1.1 |
||
501 | * @uses Give_API::output() |
||
502 | * @return void |
||
503 | */ |
||
504 | View Code Duplication | private function invalid_key() { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
505 | $error = array(); |
||
506 | $error['error'] = __( 'Invalid API key.', 'give' ); |
||
507 | |||
508 | $this->data = $error; |
||
509 | $this->output( 403 ); |
||
510 | } |
||
511 | |||
512 | /** |
||
513 | * Displays an invalid version error if the version number passed isn't valid |
||
514 | * |
||
515 | * @access private |
||
516 | * @since 1.1 |
||
517 | * @uses Give_API::output() |
||
518 | * @return void |
||
519 | */ |
||
520 | View Code Duplication | private function invalid_version() { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
521 | $error = array(); |
||
522 | $error['error'] = __( 'Invalid API version.', 'give' ); |
||
523 | |||
524 | $this->data = $error; |
||
525 | $this->output( 404 ); |
||
526 | } |
||
527 | |||
528 | /** |
||
529 | * Listens for the API and then processes the API requests |
||
530 | * |
||
531 | * @access public |
||
532 | * @global $wp_query |
||
533 | * @since 1.1 |
||
534 | * @return void |
||
535 | */ |
||
536 | public function process_query() { |
||
537 | |||
538 | global $wp_query; |
||
539 | |||
540 | // Start logging how long the request takes for logging |
||
541 | $before = microtime( true ); |
||
542 | |||
543 | // Check for give-api var. Get out if not present |
||
544 | if ( empty( $wp_query->query_vars['give-api'] ) ) { |
||
545 | return; |
||
546 | } |
||
547 | |||
548 | // Determine which version was queried |
||
549 | $this->set_queried_version(); |
||
550 | |||
551 | // Determine the kind of query |
||
552 | $this->set_query_mode(); |
||
553 | |||
554 | // Check for a valid user and set errors if necessary |
||
555 | $this->validate_request(); |
||
556 | |||
557 | // Only proceed if no errors have been noted |
||
558 | if ( ! $this->is_valid_request ) { |
||
559 | return; |
||
560 | } |
||
561 | |||
562 | if ( ! defined( 'GIVE_DOING_API' ) ) { |
||
563 | define( 'GIVE_DOING_API', true ); |
||
564 | } |
||
565 | |||
566 | $data = array(); |
||
567 | $this->routes = new $this->versions[$this->get_queried_version()]; |
||
0 ignored issues
–
show
|
|||
568 | $this->routes->validate_request(); |
||
569 | |||
570 | switch ( $this->endpoint ) : |
||
571 | |||
572 | case 'stats' : |
||
573 | |||
574 | $data = $this->routes->get_stats( array( |
||
575 | 'type' => isset( $wp_query->query_vars['type'] ) ? $wp_query->query_vars['type'] : null, |
||
576 | 'form' => isset( $wp_query->query_vars['form'] ) ? $wp_query->query_vars['form'] : null, |
||
577 | 'date' => isset( $wp_query->query_vars['date'] ) ? $wp_query->query_vars['date'] : null, |
||
578 | 'startdate' => isset( $wp_query->query_vars['startdate'] ) ? $wp_query->query_vars['startdate'] : null, |
||
579 | 'enddate' => isset( $wp_query->query_vars['enddate'] ) ? $wp_query->query_vars['enddate'] : null, |
||
580 | ) ); |
||
581 | |||
582 | break; |
||
583 | |||
584 | case 'forms' : |
||
585 | |||
586 | $form = isset( $wp_query->query_vars['form'] ) ? $wp_query->query_vars['form'] : null; |
||
587 | |||
588 | $data = $this->routes->get_forms( $form ); |
||
589 | |||
590 | break; |
||
591 | |||
592 | case 'donors' : |
||
593 | |||
594 | $donor = isset( $wp_query->query_vars['donor'] ) ? $wp_query->query_vars['donor'] : null; |
||
595 | |||
596 | $data = $this->routes->get_donors( $donor ); |
||
597 | |||
598 | break; |
||
599 | |||
600 | case 'donations' : |
||
601 | |||
602 | /** |
||
603 | * Call to get recent donations |
||
604 | * |
||
605 | * @params text date | today, yesterday or range |
||
606 | * @params date startdate | required when date = range and format to be YYYYMMDD (i.e. 20170524) |
||
607 | * @params date enddate | required when date = range and format to be YYYYMMDD (i.e. 20170524) |
||
608 | */ |
||
609 | $data = $this->routes->get_recent_donations( array( |
||
610 | 'id' => isset( $wp_query->query_vars['id'] ) ? $wp_query->query_vars['id'] : null, |
||
611 | 'date' => isset( $wp_query->query_vars['date'] ) ? $wp_query->query_vars['date'] : null, |
||
612 | 'startdate' => isset( $wp_query->query_vars['startdate'] ) ? $wp_query->query_vars['startdate'] : null, |
||
613 | 'enddate' => isset( $wp_query->query_vars['enddate'] ) ? $wp_query->query_vars['enddate'] : null, |
||
614 | ) ); |
||
615 | |||
616 | break; |
||
617 | |||
618 | endswitch; |
||
619 | |||
620 | // Allow extensions to setup their own return data |
||
621 | $this->data = apply_filters( 'give_api_output_data', $data, $this->endpoint, $this ); |
||
622 | |||
623 | $after = microtime( true ); |
||
624 | $request_time = ( $after - $before ); |
||
625 | $this->data['request_speed'] = $request_time; |
||
626 | |||
627 | // Log this API request, if enabled. We log it here because we have access to errors. |
||
628 | $this->log_request( $this->data ); |
||
629 | |||
630 | // Send out data to the output function |
||
631 | $this->output(); |
||
632 | 11 | } |
|
633 | 11 | ||
634 | /** |
||
635 | 11 | * Returns the API endpoint requested |
|
636 | * |
||
637 | * @access public |
||
638 | * @since 1.1 |
||
639 | * @return string $query Query mode |
||
640 | */ |
||
641 | public function get_query_mode() { |
||
642 | |||
643 | return $this->endpoint; |
||
644 | } |
||
645 | |||
646 | /** |
||
647 | 11 | * Determines the kind of query requested and also ensure it is a valid query |
|
648 | 11 | * |
|
649 | * @access public |
||
650 | 11 | * @since 1.1 |
|
651 | * @global $wp_query |
||
652 | 11 | */ |
|
653 | public function set_query_mode() { |
||
654 | |||
655 | global $wp_query; |
||
656 | 11 | ||
657 | // Whitelist our query options |
||
658 | $accepted = apply_filters( 'give_api_valid_query_modes', array( |
||
659 | 'stats', |
||
660 | 'forms', |
||
661 | 'donors', |
||
662 | 'donations', |
||
663 | ) ); |
||
664 | |||
665 | $query = isset( $wp_query->query_vars['give-api'] ) ? $wp_query->query_vars['give-api'] : null; |
||
666 | $query = str_replace( $this->queried_version . '/', '', $query ); |
||
667 | |||
668 | $error = array(); |
||
669 | |||
670 | // Make sure our query is valid |
||
671 | if ( ! in_array( $query, $accepted ) ) { |
||
672 | $error['error'] = __( 'Invalid query.', 'give' ); |
||
673 | |||
674 | $this->data = $error; |
||
675 | // 400 is Bad Request |
||
676 | $this->output( 400 ); |
||
677 | } |
||
678 | |||
679 | $this->endpoint = $query; |
||
680 | } |
||
681 | |||
682 | /** |
||
683 | * Get page number |
||
684 | * |
||
685 | * @access public |
||
686 | * @since 1.1 |
||
687 | * @global $wp_query |
||
688 | * @return int $wp_query->query_vars['page'] if page number returned (default: 1) |
||
689 | */ |
||
690 | public function get_paged() { |
||
691 | global $wp_query; |
||
692 | |||
693 | return isset( $wp_query->query_vars['page'] ) ? $wp_query->query_vars['page'] : 1; |
||
694 | } |
||
695 | |||
696 | |||
697 | /** |
||
698 | * Number of results to display per page |
||
699 | * |
||
700 | * @access public |
||
701 | * @since 1.1 |
||
702 | * @global $wp_query |
||
703 | * @return int $per_page Results to display per page (default: 10) |
||
704 | */ |
||
705 | public function per_page() { |
||
706 | global $wp_query; |
||
707 | |||
708 | $per_page = isset( $wp_query->query_vars['number'] ) ? $wp_query->query_vars['number'] : 10; |
||
709 | |||
710 | if ( $per_page < 0 && $this->get_query_mode() == 'donors' ) { |
||
0 ignored issues
–
show
|
|||
711 | $per_page = 99999999; |
||
712 | } // End if(). |
||
713 | |||
714 | return apply_filters( 'give_api_results_per_page', $per_page ); |
||
715 | } |
||
716 | |||
717 | /** |
||
718 | * Sets up the dates used to retrieve earnings/donations |
||
719 | * |
||
720 | * @access public |
||
721 | * @since 1.2 |
||
722 | * |
||
723 | * @param array $args Arguments to override defaults |
||
724 | * |
||
725 | * @return array $dates |
||
726 | */ |
||
727 | public function get_dates( $args = array() ) { |
||
728 | $dates = array(); |
||
729 | |||
730 | $defaults = array( |
||
731 | 'type' => '', |
||
732 | 'form' => null, |
||
733 | 'date' => null, |
||
734 | 'startdate' => null, |
||
735 | 'enddate' => null, |
||
736 | ); |
||
737 | |||
738 | $args = wp_parse_args( $args, $defaults ); |
||
739 | |||
740 | $current_time = current_time( 'timestamp' ); |
||
741 | |||
742 | if ( 'range' === $args['date'] ) { |
||
743 | $startdate = strtotime( $args['startdate'] ); |
||
744 | $enddate = strtotime( $args['enddate'] ); |
||
745 | $dates['day_start'] = date( 'd', $startdate ); |
||
746 | $dates['day_end'] = date( 'd', $enddate ); |
||
747 | $dates['m_start'] = date( 'n', $startdate ); |
||
748 | $dates['m_end'] = date( 'n', $enddate ); |
||
749 | $dates['year'] = date( 'Y', $startdate ); |
||
750 | $dates['year_end'] = date( 'Y', $enddate ); |
||
751 | } else { |
||
752 | // Modify dates based on predefined ranges |
||
753 | switch ( $args['date'] ) : |
||
754 | |||
755 | View Code Duplication | case 'this_month' : |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
756 | $dates['day'] = null; |
||
757 | $dates['m_start'] = date( 'n', $current_time ); |
||
758 | $dates['m_end'] = date( 'n', $current_time ); |
||
759 | $dates['year'] = date( 'Y', $current_time ); |
||
760 | break; |
||
761 | |||
762 | case 'last_month' : |
||
763 | $dates['day'] = null; |
||
764 | $dates['m_start'] = date( 'n', $current_time ) == 1 ? 12 : date( 'n', $current_time ) - 1; |
||
765 | $dates['m_end'] = $dates['m_start']; |
||
766 | $dates['year'] = date( 'n', $current_time ) == 1 ? date( 'Y', $current_time ) - 1 : date( 'Y', $current_time ); |
||
767 | break; |
||
768 | |||
769 | View Code Duplication | case 'today' : |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
770 | $dates['day'] = date( 'd', $current_time ); |
||
771 | $dates['m_start'] = date( 'n', $current_time ); |
||
772 | $dates['m_end'] = date( 'n', $current_time ); |
||
773 | $dates['year'] = date( 'Y', $current_time ); |
||
774 | break; |
||
775 | |||
776 | View Code Duplication | case 'yesterday' : |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
777 | |||
778 | $year = date( 'Y', $current_time ); |
||
779 | $month = date( 'n', $current_time ); |
||
780 | $day = date( 'd', $current_time ); |
||
781 | |||
782 | if ( $month == 1 && $day == 1 ) { |
||
0 ignored issues
–
show
|
|||
783 | |||
784 | $year -= 1; |
||
785 | $month = 12; |
||
786 | $day = cal_days_in_month( CAL_GREGORIAN, $month, $year ); |
||
787 | |||
788 | } elseif ( $month > 1 && $day == 1 ) { |
||
0 ignored issues
–
show
|
|||
789 | |||
790 | $month -= 1; |
||
791 | $day = cal_days_in_month( CAL_GREGORIAN, $month, $year ); |
||
792 | |||
793 | } else { |
||
794 | |||
795 | $day -= 1; |
||
796 | |||
797 | } |
||
798 | |||
799 | $dates['day'] = $day; |
||
800 | $dates['m_start'] = $month; |
||
801 | $dates['m_end'] = $month; |
||
802 | $dates['year'] = $year; |
||
803 | |||
804 | break; |
||
805 | |||
806 | View Code Duplication | case 'this_quarter' : |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
807 | $month_now = date( 'n', $current_time ); |
||
808 | |||
809 | $dates['day'] = null; |
||
810 | |||
811 | if ( $month_now <= 3 ) { |
||
812 | |||
813 | $dates['m_start'] = 1; |
||
814 | $dates['m_end'] = 3; |
||
815 | $dates['year'] = date( 'Y', $current_time ); |
||
816 | |||
817 | } elseif ( $month_now <= 6 ) { |
||
818 | |||
819 | $dates['m_start'] = 4; |
||
820 | $dates['m_end'] = 6; |
||
821 | $dates['year'] = date( 'Y', $current_time ); |
||
822 | |||
823 | } elseif ( $month_now <= 9 ) { |
||
824 | |||
825 | $dates['m_start'] = 7; |
||
826 | $dates['m_end'] = 9; |
||
827 | $dates['year'] = date( 'Y', $current_time ); |
||
828 | |||
829 | } else { |
||
830 | |||
831 | $dates['m_start'] = 10; |
||
832 | $dates['m_end'] = 12; |
||
833 | $dates['year'] = date( 'Y', $current_time ); |
||
834 | |||
835 | } |
||
836 | break; |
||
837 | |||
838 | View Code Duplication | case 'last_quarter' : |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
839 | $month_now = date( 'n', $current_time ); |
||
840 | |||
841 | $dates['day'] = null; |
||
842 | |||
843 | if ( $month_now <= 3 ) { |
||
844 | |||
845 | $dates['m_start'] = 10; |
||
846 | $dates['m_end'] = 12; |
||
847 | $dates['year'] = date( 'Y', $current_time ) - 1; // Previous year |
||
848 | |||
849 | } elseif ( $month_now <= 6 ) { |
||
850 | |||
851 | $dates['m_start'] = 1; |
||
852 | 1 | $dates['m_end'] = 3; |
|
853 | $dates['year'] = date( 'Y', $current_time ); |
||
854 | 1 | ||
855 | 1 | } elseif ( $month_now <= 9 ) { |
|
856 | 1 | ||
857 | $dates['m_start'] = 4; |
||
858 | $dates['m_end'] = 6; |
||
859 | $dates['year'] = date( 'Y', $current_time ); |
||
860 | 1 | ||
861 | } else { |
||
862 | 1 | ||
863 | 1 | $dates['m_start'] = 7; |
|
864 | 1 | $dates['m_end'] = 9; |
|
865 | $dates['year'] = date( 'Y', $current_time ); |
||
866 | 1 | ||
867 | } |
||
868 | break; |
||
869 | 1 | ||
870 | View Code Duplication | case 'this_year' : |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
871 | $dates['day'] = null; |
||
872 | 1 | $dates['m_start'] = null; |
|
873 | 1 | $dates['m_end'] = null; |
|
874 | 1 | $dates['year'] = date( 'Y', $current_time ); |
|
875 | break; |
||
876 | 1 | ||
877 | 1 | View Code Duplication | case 'last_year' : |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
878 | $dates['day'] = null; |
||
879 | 1 | $dates['m_start'] = null; |
|
880 | $dates['m_end'] = null; |
||
881 | 1 | $dates['year'] = date( 'Y', $current_time ) - 1; |
|
882 | break; |
||
883 | 1 | ||
884 | 1 | endswitch; |
|
885 | 1 | }// End if(). |
|
886 | 1 | ||
887 | 1 | /** |
|
888 | 1 | * Returns the filters for the dates used to retrieve earnings. |
|
889 | 1 | * |
|
890 | * @since 1.2 |
||
891 | 1 | * |
|
892 | 1 | * @param array $dates The dates used for retrieving earnings. |
|
893 | 1 | */ |
|
894 | 1 | return apply_filters( 'give_api_stat_dates', $dates ); |
|
895 | 1 | } |
|
896 | 1 | ||
897 | 1 | /** |
|
898 | * Process Get Donors API Request. |
||
899 | 1 | * |
|
900 | * @access public |
||
901 | 1 | * @since 1.1 |
|
902 | * @global WPDB $wpdb Used to query the database using the WordPress Database API. |
||
903 | * |
||
904 | 1 | * @param int $donor Donor ID. |
|
905 | 1 | * |
|
906 | 1 | * @return array $donors Multidimensional array of the donors. |
|
907 | */ |
||
908 | 1 | public function get_donors( $donor = null ) { |
|
909 | |||
910 | 1 | $donors = array(); |
|
911 | 1 | $error = array(); |
|
912 | if ( ! user_can( $this->user_id, 'view_give_sensitive_data' ) && ! $this->override ) { |
||
913 | 1 | return $donors; |
|
914 | } |
||
915 | 1 | ||
916 | $paged = $this->get_paged(); |
||
917 | 1 | $per_page = $this->per_page(); |
|
918 | $offset = $per_page * ( $paged - 1 ); |
||
919 | |||
920 | if ( is_numeric( $donor ) ) { |
||
921 | $field = 'id'; |
||
922 | } else { |
||
923 | $field = 'email'; |
||
924 | } |
||
925 | |||
926 | $donor_query = Give()->donors->get_donors( array( |
||
927 | 'number' => $per_page, |
||
928 | 'offset' => $offset, |
||
929 | $field => $donor, |
||
930 | ) ); |
||
931 | $donor_count = 0; |
||
932 | |||
933 | if ( $donor_query ) { |
||
934 | |||
935 | 1 | foreach ( $donor_query as $donor_obj ) { |
|
936 | |||
937 | $names = explode( ' ', $donor_obj->name ); |
||
938 | $first_name = ! empty( $names[0] ) ? $names[0] : ''; |
||
939 | $last_name = ''; |
||
940 | if ( ! empty( $names[1] ) ) { |
||
941 | unset( $names[0] ); |
||
942 | $last_name = implode( ' ', $names ); |
||
943 | } |
||
944 | |||
945 | $title_prefix = Give()->donor_meta->get_meta( $donor_obj->id, '_give_donor_title_prefix', true ); |
||
946 | |||
947 | // Set title prefix empty, if not available in db. |
||
948 | 11 | if ( empty( $title_prefix ) ) { |
|
949 | $title_prefix = ''; |
||
950 | 11 | } |
|
951 | 11 | ||
952 | $donors['donors'][ $donor_count ]['info']['user_id'] = ''; |
||
953 | 11 | $donors['donors'][ $donor_count ]['info']['username'] = ''; |
|
954 | 11 | $donors['donors'][ $donor_count ]['info']['display_name'] = ''; |
|
955 | $donors['donors'][ $donor_count ]['info']['donor_id'] = $donor_obj->id; |
||
956 | 11 | $donors['donors'][ $donor_count ]['info']['title_prefix'] = $title_prefix; |
|
957 | 11 | $donors['donors'][ $donor_count ]['info']['first_name'] = $first_name; |
|
958 | 11 | $donors['donors'][ $donor_count ]['info']['last_name'] = $last_name; |
|
959 | 11 | $donors['donors'][ $donor_count ]['info']['email'] = $donor_obj->email; |
|
960 | 11 | ||
961 | 11 | if ( ! empty( $donor_obj->user_id ) ) { |
|
962 | |||
963 | 11 | $user_data = get_userdata( $donor_obj->user_id ); |
|
964 | 11 | ||
965 | 11 | // Donor with registered account. |
|
966 | 11 | $donors['donors'][ $donor_count ]['info']['user_id'] = $donor_obj->user_id; |
|
967 | 11 | $donors['donors'][ $donor_count ]['info']['username'] = $user_data->user_login; |
|
968 | 11 | $donors['donors'][ $donor_count ]['info']['display_name'] = $user_data->display_name; |
|
969 | 11 | ||
970 | 11 | } |
|
971 | |||
972 | $donors['donors'][ $donor_count ]['stats']['total_donations'] = $donor_obj->purchase_count; |
||
973 | $donors['donors'][ $donor_count ]['stats']['total_spent'] = $donor_obj->purchase_value; |
||
974 | |||
975 | $donor = new Give_Donor( $donor_obj->id ); |
||
976 | |||
977 | // Get donor's addresses. |
||
978 | $donors['donors'][ $donor_count ]['address'] = $donor->address; |
||
979 | |||
980 | $donor_count ++; |
||
981 | |||
982 | } // End foreach(). |
||
983 | } elseif ( $donor ) { |
||
984 | |||
985 | $error['error'] = sprintf( |
||
986 | /* translators: %s: donor */ |
||
987 | 11 | __( 'Donor %s not found.', 'give' ), |
|
988 | $donor |
||
989 | ); |
||
990 | |||
991 | return $error; |
||
992 | |||
993 | } else { |
||
994 | |||
995 | $error['error'] = __( 'No donors found.', 'give' ); |
||
996 | |||
997 | return $error; |
||
998 | |||
999 | 11 | } // End if(). |
|
1000 | |||
1001 | 11 | return $donors; |
|
1002 | } |
||
1003 | 11 | ||
1004 | 11 | /** |
|
1005 | 11 | * Process Get Donation Forms API Request |
|
1006 | 11 | * |
|
1007 | 11 | * @access public |
|
1008 | 11 | * @since 1.1 |
|
1009 | 11 | * |
|
1010 | 11 | * @param int $form Give Form ID. |
|
1011 | 11 | * |
|
1012 | * @return array $donors Multidimensional array of the forms. |
||
1013 | 11 | */ |
|
1014 | public function get_forms( $form = null ) { |
||
1015 | |||
1016 | $forms = array(); |
||
1017 | 11 | $error = array(); |
|
1018 | |||
1019 | if ( $form == null ) { |
||
0 ignored issues
–
show
|
|||
1020 | $forms['forms'] = array(); |
||
1021 | 11 | ||
1022 | 11 | $form_list = get_posts( array( |
|
1023 | 11 | 'post_type' => 'give_forms', |
|
1024 | 11 | 'posts_per_page' => $this->per_page(), |
|
1025 | 11 | 'suppress_filters' => true, |
|
1026 | 11 | 'paged' => $this->get_paged(), |
|
1027 | ) ); |
||
1028 | 11 | ||
1029 | 11 | if ( $form_list ) { |
|
1030 | 11 | $i = 0; |
|
1031 | 11 | foreach ( $form_list as $form_info ) { |
|
1032 | $forms['forms'][ $i ] = $this->get_form_data( $form_info ); |
||
1033 | 11 | $i ++; |
|
1034 | 11 | } |
|
1035 | } |
||
1036 | 11 | } else { |
|
1037 | 11 | if ( get_post_type( $form ) == 'give_forms' ) { |
|
0 ignored issues
–
show
|
|||
1038 | $form_info = get_post( $form ); |
||
1039 | |||
1040 | $forms['forms'][0] = $this->get_form_data( $form_info ); |
||
1041 | 11 | ||
1042 | } else { |
||
1043 | $error['error'] = sprintf( /* translators: %s: form */ |
||
1044 | 11 | __( 'Form %s not found.', 'give' ), $form ); |
|
0 ignored issues
–
show
|
|||
1045 | |||
1046 | 11 | return $error; |
|
1047 | } |
||
1048 | 11 | } |
|
1049 | |||
1050 | return $forms; |
||
1051 | } |
||
1052 | |||
1053 | /** |
||
1054 | * Given a give_forms post object, generate the data for the API output |
||
1055 | * |
||
1056 | * @since 1.1 |
||
1057 | * |
||
1058 | * @param object $form_info The Give Form's Post Object. |
||
1059 | * |
||
1060 | * @return array Array of post data to return back in the API. |
||
1061 | */ |
||
1062 | private function get_form_data( $form_info ) { |
||
1063 | |||
1064 | $form = array(); |
||
1065 | |||
1066 | $form['info']['id'] = $form_info->ID; |
||
1067 | $form['info']['slug'] = $form_info->post_name; |
||
1068 | $form['info']['title'] = $form_info->post_title; |
||
1069 | $form['info']['create_date'] = $form_info->post_date; |
||
1070 | $form['info']['modified_date'] = $form_info->post_modified; |
||
1071 | $form['info']['status'] = $form_info->post_status; |
||
1072 | $form['info']['link'] = html_entity_decode( $form_info->guid ); |
||
1073 | $form['info']['content'] = give_get_meta( $form_info->ID, '_give_form_content', true ); |
||
1074 | $form['info']['thumbnail'] = wp_get_attachment_url( get_post_thumbnail_id( $form_info->ID ) ); |
||
1075 | |||
1076 | if ( give_is_setting_enabled( give_get_option( 'categories', 'disabled' ) ) ) { |
||
1077 | $form['info']['category'] = get_the_terms( $form_info, 'give_forms_category' ); |
||
1078 | $form['info']['tags'] = get_the_terms( $form_info, 'give_forms_tag' ); |
||
1079 | } |
||
1080 | if ( give_is_setting_enabled( give_get_option( 'tags', 'disabled' ) ) ) { |
||
1081 | $form['info']['tags'] = get_the_terms( $form_info, 'give_forms_tag' ); |
||
1082 | } |
||
1083 | |||
1084 | // Check whether any goal is to be achieved for the donation form. |
||
1085 | $goal_option = give_get_meta( $form_info->ID, '_give_goal_option', true ); |
||
1086 | $goal_amount = give_get_meta( $form_info->ID, '_give_set_goal', true ); |
||
1087 | if ( give_is_setting_enabled( $goal_option ) && $goal_amount ) { |
||
1088 | $total_income = give_get_form_earnings_stats( $form_info->ID ); |
||
1089 | $goal_percentage_completed = ( $total_income < $goal_amount ) ? round( ( $total_income / $goal_amount ) * 100, 2 ) : 100; |
||
1090 | $form['goal']['amount'] = isset( $goal_amount ) ? $goal_amount : ''; |
||
1091 | $form['goal']['percentage_completed'] = isset( $goal_percentage_completed ) ? $goal_percentage_completed : ''; |
||
1092 | } |
||
1093 | |||
1094 | if ( user_can( $this->user_id, 'view_give_reports' ) || $this->override ) { |
||
1095 | $form['stats']['total']['donations'] = give_get_form_sales_stats( $form_info->ID ); |
||
1096 | $form['stats']['total']['earnings'] = give_get_form_earnings_stats( $form_info->ID ); |
||
1097 | $form['stats']['monthly_average']['donations'] = give_get_average_monthly_form_sales( $form_info->ID ); |
||
1098 | $form['stats']['monthly_average']['earnings'] = give_get_average_monthly_form_earnings( $form_info->ID ); |
||
1099 | } |
||
1100 | |||
1101 | $counter = 0; |
||
1102 | if ( give_has_variable_prices( $form_info->ID ) ) { |
||
1103 | foreach ( give_get_variable_prices( $form_info->ID ) as $price ) { |
||
0 ignored issues
–
show
The expression
give_get_variable_prices($form_info->ID) of type false|array is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
1104 | $counter ++; |
||
1105 | // multi-level item |
||
1106 | $level = isset( $price['_give_text'] ) ? $price['_give_text'] : 'level-' . $counter; |
||
1107 | $form['pricing'][ sanitize_key( $level ) ] = $price['_give_amount']; |
||
1108 | |||
1109 | } |
||
1110 | } else { |
||
1111 | $form['pricing']['amount'] = give_get_form_price( $form_info->ID ); |
||
1112 | } |
||
1113 | |||
1114 | if ( user_can( $this->user_id, 'view_give_sensitive_data' ) || $this->override ) { |
||
1115 | |||
1116 | /** |
||
1117 | * Fires when generating API sensitive data. |
||
1118 | * |
||
1119 | * @since 1.1 |
||
1120 | */ |
||
1121 | do_action( 'give_api_sensitive_data' ); |
||
1122 | |||
1123 | } |
||
1124 | |||
1125 | return apply_filters( 'give_api_forms_form', $form ); |
||
1126 | |||
1127 | } |
||
1128 | |||
1129 | /** |
||
1130 | * Process Get Stats API Request |
||
1131 | * |
||
1132 | * @since 1.1 |
||
1133 | * |
||
1134 | * @global WPDB $wpdb Used to query the database using the WordPress. |
||
1135 | * |
||
1136 | * @param array $args Arguments provided by API Request. |
||
1137 | * |
||
1138 | * @return array |
||
1139 | */ |
||
1140 | public function get_stats( $args = array() ) { |
||
1141 | $defaults = array( |
||
1142 | 'type' => null, |
||
1143 | 'form' => null, |
||
1144 | 'date' => null, |
||
1145 | 'startdate' => null, |
||
1146 | 'enddate' => null, |
||
1147 | ); |
||
1148 | |||
1149 | $args = wp_parse_args( $args, $defaults ); |
||
1150 | |||
1151 | $dates = $this->get_dates( $args ); |
||
1152 | |||
1153 | $stats = array(); |
||
1154 | $earnings = array( |
||
1155 | 'earnings' => array(), |
||
1156 | ); |
||
1157 | $donations = array( |
||
1158 | 'donations' => array(), |
||
1159 | ); |
||
1160 | $error = array(); |
||
1161 | |||
1162 | if ( ! user_can( $this->user_id, 'view_give_reports' ) && ! $this->override ) { |
||
1163 | return $stats; |
||
1164 | } |
||
1165 | |||
1166 | if ( $args['type'] == 'donations' ) { |
||
0 ignored issues
–
show
|
|||
1167 | |||
1168 | if ( $args['form'] == null ) { |
||
1169 | if ( $args['date'] == null ) { |
||
1170 | $donations = $this->get_default_sales_stats(); |
||
1171 | } elseif ( $args['date'] === 'range' ) { |
||
0 ignored issues
–
show
|
|||
1172 | // Return donations for a date range. |
||
1173 | // Ensure the end date is later than the start date. |
||
1174 | View Code Duplication | if ( $args['enddate'] < $args['startdate'] ) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1175 | $error['error'] = __( 'The end date must be later than the start date.', 'give' ); |
||
1176 | } |
||
1177 | |||
1178 | // Ensure both the start and end date are specified |
||
1179 | View Code Duplication | if ( empty( $args['startdate'] ) || empty( $args['enddate'] ) ) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1180 | $error['error'] = __( 'Invalid or no date range specified.', 'give' ); |
||
1181 | } |
||
1182 | |||
1183 | $total = 0; |
||
1184 | |||
1185 | // Loop through the years |
||
1186 | $y = $dates['year']; |
||
1187 | View Code Duplication | while ( $y <= $dates['year_end'] ) : |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1188 | |||
1189 | if ( $dates['year'] == $dates['year_end'] ) { |
||
1190 | $month_start = $dates['m_start']; |
||
1191 | $month_end = $dates['m_end']; |
||
1192 | } elseif ( $y == $dates['year'] && $dates['year_end'] > $dates['year'] ) { |
||
1193 | $month_start = $dates['m_start']; |
||
1194 | $month_end = 12; |
||
1195 | } elseif ( $y == $dates['year_end'] ) { |
||
1196 | $month_start = 1; |
||
1197 | $month_end = $dates['m_end']; |
||
1198 | } else { |
||
1199 | $month_start = 1; |
||
1200 | $month_end = 12; |
||
1201 | } |
||
1202 | |||
1203 | $i = $month_start; |
||
1204 | while ( $i <= $month_end ) : |
||
1205 | |||
1206 | if ( $i == $dates['m_start'] ) { |
||
1207 | $d = $dates['day_start']; |
||
1208 | } else { |
||
1209 | $d = 1; |
||
1210 | } |
||
1211 | |||
1212 | if ( $i == $dates['m_end'] ) { |
||
1213 | $num_of_days = $dates['day_end']; |
||
1214 | } else { |
||
1215 | $num_of_days = cal_days_in_month( CAL_GREGORIAN, $i, $y ); |
||
1216 | } |
||
1217 | |||
1218 | while ( $d <= $num_of_days ) : |
||
1219 | $sale_count = give_get_sales_by_date( $d, $i, $y ); |
||
1220 | $date_key = date( 'Ymd', strtotime( $y . '/' . $i . '/' . $d ) ); |
||
1221 | if ( ! isset( $donations['sales'][ $date_key ] ) ) { |
||
1222 | $donations['sales'][ $date_key ] = 0; |
||
1223 | } |
||
1224 | $donations['sales'][ $date_key ] += $sale_count; |
||
1225 | $total += $sale_count; |
||
1226 | $d ++; |
||
1227 | endwhile; |
||
1228 | $i ++; |
||
1229 | endwhile; |
||
1230 | |||
1231 | $y ++; |
||
1232 | endwhile; |
||
1233 | |||
1234 | $donations['totals'] = $total; |
||
1235 | View Code Duplication | } else { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1236 | if ( $args['date'] == 'this_quarter' || $args['date'] == 'last_quarter' ) { |
||
0 ignored issues
–
show
|
|||
1237 | $donations_count = 0; |
||
1238 | |||
1239 | // Loop through the months |
||
1240 | $month = $dates['m_start']; |
||
1241 | |||
1242 | while ( $month <= $dates['m_end'] ) : |
||
1243 | $donations_count += give_get_sales_by_date( null, $month, $dates['year'] ); |
||
1244 | $month ++; |
||
1245 | endwhile; |
||
1246 | |||
1247 | $donations['donations'][ $args['date'] ] = $donations_count; |
||
1248 | } else { |
||
1249 | $donations['donations'][ $args['date'] ] = give_get_sales_by_date( $dates['day'], $dates['m_start'], $dates['year'] ); |
||
1250 | } |
||
1251 | }// End if(). |
||
1252 | } elseif ( $args['form'] == 'all' ) { |
||
0 ignored issues
–
show
|
|||
1253 | $forms = get_posts( array( |
||
1254 | 'post_type' => 'give_forms', |
||
1255 | 'nopaging' => true, |
||
0 ignored issues
–
show
|
|||
1256 | ) ); |
||
1257 | $i = 0; |
||
1258 | foreach ( $forms as $form_info ) { |
||
1259 | $donations['donations'][ $i ] = array( |
||
1260 | $form_info->post_name => $this->stats->get_sales( |
||
1261 | $form_info->ID, |
||
1262 | is_numeric( $args['startdate'] ) |
||
1263 | ? strtotime( $args['startdate'] ) |
||
1264 | : $args['startdate'], |
||
1265 | is_numeric( $args['enddate'] ) |
||
1266 | ? strtotime( $args['enddate'] ) |
||
1267 | : $args['enddate'] |
||
1268 | ), |
||
1269 | ); |
||
1270 | $i ++; |
||
1271 | } |
||
1272 | View Code Duplication | } else { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1273 | if ( get_post_type( $args['form'] ) == 'give_forms' ) { |
||
0 ignored issues
–
show
|
|||
1274 | $form_info = get_post( $args['form'] ); |
||
1275 | $donations['donations'][0] = array( |
||
1276 | $form_info->post_name => $this->stats->get_sales( |
||
1277 | $args['form'], |
||
1278 | is_numeric( $args['startdate'] ) |
||
1279 | ? strtotime( $args['startdate'] ) |
||
1280 | : $args['startdate'], |
||
1281 | is_numeric( $args['enddate'] ) |
||
1282 | ? strtotime( $args['enddate'] ) |
||
1283 | : $args['enddate'] |
||
1284 | ), |
||
1285 | ); |
||
1286 | } else { |
||
1287 | $error['error'] = sprintf( /* translators: %s: form */ |
||
1288 | __( 'Form %s not found.', 'give' ), $args['form'] ); |
||
0 ignored issues
–
show
|
|||
1289 | } |
||
1290 | }// End if(). |
||
1291 | |||
1292 | if ( ! empty( $error ) ) { |
||
1293 | return $error; |
||
1294 | } |
||
1295 | |||
1296 | return $donations; |
||
1297 | |||
1298 | } elseif ( $args['type'] == 'earnings' ) { |
||
0 ignored issues
–
show
|
|||
1299 | if ( $args['form'] == null ) { |
||
1300 | if ( $args['date'] == null ) { |
||
1301 | $earnings = $this->get_default_earnings_stats(); |
||
1302 | } elseif ( $args['date'] === 'range' ) { |
||
0 ignored issues
–
show
|
|||
1303 | // Return sales for a date range |
||
1304 | // Ensure the end date is later than the start date |
||
1305 | View Code Duplication | if ( $args['enddate'] < $args['startdate'] ) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1306 | $error['error'] = __( 'The end date must be later than the start date.', 'give' ); |
||
1307 | } |
||
1308 | |||
1309 | // Ensure both the start and end date are specified |
||
1310 | View Code Duplication | if ( empty( $args['startdate'] ) || empty( $args['enddate'] ) ) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1311 | $error['error'] = __( 'Invalid or no date range specified.', 'give' ); |
||
1312 | } |
||
1313 | |||
1314 | $total = (float) 0.00; |
||
1315 | |||
1316 | // Loop through the years |
||
1317 | $y = $dates['year']; |
||
1318 | if ( ! isset( $earnings['earnings'] ) ) { |
||
1319 | $earnings['earnings'] = array(); |
||
1320 | } |
||
1321 | View Code Duplication | while ( $y <= $dates['year_end'] ) : |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1322 | |||
1323 | if ( $dates['year'] == $dates['year_end'] ) { |
||
1324 | $month_start = $dates['m_start']; |
||
1325 | $month_end = $dates['m_end']; |
||
1326 | } elseif ( $y == $dates['year'] && $dates['year_end'] > $dates['year'] ) { |
||
1327 | $month_start = $dates['m_start']; |
||
1328 | $month_end = 12; |
||
1329 | } elseif ( $y == $dates['year_end'] ) { |
||
1330 | $month_start = 1; |
||
1331 | $month_end = $dates['m_end']; |
||
1332 | } else { |
||
1333 | $month_start = 1; |
||
1334 | $month_end = 12; |
||
1335 | } |
||
1336 | |||
1337 | $i = $month_start; |
||
1338 | while ( $i <= $month_end ) : |
||
1339 | 11 | ||
1340 | 11 | if ( $i == $dates['m_start'] ) { |
|
1341 | $d = $dates['day_start']; |
||
1342 | 11 | } else { |
|
1343 | $d = 1; |
||
1344 | 11 | } |
|
1345 | |||
1346 | if ( $i == $dates['m_end'] ) { |
||
1347 | $num_of_days = $dates['day_end']; |
||
1348 | 11 | } else { |
|
1349 | $num_of_days = cal_days_in_month( CAL_GREGORIAN, $i, $y ); |
||
1350 | } |
||
1351 | 11 | ||
1352 | while ( $d <= $num_of_days ) : |
||
1353 | $earnings_stat = give_get_earnings_by_date( $d, $i, $y ); |
||
1354 | 11 | $date_key = date( 'Ymd', strtotime( $y . '/' . $i . '/' . $d ) ); |
|
1355 | if ( ! isset( $earnings['earnings'][ $date_key ] ) ) { |
||
1356 | $earnings['earnings'][ $date_key ] = 0; |
||
1357 | } |
||
1358 | $earnings['earnings'][ $date_key ] += $earnings_stat; |
||
1359 | $total += $earnings_stat; |
||
1360 | $d ++; |
||
1361 | endwhile; |
||
1362 | |||
1363 | $i ++; |
||
1364 | endwhile; |
||
1365 | |||
1366 | 11 | $y ++; |
|
1367 | 11 | endwhile; |
|
1368 | 11 | ||
1369 | $earnings['totals'] = $total; |
||
1370 | 11 | View Code Duplication | } else { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1371 | 11 | if ( $args['date'] == 'this_quarter' || $args['date'] == 'last_quarter' ) { |
|
0 ignored issues
–
show
|
|||
1372 | $earnings_count = (float) 0.00; |
||
1373 | 11 | ||
1374 | 11 | // Loop through the months |
|
1375 | 11 | $month = $dates['m_start']; |
|
1376 | |||
1377 | 11 | while ( $month <= $dates['m_end'] ) : |
|
1378 | 11 | $earnings_count += give_get_earnings_by_date( null, $month, $dates['year'] ); |
|
1379 | 11 | $month ++; |
|
1380 | 11 | endwhile; |
|
1381 | 11 | ||
1382 | $earnings['earnings'][ $args['date'] ] = $earnings_count; |
||
1383 | } else { |
||
1384 | $earnings['earnings'][ $args['date'] ] = give_get_earnings_by_date( $dates['day'], $dates['m_start'], $dates['year'] ); |
||
1385 | 11 | } |
|
1386 | 11 | }// End if(). |
|
1387 | } elseif ( $args['form'] == 'all' ) { |
||
0 ignored issues
–
show
|
|||
1388 | 11 | $forms = get_posts( array( |
|
1389 | 11 | 'post_type' => 'give_forms', |
|
1390 | 'nopaging' => true, |
||
0 ignored issues
–
show
|
|||
1391 | 11 | ) ); |
|
1392 | 11 | ||
1393 | 11 | $i = 0; |
|
1394 | 11 | foreach ( $forms as $form_info ) { |
|
1395 | 11 | $earnings['earnings'][ $i ] = array( |
|
1396 | 11 | $form_info->post_name => give_get_form_earnings_stats( $form_info->ID ), |
|
1397 | 11 | ); |
|
1398 | 11 | $i ++; |
|
1399 | 11 | } |
|
1400 | 11 | View Code Duplication | } else { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1401 | if ( get_post_type( $args['form'] ) == 'give_forms' ) { |
||
0 ignored issues
–
show
|
|||
1402 | 11 | $form_info = get_post( $args['form'] ); |
|
1403 | 11 | $earnings['earnings'][0] = array( |
|
1404 | 11 | $form_info->post_name => $this->stats->get_earnings( |
|
1405 | $args['form'], |
||
0 ignored issues
–
show
|
|||
1406 | 11 | is_numeric( $args['startdate'] ) |
|
0 ignored issues
–
show
|
|||
1407 | 11 | ? strtotime( $args['startdate'] ) |
|
1408 | 11 | : $args['startdate'], |
|
1409 | is_numeric( $args['enddate'] ) |
||
0 ignored issues
–
show
|
|||
1410 | 11 | ? strtotime( $args['enddate'] ) |
|
1411 | 11 | : $args['enddate'] |
|
1412 | 11 | ), |
|
1413 | 11 | ); |
|
1414 | 11 | } else { |
|
1415 | 11 | $error['error'] = sprintf( /* translators: %s: form */ |
|
1416 | __( 'Form %s not found.', 'give' ), $args['form'] ); |
||
0 ignored issues
–
show
|
|||
1417 | 11 | } |
|
1418 | 11 | }// End if(). |
|
1419 | |||
1420 | if ( ! empty( $error ) ) { |
||
1421 | 11 | return $error; |
|
1422 | } |
||
1423 | |||
1424 | 11 | return $earnings; |
|
1425 | 11 | } elseif ( $args['type'] == 'donors' ) { |
|
0 ignored issues
–
show
|
|||
1426 | 11 | $donors = new Give_DB_Donors(); |
|
1427 | 11 | $stats['donations']['total_donors'] = $donors->count(); |
|
1428 | 11 | ||
1429 | 11 | return $stats; |
|
1430 | 11 | ||
1431 | 11 | } elseif ( empty( $args['type'] ) ) { |
|
1432 | $stats = array_merge( $stats, $this->get_default_sales_stats() ); |
||
1433 | $stats = array_merge( $stats, $this->get_default_earnings_stats() ); |
||
1434 | 11 | ||
1435 | 11 | return array( |
|
1436 | 'stats' => $stats, |
||
1437 | ); |
||
1438 | 11 | }// End if(). |
|
1439 | } |
||
1440 | 11 | ||
1441 | /** |
||
1442 | 11 | * Retrieves Recent Donations |
|
1443 | 11 | * |
|
1444 | 11 | * @access public |
|
1445 | * @since 1.1 |
||
1446 | 11 | * |
|
1447 | * @param $args array |
||
1448 | * |
||
1449 | * @return array |
||
1450 | */ |
||
1451 | public function get_recent_donations( $args = array() ) { |
||
1452 | global $wp_query; |
||
1453 | |||
1454 | $defaults = array( |
||
1455 | 'id' => null, |
||
1456 | 'date' => null, |
||
1457 | 'startdate' => null, |
||
1458 | 'enddate' => null, |
||
1459 | ); |
||
1460 | |||
1461 | $args = wp_parse_args( $args, $defaults ); |
||
1462 | |||
1463 | $donations = array(); |
||
1464 | |||
1465 | if ( ! user_can( $this->user_id, 'view_give_reports' ) && ! $this->override ) { |
||
1466 | return $donations; |
||
1467 | } |
||
1468 | |||
1469 | if ( isset( $wp_query->query_vars['id'] ) ) { |
||
1470 | $query = array(); |
||
1471 | $query[] = new Give_Payment( $wp_query->query_vars['id'] ); |
||
1472 | } elseif ( isset( $wp_query->query_vars['purchasekey'] ) ) { |
||
1473 | $query = array(); |
||
1474 | $query[] = give_get_payment_by( 'key', $wp_query->query_vars['purchasekey'] ); |
||
1475 | } elseif ( isset( $wp_query->query_vars['email'] ) ) { |
||
1476 | $args = array( |
||
1477 | 'fields' => 'ids', |
||
1478 | 'meta_key' => '_give_payment_donor_email', |
||
0 ignored issues
–
show
|
|||
1479 | 'meta_value' => $wp_query->query_vars['email'], |
||
0 ignored issues
–
show
|
|||
1480 | 'number' => $this->per_page(), |
||
1481 | 'page' => $this->get_paged(), |
||
1482 | ); |
||
1483 | $query = give_get_payments( $args ); |
||
1484 | } elseif ( isset( $wp_query->query_vars['date'] ) ) { |
||
1485 | |||
1486 | $current_time = current_time( 'timestamp' ); |
||
1487 | $dates = $this->get_dates( $args ); |
||
1488 | $start_date = ''; |
||
1489 | $end_date = ''; |
||
1490 | |||
1491 | /** |
||
1492 | * Switch case for date query argument |
||
1493 | * |
||
1494 | * @since 1.8.8 |
||
1495 | * |
||
1496 | * @params text date | today, yesterday or range |
||
1497 | * @params date startdate | required when date = range and format to be YYYYMMDD (i.e. 20170524) |
||
1498 | * @params date enddate | required when date = range and format to be YYYYMMDD (i.e. 20170524) |
||
1499 | */ |
||
1500 | switch ( $wp_query->query_vars['date'] ) { |
||
1501 | |||
1502 | case 'today': |
||
1503 | |||
1504 | // Set and Format Start and End Date to be date of today. |
||
1505 | $start_date = $end_date = date( 'Y/m/d', $current_time ); |
||
1506 | |||
1507 | break; |
||
1508 | |||
1509 | case 'yesterday': |
||
1510 | |||
1511 | // Set and Format Start and End Date to be date of yesterday. |
||
1512 | $start_date = $end_date = date( 'Y/m', $current_time ) . '/' . ( date( 'd', $current_time ) - 1 ); |
||
1513 | |||
1514 | break; |
||
1515 | |||
1516 | case 'range': |
||
1517 | |||
1518 | // Format Start Date and End Date for filtering payment based on date range. |
||
1519 | $start_date = $dates['year'] . '/' . $dates['m_start'] . '/' . $dates['day_start']; |
||
1520 | $end_date = $dates['year_end'] . '/' . $dates['m_end'] . '/' . $dates['day_end']; |
||
1521 | |||
1522 | break; |
||
1523 | |||
1524 | } |
||
1525 | |||
1526 | $args = array( |
||
1527 | 'fields' => 'ids', |
||
1528 | 'start_date' => $start_date, |
||
1529 | 'end_date' => $end_date, |
||
1530 | 'number' => $this->per_page(), |
||
1531 | 'page' => $this->get_paged(), |
||
1532 | ); |
||
1533 | |||
1534 | $query = give_get_payments( $args ); |
||
1535 | } else { |
||
1536 | $args = array( |
||
1537 | 'fields' => 'ids', |
||
1538 | 'number' => $this->per_page(), |
||
1539 | 'page' => $this->get_paged(), |
||
1540 | ); |
||
1541 | $query = give_get_payments( $args ); |
||
1542 | }// End if(). |
||
1543 | |||
1544 | if ( $query ) { |
||
0 ignored issues
–
show
The expression
$query of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
1545 | $i = 0; |
||
1546 | foreach ( $query as $payment ) { |
||
1547 | |||
1548 | if ( is_numeric( $payment ) ) { |
||
1549 | $payment = new Give_Payment( $payment ); |
||
1550 | $payment_meta = $payment->get_meta(); |
||
0 ignored issues
–
show
$payment_meta is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
1551 | $user_info = $payment->user_info; |
||
0 ignored issues
–
show
$user_info is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
1552 | } |
||
1553 | |||
1554 | $payment_meta = $payment->get_meta(); |
||
1555 | $user_info = $payment->user_info; |
||
1556 | |||
1557 | $first_name = isset( $user_info['first_name'] ) ? $user_info['first_name'] : ''; |
||
1558 | $last_name = isset( $user_info['last_name'] ) ? $user_info['last_name'] : ''; |
||
1559 | |||
1560 | $donations['donations'][ $i ]['ID'] = $payment->ID; |
||
1561 | $donations['donations'][ $i ]['number'] = $payment->number; |
||
1562 | $donations['donations'][ $i ]['transaction_id'] = $payment->transaction_id; |
||
1563 | $donations['donations'][ $i ]['key'] = $payment->key; |
||
1564 | $donations['donations'][ $i ]['total'] = $payment->total; |
||
1565 | $donations['donations'][ $i ]['status'] = give_get_payment_status( $payment, true ); |
||
1566 | $donations['donations'][ $i ]['gateway'] = $payment->gateway; |
||
1567 | $donations['donations'][ $i ]['name'] = $first_name . ' ' . $last_name; |
||
1568 | $donations['donations'][ $i ]['fname'] = $first_name; |
||
1569 | $donations['donations'][ $i ]['lname'] = $last_name; |
||
1570 | $donations['donations'][ $i ]['email'] = $payment->email; |
||
1571 | $donations['donations'][ $i ]['date'] = $payment->date; |
||
1572 | $donations['donations'][ $i ]['payment_meta'] = array(); |
||
1573 | |||
1574 | $form_id = isset( $payment_meta['form_id'] ) ? $payment_meta['form_id'] : $payment_meta; |
||
1575 | $price = isset( $payment_meta['form_id'] ) ? give_get_form_price( $payment_meta['form_id'] ) : false; |
||
1576 | $price_id = isset( $payment_meta['price_id'] ) ? $payment_meta['price_id'] : null; |
||
1577 | |||
1578 | $donations['donations'][ $i ]['form']['id'] = $form_id; |
||
1579 | $donations['donations'][ $i ]['form']['name'] = get_the_title( $payment_meta['form_id'] ); |
||
1580 | $donations['donations'][ $i ]['form']['price'] = $price; |
||
1581 | |||
1582 | if ( give_has_variable_prices( $form_id ) ) { |
||
1583 | if ( isset( $payment_meta['price_id'] ) ) { |
||
1584 | $price_name = give_get_price_option_name( $form_id, $payment_meta['price_id'], $payment->ID ); |
||
1585 | $donations['donations'][ $i ]['form']['price_name'] = $price_name; |
||
1586 | $donations['donations'][ $i ]['form']['price_id'] = $price_id; |
||
1587 | $donations['donations'][ $i ]['form']['price'] = give_get_price_option_amount( $form_id, $price_id ); |
||
1588 | |||
1589 | } |
||
1590 | } |
||
1591 | |||
1592 | if( ! empty( $payment_meta ) ) { |
||
0 ignored issues
–
show
|
|||
1593 | // Add custom meta to API |
||
1594 | foreach ( $payment_meta as $meta_key => $meta_value ) { |
||
1595 | |||
1596 | $exceptions = array( |
||
1597 | 'form_title', |
||
1598 | 'form_id', |
||
1599 | 'price_id', |
||
1600 | 'user_info', |
||
1601 | 'key', |
||
1602 | 'email', |
||
1603 | 'date', |
||
1604 | ); |
||
1605 | |||
1606 | // Don't clutter up results with dupes |
||
1607 | if ( in_array( $meta_key, $exceptions ) ) { |
||
1608 | continue; |
||
1609 | } |
||
1610 | |||
1611 | $donations['donations'][ $i ]['payment_meta'][ $meta_key ] = $meta_value; |
||
1612 | |||
1613 | } |
||
1614 | } |
||
1615 | |||
1616 | $i ++; |
||
1617 | }// End foreach(). |
||
1618 | }// End if(). |
||
1619 | |||
1620 | return apply_filters( 'give_api_donations_endpoint', $donations ); |
||
1621 | } |
||
1622 | |||
1623 | /** |
||
1624 | * Retrieve the output format. |
||
1625 | * |
||
1626 | * Determines whether results should be displayed in XML or JSON. |
||
1627 | * |
||
1628 | * @since 1.1 |
||
1629 | * @access public |
||
1630 | * |
||
1631 | * @return mixed |
||
1632 | */ |
||
1633 | public function get_output_format() { |
||
1634 | global $wp_query; |
||
1635 | |||
1636 | $format = isset( $wp_query->query_vars['format'] ) ? $wp_query->query_vars['format'] : 'json'; |
||
1637 | |||
1638 | return apply_filters( 'give_api_output_format', $format ); |
||
1639 | } |
||
1640 | |||
1641 | |||
1642 | /** |
||
1643 | * Log each API request, if enabled. |
||
1644 | * |
||
1645 | * @access private |
||
1646 | * @since 1.1 |
||
1647 | * |
||
1648 | * @global WP_Query $wp_query |
||
1649 | * |
||
1650 | * @param array $data |
||
1651 | * |
||
1652 | * @return void |
||
1653 | */ |
||
1654 | private function log_request( $data = array() ) { |
||
1655 | if ( ! $this->log_requests ) { |
||
1656 | return; |
||
1657 | } |
||
1658 | |||
1659 | /** |
||
1660 | * @var WP_Query $wp_query |
||
1661 | */ |
||
1662 | global $wp_query; |
||
1663 | |||
1664 | $query = array( |
||
1665 | 'give-api' => $wp_query->query_vars['give-api'], |
||
1666 | 'key' => isset( $wp_query->query_vars['key'] ) ? $wp_query->query_vars['key'] : null, |
||
1667 | 'token' => isset( $wp_query->query_vars['token'] ) ? $wp_query->query_vars['token'] : null, |
||
1668 | 'query' => isset( $wp_query->query_vars['query'] ) ? $wp_query->query_vars['query'] : null, |
||
1669 | 'type' => isset( $wp_query->query_vars['type'] ) ? $wp_query->query_vars['type'] : null, |
||
1670 | 'form' => isset( $wp_query->query_vars['form'] ) ? $wp_query->query_vars['form'] : null, |
||
1671 | 'donor' => isset( $wp_query->query_vars['donor'] ) ? $wp_query->query_vars['donor'] : null, |
||
1672 | 'date' => isset( $wp_query->query_vars['date'] ) ? $wp_query->query_vars['date'] : null, |
||
1673 | 'startdate' => isset( $wp_query->query_vars['startdate'] ) ? $wp_query->query_vars['startdate'] : null, |
||
1674 | 'enddate' => isset( $wp_query->query_vars['enddate'] ) ? $wp_query->query_vars['enddate'] : null, |
||
1675 | 'id' => isset( $wp_query->query_vars['id'] ) ? $wp_query->query_vars['id'] : null, |
||
1676 | 'purchasekey' => isset( $wp_query->query_vars['purchasekey'] ) ? $wp_query->query_vars['purchasekey'] : null, |
||
1677 | 'email' => isset( $wp_query->query_vars['email'] ) ? $wp_query->query_vars['email'] : null, |
||
1678 | ); |
||
1679 | |||
1680 | $log_data = array( |
||
1681 | 'log_type' => 'api_request', |
||
1682 | 'post_excerpt' => http_build_query( $query ), |
||
1683 | 'post_content' => ! empty( $data['error'] ) ? $data['error'] : '', |
||
1684 | ); |
||
1685 | |||
1686 | $log_meta = array( |
||
1687 | 'api_query' => http_build_query( $query ), |
||
1688 | 'request_ip' => give_get_ip(), |
||
1689 | 'user' => $this->user_id, |
||
1690 | 'key' => isset( $wp_query->query_vars['key'] ) ? $wp_query->query_vars['key'] : null, |
||
1691 | 'token' => isset( $wp_query->query_vars['token'] ) ? $wp_query->query_vars['token'] : null, |
||
1692 | 'time' => $data['request_speed'], |
||
1693 | 'version' => $this->get_queried_version(), |
||
1694 | ); |
||
1695 | |||
1696 | Give()->logs->insert_log( $log_data, $log_meta ); |
||
1697 | } |
||
1698 | |||
1699 | |||
1700 | /** |
||
1701 | * Retrieve the output data. |
||
1702 | * |
||
1703 | * @access public |
||
1704 | * @since 1.1 |
||
1705 | * @return array |
||
1706 | */ |
||
1707 | public function get_output() { |
||
1708 | return $this->data; |
||
1709 | } |
||
1710 | |||
1711 | /** |
||
1712 | * Output Query in either JSON/XML. |
||
1713 | * The query data is outputted as JSON by default. |
||
1714 | * |
||
1715 | * @since 1.1 |
||
1716 | * @global WP_Query $wp_query |
||
1717 | * |
||
1718 | * @param int $status_code |
||
1719 | */ |
||
1720 | public function output( $status_code = 200 ) { |
||
1721 | |||
1722 | $format = $this->get_output_format(); |
||
1723 | |||
1724 | status_header( $status_code ); |
||
1725 | |||
1726 | /** |
||
1727 | * Fires before outputting the API. |
||
1728 | * |
||
1729 | * @since 1.1 |
||
1730 | * |
||
1731 | * @param array $data Response data to return. |
||
1732 | * @param Give_API $this The Give_API object. |
||
1733 | * @param string $format Output format, XML or JSON. Default is JSON. |
||
1734 | */ |
||
1735 | do_action( 'give_api_output_before', $this->data, $this, $format ); |
||
1736 | |||
1737 | switch ( $format ) : |
||
1738 | |||
1739 | case 'xml' : |
||
1740 | |||
1741 | require_once GIVE_PLUGIN_DIR . 'includes/libraries/array2xml.php'; |
||
1742 | $xml = Array2XML::createXML( 'give', $this->data ); |
||
1743 | echo $xml->saveXML(); |
||
0 ignored issues
–
show
|
|||
1744 | |||
1745 | break; |
||
1746 | |||
1747 | case 'json' : |
||
1748 | |||
1749 | header( 'Content-Type: application/json' ); |
||
1750 | if ( ! empty( $this->pretty_print ) ) { |
||
1751 | echo json_encode( $this->data, $this->pretty_print ); |
||
1752 | } else { |
||
1753 | echo json_encode( $this->data ); |
||
1754 | } |
||
1755 | |||
1756 | break; |
||
1757 | |||
1758 | default : |
||
1759 | |||
1760 | /** |
||
1761 | * Fires by the API while outputting other formats. |
||
1762 | * |
||
1763 | * @since 1.1 |
||
1764 | * |
||
1765 | * @param array $data Response data to return. |
||
1766 | * @param Give_API $this The Give_API object. |
||
1767 | */ |
||
1768 | do_action( "give_api_output_{$format}", $this->data, $this ); |
||
1769 | |||
1770 | break; |
||
1771 | |||
1772 | endswitch; |
||
1773 | |||
1774 | /** |
||
1775 | * Fires after outputting the API. |
||
1776 | * |
||
1777 | * @since 1.1 |
||
1778 | * |
||
1779 | * @param array $data Response data to return. |
||
1780 | * @param Give_API $this The Give_API object. |
||
1781 | * @param string $format Output format, XML or JSON. Default is JSON. |
||
1782 | */ |
||
1783 | do_action( 'give_api_output_after', $this->data, $this, $format ); |
||
1784 | |||
1785 | give_die(); |
||
1786 | } |
||
1787 | |||
1788 | /** |
||
1789 | * Modify User Profile |
||
1790 | * |
||
1791 | * Modifies the output of profile.php to add key generation/revocation. |
||
1792 | * |
||
1793 | * @access public |
||
1794 | * @since 1.1 |
||
1795 | * |
||
1796 | * @param object $user Current user info |
||
1797 | 2 | * |
|
1798 | 2 | * @return void |
|
1799 | */ |
||
1800 | function user_key_field( $user ) { |
||
0 ignored issues
–
show
|
|||
1801 | |||
1802 | if ( ( give_get_option( 'api_allow_user_keys', false ) || current_user_can( 'manage_give_settings' ) ) && current_user_can( 'edit_user', $user->ID ) ) { |
||
1803 | |||
1804 | $user = get_userdata( $user->ID ); |
||
1805 | ?> |
||
1806 | <table class="form-table"> |
||
1807 | <tbody> |
||
1808 | <tr> |
||
1809 | <th> |
||
1810 | <?php _e( 'Give API Keys', 'give' ); ?> |
||
1811 | </th> |
||
1812 | <td> |
||
1813 | <?php |
||
1814 | 2 | $public_key = $this->get_user_public_key( $user->ID ); |
|
1815 | 2 | $secret_key = $this->get_user_secret_key( $user->ID ); |
|
1816 | ?> |
||
1817 | 2 | <?php if ( empty( $user->give_user_public_key ) ) { ?> |
|
1818 | <input name="give_set_api_key" type="checkbox" id="give_set_api_key" /> |
||
1819 | 2 | <span class="description"><?php _e( 'Generate API Key', 'give' ); ?></span> |
|
1820 | 2 | <?php } else { ?> |
|
1821 | <strong style="display:inline-block; width: 125px;"><?php _e( 'Public key:', 'give' ); ?> |
||
1822 | 2 | </strong> |
|
1823 | 2 | <input type="text" disabled="disabled" class="regular-text" id="publickey" value="<?php echo esc_attr( $public_key ); ?>" /> |
|
1824 | 2 | <br /> |
|
1825 | <strong style="display:inline-block; width: 125px;"><?php _e( 'Secret key:', 'give' ); ?> |
||
1826 | 2 | </strong> |
|
1827 | 2 | <input type="text" disabled="disabled" class="regular-text" id="privatekey" value="<?php echo esc_attr( $secret_key ); ?>" /> |
|
1828 | 2 | <br /> |
|
1829 | <strong style="display:inline-block; width: 125px;"><?php _e( 'Token:', 'give' ); ?> |
||
1830 | </strong> |
||
1831 | 2 | <input type="text" disabled="disabled" class="regular-text" id="token" value="<?php echo esc_attr( $this->get_token( $user->ID ) ); ?>" /> |
|
1832 | 2 | <br /> |
|
1833 | <input name="give_revoke_api_key" type="checkbox" id="give_revoke_api_key" /> |
||
1834 | <span class="description"><label for="give_revoke_api_key"><?php _e( 'Revoke API Keys', 'give' ); ?></label></span> |
||
1835 | <?php } ?> |
||
1836 | </td> |
||
1837 | </tr> |
||
1838 | </tbody> |
||
1839 | </table> |
||
1840 | <?php }// End if(). |
||
1841 | } |
||
1842 | |||
1843 | /** |
||
1844 | 2 | * Process an API key generation/revocation |
|
1845 | 2 | * |
|
1846 | 2 | * @access public |
|
1847 | * @since 1.1 |
||
1848 | 2 | * |
|
1849 | * @param array $args |
||
1850 | * |
||
1851 | * @return void |
||
1852 | */ |
||
1853 | public function process_api_key( $args ) { |
||
1854 | |||
1855 | View Code Duplication | if ( ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'give-api-nonce' ) ) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1856 | wp_die( __( 'Nonce verification failed.', 'give' ), __( 'Error', 'give' ), array( |
||
1857 | 'response' => 403, |
||
1858 | ) ); |
||
1859 | } |
||
1860 | |||
1861 | 2 | View Code Duplication | if ( empty( $args['user_id'] ) ) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1862 | 2 | wp_die( __( 'User ID Required.', 'give' ), __( 'Error', 'give' ), array( |
|
1863 | 2 | 'response' => 401, |
|
1864 | ) ); |
||
1865 | 2 | } |
|
1866 | |||
1867 | if ( is_numeric( $args['user_id'] ) ) { |
||
1868 | $user_id = isset( $args['user_id'] ) ? absint( $args['user_id'] ) : get_current_user_id(); |
||
1869 | } else { |
||
1870 | $userdata = get_user_by( 'login', $args['user_id'] ); |
||
1871 | $user_id = $userdata->ID; |
||
1872 | } |
||
1873 | $process = isset( $args['give_api_process'] ) ? strtolower( $args['give_api_process'] ) : false; |
||
1874 | |||
1875 | if ( $user_id == get_current_user_id() && ! give_get_option( 'allow_user_api_keys' ) && ! current_user_can( 'manage_give_settings' ) ) { |
||
1876 | wp_die( sprintf( /* translators: %s: process */ |
||
1877 | __( 'You do not have permission to %s API keys for this user.', 'give' ), $process ), __( 'Error', 'give' ), array( |
||
0 ignored issues
–
show
|
|||
1878 | 'response' => 403, |
||
1879 | ) ); |
||
1880 | View Code Duplication | } elseif ( ! current_user_can( 'manage_give_settings' ) ) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1881 | wp_die( sprintf( /* translators: %s: process */ |
||
1882 | __( 'You do not have permission to %s API keys for this user.', 'give' ), $process ), __( 'Error', 'give' ), array( |
||
0 ignored issues
–
show
|
|||
1883 | 'response' => 403, |
||
1884 | ) ); |
||
1885 | } |
||
1886 | |||
1887 | switch ( $process ) { |
||
1888 | case 'generate': |
||
1889 | if ( $this->generate_api_key( $user_id ) ) { |
||
1890 | Give_Cache::delete( Give_Cache::get_key( 'give_total_api_keys' ) ); |
||
1891 | wp_redirect( add_query_arg( 'give-messages[]', 'api-key-generated', 'edit.php?post_type=give_forms&page=give-tools&tab=api' ) ); |
||
1892 | exit(); |
||
1893 | } else { |
||
1894 | wp_redirect( add_query_arg( 'give-messages[]', 'api-key-failed', 'edit.php?post_type=give_forms&page=give-tools&tab=api' ) ); |
||
1895 | exit(); |
||
1896 | } |
||
1897 | break; |
||
0 ignored issues
–
show
break; does not seem to be reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last ![]() |
|||
1898 | View Code Duplication | case 'regenerate': |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1899 | $this->generate_api_key( $user_id, true ); |
||
1900 | Give_Cache::delete( Give_Cache::get_key( 'give_total_api_keys' ) ); |
||
1901 | wp_redirect( add_query_arg( 'give-messages[]', 'api-key-regenerated', 'edit.php?post_type=give_forms&page=give-tools&tab=api' ) ); |
||
1902 | exit(); |
||
1903 | break; |
||
0 ignored issues
–
show
break; does not seem to be reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last ![]() |
|||
1904 | View Code Duplication | case 'revoke': |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1905 | $this->revoke_api_key( $user_id ); |
||
1906 | Give_Cache::delete( Give_Cache::get_key( 'give_total_api_keys' ) ); |
||
1907 | wp_redirect( add_query_arg( 'give-messages[]', 'api-key-revoked', 'edit.php?post_type=give_forms&page=give-tools&tab=api' ) ); |
||
1908 | exit(); |
||
1909 | break; |
||
0 ignored issues
–
show
break; does not seem to be reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last ![]() |
|||
1910 | default; |
||
1911 | break; |
||
1912 | } |
||
1913 | } |
||
1914 | |||
1915 | /** |
||
1916 | * Generate new API keys for a user |
||
1917 | * |
||
1918 | * @param int $user_id User ID the key is being generated for. |
||
1919 | * @param boolean $regenerate Regenerate the key for the user. |
||
1920 | * |
||
1921 | * @access public |
||
1922 | * @since 1.1 |
||
1923 | * |
||
1924 | * @return boolean True if (re)generated successfully, false otherwise. |
||
1925 | */ |
||
1926 | public function generate_api_key( $user_id = 0, $regenerate = false ) { |
||
1927 | |||
1928 | // Bail out, if user doesn't exists. |
||
1929 | if ( empty( $user_id ) ) { |
||
1930 | return false; |
||
1931 | } |
||
1932 | |||
1933 | $user = get_userdata( $user_id ); |
||
1934 | 56 | ||
1935 | // Bail Out, if user object doesn't exists. |
||
1936 | 56 | if ( ! $user ) { |
|
1937 | 56 | return false; |
|
1938 | } |
||
1939 | |||
1940 | $new_public_key = ''; |
||
1941 | $new_secret_key = ''; |
||
1942 | |||
1943 | if( ! empty( $_POST['from'] ) && 'profile' === $_POST['from'] ) { |
||
0 ignored issues
–
show
|
|||
1944 | // For User Profile Page. |
||
1945 | if( ! empty( $_POST['give_set_api_key'] ) ) { |
||
0 ignored issues
–
show
|
|||
1946 | // Generate API Key from User Profile page. |
||
1947 | $new_public_key = $this->generate_public_key( $user->user_email ); |
||
1948 | $new_secret_key = $this->generate_private_key( $user->ID ); |
||
1949 | } elseif ( ! empty( $_POST['give_revoke_api_key'] ) ) { |
||
0 ignored issues
–
show
|
|||
1950 | // Revoke API Key from User Profile page. |
||
1951 | $this->revoke_api_key( $user->ID ); |
||
1952 | } else { |
||
1953 | return false; |
||
1954 | } |
||
1955 | } else { |
||
1956 | // For Tools > API page. |
||
1957 | $public_key = $this->get_user_public_key( $user_id ); |
||
1958 | |||
1959 | if ( empty( $public_key ) && ! $regenerate ) { |
||
1960 | // Generating API for first time. |
||
1961 | $new_public_key = $this->generate_public_key( $user->user_email ); |
||
1962 | $new_secret_key = $this->generate_private_key( $user->ID ); |
||
1963 | } elseif ( $public_key && $regenerate ) { |
||
1964 | // API Key already exists and Regenerating API Key. |
||
1965 | $this->revoke_api_key( $user->ID ); |
||
1966 | $new_public_key = $this->generate_public_key( $user->user_email ); |
||
1967 | $new_secret_key = $this->generate_private_key( $user->ID ); |
||
1968 | } elseif ( ! empty( $public_key ) && ! $regenerate ) { |
||
1969 | // Doing nothing, when API Key exists but still try to generate again instead of regenerating. |
||
1970 | return false; |
||
1971 | } else { |
||
1972 | // Revoke API Key. |
||
1973 | $this->revoke_api_key( $user->ID ); |
||
1974 | } |
||
1975 | } |
||
1976 | |||
1977 | update_user_meta( $user_id, $new_public_key, 'give_user_public_key' ); |
||
0 ignored issues
–
show
|
|||
1978 | update_user_meta( $user_id, $new_secret_key, 'give_user_secret_key' ); |
||
0 ignored issues
–
show
|
|||
1979 | |||
1980 | return true; |
||
1981 | } |
||
1982 | |||
1983 | /** |
||
1984 | * Revoke a users API keys |
||
1985 | * |
||
1986 | * @access public |
||
1987 | * @since 1.1 |
||
1988 | * |
||
1989 | * @param int $user_id User ID of user to revoke key for |
||
1990 | * |
||
1991 | * @return bool |
||
1992 | */ |
||
1993 | public function revoke_api_key( $user_id = 0 ) { |
||
1994 | |||
1995 | if ( empty( $user_id ) ) { |
||
1996 | return false; |
||
1997 | } |
||
1998 | |||
1999 | $user = get_userdata( $user_id ); |
||
2000 | |||
2001 | if ( ! $user ) { |
||
2002 | return false; |
||
2003 | } |
||
2004 | |||
2005 | $public_key = $this->get_user_public_key( $user_id ); |
||
2006 | $secret_key = $this->get_user_secret_key( $user_id ); |
||
2007 | if ( ! empty( $public_key ) ) { |
||
2008 | Give_Cache::delete( Give_Cache::get_key( md5( 'give_api_user_' . $public_key ) ) ); |
||
2009 | Give_Cache::delete( Give_Cache::get_key( md5( 'give_api_user_public_key' . $user_id ) ) ); |
||
2010 | Give_Cache::delete( Give_Cache::get_key( md5( 'give_api_user_secret_key' . $user_id ) ) ); |
||
2011 | delete_user_meta( $user_id, $public_key ); |
||
0 ignored issues
–
show
|
|||
2012 | delete_user_meta( $user_id, $secret_key ); |
||
0 ignored issues
–
show
|
|||
2013 | } else { |
||
2014 | return false; |
||
2015 | } |
||
2016 | |||
2017 | return true; |
||
2018 | } |
||
2019 | |||
2020 | public function get_version() { |
||
2021 | return self::VERSION; |
||
2022 | } |
||
2023 | |||
2024 | /** |
||
2025 | * Generate the public key for a user |
||
2026 | * |
||
2027 | * @access private |
||
2028 | * @since 1.1 |
||
2029 | * |
||
2030 | * @param string $user_email |
||
2031 | * |
||
2032 | * @return string |
||
2033 | */ |
||
2034 | private function generate_public_key( $user_email = '' ) { |
||
2035 | $auth_key = defined( 'AUTH_KEY' ) ? AUTH_KEY : ''; |
||
2036 | $public = hash( 'md5', $user_email . $auth_key . date( 'U' ) ); |
||
2037 | |||
2038 | return $public; |
||
2039 | } |
||
2040 | |||
2041 | /** |
||
2042 | * Generate the secret key for a user |
||
2043 | * |
||
2044 | * @access private |
||
2045 | * @since 1.1 |
||
2046 | * |
||
2047 | * @param int $user_id |
||
2048 | * |
||
2049 | * @return string |
||
2050 | */ |
||
2051 | private function generate_private_key( $user_id = 0 ) { |
||
2052 | $auth_key = defined( 'AUTH_KEY' ) ? AUTH_KEY : ''; |
||
2053 | $secret = hash( 'md5', $user_id . $auth_key . date( 'U' ) ); |
||
2054 | |||
2055 | return $secret; |
||
2056 | } |
||
2057 | |||
2058 | /** |
||
2059 | * Retrieve the user's token |
||
2060 | * |
||
2061 | * @access private |
||
2062 | * @since 1.1 |
||
2063 | * |
||
2064 | * @param int $user_id |
||
2065 | * |
||
2066 | * @return string |
||
2067 | */ |
||
2068 | public function get_token( $user_id = 0 ) { |
||
2069 | return hash( 'md5', $this->get_user_secret_key( $user_id ) . $this->get_user_public_key( $user_id ) ); |
||
2070 | } |
||
2071 | |||
2072 | /** |
||
2073 | * Generate the default donation stats returned by the 'stats' endpoint |
||
2074 | * |
||
2075 | * @access private |
||
2076 | * @since 1.1 |
||
2077 | * @return array default sales statistics |
||
2078 | */ |
||
2079 | View Code Duplication | private function get_default_sales_stats() { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
2080 | |||
2081 | // Default sales return |
||
2082 | $donations = array(); |
||
2083 | $donations['donations']['today'] = $this->stats->get_sales( 0, 'today' ); |
||
2084 | $donations['donations']['current_month'] = $this->stats->get_sales( 0, 'this_month' ); |
||
2085 | $donations['donations']['last_month'] = $this->stats->get_sales( 0, 'last_month' ); |
||
2086 | $donations['donations']['totals'] = give_get_total_donations(); |
||
2087 | |||
2088 | return $donations; |
||
2089 | } |
||
2090 | |||
2091 | /** |
||
2092 | * Generate the default earnings stats returned by the 'stats' endpoint |
||
2093 | * |
||
2094 | * @access private |
||
2095 | * @since 1.1 |
||
2096 | * @return array default earnings statistics |
||
2097 | */ |
||
2098 | View Code Duplication | private function get_default_earnings_stats() { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
2099 | |||
2100 | // Default earnings return |
||
2101 | $earnings = array(); |
||
2102 | $earnings['earnings']['today'] = $this->stats->get_earnings( 0, 'today' ); |
||
2103 | $earnings['earnings']['current_month'] = $this->stats->get_earnings( 0, 'this_month' ); |
||
2104 | $earnings['earnings']['last_month'] = $this->stats->get_earnings( 0, 'last_month' ); |
||
2105 | $earnings['earnings']['totals'] = give_get_total_earnings(); |
||
2106 | |||
2107 | return $earnings; |
||
2108 | } |
||
2109 | |||
2110 | /** |
||
2111 | * API Key Backwards Compatibility |
||
2112 | * |
||
2113 | * A Backwards Compatibility call for the change of meta_key/value for users API Keys. |
||
2114 | * |
||
2115 | * @since 1.3.6 |
||
2116 | * |
||
2117 | * @param string $check Whether to check the cache or not |
||
2118 | * @param int $object_id The User ID being passed |
||
2119 | * @param string $meta_key The user meta key |
||
2120 | * @param bool $single If it should return a single value or array |
||
2121 | * |
||
2122 | * @return string The API key/secret for the user supplied |
||
2123 | */ |
||
2124 | public function api_key_backwards_compat( $check, $object_id, $meta_key, $single ) { |
||
2125 | |||
2126 | if ( $meta_key !== 'give_user_public_key' && $meta_key !== 'give_user_secret_key' ) { |
||
0 ignored issues
–
show
|
|||
2127 | return $check; |
||
2128 | } |
||
2129 | |||
2130 | $return = $check; |
||
2131 | |||
2132 | switch ( $meta_key ) { |
||
2133 | case 'give_user_public_key': |
||
2134 | $return = Give()->api->get_user_public_key( $object_id ); |
||
2135 | break; |
||
2136 | case 'give_user_secret_key': |
||
2137 | $return = Give()->api->get_user_secret_key( $object_id ); |
||
2138 | break; |
||
2139 | } |
||
2140 | |||
2141 | if ( ! $single ) { |
||
2142 | $return = array( $return ); |
||
2143 | } |
||
2144 | |||
2145 | return $return; |
||
2146 | |||
2147 | } |
||
2148 | |||
2149 | } |
||
2150 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.