Completed
Push — issues/1132 ( 716ec5...9a1477 )
by Ravinder
16:46
created

Give_Payment_History_Table   D

Complexity

Total Complexity 103

Size/Duplication

Total Lines 811
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 811
rs 4.4444
c 0
b 0
f 0
wmc 103
lcom 2
cbo 2

19 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 13 1
C advanced_filters() 0 28 7
B search_box() 0 31 5
C get_views() 0 49 11
A get_columns() 0 13 1
A get_sortable_columns() 0 11 1
A get_primary_column_name() 0 3 1
C column_default() 0 65 11
A get_donor_email() 0 12 2
B get_row_actions() 0 49 5
A get_payment_status() 0 8 2
A column_cb() 0 7 1
A get_payment_id() 0 3 1
B get_donor() 0 28 4
A get_bulk_actions() 0 15 1
C process_bulk_action() 0 73 15
C get_payment_counts() 0 37 7
F payments_data() 0 46 16
C prepare_items() 0 56 11

How to fix   Complexity   

Complex Class

Complex classes like Give_Payment_History_Table often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Give_Payment_History_Table, and based on these observations, apply Extract Interface, too.

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 29 and the first side effect is on line 14.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * Payment History Table Class
4
 *
5
 * @package     Give
6
 * @subpackage  Admin/Payments
7
 * @copyright   Copyright (c) 2016, Give
8
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
9
 * @since       1.0
10
 */
11
12
// Exit if accessed directly.
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
// Load WP_List_Table if not loaded.
18
if ( ! class_exists( 'WP_List_Table' ) ) {
19
	require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
20
}
21
22
/**
23
 * Give_Payment_History_Table Class
24
 *
25
 * Renders the Payment History table on the Payment History page
26
 *
27
 * @since 1.0
28
 */
29
class Give_Payment_History_Table extends WP_List_Table {
30
31
	/**
32
	 * Number of results to show per page
33
	 *
34
	 * @var string
35
	 * @since 1.0
36
	 */
37
	public $per_page = 30;
38
39
	/**
40
	 * URL of this page
41
	 *
42
	 * @var string
43
	 * @since 1.0.1
44
	 */
45
	public $base_url;
46
47
	/**
48
	 * Total number of payments
49
	 *
50
	 * @var int
51
	 * @since 1.0
52
	 */
53
	public $total_count;
54
55
	/**
56
	 * Total number of complete payments
57
	 *
58
	 * @var int
59
	 * @since 1.0
60
	 */
61
	public $complete_count;
62
63
	/**
64
	 * Total number of pending payments
65
	 *
66
	 * @var int
67
	 * @since 1.0
68
	 */
69
	public $pending_count;
70
71
	/**
72
	 * Total number of refunded payments
73
	 *
74
	 * @var int
75
	 * @since 1.0
76
	 */
77
	public $refunded_count;
78
79
	/**
80
	 * Total number of failed payments
81
	 *
82
	 * @var int
83
	 * @since 1.0
84
	 */
85
	public $failed_count;
86
87
	/**
88
	 * Total number of revoked payments
89
	 *
90
	 * @var int
91
	 * @since 1.0
92
	 */
93
	public $revoked_count;
94
95
	/**
96
	 * Total number of cancelled payments
97
	 *
98
	 * @var int
99
	 * @since 1.4
100
	 */
101
	public $cancelled_count;
102
103
	/**
104
	 * Total number of abandoned payments
105
	 *
106
	 * @var int
107
	 * @since 1.6
108
	 */
109
	public $abandoned_count;
110
111
	/**
112
	 * Get things started.
113
	 *
114
	 * @since 1.0
115
	 * @uses  Give_Payment_History_Table::get_payment_counts()
116
	 * @see   WP_List_Table::__construct()
117
	 */
118
	public function __construct() {
119
120
		// Set parent defaults.
121
		parent::__construct( array(
122
			'singular' => give_get_forms_label_singular(),    // Singular name of the listed records.
123
			'plural'   => give_get_forms_label_plural(),      // Plural name of the listed records.
124
			'ajax'     => false,                              // Does this table support ajax?
125
		) );
126
127
		$this->get_payment_counts();
128
		$this->process_bulk_action();
129
		$this->base_url = admin_url( 'edit.php?post_type=give_forms&page=give-payment-history' );
130
	}
131
132
	/**
133
	 * Add donation search filter.
134
	 *
135
	 * @return void
136
	 */
137
	public function advanced_filters() {
138
		$start_date = isset( $_GET['start-date'] ) ? sanitize_text_field( $_GET['start-date'] ) : null;
139
		$end_date   = isset( $_GET['end-date'] ) ? sanitize_text_field( $_GET['end-date'] ) : null;
140
		$status     = isset( $_GET['status'] ) ? $_GET['status'] : '';
141
		?>
142
        <div id="give-payment-filters">
143
			<span id="give-payment-date-filters">
144
				<label for="start-date"
145
                       class="give-start-date-label"><?php esc_html_e( 'Start Date:', 'give' ); ?></label>
146
				<input type="text" id="start-date" name="start-date" class="give_datepicker"
147
                       value="<?php echo $start_date; ?>" placeholder="mm/dd/yyyy"/>
148
				<label for="end-date" class="give-end-date-label"><?php esc_html_e( 'End Date:', 'give' ); ?></label>
149
				<input type="text" id="end-date" name="end-date" class="give_datepicker"
150
                       value="<?php echo $end_date; ?>" placeholder="mm/dd/yyyy"/>
151
				<input type="submit" class="button-secondary" value="<?php esc_attr_e( 'Apply', 'give' ); ?>"/>
152
			</span>
153
			<?php if ( ! empty( $status ) ) : ?>
154
                <input type="hidden" name="status" value="<?php echo esc_attr( $status ); ?>"/>
155
			<?php endif; ?>
156
			<?php if ( ! empty( $start_date ) || ! empty( $end_date ) ) : ?>
157
                <a href="<?php echo admin_url( 'edit.php?post_type=give_forms&page=give-payment-history' ); ?>"
158
                   class="button-secondary"><?php esc_html_e( 'Clear Filter', 'give' ); ?></a>
159
			<?php endif; ?>
160
			<?php $this->search_box( esc_html__( 'Search', 'give' ), 'give-payments' ); ?>
161
        </div>
162
163
		<?php
164
	}
165
166
	/**
167
	 * Show the search field
168
	 *
169
	 * @since  1.0
170
	 * @access public
171
	 *
172
	 * @param string $text     Label for the search box
173
	 * @param string $input_id ID of the search box
174
	 *
175
	 * @return void
176
	 */
177
	public function search_box( $text, $input_id ) {
178
		if ( empty( $_REQUEST['s'] ) && ! $this->has_items() ) {
179
			return;
180
		}
181
182
		$input_id = $input_id . '-search-input';
183
184
		if ( ! empty( $_REQUEST['orderby'] ) ) {
185
			echo '<input type="hidden" name="orderby" value="' . esc_attr( $_REQUEST['orderby'] ) . '" />';
186
		}
187
		if ( ! empty( $_REQUEST['order'] ) ) {
188
			echo '<input type="hidden" name="order" value="' . esc_attr( $_REQUEST['order'] ) . '" />';
189
		}
190
		?>
191
        <p class="search-box" role="search">
192
			<?php
193
			/**
194
			 * Fires in the payment history search box.
195
			 *
196
			 * Allows you to add new elements before the search box.
197
			 *
198
			 * @since 1.7
199
			 */
200
			do_action( 'give_payment_history_search' );
201
			?>
202
            <label class="screen-reader-text" for="<?php echo $input_id ?>"><?php echo $text; ?>:</label>
203
            <input type="search" id="<?php echo $input_id ?>" name="s" value="<?php _admin_search_query(); ?>"/>
204
			<?php submit_button( $text, 'button', false, false, array( 'ID' => 'search-submit' ) ); ?><br/>
205
        </p>
206
		<?php
207
	}
208
209
	/**
210
	 * Retrieve the view types
211
	 *
212
	 * @access public
213
	 * @since  1.0
214
	 * @return array $views All the views available
215
	 */
216
	public function get_views() {
217
218
		$current         = isset( $_GET['status'] ) ? $_GET['status'] : '';
219
		$total_count     = '&nbsp;<span class="count">(' . $this->total_count . ')</span>';
220
		$complete_count  = '&nbsp;<span class="count">(' . $this->complete_count . ')</span>';
221
		$cancelled_count = '&nbsp;<span class="count">(' . $this->cancelled_count . ')</span>';
222
		$pending_count   = '&nbsp;<span class="count">(' . $this->pending_count . ')</span>';
223
		$refunded_count  = '&nbsp;<span class="count">(' . $this->refunded_count . ')</span>';
224
		$failed_count    = '&nbsp;<span class="count">(' . $this->failed_count . ')</span>';
225
		$abandoned_count = '&nbsp;<span class="count">(' . $this->abandoned_count . ')</span>';
226
		$revoked_count   = '&nbsp;<span class="count">(' . $this->revoked_count . ')</span>';
227
228
		$views = array(
229
			'all'       => sprintf( '<a href="%s"%s>%s</a>', remove_query_arg( array(
230
				'status',
231
				'paged',
232
			) ), $current === 'all' || $current == '' ? ' class="current"' : '', esc_html__( 'All', 'give' ) . $total_count ),
233
			'publish'   => sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( array(
234
				'status' => 'publish',
235
				'paged'  => false,
236
			) ) ), $current === 'publish' ? ' class="current"' : '', esc_html__( 'Completed', 'give' ) . $complete_count ),
237
			'pending'   => sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( array(
238
				'status' => 'pending',
239
				'paged'  => false,
240
			) ) ), $current === 'pending' ? ' class="current"' : '', esc_html__( 'Pending', 'give' ) . $pending_count ),
241
			'refunded'  => sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( array(
242
				'status' => 'refunded',
243
				'paged'  => false,
244
			) ) ), $current === 'refunded' ? ' class="current"' : '', esc_html__( 'Refunded', 'give' ) . $refunded_count ),
245
			'revoked'   => sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( array(
246
				'status' => 'revoked',
247
				'paged'  => false,
248
			) ) ), $current === 'revoked' ? ' class="current"' : '', esc_html__( 'Revoked', 'give' ) . $revoked_count ),
249
			'failed'    => sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( array(
250
				'status' => 'failed',
251
				'paged'  => false,
252
			) ) ), $current === 'failed' ? ' class="current"' : '', esc_html__( 'Failed', 'give' ) . $failed_count ),
253
			'cancelled' => sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( array(
254
				'status' => 'cancelled',
255
				'paged'  => false,
256
			) ) ), $current === 'cancelled' ? ' class="current"' : '', esc_html__( 'Cancelled', 'give' ) . $cancelled_count ),
257
			'abandoned' => sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( array(
258
				'status' => 'abandoned',
259
				'paged'  => false,
260
			) ) ), $current === 'abandoned' ? ' class="current"' : '', esc_html__( 'Abandoned', 'give' ) . $abandoned_count ),
261
		);
262
263
		return apply_filters( 'give_payments_table_views', $views );
264
	}
265
266
	/**
267
	 * Retrieve the table columns
268
	 *
269
	 * @access public
270
	 * @since  1.0
271
	 * @return array $columns Array of all the list table columns
272
	 */
273
	public function get_columns() {
274
		$columns = array(
275
			'cb'            => '<input type="checkbox" />', // Render a checkbox instead of text.
276
			'donation'      => esc_html__( 'Donation', 'give' ),
277
			'donation_form' => esc_html__( 'Donation Form', 'give' ),
278
			'status'        => esc_html__( 'Status', 'give' ),
279
			'date'          => esc_html__( 'Date', 'give' ),
280
			'amount'        => esc_html__( 'Amount', 'give' ),
281
			'details'       => esc_html__( 'Details', 'give' ),
282
		);
283
284
		return apply_filters( 'give_payments_table_columns', $columns );
285
	}
286
287
	/**
288
	 * Retrieve the table's sortable columns
289
	 *
290
	 * @access public
291
	 * @since  1.0
292
	 * @return array Array of all the sortable columns
293
	 */
294
	public function get_sortable_columns() {
295
		$columns = array(
296
			'donation'      => array( 'ID', true ),
297
			'donation_form' => array( 'donation_form', false ),
298
			'status'        => array( 'status', false ),
299
			'amount'        => array( 'amount', false ),
300
			'date'          => array( 'date', false ),
301
		);
302
303
		return apply_filters( 'give_payments_table_sortable_columns', $columns );
304
	}
305
306
	/**
307
	 * Gets the name of the primary column.
308
	 *
309
	 * @since  1.5
310
	 * @access protected
311
	 *
312
	 * @return string Name of the primary column.
313
	 */
314
	protected function get_primary_column_name() {
315
		return 'donation';
316
	}
317
318
	/**
319
	 * This function renders most of the columns in the list table.
320
	 *
321
	 * @access public
322
	 * @since  1.0
323
	 *
324
	 * @param Give_Payment $payment     Payment ID.
325
	 * @param string       $column_name The name of the column
326
	 *
327
	 * @return string Column Name
328
	 */
329
	public function column_default( $payment, $column_name ) {
330
331
		$single_donation_url = esc_url( add_query_arg( 'id', $payment->ID, admin_url( 'edit.php?post_type=give_forms&page=give-payment-history&view=view-order-details' ) ) );
332
		$row_actions         = $this->get_row_actions( $payment );
333
334
		switch ( $column_name ) {
335
			case 'donation' :
336
				$value = sprintf(
337
					'<a href="%1$s" data-tooltip="%2$s">#%3$s</a>&nbsp;%4$s&nbsp;%5$s<br>',
338
					$single_donation_url,
339
					sprintf( esc_attr__( 'View Donation %s', 'give' ), $payment->ID ),
340
					$payment->ID,
341
					esc_html__( 'by', 'give' ),
342
					$this->get_donor( $payment )
343
				);
344
				$value .= $this->get_donor_email( $payment );
345
				$value .= $this->row_actions( $row_actions );
346
				break;
347
348
			case 'amount' :
349
				$amount = ! empty( $payment->total ) ? $payment->total : 0;
350
				$value  = give_currency_filter( give_format_amount( $amount ), give_get_payment_currency_code( $payment->ID ) );
351
				$value  .= sprintf(
352
					'<br><small>%1$s %2$s</small>',
353
					__( 'via', 'give' ),
354
					give_get_gateway_admin_label( $payment->gateway )
355
				);
356
				break;
357
358
			case 'donation_form' :
359
				$form_title = empty( $payment->form_title ) ? sprintf( __( 'Untitled (#%s)', 'give' ), $payment->form_id ) : $payment->form_title;
360
				$value      = '<a href="' . admin_url( 'post.php?post=' . $payment->form_id . '&action=edit' ) . '">' . $form_title . '</a>';
361
				$level      = give_get_payment_form_title( $payment->meta, true );
0 ignored issues
show
Documentation introduced by
The property meta does not exist on object<Give_Payment>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
362
363
				if ( ! empty( $level ) ) {
364
					$value .= $level;
365
				}
366
367
				break;
368
369
			case 'date' :
370
				$date  = strtotime( $payment->date );
371
				$value = date_i18n( give_date_format(), $date );
372
				break;
373
374
			case 'status' :
375
				$value = $this->get_payment_status( $payment );
376
				break;
377
378
			case 'details' :
379
				$value = sprintf(
380
					'<div class="give-payment-details-link-wrap"><a href="%1$s" class="give-payment-details-link button button-small" data-tooltip="%2$s" aria-label="%2$s"><span class="dashicons dashicons-visibility"></span></a></div>',
381
					$single_donation_url,
382
					sprintf( esc_attr__( 'View Donation %s', 'give' ), $payment->ID )
383
				);
384
				break;
385
386
			default:
387
				$value = isset( $payment->$column_name ) ? $payment->$column_name : '';
388
				break;
389
390
		}
391
392
		return apply_filters( 'give_payments_table_column', $value, $payment->ID, $column_name );
393
	}
394
395
	/**
396
	 * Get donor email html.
397
	 *
398
	 * @access public
399
	 * @since  1.0
400
	 *
401
	 * @param  Give_Payment $payment Contains all the data of the payment
402
	 *
403
	 * @return string                Data shown in the Email column
404
	 */
405
	public function get_donor_email( $payment ) {
406
407
		$email = give_get_payment_user_email( $payment->ID );
408
409
		if ( empty( $email ) ) {
410
			$email = esc_html__( '(unknown)', 'give' );
411
		}
412
413
		$value = '<a href="mailto:' . $email . '" data-tooltip="' . esc_attr__( 'Email donor', 'give' ) . '">' . $email . '</a>';
414
415
		return apply_filters( 'give_payments_table_column', $value, $payment->ID, 'email' );
416
	}
417
418
	/**
419
	 * Get Row Actions
420
	 *
421
	 * @since 1.6
422
	 *
423
	 * @param Give_Payment $payment
424
	 *
425
	 * @return array $actions
426
	 */
427
	function get_row_actions( $payment ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
428
429
		$actions = array();
430
		$email   = give_get_payment_user_email( $payment->ID );
431
432
		// Add search term string back to base URL.
433
		$search_terms = ( isset( $_GET['s'] ) ? trim( $_GET['s'] ) : '' );
434
		if ( ! empty( $search_terms ) ) {
435
			$this->base_url = add_query_arg( 's', $search_terms, $this->base_url );
436
		}
437
438
		if ( give_is_payment_complete( $payment->ID ) && ! empty( $email ) ) {
439
440
			$actions['email_links'] = sprintf(
441
				'<a href="%1$s" aria-label="%2$s">%3$s</a>',
442
				wp_nonce_url(
443
					add_query_arg(
444
						array(
445
							'give-action' => 'email_links',
446
							'purchase_id' => $payment->ID,
447
						),
448
						$this->base_url
449
					),
450
					'give_payment_nonce'
451
				),
452
				sprintf( esc_attr__( 'Resend Donation %s Receipt', 'give' ), $payment->ID ),
453
				esc_html__( 'Resend Receipt', 'give' )
454
			);
455
456
		}
457
458
		$actions['delete'] = sprintf(
459
			'<a href="%1$s" aria-label="%2$s">%3$s</a>',
460
			wp_nonce_url(
461
				add_query_arg(
462
					array(
463
						'give-action' => 'delete_payment',
464
						'purchase_id' => $payment->ID,
465
					),
466
					$this->base_url
467
				),
468
				'give_donation_nonce'
469
			),
470
			sprintf( esc_attr__( 'Delete Donation %s', 'give' ), $payment->ID ),
471
			esc_html__( 'Delete', 'give' )
472
		);
473
474
		return apply_filters( 'give_payment_row_actions', $actions, $payment );
475
	}
476
477
478
	/**
479
	 *  Get payment status html.
480
	 *
481
	 * @access public
482
	 * @since  1.0
483
	 *
484
	 * @param  Give_Payment $payment Contains all the data of the payment
485
	 *
486
	 * @return string                Data shown in the Email column
487
	 */
488
	function get_payment_status( $payment ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
489
		$value = '<div class="give-donation-status status-' . sanitize_title( give_get_payment_status( $payment, true ) ) . '"><span class="give-donation-status-icon"></span> ' . give_get_payment_status( $payment, true ) . '</div>';
490
		if ( $payment->mode == 'test' ) {
491
			$value .= ' <span class="give-item-label give-item-label-orange give-test-mode-transactions-label" data-tooltip="' . esc_attr__( 'This donation was made in test mode.', 'give' ) . '">' . esc_html__( 'Test', 'give' ) . '</span>';
492
		}
493
494
		return $value;
495
	}
496
497
	/**
498
	 * Get checkbox html.
499
	 *
500
	 * @access public
501
	 * @since  1.0
502
	 *
503
	 * @param  Give_Payment $payment Contains all the data for the checkbox column.
504
	 *
505
	 * @return string Displays a checkbox.
506
	 */
507
	public function column_cb( $payment ) {
508
		return sprintf(
509
			'<input type="checkbox" name="%1$s[]" value="%2$s" />',
510
			'payment',
511
			$payment->ID
512
		);
513
	}
514
515
	/**
516
	 * Get payment ID html.
517
	 *
518
	 * @access public
519
	 * @since  1.0
520
	 *
521
	 * @param  Give_Payment $payment Contains all the data for the checkbox column.
522
	 *
523
	 * @return string Displays a checkbox.
524
	 */
525
	public function get_payment_id( $payment ) {
526
		return '<span class="give-payment-id">' . give_get_payment_number( $payment->ID ) . '</span>';
527
	}
528
529
	/**
530
	 * Get donor html.
531
	 *
532
	 * @access public
533
	 * @since  1.0
534
	 *
535
	 * @param  Give_Payment $payment Contains all the data of the payment
536
	 *
537
	 * @return string Data shown in the User column
538
	 */
539
	public function get_donor( $payment ) {
540
541
		$donor_id    = give_get_payment_customer_id( $payment->ID );
542
        $donor_billing_name     = give_get_donor_name_by( $payment->ID, 'donation');
543
        $donor_name  = give_get_donor_name_by( $donor_id, 'donor');
544
545
        $value = '';
546
		if ( ! empty( $donor_id ) ) {
547
548
            // Check whether the donor name and WP_User name is same or not.
549
            if( sanitize_title( $donor_billing_name ) != sanitize_title( $donor_name ) ){
550
                $value  .= $donor_billing_name . ' (';
551
            }
552
553
			$value    .= '<a href="' . esc_url( admin_url( "edit.php?post_type=give_forms&page=give-donors&view=overview&id=$donor_id" ) ) . '">' . $donor_name . '</a>';
554
555
            // Check whether the donor name and WP_User name is same or not.
556
            if( sanitize_title( $donor_billing_name ) != sanitize_title( $donor_name ) ){
557
                $value  .= ')';
558
            }
559
560
		} else {
561
			$email = give_get_payment_user_email( $payment->ID );
562
			$value .= '<a href="' . esc_url( admin_url( "edit.php?post_type=give_forms&page=give-payment-history&s=$email" ) ) . '">' . esc_html__( '(donor missing)', 'give' ) . '</a>';
563
		}
564
565
		return apply_filters( 'give_payments_table_column', $value, $payment->ID, 'donor' );
566
	}
567
568
	/**
569
	 * Retrieve the bulk actions
570
	 *
571
	 * @access public
572
	 * @since  1.0
573
	 * @return array $actions Array of the bulk actions
574
	 */
575
	public function get_bulk_actions() {
576
		$actions = array(
577
			'delete'               => esc_html__( 'Delete', 'give' ),
578
			'set-status-publish'   => esc_html__( 'Set To Completed', 'give' ),
579
			'set-status-pending'   => esc_html__( 'Set To Pending', 'give' ),
580
			'set-status-refunded'  => esc_html__( 'Set To Refunded', 'give' ),
581
			'set-status-revoked'   => esc_html__( 'Set To Revoked', 'give' ),
582
			'set-status-failed'    => esc_html__( 'Set To Failed', 'give' ),
583
			'set-status-cancelled' => esc_html__( 'Set To Cancelled', 'give' ),
584
			'set-status-abandoned' => esc_html__( 'Set To Abandoned', 'give' ),
585
			'resend-receipt'       => esc_html__( 'Resend Email Receipts', 'give' ),
586
		);
587
588
		return apply_filters( 'give_payments_table_bulk_actions', $actions );
589
	}
590
591
	/**
592
	 * Process the bulk actions
593
	 *
594
	 * @access public
595
	 * @since  1.0
596
	 * @return void
597
	 */
598
	public function process_bulk_action() {
599
		$ids    = isset( $_GET['payment'] ) ? $_GET['payment'] : false;
600
		$action = $this->current_action();
601
602
		if ( ! is_array( $ids ) ) {
603
			$ids = array( $ids );
604
		}
605
606
		if ( empty( $action ) ) {
607
			return;
608
		}
609
610
		foreach ( $ids as $id ) {
611
612
			// Detect when a bulk action is being triggered.
613
			switch ( $this->current_action() ) {
614
615
				case'delete':
616
					give_delete_purchase( $id );
617
					break;
618
619
				case 'set-status-publish':
620
					give_update_payment_status( $id, 'publish' );
621
					break;
622
623
				case 'set-status-pending':
624
					give_update_payment_status( $id, 'pending' );
625
					break;
626
627
				case 'set-status-refunded':
628
					give_update_payment_status( $id, 'refunded' );
629
					break;
630
				case 'set-status-revoked':
631
					give_update_payment_status( $id, 'revoked' );
632
					break;
633
634
				case 'set-status-failed':
635
					give_update_payment_status( $id, 'failed' );
636
					break;
637
638
				case 'set-status-cancelled':
639
					give_update_payment_status( $id, 'cancelled' );
640
					break;
641
642
				case 'set-status-abandoned':
643
					give_update_payment_status( $id, 'abandoned' );
644
					break;
645
646
				case 'set-status-preapproval':
647
					give_update_payment_status( $id, 'preapproval' );
648
					break;
649
650
				case 'resend-receipt':
651
					/**
652
					 * Fire the action
653
					 * @since 2.0
654
					 */
655
					do_action( 'give_donation-receipt_email_notification', $id );
656
					break;
657
			}
658
659
			/**
660
			 * Fires after triggering bulk action on payments table.
661
			 *
662
			 * @since 1.7
663
			 *
664
			 * @param int    $id             The ID of the payment.
665
			 * @param string $current_action The action that is being triggered.
666
			 */
667
			do_action( 'give_payments_table_do_bulk_action', $id, $this->current_action() );
668
		}
669
670
	}
671
672
	/**
673
	 * Retrieve the payment counts
674
	 *
675
	 * @access public
676
	 * @since  1.0
677
	 * @return void
678
	 */
679
	public function get_payment_counts() {
680
681
		$args = array();
682
683
		if ( isset( $_GET['user'] ) ) {
684
			$args['user'] = urldecode( $_GET['user'] );
685
		} elseif ( isset( $_GET['s'] ) ) {
686
			$is_user = strpos( $_GET['s'], strtolower( 'user:' ) ) !== false;
687
			if ( $is_user ) {
688
				$args['user'] = absint( trim( str_replace( 'user:', '', strtolower( $_GET['s'] ) ) ) );
689
				unset( $args['s'] );
690
			} else {
691
				$args['s'] = sanitize_text_field( $_GET['s'] );
692
			}
693
		}
694
695
		if ( ! empty( $_GET['start-date'] ) ) {
696
			$args['start-date'] = urldecode( $_GET['start-date'] );
697
		}
698
699
		if ( ! empty( $_GET['end-date'] ) ) {
700
			$args['end-date'] = urldecode( $_GET['end-date'] );
701
		}
702
703
		$payment_count         = give_count_payments( $args );
704
		$this->complete_count  = $payment_count->publish;
705
		$this->pending_count   = $payment_count->pending;
706
		$this->refunded_count  = $payment_count->refunded;
707
		$this->failed_count    = $payment_count->failed;
708
		$this->revoked_count   = $payment_count->revoked;
709
		$this->cancelled_count = $payment_count->cancelled;
710
		$this->abandoned_count = $payment_count->abandoned;
711
712
		foreach ( $payment_count as $count ) {
713
			$this->total_count += $count;
714
		}
715
	}
716
717
	/**
718
	 * Retrieve all the data for all the payments.
719
	 *
720
	 * @access public
721
	 * @since  1.0
722
	 * @return array  objects in array containing all the data for the payments
723
	 */
724
	public function payments_data() {
725
726
		$per_page   = $this->per_page;
727
		$orderby    = isset( $_GET['orderby'] ) ? urldecode( $_GET['orderby'] ) : 'ID';
728
		$order      = isset( $_GET['order'] ) ? $_GET['order'] : 'DESC';
729
		$user       = isset( $_GET['user'] ) ? $_GET['user'] : null;
730
		$status     = isset( $_GET['status'] ) ? $_GET['status'] : give_get_payment_status_keys();
731
		$meta_key   = isset( $_GET['meta_key'] ) ? $_GET['meta_key'] : null;
732
		$year       = isset( $_GET['year'] ) ? $_GET['year'] : null;
733
		$month      = isset( $_GET['m'] ) ? $_GET['m'] : null;
734
		$day        = isset( $_GET['day'] ) ? $_GET['day'] : null;
735
		$search     = isset( $_GET['s'] ) ? sanitize_text_field( $_GET['s'] ) : null;
736
		$start_date = isset( $_GET['start-date'] ) ? sanitize_text_field( $_GET['start-date'] ) : null;
737
		$end_date   = isset( $_GET['end-date'] ) ? sanitize_text_field( $_GET['end-date'] ) : $start_date;
738
739
		if ( ! empty( $search ) ) {
740
			$status = 'any'; // Force all payment statuses when searching.
741
		}
742
743
		$args = array(
744
			'output'     => 'payments',
745
			'number'     => $per_page,
746
			'page'       => isset( $_GET['paged'] ) ? $_GET['paged'] : null,
747
			'orderby'    => $orderby,
748
			'order'      => $order,
749
			'user'       => $user,
750
			'status'     => $status,
751
			'meta_key'   => $meta_key,
752
			'year'       => $year,
753
			'month'      => $month,
754
			'day'        => $day,
755
			's'          => $search,
756
			'start_date' => $start_date,
757
			'end_date'   => $end_date,
758
		);
759
760
		if ( is_string( $search ) && false !== strpos( $search, 'txn:' ) ) {
761
			$args['search_in_notes'] = true;
762
			$args['s']               = trim( str_replace( 'txn:', '', $args['s'] ) );
763
		}
764
765
		$p_query = new Give_Payments_Query( $args );
766
767
		return $p_query->get_payments();
768
769
	}
770
771
	/**
772
	 * Setup the final data for the table
773
	 *
774
	 * @access public
775
	 * @since  1.0
776
	 * @uses   Give_Payment_History_Table::get_columns()
777
	 * @uses   Give_Payment_History_Table::get_sortable_columns()
778
	 * @uses   Give_Payment_History_Table::payments_data()
779
	 * @uses   WP_List_Table::get_pagenum()
780
	 * @uses   WP_List_Table::set_pagination_args()
781
	 * @return void
782
	 */
783
	public function prepare_items() {
784
785
		wp_reset_vars( array( 'action', 'payment', 'orderby', 'order', 's' ) );
786
787
		$columns  = $this->get_columns();
788
		$hidden   = array(); // No hidden columns.
789
		$sortable = $this->get_sortable_columns();
790
		$data     = $this->payments_data();
791
		$status   = isset( $_GET['status'] ) ? $_GET['status'] : 'any';
792
793
		$this->_column_headers = array( $columns, $hidden, $sortable );
794
795
		switch ( $status ) {
796
			case 'publish':
797
				$total_items = $this->complete_count;
798
				break;
799
			case 'pending':
800
				$total_items = $this->pending_count;
801
				break;
802
			case 'refunded':
803
				$total_items = $this->refunded_count;
804
				break;
805
			case 'failed':
806
				$total_items = $this->failed_count;
807
				break;
808
			case 'revoked':
809
				$total_items = $this->revoked_count;
810
				break;
811
			case 'cancelled':
812
				$total_items = $this->cancelled_count;
813
				break;
814
			case 'abandoned':
815
				$total_items = $this->abandoned_count;
816
				break;
817
			case 'any':
818
				$total_items = $this->total_count;
819
				break;
820
			default:
821
				// Retrieve the count of the non-default-Give status.
822
				$count       = wp_count_posts( 'give_payment' );
823
				$total_items = isset( $count->{$status} ) ? $count->{$status} : 0;
824
				break;
825
		}
826
827
		$this->items = $data;
828
829
		$this->set_pagination_args( array(
830
				'total_items' => $total_items,
831
				// We have to calculate the total number of items.
832
				'per_page'    => $this->per_page,
833
				// We have to determine how many items to show on a page.
834
				'total_pages' => ceil( $total_items / $this->per_page ),
835
				// We have to calculate the total number of pages.
836
			)
837
		);
838
	}
839
}
840