PluginProbe
Better Payment – Instant Payments, Donations, Fundraising with Subscriptions & More / trunk
Better Payment – Instant Payments, Donations, Fundraising with Subscriptions & More vtrunk
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 trunk, at includes/Admin/DB.php

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