Test Failed
Pull Request — master (#2054)
by Devin
05:04
created

Give_Sales_Log_Table::column_default()   C

Complexity

Conditions 8
Paths 8

Size

Total Lines 37
Code Lines 23

Duplication

Lines 3
Ratio 8.11 %

Importance

Changes 0
Metric Value
cc 8
eloc 23
nc 8
nop 2
dl 3
loc 37
rs 5.3846
c 0
b 0
f 0
1
<?php
2
/**
3
 * Sales Log View Class
4
 *
5
 * @package     Give
6
 * @subpackage  Admin/Reports
7
 * @copyright   Copyright (c) 2016, WordImpress
8
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
9
 */
10
11
// Exit if accessed directly.
12
if ( ! defined( 'ABSPATH' ) ) {
13
	exit;
14
}
15
16
// Load WP_List_Table if not loaded.
17
if ( ! class_exists( 'WP_List_Table' ) ) {
18
	require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
19
}
20
21
/**
22
 * Give_Sales_Log_Table Class
23
 *
24
 * Renders the sales log list table
25
 *
26
 * @since 1.0
27
 */
28
class Give_Sales_Log_Table extends WP_List_Table {
29
	/**
30
	 * Number of results to show per page
31
	 *
32
	 * @since 1.0
33
	 * @var int
34
	 */
35
	public $per_page = 30;
36
37
	/**
38
	 * Get things started
39
	 *
40
	 * @since 1.0
41
	 * @see   WP_List_Table::__construct()
42
	 */
43 View Code Duplication
	public function __construct() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
44
		global $status, $page;
45
46
		// Set parent defaults
47
		parent::__construct( array(
48
			'singular' => give_get_forms_label_singular(),    // Singular name of the listed records
49
			'plural'   => give_get_forms_label_plural(),        // Plural name of the listed records
50
			'ajax'     => false,// Does this table support ajax?
51
		) );
52
53
		add_action( 'give_log_view_actions', array( $this, 'give_forms_filter' ) );
54
	}
55
56
	/**
57
	 * This function renders most of the columns in the list table.
58
	 *
59
	 * @access public
60
	 * @since  1.0
61
	 *
62
	 * @param array  $item        Contains all the data of the discount code
63
	 * @param string $column_name The name of the column
64
	 *
65
	 * @return string Column Name
66
	 */
67
	public function column_default( $item, $column_name ) {
68
69
		$payment = give_get_payment_by( 'id', $item['payment_id'] );
70
71
		switch ( $column_name ) {
72
			case 'form' :
73
				$form_title = get_the_title( $item[ $column_name ] );
74
				$form_title = empty( $form_title ) ? sprintf( __( 'Untitled (#%s)', 'give' ), $item[ $column_name ] ) : $form_title;
75
				return '<a href="' . esc_url( add_query_arg( 'form', $item[ $column_name ] ) ) . '" >' . $form_title . '</a>';
76
77
			case 'donor_id' :
78
				return sprintf(
79
					'<a href="%s">%s</a>',
80
					admin_url( 'edit.php?post_type=give_forms&page=give-payment-history&donor=' . absint( $item['donor_id'] ) ),
81
					$item['donor_name']
82
				);
83
84
			case 'amount' :
85
				return give_currency_filter( give_format_amount( $item['amount'], array( 'sanitize' => false ) ) );
86
87
			case 'status' :
88
89
				$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>';
90
91 View Code Duplication
				if ( $payment->mode == 'test' ) {
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...
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
92
					$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' ) . '">' . __( 'Test', 'give' ) . '</span>';
93
				}
94
95
				return $value;
96
97
			case 'payment_id' :
98
				return '<a href="' . admin_url( 'edit.php?post_type=give_forms&page=give-payment-history&view=view-payment-details&id=' . $item['payment_id'] ) . '">' . give_get_payment_number( $item['payment_id'] ) . '</a>';
99
100
			default:
101
				return $item[ $column_name ];
102
		}
103
	}
104
105
	/**
106
	 * Retrieve the table columns
107
	 *
108
	 * @access public
109
	 * @since  1.0
110
	 * @return array $columns Array of all the list table columns
111
	 */
112
	public function get_columns() {
113
		$columns = array(
114
			'ID'         => __( 'Log ID', 'give' ),
115
			'donor_id'   => __( 'Donor', 'give' ),
116
			'form'       => __( 'Form', 'give' ),
117
			'amount'     => __( 'Donation Amount', 'give' ),
118
			'status'     => __( 'Status', 'give' ),
119
			'payment_id' => __( 'Donation ID', 'give' ),
120
			'date'       => __( 'Date', 'give' ),
121
		);
122
123
		return $columns;
124
	}
125
126
	/**
127
	 * Retrieve the current page number
128
	 *
129
	 * @access public
130
	 * @since  1.0
131
	 * @return int Current page number
132
	 */
133
	public function get_paged() {
134
		return isset( $_GET['paged'] ) ? absint( $_GET['paged'] ) : 1;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
135
	}
136
137
	/**
138
	 * Retrieves the user we are filtering logs by, if any
139
	 *
140
	 * @access public
141
	 * @since  1.0
142
	 * @return mixed int If User ID, string If Email/Login
143
	 */
144
	public function get_filtered_user() {
145
		return isset( $_GET['user'] ) ? absint( $_GET['user'] ) : false;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
146
	}
147
148
	/**
149
	 * Retrieves the ID of the give_form we're filtering logs by
150
	 *
151
	 * @access public
152
	 * @since  1.0
153
	 * @return int Download ID
154
	 */
155
	public function get_filtered_give_form() {
156
		return ! empty( $_GET['form'] ) ? absint( $_GET['form'] ) : false;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
157
	}
158
159
	/**
160
	 * Retrieves the search query string
161
	 *
162
	 * @access public
163
	 * @since  1.0
164
	 * @return string|bool string If search is present, false otherwise
165
	 */
166
	public function get_search() {
167
		return ! empty( $_GET['s'] ) ? urldecode( trim( $_GET['s'] ) ) : 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...
168
	}
169
170
171
	/**
172
	 * Display Tablenav (extended)
173
	 *
174
	 * Display the table navigation above or below the table even when no items in the logs, so nav doesn't disappear
175
	 *
176
	 * @see    : https://github.com/WordImpress/Give/issues/564
177
	 *
178
	 * @since  1.4.1
179
	 * @access protected
180
	 *
181
	 * @param string $which
182
	 */
183 View Code Duplication
	protected function display_tablenav( $which ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
184
185
		if ( 'top' === $which ) {
186
			wp_nonce_field( 'bulk-' . $this->_args['plural'] );
187
		}
188
		?>
189
		<div class="tablenav <?php echo esc_attr( $which ); ?>">
190
191
			<div class="alignleft actions bulkactions">
192
				<?php $this->bulk_actions( $which ); ?>
193
			</div>
194
			<?php
195
			$this->extra_tablenav( $which );
196
			$this->pagination( $which );
197
			?>
198
199
			<br class="clear"/>
200
		</div>
201
		<?php
202
	}
203
204
205
	/**
206
	 * Gets the meta query for the log query
207
	 *
208
	 * This is used to return log entries that match our search query, user query, or form query
209
	 *
210
	 * @since  1.0
211
	 * @access public
212
	 *
213
	 * @return array $meta_query
214
	 */
215
	public function get_meta_query() {
216
		$user = $this->get_filtered_user();
217
218
		$meta_query = array();
219
220
		if ( $user ) {
221
			// Show only logs from a specific user.
222
			$meta_query[] = array(
223
				'key'   => '_give_log_user_id',
224
				'value' => $user,
225
			);
226
		}
227
228
		$search = $this->get_search();
229
		if ( $search ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $search of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
230
			if ( is_email( $search ) ) {
231
				// This is an email search. We use this to ensure it works for guest users and logged-in users.
232
				$key     = '_give_log_user_info';
233
				$compare = 'LIKE';
234
			} else {
235
				// Look for a user
236
				$key     = '_give_log_user_id';
237
				$compare = 'LIKE';
238
239
				if ( ! is_numeric( $search ) ) {
240
					// Searching for user by username
241
					$user = get_user_by( 'login', $search );
242
243
					if ( $user ) {
244
						// Found one, set meta value to user's ID.
245
						$search = $user->ID;
246
					} else {
247
						// No user found so let's do a real search query.
248
						$users = new WP_User_Query( array(
249
							'search'         => $search,
250
							'search_columns' => array( 'user_url', 'user_nicename' ),
251
							'number'         => 1,
252
							'fields'         => 'ids',
253
						) );
254
255
						$found_user = $users->get_results();
256
257
						if ( $found_user ) {
258
							$search = $found_user[0];
259
						}
260
					}
261
				}
262
			}
263
264
			if ( ! $this->file_search ) {
265
				// Meta query only works for non file name search.
266
				$meta_query[] = array(
267
					'key'     => $key,
268
					'value'   => $search,
269
					'compare' => $compare,
270
				);
271
272
			}
273
		}
274
275
		return $meta_query;
276
	}
277
278
	/**
279
	 * Outputs the log views
280
	 *
281
	 * @access public
282
	 * @since  1.0
283
	 * @return void
284
	 */
285
	function bulk_actions( $which = '' ) {
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...
286
		give_log_views();
287
	}
288
289
	/**
290
	 * Sets up the forms filter
291
	 *
292
	 * @access public
293
	 * @since  1.0
294
	 * @return void
295
	 */
296
	public function give_forms_filter() {
297
		$give_forms = get_posts( array(
298
			'post_type'              => 'give_forms',
299
			'post_status'            => 'any',
300
			'posts_per_page'         => - 1,
301
			'orderby'                => 'title',
302
			'order'                  => 'ASC',
303
			'fields'                 => 'ids',
304
			'update_post_meta_cache' => false,
305
			'update_post_term_cache' => false,
306
		) );
307
308
		if ( $give_forms ) {
309
			echo '<select name="form" id="give-log-form-filter">';
310
			echo '<option value="0">' . __( 'All', 'give' ) . '</option>';
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw '__'
Loading history...
311
			foreach ( $give_forms as $form ) {
312
				$form_title = get_the_title( $form );
313
				$form_title = empty( $form_title ) ? sprintf( __( 'Untitled (#%s)', 'give' ), $form ) : $form_title;
314
				echo '<option value="' . $form . '"' . selected( $form, $this->get_filtered_give_form() ) . '>' . esc_html( $form_title ) . '</option>';
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$form'
Loading history...
315
			}
316
			echo '</select>';
317
		}
318
	}
319
320
	/**
321
	 * Gets the log entries for the current view
322
	 *
323
	 * @access public
324
	 * @since  1.0
325
	 * @global object $give_logs Give Logs Object
326
	 * @return array $logs_data Array of all the Log entires
327
	 */
328
	public function get_logs() {
329
		/** @var Give_Logging $give_logs */
330
		global $give_logs;
331
332
		$logs_data = array();
0 ignored issues
show
Unused Code introduced by
$logs_data 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...
333
		$paged     = $this->get_paged();
334
		$give_form = empty( $_GET['s'] ) ? $this->get_filtered_give_form() : null;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
335
		$user      = $this->get_filtered_user();
0 ignored issues
show
Unused Code introduced by
$user 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...
336
337
		$log_query = array(
338
			'post_parent'    => $give_form,
339
			'log_type'       => 'sale',
340
			'paged'          => $paged,
341
			'meta_query'     => $this->get_meta_query(),
0 ignored issues
show
introduced by
Detected usage of meta_query, possible slow query.
Loading history...
342
			'posts_per_page' => $this->per_page,
343
		);
344
345
		$cache_key = Give_Cache::get_key( 'get_logs', $log_query );
346
347
		// Return result from cache if exist.
348
		if ( ! ( $logs_data = Give_Cache::get( $cache_key ) ) ) {
349
			$logs = $give_logs->get_connected_logs( $log_query );
350
351
			if ( $logs ) {
352
				foreach ( $logs as $log ) {
353
					$payment_id = give_get_meta( $log->ID, '_give_log_payment_id', true );
354
355
					// Make sure this payment hasn't been deleted.
356
					if ( get_post( $payment_id ) ) :
357
						$user_info      = give_get_payment_meta_user_info( $payment_id );
358
						$payment_amount = give_get_payment_amount( $payment_id );
359
360
						$logs_data[] = array(
361
							'ID'         => '<span class="give-item-label give-item-label-gray">' . $log->ID . '</span>',
362
							'payment_id' => $payment_id,
363
							'form'       => $log->post_parent,
364
							'amount'     => $payment_amount,
365
							'donor_id'   => give_get_payment_donor_id( $payment_id ),
366
							'donor_name' => trim( "{$user_info['first_name']} {$user_info['last_name']}" ),
367
							'date'       => get_post_field( 'post_date', $payment_id ),
368
						);
369
370
					endif;
371
				}
372
373
				// Cache results.
374
				if ( ! empty( $logs_data ) ) {
375
					Give_Cache::set( $cache_key, $logs_data );
376
				}
377
			}
378
		}
379
380
		return $logs_data;
381
	}
382
383
	/**
384
	 * Setup the final data for the table
385
	 *
386
	 * @access public
387
	 * @since  1.0
388
	 * @global object $give_logs Give Logs Object
389
	 * @uses   Give_Sales_Log_Table::get_columns()
390
	 * @uses   WP_List_Table::get_sortable_columns()
391
	 * @uses   Give_Sales_Log_Table::get_pagenum()
392
	 * @uses   Give_Sales_Log_Table::get_logs()
393
	 * @uses   Give_Sales_Log_Table::get_log_count()
394
	 * @return void
395
	 */
396
	public function prepare_items() {
397
		/** @var Give_Logging $give_logs */
398
		global $give_logs;
399
400
		$columns               = $this->get_columns();
401
		$hidden                = array();
402
		$sortable              = $this->get_sortable_columns();
403
		$this->_column_headers = array( $columns, $hidden, $sortable );
404
		$current_page          = $this->get_pagenum();
0 ignored issues
show
Unused Code introduced by
$current_page 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...
405
		$this->items           = $this->get_logs();
406
		$total_items           = $give_logs->get_log_count( $this->get_filtered_give_form(), 'sale', $this->get_meta_query() );
407
408
		$this->set_pagination_args( array(
409
				'total_items' => $total_items,
410
				'per_page'    => $this->per_page,
411
				'total_pages' => ceil( $total_items / $this->per_page ),
412
			)
413
		);
414
	}
415
}
416