Test Failed
Pull Request — master (#2559)
by
unknown
04:35
created

Give_Payment_History_Table   D

Complexity

Total Complexity 124

Size/Duplication

Total Lines 956
Duplicated Lines 3.03 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 29
loc 956
rs 4.4444
c 0
b 0
f 0
wmc 124
lcom 1
cbo 4

19 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 15 1
D advanced_filters() 0 68 14
B search_box() 0 38 5
A get_columns() 0 16 2
A get_sortable_columns() 0 11 1
A get_primary_column_name() 0 3 1
C column_default() 0 57 13
A get_donor_email() 0 12 2
B get_row_actions() 26 41 6
A get_payment_status() 3 12 4
A column_cb() 0 3 1
A get_payment_id() 0 3 1
B get_donor() 0 27 4
A get_bulk_actions() 0 17 1
C process_bulk_action() 0 73 16
D get_payment_counts() 0 46 10
F payments_data() 0 59 19
D get_views() 0 98 10
C prepare_items() 0 70 13

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

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
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 processing payments
73
	 *
74
	 * @var int
75
	 * @since 1.8.9
76
	 */
77
	public $processing_count;
78
79
	/**
80
	 * Total number of refunded payments
81
	 *
82
	 * @var int
83
	 * @since 1.0
84
	 */
85
	public $refunded_count;
86
87
	/**
88
	 * Total number of failed payments
89
	 *
90
	 * @var int
91
	 * @since 1.0
92
	 */
93
	public $failed_count;
94
95
	/**
96
	 * Total number of revoked payments
97
	 *
98
	 * @var int
99
	 * @since 1.0
100
	 */
101
	public $revoked_count;
102
103
	/**
104
	 * Total number of cancelled payments
105
	 *
106
	 * @var int
107
	 * @since 1.4
108
	 */
109
	public $cancelled_count;
110
111
	/**
112
	 * Total number of abandoned payments
113
	 *
114
	 * @var int
115
	 * @since 1.6
116
	 */
117
	public $abandoned_count;
118
119
	/**
120
	 * Total number of pre-approved payments
121
	 *
122
	 * @var int
123
	 * @since 1.8.13
124
	 */
125
	public $preapproval_count;
126
127
	/**
128
	 * Get things started.
129
	 *
130
	 * @since 1.0
131
	 * @uses  Give_Payment_History_Table::get_payment_counts()
132
	 * @see   WP_List_Table::__construct()
133
	 */
134
	public function __construct() {
135
136
		// Set parent defaults.
137
		parent::__construct(
138
			array(
139
				'singular' => give_get_forms_label_singular(),    // Singular name of the listed records.
140
				'plural'   => give_get_forms_label_plural(),      // Plural name of the listed records.
141
				'ajax'     => false,                              // Does this table support ajax?
142
			)
143
		);
144
145
		$this->process_bulk_action();
146
		$this->get_payment_counts();
147
		$this->base_url = admin_url( 'edit.php?post_type=give_forms&page=give-payment-history' );
148
	}
149
150
	/**
151
	 * Add donation search filter.
152
	 *
153
	 * @return void
154
	 */
155
	public function advanced_filters() {
156
		$start_date = isset( $_GET['start-date'] ) ? sanitize_text_field( $_GET['start-date'] ) : null;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
157
		$end_date   = isset( $_GET['end-date'] ) ? sanitize_text_field( $_GET['end-date'] ) : null;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
158
		$status     = isset( $_GET['status'] ) ? sanitize_text_field( $_GET['status'] ) : '';
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
159
		$donor      = isset( $_GET['donor'] ) ? sanitize_text_field( $_GET['donor'] ) : '';
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
160
		$search     = isset( $_GET['s'] ) ? sanitize_text_field( $_GET['s'] ) : '';
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
161
		$form_id    = ! empty( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : 0;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
162
		?>
163
		<div id="give-payment-filters" class="give-filters">
164
			<?php $this->search_box( __( 'Search', 'give' ), 'give-payments' ); ?>
165
			<div id="give-payment-date-filters">
166
				<div class="give-filter give-filter-half">
167
					<label for="start-date"
168
						   class="give-start-date-label"><?php _e( 'Start Date', 'give' ); ?></label>
169
					<input type="text" id="start-date" name="start-date" class="give_datepicker"
170
						   value="<?php echo $start_date; ?>" placeholder="mm/dd/yyyy" />
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$start_date'
Loading history...
171
				</div>
172
				<div class="give-filter give-filter-half">
173
					<label for="end-date" class="give-end-date-label"><?php _e( 'End Date', 'give' ); ?></label>
174
					<input type="text" id="end-date" name="end-date" class="give_datepicker"
175
						   value="<?php echo $end_date; ?>" placeholder="mm/dd/yyyy" />
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$end_date'
Loading history...
176
				</div>
177
			</div>
178
			<div id="give-payment-form-filter" class="give-filter">
179
				<label for="give-donation-forms-filter"
180
					   class="give-donation-forms-filter-label"><?php _e( 'Form', 'give' ); ?></label>
181
				<?php
182
				// Filter Donations by Donation Forms.
183
				echo Give()->html->forms_dropdown(
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'Give'
Loading history...
184
					array(
185
						'name'     => 'form_id',
186
						'id'       => 'give-donation-forms-filter',
187
						'class'    => 'give-donation-forms-filter',
188
						'selected' => $form_id, // Make sure to have $form_id set to 0, if there is no selection.
189
						'chosen'   => true,
190
						'number'   => - 1,
191
					)
192
				);
193
				?>
194
			</div>
195
196
			<?php
197
			/**
198
			 * Action to add hidden fields and HTML in Payment search.
199
			 *
200
			 * @since 1.8.18
201
			 */
202
			do_action( 'give_payment_table_advanced_filters' );
203
			?>
204
205
			<?php if ( ! empty( $status ) ) : ?>
206
				<input type="hidden" name="status" value="<?php echo esc_attr( $status ); ?>" />
207
			<?php endif; ?>
208
209
			<div class="give-filter">
210
				<?php submit_button( __( 'Apply', 'give' ), 'secondary', '', false ); ?>
211
				<?php
212
				// Clear active filters button.
213
				if ( ! empty( $start_date ) || ! empty( $end_date ) || ! empty( $donor ) || ! empty( $search ) || ! empty( $status ) || ! empty( $form_id ) ) :
214
				?>
215
					<a href="<?php echo admin_url( 'edit.php?post_type=give_forms&page=give-payment-history' ); ?>"
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'admin_url'
Loading history...
216
					   class="button give-clear-filters-button"><?php _e( 'Clear Filters', 'give' ); ?></a>
217
				<?php endif; ?>
218
			</div>
219
		</div>
220
221
		<?php
222
	}
223
224
	/**
225
	 * Show the search field
226
	 *
227
	 * @param string $text     Label for the search box.
228
	 * @param string $input_id ID of the search box.
229
	 *
230
	 * @since  1.0
231
	 * @access public
232
	 *
233
	 * @return void
234
	 */
235
	public function search_box( $text, $input_id ) {
236
		if ( empty( $_REQUEST['s'] ) && ! $this->has_items() ) {
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
237
			return;
238
		}
239
240
		$input_id = $input_id . '-search-input';
241
242
		if ( ! empty( $_REQUEST['orderby'] ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
243
			echo '<input type="hidden" name="orderby" value="' . esc_attr( $_REQUEST['orderby'] ) . '" />';
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
244
		}
245
		if ( ! empty( $_REQUEST['order'] ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
246
			echo '<input type="hidden" name="order" value="' . esc_attr( $_REQUEST['order'] ) . '" />';
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
247
		}
248
		?>
249
		<div class="give-filter give-filter-search" role="search">
250
			<?php
251
			/**
252
			 * Fires in the payment history search box.
253
			 *
254
			 * Allows you to add new elements before the search box.
255
			 *
256
			 * @since 1.7
257
			 */
258
			do_action( 'give_payment_history_search' );
259
			?>
260
			<label class="screen-reader-text" for="<?php echo $input_id; ?>"><?php echo $text; ?>:</label>
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$input_id'
Loading history...
introduced by
Expected next thing to be a escaping function, not '$text'
Loading history...
261
			<input type="search" id="<?php echo $input_id; ?>" name="s" value="<?php _admin_search_query(); ?>" />
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$input_id'
Loading history...
262
			<?php
263
			submit_button(
264
				$text, 'button', false, false, array(
265
					'ID' => 'search-submit',
266
				)
267
			);
268
			?>
269
			<br />
270
		</div>
271
		<?php
272
	}
273
274
	/**
275
	 * Retrieve the view types
276
	 *
277
	 * @access public
278
	 * @since  1.0
279
	 *
280
	 * @return array $views All the views available
281
	 */
282
	public function get_views() {
283
284
		$current = isset( $_GET['status'] ) ? $_GET['status'] : '';
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
285
		$views   = array();
286
		$tabs    = array(
287
			'all'         => array(
288
				'total_count',
289
				__( 'All', 'give' ),
290
			),
291
			'publish'     => array(
292
				'complete_count',
293
				__( 'Completed', 'give' ),
294
			),
295
			'pending'     => array(
296
				'pending_count',
297
				__( 'Pending', 'give' ),
298
			),
299
			'processing'  => array(
300
				'processing_count',
301
				__( 'Processing', 'give' ),
302
			),
303
			'refunded'    => array(
304
				'refunded_count',
305
				__( 'Refunded', 'give' ),
306
			),
307
			'revoked'     => array(
308
				'revoked_count',
309
				__( 'Revoked', 'give' ),
310
			),
311
			'failed'      => array(
312
				'failed_count',
313
				__( 'Failed', 'give' ),
314
			),
315
			'cancelled'   => array(
316
				'cancelled_count',
317
				__( 'Cancelled', 'give' ),
318
			),
319
			'abandoned'   => array(
320
				'abandoned_count',
321
				__( 'Abandoned', 'give' ),
322
			),
323
			'preapproval' => array(
324
				'preapproval_count',
325
				__( 'Preapproval Pending', 'give' ),
326
			),
327
		);
328
329
		/**
330
		 * Remove Query from Args of the URL that are being pass to Donation Status.
331
		 *
332
		 * @since 1.8.18
333
		 */
334
		$args = (array) apply_filters( 'give_payments_table_status_remove_query_arg', array( 'paged', '_wpnonce', '_wp_http_referer' ) );
335
336
		// Build URL.
337
		$staus_url = remove_query_arg( $args );
338
339
		foreach ( $tabs as $key => $tab ) {
340
			$count_key = $tab[0];
341
			$name      = $tab[1];
342
			$count     = $this->$count_key;
343
344
			/**
345
			 * Filter can be used to show all the status inside the donation tabs.
346
			 *
347
			 * Filter can be used to show all the status inside the donation submenu tabs return true to show all the tab.
348
			 *
349
			 * @param string $key   Current view tab value.
350
			 * @param int    $count Number of donation inside the tab.
351
			 *
352
			 * @since 1.8.12
353
			 */
354
			if ( 'all' === $key || $key === $current || apply_filters( 'give_payments_table_show_all_status', 0 < $count, $key, $count ) ) {
355
356
				$staus_url = 'all' === $key ?
357
					add_query_arg( array( 'status' => false ), $staus_url ) :
358
					add_query_arg( array( 'status' => $key ), $staus_url );
359
360
				$views[ $key ] = sprintf(
361
					'<a href="%s"%s>%s&nbsp;<span class="count">(%s)</span></a>',
362
					esc_url( $staus_url ),
363
					( ( 'all' === $key && empty( $current ) ) ) ? ' class="current"' : ( $current == $key ? 'class="current"' : '' ),
364
					$name,
365
					$count
366
				);
367
			}
368
		}
369
370
		/**
371
		 * Filter the donation listing page views.
372
		 *
373
		 * @since 1.0
374
		 *
375
		 * @param array $views
376
		 * @param Give_Payment_History_Table 
377
		 */
378
		return apply_filters( 'give_payments_table_views', $views, $this );
379
	}
380
381
	/**
382
	 * Retrieve the table columns
383
	 *
384
	 * @access public
385
	 * @since  1.0
386
	 *
387
	 * @return array $columns Array of all the list table columns
388
	 */
389
	public function get_columns() {
390
		$columns = array(
391
			'cb'            => '<input type="checkbox" />', // Render a checkbox instead of text.
392
			'donation'      => __( 'Donation', 'give' ),
393
			'donation_form' => __( 'Donation Form', 'give' ),
394
			'status'        => __( 'Status', 'give' ),
395
			'date'          => __( 'Date', 'give' ),
396
			'amount'        => __( 'Amount', 'give' ),
397
		);
398
399
		if ( current_user_can( 'view_give_payments' ) ) {
400
			$columns['details'] = __( 'Details', 'give' );
401
		}
402
403
		return apply_filters( 'give_payments_table_columns', $columns );
404
	}
405
406
	/**
407
	 * Retrieve the table's sortable columns
408
	 *
409
	 * @access public
410
	 * @since  1.0
411
	 *
412
	 * @return array Array of all the sortable columns
413
	 */
414
	public function get_sortable_columns() {
415
		$columns = array(
416
			'donation'      => array( 'ID', true ),
417
			'donation_form' => array( 'donation_form', false ),
418
			'status'        => array( 'status', false ),
419
			'amount'        => array( 'amount', false ),
420
			'date'          => array( 'date', false ),
421
		);
422
423
		return apply_filters( 'give_payments_table_sortable_columns', $columns );
424
	}
425
426
	/**
427
	 * Gets the name of the primary column.
428
	 *
429
	 * @since  1.5
430
	 * @access protected
431
	 *
432
	 * @return string Name of the primary column.
433
	 */
434
	protected function get_primary_column_name() {
435
		return 'donation';
436
	}
437
438
	/**
439
	 * This function renders most of the columns in the list table.
440
	 *
441
	 * @param Give_Payment $payment     Payment ID.
442
	 * @param string       $column_name The name of the column.
443
	 *
444
	 * @access public
445
	 * @since  1.0
446
	 *
447
	 * @return string Column Name
448
	 */
449
	public function column_default( $payment, $column_name ) {
450
451
		$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-payment-details' ) ) );
452
		$row_actions         = $this->get_row_actions( $payment );
453
		$value = '';
454
455
		switch ( $column_name ) {
456
			case 'donation':
457
				if ( current_user_can( 'view_give_payments' ) ) {
458
					$value = sprintf( '<a href="%1$s" data-tooltip="%2$s">#%3$s</a>&nbsp;%4$s&nbsp;%5$s<br>', $single_donation_url, sprintf( __( 'View Donation #%s', 'give' ), $payment->ID ), $payment->ID, __( 'by', 'give' ), $this->get_donor( $payment ) );
459
				} else {
460
					$value = sprintf( '#%1$s ' . __( 'by', 'give' ) . ' %2$s <br/>', $payment->ID, $this->get_donor( $payment ) );
461
				}
462
				$value .= $this->get_donor_email( $payment );
463
				$value .= $this->row_actions( $row_actions );
464
				break;
465
466
			case 'amount':
467
				$amount = ! empty( $payment->total ) ? $payment->total : 0;
0 ignored issues
show
Unused Code introduced by
$amount 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 $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
468
				$value  = give_donation_amount( $payment, true );
469
				$value .= sprintf( '<br><small>%1$s %2$s</small>', __( 'via', 'give' ), give_get_gateway_admin_label( $payment->gateway ) );
470
				break;
471
472
			case 'donation_form':
473
				$form_title = empty( $payment->form_title ) ? sprintf( __( 'Untitled (#%s)', 'give' ), $payment->form_id ) : $payment->form_title;
474
				$value      = '<a href="' . admin_url( 'post.php?post=' . $payment->form_id . '&action=edit' ) . '">' . $form_title . '</a>';
475
				$level      = give_get_payment_form_title( $payment->meta, true );
476
477
				if ( ! empty( $level ) ) {
478
					$value .= $level;
479
				}
480
481
				break;
482
483
			case 'date':
484
				$date  = strtotime( $payment->date );
485
				$value = date_i18n( give_date_format(), $date );
486
				break;
487
488
			case 'status':
489
				$value = $this->get_payment_status( $payment );
490
				break;
491
492
			case 'details':
493
				if ( current_user_can( 'view_give_payments' ) ) {
494
					$value = sprintf( '<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>', $single_donation_url, sprintf( __( 'View Donation #%s', 'give' ), $payment->ID ) );
495
				}
496
				break;
497
498
			default:
499
				$value = isset( $payment->$column_name ) ? $payment->$column_name : '';
500
				break;
501
502
		}// End switch().
503
504
		return apply_filters( 'give_payments_table_column', $value, $payment->ID, $column_name );
505
	}
506
507
	/**
508
	 * Get donor email html.
509
	 *
510
	 * @param object $payment Contains all the data of the payment.
511
	 *
512
	 * @access public
513
	 * @since  1.0
514
	 *
515
	 * @return string Data shown in the Email column
516
	 */
517
	public function get_donor_email( $payment ) {
518
519
		$email = give_get_payment_user_email( $payment->ID );
520
521
		if ( empty( $email ) ) {
522
			$email = __( '(unknown)', 'give' );
523
		}
524
525
		$value = '<a href="mailto:' . $email . '" data-tooltip="' . __( 'Email donor', 'give' ) . '">' . $email . '</a>';
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$email'
Loading history...
526
527
		return apply_filters( 'give_payments_table_column', $value, $payment->ID, 'email' );
528
	}
529
530
	/**
531
	 * Get Row Actions
532
	 *
533
	 * @param object $payment Payment Data.
534
	 *
535
	 * @since 1.6
536
	 *
537
	 * @return array $actions
538
	 */
539
	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...
540
541
		$actions = array();
542
		$email   = give_get_payment_user_email( $payment->ID );
543
544
		// Add search term string back to base URL.
545
		$search_terms = ( isset( $_GET['s'] ) ? trim( $_GET['s'] ) : '' );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
546
		if ( ! empty( $search_terms ) ) {
547
			$this->base_url = add_query_arg( 's', $search_terms, $this->base_url );
548
		}
549
550 View Code Duplication
		if ( give_is_payment_complete( $payment->ID ) && ! empty( $email ) ) {
0 ignored issues
show
Duplication introduced by
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.

Loading history...
551
552
			$actions['email_links'] = sprintf(
553
				'<a class="resend-single-donation-receipt" href="%1$s" aria-label="%2$s">%3$s</a>', wp_nonce_url(
554
					add_query_arg(
555
						array(
556
							'give-action' => 'email_links',
557
							'purchase_id' => $payment->ID,
558
						), $this->base_url
559
					), 'give_payment_nonce'
560
				), sprintf( __( 'Resend Donation %s Receipt', 'give' ), $payment->ID ), __( 'Resend Receipt', 'give' )
561
			);
562
563
		}
564
565 View Code Duplication
		if ( current_user_can( 'view_give_payments' ) ) {
0 ignored issues
show
Duplication introduced by
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.

Loading history...
566
			$actions['delete'] = sprintf(
567
				'<a class="delete-single-donation" href="%1$s" aria-label="%2$s">%3$s</a>', wp_nonce_url(
568
					add_query_arg(
569
						array(
570
							'give-action' => 'delete_payment',
571
							'purchase_id' => $payment->ID,
572
						), $this->base_url
573
					), 'give_donation_nonce'
574
				), sprintf( __( 'Delete Donation %s', 'give' ), $payment->ID ), __( 'Delete', 'give' )
575
			);
576
		}
577
578
		return apply_filters( 'give_payment_row_actions', $actions, $payment );
579
	}
580
581
582
	/**
583
	 *  Get payment status html.
584
	 *
585
	 * @param object $payment Contains all the data of the payment.
586
	 *
587
	 * @access public
588
	 * @since  1.0
589
	 *
590
	 * @return string Data shown in the Email column
591
	 */
592
	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...
593
		$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>';
594 View Code Duplication
		if ( 'test' === $payment->mode ) {
0 ignored issues
show
Duplication introduced by
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.

Loading history...
595
			$value .= ' <span class="give-item-label give-item-label-orange give-test-mode-transactions-label" data-tooltip="' . __( 'This donation was made in test mode.', 'give' ) . '">' . __( 'Test', 'give' ) . '</span>';
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw '__'
Loading history...
596
		}
597
598
		if ( true === $payment->import && true === (bool) apply_filters( 'give_payment_show_importer_label', false ) ) {
599
			$value .= ' <span class="give-item-label give-item-label-orange give-test-mode-transactions-label" data-tooltip="' . __( 'This donation was imported.', 'give' ) . '">' . __( 'Import', 'give' ) . '</span>';
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw '__'
Loading history...
600
		}
601
602
		return $value;
603
	}
604
605
	/**
606
	 * Get checkbox html.
607
	 *
608
	 * @param object $payment Contains all the data for the checkbox column.
609
	 *
610
	 * @access public
611
	 * @since  1.0
612
	 *
613
	 * @return string Displays a checkbox.
614
	 */
615
	public function column_cb( $payment ) {
616
		return sprintf( '<input type="checkbox" name="%1$s[]" value="%2$s" />', 'payment', $payment->ID );
617
	}
618
619
	/**
620
	 * Get payment ID html.
621
	 *
622
	 * @param object $payment Contains all the data for the checkbox column.
623
	 * @access public
624
	 * @since  1.0
625
	 *
626
	 * @return string Displays a checkbox.
627
	 */
628
	public function get_payment_id( $payment ) {
629
		return '<span class="give-payment-id">' . give_get_payment_number( $payment->ID ) . '</span>';
630
	}
631
632
	/**
633
	 * Get donor html.
634
	 *
635
	 * @param object $payment Contains all the data of the payment.
636
	 *
637
	 * @access public
638
	 * @since  1.0
639
	 *
640
	 * @return string Data shown in the User column
641
	 */
642
	public function get_donor( $payment ) {
643
644
		$donor_id           = give_get_payment_donor_id( $payment->ID );
645
		$donor_billing_name = give_get_donor_name_by( $payment->ID, 'donation' );
646
		$donor_name         = give_get_donor_name_by( $donor_id, 'donor' );
647
648
		$value = '';
649
		if ( ! empty( $donor_id ) ) {
650
651
			// Check whether the donor name and WP_User name is same or not.
652
			if ( sanitize_title( $donor_billing_name ) != sanitize_title( $donor_name ) ) {
653
				$value .= $donor_billing_name . ' (';
654
			}
655
656
			$value .= '<a href="' . esc_url( admin_url( "edit.php?post_type=give_forms&page=give-donors&view=overview&id=$donor_id" ) ) . '">' . $donor_name . '</a>';
657
658
			// Check whether the donor name and WP_User name is same or not.
659
			if ( sanitize_title( $donor_billing_name ) != sanitize_title( $donor_name ) ) {
660
				$value .= ')';
661
			}
662
		} else {
663
			$email  = give_get_payment_user_email( $payment->ID );
664
			$value .= '<a href="' . esc_url( admin_url( "edit.php?post_type=give_forms&page=give-payment-history&s=$email" ) ) . '">' . __( '(donor missing)', 'give' ) . '</a>';
665
		}
666
667
		return apply_filters( 'give_payments_table_column', $value, $payment->ID, 'donor' );
668
	}
669
670
	/**
671
	 * Retrieve the bulk actions
672
	 *
673
	 * @access public
674
	 * @since  1.0
675
	 *
676
	 * @return array $actions Array of the bulk actions
677
	 */
678
	public function get_bulk_actions() {
679
		$actions = array(
680
			'delete'                 => __( 'Delete', 'give' ),
681
			'set-status-publish'     => __( 'Set To Completed', 'give' ),
682
			'set-status-pending'     => __( 'Set To Pending', 'give' ),
683
			'set-status-processing'  => __( 'Set To Processing', 'give' ),
684
			'set-status-refunded'    => __( 'Set To Refunded', 'give' ),
685
			'set-status-revoked'     => __( 'Set To Revoked', 'give' ),
686
			'set-status-failed'      => __( 'Set To Failed', 'give' ),
687
			'set-status-cancelled'   => __( 'Set To Cancelled', 'give' ),
688
			'set-status-abandoned'   => __( 'Set To Abandoned', 'give' ),
689
			'set-status-preapproval' => __( 'Set To Preapproval', 'give' ),
690
			'resend-receipt'         => __( 'Resend Email Receipts', 'give' ),
691
		);
692
693
		return apply_filters( 'give_payments_table_bulk_actions', $actions );
694
	}
695
696
	/**
697
	 * Process the bulk actions
698
	 *
699
	 * @access public
700
	 * @since  1.0
701
	 *
702
	 * @return void
703
	 */
704
	public function process_bulk_action() {
705
		$ids    = isset( $_GET['payment'] ) ? $_GET['payment'] : false;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
706
		$action = $this->current_action();
707
708
		if ( ! is_array( $ids ) ) {
709
			$ids = array( $ids );
710
		}
711
712
		if ( empty( $action ) ) {
713
			return;
714
		}
715
716
		foreach ( $ids as $id ) {
717
718
			// Detect when a bulk action is being triggered.
719
			switch ( $this->current_action() ) {
720
721
				case 'delete':
722
					give_delete_donation( $id );
723
					break;
724
725
				case 'set-status-publish':
726
					give_update_payment_status( $id, 'publish' );
727
					break;
728
729
				case 'set-status-pending':
730
					give_update_payment_status( $id, 'pending' );
731
					break;
732
733
				case 'set-status-processing':
734
					give_update_payment_status( $id, 'processing' );
735
					break;
736
737
				case 'set-status-refunded':
738
					give_update_payment_status( $id, 'refunded' );
739
					break;
740
				case 'set-status-revoked':
741
					give_update_payment_status( $id, 'revoked' );
742
					break;
743
744
				case 'set-status-failed':
745
					give_update_payment_status( $id, 'failed' );
746
					break;
747
748
				case 'set-status-cancelled':
749
					give_update_payment_status( $id, 'cancelled' );
750
					break;
751
752
				case 'set-status-abandoned':
753
					give_update_payment_status( $id, 'abandoned' );
754
					break;
755
756
				case 'set-status-preapproval':
757
					give_update_payment_status( $id, 'preapproval' );
758
					break;
759
760
				case 'resend-receipt':
761
					give_email_donation_receipt( $id, false );
762
					break;
763
			}// End switch().
764
765
			/**
766
			 * Fires after triggering bulk action on payments table.
767
			 *
768
			 * @param int    $id             The ID of the payment.
769
			 * @param string $current_action The action that is being triggered.
770
			 *
771
			 * @since 1.7
772
			 */
773
			do_action( 'give_payments_table_do_bulk_action', $id, $this->current_action() );
774
		}// End foreach().
775
776
	}
777
778
	/**
779
	 * Retrieve the payment counts
780
	 *
781
	 * @access public
782
	 * @since  1.0
783
	 *
784
	 * @return object
785
	 */
786
	public function get_payment_counts() {
787
788
		$args = array();
789
790
		if ( isset( $_GET['user'] ) ) {
791
			$args['user'] = urldecode( $_GET['user'] );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
792
		} elseif ( isset( $_GET['donor'] ) ) {
793
			$args['donor'] = absint( $_GET['donor'] );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
794
		} elseif ( isset( $_GET['s'] ) ) {
795
			$is_user = strpos( $_GET['s'], strtolower( 'user:' ) ) !== false;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
796
			if ( $is_user ) {
797
				$args['user'] = absint( trim( str_replace( 'user:', '', strtolower( $_GET['s'] ) ) ) );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
798
				unset( $args['s'] );
799
			} else {
800
				$args['s'] = sanitize_text_field( $_GET['s'] );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
801
			}
802
		}
803
804
		if ( ! empty( $_GET['start-date'] ) ) {
805
			$args['start-date'] = urldecode( $_GET['start-date'] );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
806
		}
807
808
		if ( ! empty( $_GET['end-date'] ) ) {
809
			$args['end-date'] = urldecode( $_GET['end-date'] );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
810
		}
811
812
		$args['form_id'] = ! empty( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : null;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
813
		$args['gateway'] = ! empty( $_GET['gateway'] ) ? give_clean( $_GET['gateway'] ) : null;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
814
815
		$payment_count           = give_count_payments( $args );
816
		$this->complete_count    = $payment_count->publish;
817
		$this->pending_count     = $payment_count->pending;
818
		$this->processing_count  = $payment_count->processing;
819
		$this->refunded_count    = $payment_count->refunded;
820
		$this->failed_count      = $payment_count->failed;
821
		$this->revoked_count     = $payment_count->revoked;
822
		$this->cancelled_count   = $payment_count->cancelled;
823
		$this->abandoned_count   = $payment_count->abandoned;
824
		$this->preapproval_count = $payment_count->preapproval;
825
826
		foreach ( $payment_count as $count ) {
827
			$this->total_count += $count;
828
		}
829
830
		return $payment_count;
831
	}
832
833
	/**
834
	 * Retrieve all the data for all the payments.
835
	 *
836
	 * @access public
837
	 * @since  1.0
838
	 *
839
	 * @return array  objects in array containing all the data for the payments
840
	 */
841
	public function payments_data() {
842
843
		$per_page   = $this->per_page;
844
		$orderby    = isset( $_GET['orderby'] ) ? urldecode( $_GET['orderby'] ) : 'ID';
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
845
		$order      = isset( $_GET['order'] ) ? $_GET['order'] : 'DESC';
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
846
		$user       = isset( $_GET['user'] ) ? $_GET['user'] : null;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
847
		$donor      = isset( $_GET['donor'] ) ? $_GET['donor'] : null;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
848
		$status     = isset( $_GET['status'] ) ? $_GET['status'] : give_get_payment_status_keys();
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
849
		$meta_key   = isset( $_GET['meta_key'] ) ? $_GET['meta_key'] : null;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
850
		$year       = isset( $_GET['year'] ) ? $_GET['year'] : null;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
851
		$month      = isset( $_GET['m'] ) ? $_GET['m'] : null;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
852
		$day        = isset( $_GET['day'] ) ? $_GET['day'] : null;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
853
		$search     = isset( $_GET['s'] ) ? sanitize_text_field( $_GET['s'] ) : null;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
854
		$start_date = isset( $_GET['start-date'] ) ? sanitize_text_field( $_GET['start-date'] ) : null;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
855
		$end_date   = isset( $_GET['end-date'] ) ? sanitize_text_field( $_GET['end-date'] ) : $start_date;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
856
		$form_id    = ! empty( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : null;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
857
		$gateway    = ! empty( $_GET['gateway'] ) ? give_clean( $_GET['gateway'] ) : null;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
858
859
		if ( ! empty( $search ) ) {
860
			$status = 'any'; // Force all payment statuses when searching.
861
		}
862
863
		$args = array(
864
			'output'     => 'payments',
865
			'number'     => $per_page,
866
			'page'       => isset( $_GET['paged'] ) ? $_GET['paged'] : null,
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
867
			'orderby'    => $orderby,
868
			'order'      => $order,
869
			'user'       => $user,
870
			'donor'      => $donor,
871
			'status'     => $status,
872
			'meta_key'   => $meta_key,
0 ignored issues
show
introduced by
Detected usage of meta_key, possible slow query.
Loading history...
873
			'year'       => $year,
874
			'month'      => $month,
875
			'day'        => $day,
876
			's'          => $search,
877
			'start_date' => $start_date,
878
			'gateway'    => $gateway,
879
			'end_date'   => $end_date,
880
			'give_forms' => $form_id,
881
		);
882
883
		if ( is_string( $search ) && false !== strpos( $search, 'txn:' ) ) {
884
			$args['search_in_notes'] = true;
885
			$args['s']               = trim( str_replace( 'txn:', '', $args['s'] ) );
886
		}
887
888
		/**
889
		 * Filter to modify payment table argument.
890
		 *
891
		 * @since 1.8.18
892
		 */
893
		$args = (array) apply_filters( 'give_payment_table_payments_query', $args );
894
895
		$p_query = new Give_Payments_Query( $args );
896
897
		return $p_query->get_payments();
898
899
	}
900
901
	/**
902
	 * Setup the final data for the table
903
	 *
904
	 * @access public
905
	 * @since  1.0
906
	 * @uses   Give_Payment_History_Table::get_columns()
907
	 * @uses   Give_Payment_History_Table::get_sortable_columns()
908
	 * @uses   Give_Payment_History_Table::payments_data()
909
	 * @uses   WP_List_Table::get_pagenum()
910
	 * @uses   WP_List_Table::set_pagination_args()
911
	 *
912
	 * @return void
913
	 */
914
	public function prepare_items() {
915
916
		wp_reset_vars( array( 'action', 'payment', 'orderby', 'order', 's' ) );
917
918
		$columns  = $this->get_columns();
919
		$hidden   = array(); // No hidden columns.
920
		$sortable = $this->get_sortable_columns();
921
		$data     = $this->payments_data();
922
		$status   = isset( $_GET['status'] ) ? $_GET['status'] : 'any';
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
923
924
		$this->_column_headers = array( $columns, $hidden, $sortable );
925
926
		switch ( $status ) {
927
			case 'publish':
928
				$total_items = $this->complete_count;
929
				break;
930
			case 'pending':
931
				$total_items = $this->pending_count;
932
				break;
933
			case 'processing':
934
				$total_items = $this->processing_count;
935
				break;
936
			case 'refunded':
937
				$total_items = $this->refunded_count;
938
				break;
939
			case 'failed':
940
				$total_items = $this->failed_count;
941
				break;
942
			case 'revoked':
943
				$total_items = $this->revoked_count;
944
				break;
945
			case 'cancelled':
946
				$total_items = $this->cancelled_count;
947
				break;
948
			case 'abandoned':
949
				$total_items = $this->abandoned_count;
950
				break;
951
			case 'preapproval':
952
				$total_items = $this->preapproval_count;
953
				break;
954
			case 'any':
955
				$total_items = $this->total_count;
956
				break;
957
			default:
958
				// Retrieve the count of the non-default-Give status.
959
				$count       = wp_count_posts( 'give_payment' );
960
				$total_items = isset( $count->{$status} ) ? $count->{$status} : 0;
961
				break;
962
		}
963
964
		$this->items = $data;
965
966
		/**
967
		 * Filter to modify total count of the pagination.
968
		 *
969
		 * @since 1.8.19
970
		 */
971
		$total_items = (int) apply_filters( 'give_payment_table_pagination_total_count', $total_items, $this );
972
973
		$this->set_pagination_args(
974
			array(
975
				'total_items' => $total_items,
976
				// We have to calculate the total number of items.
977
				'per_page'    => $this->per_page,
978
				// We have to determine how many items to show on a page.
979
				'total_pages' => ceil( $total_items / $this->per_page ),
980
			// We have to calculate the total number of pages.
981
			)
982
		);
983
	}
984
}
985