PluginProbe
Better Payment – Instant Payments, Donations, Fundraising with Subscriptions & More / 2.3.0
Better Payment – Instant Payments, Donations, Fundraising with Subscriptions & More v2.3.0
2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.2 2.2.1 2.2.0 2.1.2 2.1.1 trunk 0.0.1 0.0.2 0.0.3 0.0.4 0.0.5 0.0.6 0.0.7 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 All 66 releases
better-payment / includes / Admin / DB.php

DB.php in Better Payment – Instant Payments, Donations, Fundraising with Subscriptions & More 2.3.0, at includes/Admin/DB.php

776 lines 29.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Better_Payment\Lite\Admin;
4
5 use Better_Payment\Lite\Classes\Helper;
6
7 /**
8 * Exit if accessed directly
9 */
10 if (!defined('ABSPATH')) {
11 exit;
12 }
13
14 /**
15 * This class responsible for database work
16 * using wordpress functionality
17 * get_option and update_option.
18 *
19 * @since 0.0.1
20 */
21 class DB {
22
23 public static function get_table_name() {
24 global $wpdb;
25
26 $table = "{$wpdb->prefix}better_payment";
27 return $table;
28 }
29 /**
30 * Get all default settings value.
31 *
32 * @param string $name
33 * @return array
34 * @since 0.0.1
35 */
36 public static function default_settings() {
37 return apply_filters('better_payment_option_default_settings', array(
38 'better_payment_settings_general_general_paypal' => 'yes',
39 'better_payment_settings_general_general_stripe' => 'yes',
40 'better_payment_settings_general_general_paystack' => '',
41 'better_payment_settings_general_general_user_dashboard' => 'yes',
42 'better_payment_settings_general_general_fundraising_campaign' => 'yes',
43 'better_payment_settings_general_general_email' => 'yes',
44 'better_payment_settings_general_general_currency' => 'USD',
45
46 'better_payment_settings_general_email_to' => '',
47 'better_payment_settings_general_email_subject' => '',
48 'better_payment_settings_general_email_message_admin' => '',
49 'better_payment_settings_general_email_from_email' => '',
50 'better_payment_settings_general_email_from_name' => '',
51 'better_payment_settings_general_email_reply_to' => '',
52 'better_payment_settings_general_email_cc' => '',
53 'better_payment_settings_general_email_bcc' => '',
54 'better_payment_settings_general_email_send_as' => 'html',
55
56 'better_payment_settings_general_email_subject_customer' => '',
57 'better_payment_settings_general_email_message_customer' => '',
58 'better_payment_settings_general_email_from_email_customer' => '',
59 'better_payment_settings_general_email_from_name_customer' => '',
60 'better_payment_settings_general_email_reply_to_customer' => '',
61 'better_payment_settings_general_email_cc_customer' => '',
62 'better_payment_settings_general_email_bcc_customer' => '',
63 'better_payment_settings_general_email_send_as_customer' => 'html',
64
65 'better_payment_settings_payment_paypal_live_mode' => 'no',
66 'better_payment_settings_payment_paypal_email' => '',
67 'better_payment_settings_opt_in' => '',
68 'better_payment_settings_payment_paypal_live_client_id' => '',
69 'better_payment_settings_payment_paypal_test_client_id' => '',
70 'better_payment_settings_payment_paypal_live_secret' => '',
71 'better_payment_settings_payment_paypal_test_secret' => '',
72 'better_payment_settings_payment_stripe_live_mode' => 'no',
73 'better_payment_settings_payment_stripe_live_public' => '',
74 'better_payment_settings_payment_stripe_live_secret' => '',
75 'better_payment_settings_payment_stripe_test_public' => '',
76 'better_payment_settings_payment_stripe_test_secret' => '',
77 'better_payment_settings_payment_paystack_live_mode' => 'no',
78 'better_payment_settings_payment_paystack_live_public' => '',
79 'better_payment_settings_payment_paystack_live_secret' => '',
80 'better_payment_settings_payment_paystack_test_public' => '',
81 'better_payment_settings_payment_paystack_test_secret' => '',
82
83 // AI Assistant (Campaign Builder). See includes/AI/.
84 'better_payment_settings_ai_enabled' => '',
85 'better_payment_settings_ai_provider' => 'openai',
86 'better_payment_settings_ai_model' => '',
87 'better_payment_settings_ai_image_model' => '',
88 'better_payment_settings_ai_temperature' => '0.7',
89 'better_payment_settings_ai_max_tokens' => '4096',
90 'better_payment_settings_ai_system_prompt' => '',
91 'better_payment_settings_ai_api_key_openai' => '',
92 'better_payment_settings_ai_api_key_claude' => '',
93 'better_payment_settings_ai_api_key_gemini' => '',
94 'better_payment_settings_ai_api_key_openrouter' => '',
95 ));
96 }
97 /**
98 * Get all settings value from options table.
99 *
100 * Returns the full settings array when $name is empty, otherwise the single
101 * value for that key (which may be a string, array, etc.).
102 *
103 * @param string $name
104 * @return mixed
105 * @since 0.0.1
106 */
107 public static function get_settings($name = '')
108 {
109 $settings = get_option('better_payment_settings', true);
110 $default = self::default_settings();
111
112 $settings = wp_parse_args($settings, $default);
113
114 if (!empty($name) && isset($settings[$name])) {
115 return $settings[$name];
116 }
117
118 if (!empty($name) && !isset($settings[$name]) && isset($default[$name])) {
119 return $default[$name];
120 }
121
122 if (!empty($name) && !isset($settings[$name]) && !isset($default[$name])) {
123 return '';
124 }
125
126 return is_array($settings) ? $settings : [];
127 }
128 /**
129 * Update settings
130 * @param array $value
131 * @return boolean
132 * @since 0.0.1
133 */
134 public static function update_settings($value, $key = '')
135 {
136 if (!empty($key)) {
137 return update_option($key, $value);
138 }
139 return update_option('better_payment_settings', $value);
140 }
141
142 /**
143 * Get all transactions from better payment table.
144 *
145 * @param string $args
146 * @return array
147 * @since 0.0.1
148 */
149 public static function get_transactions($args = [], $count_only=0, $version = 'v1', $fetchNull = 0, $transaction_type = '')
150 {
151 global $wpdb;
152 $items = '';
153
154 $defaults = array(
155 'search_text' => '',
156 'payment_date_from' => '',
157 'payment_date_to' => '',
158 'order_by' => 'payment_date',
159 'order' => 'DESC',
160 'currency' => 'all',
161 'source' => '',
162 'paged' => 1,
163 'per_page' => 20,
164 'offset' => 0,
165 'status' => 'all',
166 );
167
168 $allowed_order_by = array(
169 'id',
170 'payment_date',
171 'email',
172 'amount'
173 );
174
175 $allowed_order = array(
176 'DESC',
177 'ASC'
178 );
179
180 $better_payment_db_obj = new DB();
181 $better_payment_helper_obj = new Helper();
182
183 $allowed_statuses = $better_payment_db_obj->allowed_statuses('all', 'v2');
184 $allowed_statuses_types = $better_payment_db_obj->allowed_statuses_types('v2');
185
186 $args = wp_parse_args($args, $defaults);
187 $table = self::get_table_name();
188
189 $search_text = sanitize_text_field($args['search_text']);
190 $search_text = empty($search_text) ? '' : "%$search_text%";
191
192 $order_by = in_array($args['order_by'], $allowed_order_by) ? sanitize_text_field($args['order_by']) : $defaults['order_by'];
193 $order = in_array($args['order'], $allowed_order) ? sanitize_text_field($args['order']) : $defaults['order'];
194 $offset = $args['offset'] > 0 ? intval($args['offset']) : $defaults['offset'];
195 $per_page = $args['per_page'] > 0 ? intval($args['per_page']) : $defaults['per_page'];
196
197 if($args['status'] == 'null') {
198 $status = sanitize_text_field($args['status']);
199 }else {
200 $allowed_statuses_by_version = ($version == 'v1') ? $allowed_statuses : $allowed_statuses_types;
201 $status = in_array($args['status'], $allowed_statuses_by_version) ? sanitize_text_field($args['status']) : $defaults['status'];
202 }
203
204 $statuses_by_transaction_type = array();
205
206 if( !empty($transaction_type) ){
207 $statuses_by_types = $better_payment_helper_obj->transaction_statuses_with_type_v2();
208 $statuses_by_transaction_type = isset($statuses_by_types[$transaction_type]['statuses']) ? $statuses_by_types[$transaction_type]['statuses'] : $defaults['status'];
209 $status = '';
210 }
211
212 $whereQuery = '';
213
214 $valid_search_text = $search_text != '' && strlen($search_text) >= 2;
215 if($valid_search_text){
216 $whereQuery = $wpdb->prepare(' AND ( email LIKE %s OR form_fields_info LIKE %s OR transaction_id LIKE %s OR amount LIKE %s OR source LIKE %s ) ', $search_text, $search_text ,$search_text, $search_text, $search_text );
217 }
218
219 if( $args['source'] != '' ){
220 $whereQuery .= $wpdb->prepare(" AND source = %s", $args['source']);
221 }
222
223 if( $args['currency'] != 'all' ){
224 $whereQuery .= $wpdb->prepare(" AND currency = %s", $args['currency']);
225 }
226
227 if( $status != 'all' ){
228 if($status == 'null'){
229 $whereQuery .= esc_sql(" AND status is NULL");
230 }else {
231 //version 2
232 if('v1' === $version){
233 $whereQuery .= $wpdb->prepare( " AND status = %s OR status = %s", $status, strtolower($status) );
234 } else {
235
236 if($transaction_type){
237 $statuses_by_type = $statuses_by_transaction_type;
238 }else {
239 $statuses_by_type = $better_payment_db_obj->allowed_statuses($status, 'v2');
240 }
241
242 $statuses = array_map(function($status) {
243 return "'" . esc_sql($status) . "'";
244 }, $statuses_by_type);
245
246 $statuses = implode(',', $statuses);
247
248 $nullDataQuery = $fetchNull ? " OR status IS NULL " : '';
249 $whereQuery .= " AND ( status IN ( $statuses ) " . esc_sql($nullDataQuery) . " ) ";
250 }
251 }
252 }
253
254 if( $args['payment_date_from'] != '' && $args['payment_date_to'] != ''){
255 $whereQuery .= $wpdb->prepare(" AND payment_date BETWEEN %s AND %s", $args['payment_date_from'], $args['payment_date_to']);
256 }
257
258 if($count_only === 1){
259 if($valid_search_text){
260 $items = $wpdb->get_var(
261 "SELECT count(id) FROM $table WHERE 1
262 $whereQuery
263 ORDER BY $order_by $order
264 "
265 );
266 }else {
267 $items = $wpdb->get_var(
268 $wpdb->prepare(
269 "SELECT count(id) FROM $table WHERE 1
270 $whereQuery
271 ORDER BY $order_by $order
272 LIMIT %d, %d
273 ",
274 $offset,
275 $per_page
276 )
277 );
278 }
279
280 }else {
281 $items = $wpdb->get_results(
282 $wpdb->prepare(
283 "SELECT * FROM $table WHERE 1
284 $whereQuery
285 ORDER BY $order_by $order
286 LIMIT %d, %d
287 ",
288 $offset,
289 $per_page
290 )
291 );
292
293 }
294
295 return $items;
296 }
297
298 /**
299 * Get the count of total transactions
300 *
301 * @return int
302 * @since 0.0.1
303 */
304 public static function get_transaction_count($args = '', $version = 'v1', $fetchNull = 0, $transaction_type = '')
305 {
306 global $wpdb;
307 $table = self::get_table_name();
308
309 $count = 0;
310
311 if( !empty($transaction_type) ){
312 $count = self::get_transactions($args, 1, $version, $fetchNull, $transaction_type);
313 return $count;
314 }
315
316 if($args !== ''){
317 $count = self::get_transactions($args, 1, $version, $fetchNull);
318 }else {
319 $count = $wpdb->get_var(
320 "SELECT count(id) FROM $table"
321 );
322 }
323
324 return $count;
325 }
326
327 /**
328 * Get transactions analytics
329 *
330 * @return int
331 * @since 0.0.1
332 */
333 public static function get_transactions_analytics($filtered_transactions = array())
334 {
335 global $wpdb;
336 $transaction_analytics = [];
337
338 $table = self::get_table_name();
339 $better_payment_db_obj = new DB();
340
341 $total_transactions = $better_payment_db_obj->get_transactions_amount_by_statuses(array(), '', '', 'count', 1, $filtered_transactions );
342
343 $completed_statuses = $better_payment_db_obj->allowed_statuses('completed', 'v2');
344 $completed_transactions = $better_payment_db_obj->get_transactions_amount_by_statuses( $completed_statuses, '', '', 'count', 0, $filtered_transactions );
345
346 $incomplete_statuses = $better_payment_db_obj->allowed_statuses('incomplete', 'v2');
347 $incomplete_transactions = $better_payment_db_obj->get_transactions_amount_by_statuses( $incomplete_statuses, '', '', 'count', 1, $filtered_transactions );
348
349 $transaction_analytics['total_transactions'] = $total_transactions;
350 $transaction_analytics['completed_transactions'] = $completed_transactions;
351 $transaction_analytics['incomplete_transactions'] = $incomplete_transactions;
352
353 return $transaction_analytics;
354 }
355
356 /**
357 * Get transactions analytics
358 *
359 * @return int
360 * @since 0.0.1
361 */
362 public static function get_transactions_analytics_dashboard($filtered_transactions = array())
363 {
364 global $wpdb;
365 $transaction_analytics = [];
366
367 $table = self::get_table_name();
368 $better_payment_db_obj = new DB();
369
370 $total_transactions_count = 0;
371 $completed_transactions_count = 0;
372 $incomplete_transactions_count = 0;
373 $refunded_transactions_count = 0;
374
375 $total_transactions_amount = 0;
376 $completed_transactions_amount = 0;
377 $incomplete_transactions_amount = 0;
378 $refunded_transactions_amount = 0;
379
380 if ( is_array( $filtered_transactions ) && count( $filtered_transactions ) ) {
381 $total_transactions_count = $better_payment_db_obj->get_transactions_amount_by_statuses(array(), '', '', 'count', 1, $filtered_transactions );
382 $total_transactions_amount = $better_payment_db_obj->get_transactions_amount_by_statuses(array(), '', '', 'amount', 1, $filtered_transactions );
383
384 $completed_statuses = $better_payment_db_obj->allowed_statuses('completed', 'v2');
385 $completed_transactions_count = $better_payment_db_obj->get_transactions_amount_by_statuses( $completed_statuses, '', '', 'count', 0, $filtered_transactions );
386 $completed_transactions_amount = $better_payment_db_obj->get_transactions_amount_by_statuses( $completed_statuses, '', '', 'amount', 0, $filtered_transactions );
387
388 $incomplete_statuses = $better_payment_db_obj->allowed_statuses('incomplete', 'v2');
389 $incomplete_transactions_count = $better_payment_db_obj->get_transactions_amount_by_statuses( $incomplete_statuses, '', '', 'count', 1, $filtered_transactions );
390 $incomplete_transactions_amount = $better_payment_db_obj->get_transactions_amount_by_statuses( $incomplete_statuses, '', '', 'amount', 1, $filtered_transactions );
391
392 $refunded_statuses = $better_payment_db_obj->allowed_statuses('refunded', 'v2');
393 $refunded_transactions_count = $better_payment_db_obj->get_transactions_amount_by_statuses( $refunded_statuses, '', '', 'count', 0, $filtered_transactions );
394 $refunded_transactions_amount = $better_payment_db_obj->get_transactions_amount_by_statuses( $refunded_statuses, '', '', 'amount', 0, $filtered_transactions );
395 }
396
397 $transaction_analytics['total_transactions_count'] = $total_transactions_count;
398 $transaction_analytics['completed_transactions_count'] = $completed_transactions_count;
399 $transaction_analytics['incomplete_transactions_count'] = $incomplete_transactions_count;
400 $transaction_analytics['refunded_transactions_count'] = $refunded_transactions_count;
401
402 $transaction_analytics['total_transactions_amount'] = $total_transactions_amount;
403 $transaction_analytics['completed_transactions_amount'] = $completed_transactions_amount;
404 $transaction_analytics['incomplete_transactions_amount'] = $incomplete_transactions_amount;
405 $transaction_analytics['refunded_transactions_amount'] = $refunded_transactions_amount;
406
407 // Recent transactions
408
409 return $transaction_analytics;
410 }
411
412 /**
413 * Get transaction details from better payment table.
414 *
415 * @param string $args
416 * @return object
417 * @since 0.0.1
418 */
419 public static function get_transaction($id)
420 {
421 global $wpdb;
422
423 $table = self::get_table_name();
424 $transaction_id = (int) sanitize_text_field($id);
425
426 $item = $wpdb->get_row(
427 $wpdb->prepare(
428 "SELECT * FROM $table WHERE id = %d",
429 $transaction_id
430 )
431 );
432
433 return $item;
434 }
435
436 /**
437 * Get transaction details from better payment table.
438 *
439 * @param string $args
440 * @return object
441 * @since 0.0.1
442 */
443 public static function get_transactions_by_email($email)
444 {
445 global $wpdb;
446
447 $table = self::get_table_name();
448 $email = sanitize_text_field($email);
449
450 $item = $wpdb->get_results(
451 $wpdb->prepare(
452 "SELECT * FROM $table WHERE email = %s order by payment_date DESC",
453 $email
454 )
455 );
456
457 return $item;
458 }
459
460 /**
461 * Get analytics counts and amounts for a specific user via a single SQL aggregate query.
462 * Returns the same shape as get_transactions_analytics_dashboard() without loading all rows.
463 *
464 * @param string $email
465 * @return array
466 */
467 public static function get_user_analytics_by_email( $email ) {
468 global $wpdb;
469 $table = self::get_table_name();
470 $email = sanitize_text_field( $email );
471 $ffi_like = '%' . $wpdb->esc_like( '"' . $email . '"' ) . '%';
472
473 $row = $wpdb->get_row(
474 $wpdb->prepare(
475 "SELECT
476 COUNT(*) AS total_count,
477 SUM(CAST(amount AS DECIMAL(10,2))) AS total_amount,
478 SUM(CASE WHEN status IN ('paid','Completed','completed','success')
479 THEN 1 ELSE 0 END) AS completed_count,
480 SUM(CASE WHEN status IN ('paid','Completed','completed','success')
481 THEN CAST(amount AS DECIMAL(10,2)) ELSE 0 END) AS completed_amount,
482 SUM(CASE WHEN status IN ('pending','Pending','unpaid','incomplete','Incomplete') OR status IS NULL
483 THEN 1 ELSE 0 END) AS incomplete_count,
484 SUM(CASE WHEN status IN ('pending','Pending','unpaid','incomplete','Incomplete') OR status IS NULL
485 THEN CAST(amount AS DECIMAL(10,2)) ELSE 0 END) AS incomplete_amount,
486 SUM(CASE WHEN status = 'refunded' THEN 1 ELSE 0 END) AS refunded_count,
487 SUM(CASE WHEN status = 'refunded'
488 THEN CAST(amount AS DECIMAL(10,2)) ELSE 0 END) AS refunded_amount
489 FROM $table WHERE ( email = %s OR form_fields_info LIKE %s )",
490 $email,
491 $ffi_like
492 )
493 );
494
495 if ( ! $row ) {
496 $row = (object) array_fill_keys(
497 array( 'total_count', 'total_amount', 'completed_count', 'completed_amount', 'incomplete_count', 'incomplete_amount', 'refunded_count', 'refunded_amount' ),
498 0
499 );
500 }
501
502 return [
503 'total_transactions_count' => (int) $row->total_count,
504 'total_transactions_amount' => (float) $row->total_amount,
505 'completed_transactions_count' => (int) $row->completed_count,
506 'completed_transactions_amount' => (float) $row->completed_amount,
507 'incomplete_transactions_count' => (int) $row->incomplete_count,
508 'incomplete_transactions_amount' => (float) $row->incomplete_amount,
509 'refunded_transactions_count' => (int) $row->refunded_count,
510 'refunded_transactions_amount' => (float) $row->refunded_amount,
511 ];
512 }
513
514 /**
515 * Get paginated transactions for a specific user email.
516 *
517 * @param string $email
518 * @param array $args page, per_page, type ('transactions'|'subscriptions')
519 * @return array { transactions: array, total: int, pages: int }
520 */
521 public static function get_user_transactions_paginated( $email, $args = [] ) {
522 global $wpdb;
523
524 $defaults = [
525 'page' => 1,
526 'per_page' => 10,
527 'type' => 'transactions',
528 ];
529 $args = wp_parse_args( $args, $defaults );
530 $table = self::get_table_name();
531 $email = sanitize_text_field( $email );
532 $page = max( 1, intval( $args['page'] ) );
533 $per_page = max( 1, intval( $args['per_page'] ) );
534 $offset = ( $page - 1 ) * $per_page;
535
536 $type_where = '';
537 if ( 'subscriptions' === $args['type'] ) {
538 $type_where = " AND form_fields_info LIKE '%\"subscription_id\"%'";
539 }
540
541 // Match rows where the email column is set directly OR where the email
542 // appears as a quoted value inside the serialized form_fields_info blob.
543 // The initial payment_create() insert never writes the email column —
544 // only the payment-confirmed callback does — so many rows have the user's
545 // email exclusively inside form_fields_info.
546 $ffi_like = '%' . $wpdb->esc_like( '"' . $email . '"' ) . '%';
547
548 $email_where = 'email = %s OR form_fields_info LIKE %s';
549
550 $total = (int) $wpdb->get_var(
551 $wpdb->prepare(
552 "SELECT COUNT(id) FROM $table WHERE ( $email_where )" . $type_where,
553 $email,
554 $ffi_like
555 )
556 );
557
558 $transactions = $wpdb->get_results(
559 $wpdb->prepare(
560 "SELECT * FROM $table WHERE ( $email_where )" . $type_where . " ORDER BY payment_date DESC LIMIT %d OFFSET %d",
561 $email,
562 $ffi_like,
563 $per_page,
564 $offset
565 )
566 );
567
568 return [
569 'transactions' => $transactions,
570 'total' => $total,
571 'pages' => $total > 0 ? (int) ceil( $total / $per_page ) : 1,
572 'page' => $page,
573 'per_page' => $per_page,
574 ];
575 }
576
577 /**
578 * Delete a transaction
579 *
580 * @param int $id
581 *
582 * @return int|boolean
583 * @since 0.0.1
584 */
585 public static function delete_transaction($id)
586 {
587 global $wpdb;
588 $table = self::get_table_name();
589
590 return $wpdb->delete(
591 $table,
592 ['id' => $id],
593 ['%d']
594 );
595 }
596
597 /**
598 * Allowed transaction statuses
599 *
600 * @since 0.0.1
601 */
602 public function allowed_statuses($type = 'all', $version = 'v1'){
603 $helperObj = new Helper();
604 $statuses = $helperObj->get_statuses_by_transaction_type($type, $version);
605
606 return $statuses;
607 }
608
609 /**
610 * Allowed transaction statuses
611 *
612 * @since 0.0.1
613 */
614 public function allowed_statuses_types($version = 'v1'){
615 $helperObj = new Helper();
616 $statuses = $helperObj->get_transaction_types($version);
617
618 return $statuses;
619 }
620
621 /**
622 * Get transactions amount
623 *
624 * @return array
625 * @since 0.0.1
626 */
627 public function get_transactions_by_statuses($statuses = array(), $payment_date_from = '', $payment_date_to = '', $fetchNull=0) {
628 global $wpdb;
629
630 $table = DB::get_table_name();
631 $allowed_statuses = $this->allowed_statuses('all', 'v2');
632
633 $nullDataQuery = $fetchNull ? " OR status IS NULL " : '';
634
635 $statuses = is_array($statuses) && count($statuses) ? $statuses : $allowed_statuses;
636
637 #ToDo: Consider currency while calculating total amount
638 $statuses = array_map(function($status) use ($allowed_statuses) {
639 if(!in_array($status, $allowed_statuses)) {
640 return false;
641 }
642
643 return "'" . esc_sql($status) . "'";
644 }, $statuses);
645
646 $statuses = implode(',', $statuses);
647
648 if(!empty($payment_date_from) && !empty($payment_date_to)){
649 $amount = $wpdb->get_results(
650 "SELECT amount, payment_date, email FROM $table WHERE ( status IN (" . $statuses . ") " . esc_sql($nullDataQuery) . ") AND payment_date BETWEEN '" . esc_sql($payment_date_from) . "' AND '" . esc_sql($payment_date_to) . "'"
651 );
652 } else if(!empty($payment_date_from) && empty($payment_date_to)){
653 $amount = $wpdb->get_results(
654 "SELECT amount, payment_date, email FROM $table WHERE ( status IN (" . $statuses . ") " . esc_sql($nullDataQuery) . ") AND payment_date >= '" . esc_sql($payment_date_from) . "'"
655 );
656 } else {
657 $amount = $wpdb->get_results(
658 "SELECT amount, payment_date, email FROM $table WHERE ( status IN (" . $statuses . ") " . esc_sql($nullDataQuery) . " )"
659 );
660 }
661
662 return $amount;
663 }
664
665 /**
666 * Get transactions amount
667 *
668 * @return array
669 * @since 0.0.1
670 */
671 public function get_transactions_amount_by_statuses($statuses = array(), $payment_date_from = '', $payment_date_to = '', $count_or_amount = 'amount', $fetchNull=0, $filtered_transactions = array() ) {
672 global $wpdb;
673
674 $table = DB::get_table_name();
675 $allowed_statuses = $this->allowed_statuses('all', 'v2');
676
677 $nullDataQuery = $fetchNull ? " OR status IS NULL " : '';
678
679 $statuses = is_array($statuses) && count($statuses) ? $statuses : $allowed_statuses;
680 $statuses_original = $statuses;
681
682 #ToDo: Consider currency while calculating total amount
683 $statuses = array_map(function($status) use ($allowed_statuses) {
684 if(!in_array($status, $allowed_statuses)) {
685 return false;
686 }
687
688 return "'" . esc_sql($status) . "'";
689 }, $statuses);
690
691 $statuses = implode(',', $statuses);
692
693 if( is_array($filtered_transactions) && count($filtered_transactions) ){
694 $filtered_transactions_by_statuses = array();
695 $filtered_transactions_amount = 0;
696
697 foreach($filtered_transactions as $filtered_transaction) {
698 if( in_array($filtered_transaction->status, $statuses_original) ) {
699 $filtered_transactions_by_statuses[] = $filtered_transaction->id;
700 $filtered_transactions_amount += ! empty( $filtered_transaction->amount ) ? floatval( $filtered_transaction->amount ) : 0;
701 }
702 }
703
704 if($count_or_amount == 'count'){
705 $filtered_transactions_by_statuses_count = count($filtered_transactions_by_statuses);
706 return $filtered_transactions_by_statuses_count;
707 }
708
709 if($count_or_amount == 'amount'){
710 return $filtered_transactions_amount;
711 }
712 }
713
714 if($count_or_amount == 'count') {
715 $count = (int) $wpdb->get_var(
716 "SELECT count(id) FROM $table WHERE ( status IN (" . $statuses . ") " . esc_sql($nullDataQuery) . " )"
717 );
718
719 return $count;
720 }
721
722 if(!empty($payment_date_from) && !empty($payment_date_to)){
723 $amount = $wpdb->get_var(
724 "SELECT sum(amount) FROM $table WHERE ( status IN (" . $statuses . ") " . esc_sql($nullDataQuery) . ") AND payment_date BETWEEN '" . esc_sql($payment_date_from) . "' AND '" . esc_sql($payment_date_to) . "'"
725 );
726 }else {
727 $amount = $wpdb->get_var(
728 // #TODO Amount based on filtered transactions
729 "SELECT sum(amount) FROM $table WHERE ( status IN (" . $statuses . ") " . esc_sql($nullDataQuery) . ")"
730 );
731 }
732
733 return $amount;
734 }
735
736 public static function search_transactions($items, $search_text, $offset, $per_page){
737 $filtered_items = array();
738 $search_text = str_replace('%', '', $search_text);
739
740 if(count($items) > 0){
741 $filtered_items = array_filter($items, function($item) use ($search_text){
742 $form_fields_info = maybe_unserialize($item->form_fields_info);
743
744 if(
745 isset($form_fields_info['first_name']) && stripos($form_fields_info['first_name'], $search_text) !== false
746 || isset($form_fields_info['last_name']) && stripos($form_fields_info['last_name'], $search_text) !== false
747 || isset($form_fields_info['primary_first_name']) && stripos($form_fields_info['primary_first_name'], $search_text) !== false
748 || isset($form_fields_info['primary_last_name']) && stripos($form_fields_info['primary_last_name'], $search_text) !== false
749 || isset($form_fields_info['email']) && stripos($form_fields_info['email'], $search_text) !== false
750 || isset($form_fields_info['primary_email']) && stripos($form_fields_info['primary_email'], $search_text) !== false
751 ){
752 return true;
753 }
754
755 });
756
757 }
758
759 return $filtered_items;
760 }
761
762 public static function mark_as_completed($id)
763 {
764 global $wpdb;
765 $table = self::get_table_name();
766
767 $id = (int) sanitize_text_field($id);
768
769 if ($id > 0) {
770 return $wpdb->update($table, ['status' => 'Completed'], ['id' => $id]);
771 }
772
773 return false;
774 }
775 }
776