Passed
Push — master ( bc47b8...bbb493 )
by Brian
07:35
created

WPInv_Customers_Table::column_country()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 6
rs 10
1
<?php
2
/**
3
 * Customers Table Class
4
 *
5
 */
6
7
// Exit if accessed directly
8
if ( ! defined( 'ABSPATH' ) ) exit;
9
10
// Load WP_List_Table if not loaded
11
if ( ! class_exists( 'WP_List_Table' ) ) {
12
	require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
13
}
14
15
/**
16
 * WPInv_Customers_Table Class
17
 *
18
 * Renders the Gateway Reports table
19
 *
20
 * @since 1.0.19
21
 */
22
class WPInv_Customers_Table extends WP_List_Table {
23
24
	/**
25
	 * @var int Number of items per page
26
	 * @since 1.0.19
27
	 */
28
	public $per_page = 10;
29
30
	/**
31
	 * @var int Number of items
32
	 * @since 1.0.19
33
	 */
34
	public $total = 0;
35
36
	/**
37
	 * Get things started
38
	 *
39
	 * @since 1.0.19
40
	 * @see WP_List_Table::__construct()
41
	 */
42
	public function __construct() {
43
44
		// Set parent defaults
45
		parent::__construct( array(
46
			'singular' => 'id',
47
			'plural'   => 'ids',
48
			'ajax'     => false,
49
		) );
50
51
	}
52
53
	/**
54
	 * Gets the name of the primary column.
55
	 *
56
	 * @since 1.0.19
57
	 * @access protected
58
	 *
59
	 * @return string Name of the primary column.
60
	 */
61
	protected function get_primary_column_name() {
62
		return 'name';
63
	}
64
65
	/**
66
	 * This function renders most of the columns in the list table.
67
	 *
68
	 * @since 1.0.19
69
	 *
70
	 * @param WP_User $item
71
	 * @param string $column_name The name of the column
72
	 *
73
	 * @return string Column Name
74
	 */
75
	public function column_default( $item, $column_name ) {
76
		$value = sanitize_text_field( get_user_meta( $item->ID, '_wpinv_' . $column_name, true ) );
0 ignored issues
show
Bug introduced by
It seems like get_user_meta($item->ID,...' . $column_name, true) can also be of type false; however, parameter $str of sanitize_text_field() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

76
		$value = sanitize_text_field( /** @scrutinizer ignore-type */ get_user_meta( $item->ID, '_wpinv_' . $column_name, true ) );
Loading history...
77
		return apply_filters( 'wpinv_customers_table_column' . $column_name, $value, $item );
78
	}
79
80
	/**
81
	 * Displays the country column.
82
	 *
83
	 * @since 1.0.19
84
	 *
85
	 * @param WP_User $user
86
	 *
87
	 * @return string Column Name
88
	 */
89
	public function column_country( $user ) {
90
		$country = wpinv_sanitize_country( $user->_wpinv_country );
91
		if ( $country ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $country of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
92
			$country = wpinv_country_name( $country );
93
		}
94
		return sanitize_text_field( $country );
95
	}
96
97
	/**
98
	 * Displays the state column.
99
	 *
100
	 * @since 1.0.19
101
	 *
102
	 * @param WP_User $user
103
	 *
104
	 * @return string Column Name
105
	 */
106
	public function column_state( $user ) {
107
		$country = wpinv_sanitize_country( $user->_wpinv_country );
108
		$state   = $user->_wpinv_state;
109
		if ( $state ) {
110
			$state = wpinv_state_name( $state, $country );
111
		}
112
113
		return sanitize_text_field( $state );
114
	}
115
116
	/**
117
	 * Displays the signup column.
118
	 *
119
	 * @since 1.0.19
120
	 *
121
	 * @param WP_User $user
122
	 *
123
	 * @return string Column Name
124
	 */
125
	public function column_signup( $user ) {
126
		return getpaid_format_date_value( $user->user_registered );
127
	}
128
129
	/**
130
	 * Displays the total spent column.
131
	 *
132
	 * @since 1.0.19
133
	 *
134
	 * @param WP_User $user
135
	 *
136
	 * @return string Column Name
137
	 */
138
	public function column_total( $user ) {
139
		return wpinv_price( $this->column_total_raw( $user ) );
140
	}
141
142
	/**
143
	 * Displays the total spent column.
144
	 *
145
	 * @since 1.0.19
146
	 *
147
	 * @param WP_User $user
148
	 *
149
	 * @return float
150
	 */
151
	public function column_total_raw( $user ) {
152
153
		$args = array(
154
			'data'             => array(
155
156
				'total'        => array(
157
					'type'     => 'invoice_data',
158
					'function' => 'SUM',
159
					'name'     => 'total_sales',
160
				)
161
162
			),
163
			'where'            => array(
164
165
				'author'       => array(
166
					'type'     => 'post_data',
167
					'value'    => absint( $user->ID ),
168
					'key'      => 'posts.post_author',
169
					'operator' => '=',
170
				),
171
172
			),
173
			'query_type'     => 'get_var',
174
			'invoice_status' => array( 'wpi-renewal', 'wpi-processing', 'publish' ),
175
		);
176
177
		return wpinv_round_amount( GetPaid_Reports_Helper::get_invoice_report_data( $args ) );
0 ignored issues
show
Bug introduced by
It seems like GetPaid_Reports_Helper::...oice_report_data($args) can also be of type string; however, parameter $amount of wpinv_round_amount() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

177
		return wpinv_round_amount( /** @scrutinizer ignore-type */ GetPaid_Reports_Helper::get_invoice_report_data( $args ) );
Loading history...
178
179
	}
180
181
	/**
182
	 * Displays the total spent column.
183
	 *
184
	 * @since 1.0.19
185
	 *
186
	 * @param WP_User $user
187
	 *
188
	 * @return string Column Name
189
	 */
190
	public function column_invoices( $user ) {
191
192
		$args = array(
193
			'data'             => array(
194
195
				'ID'           => array(
196
					'type'     => 'post_data',
197
					'function' => 'COUNT',
198
					'name'     => 'count',
199
					'distinct' => true,
200
				),
201
202
			),
203
			'where'            => array(
204
205
				'author'       => array(
206
					'type'     => 'post_data',
207
					'value'    => absint( $user->ID ),
208
					'key'      => 'posts.post_author',
209
					'operator' => '=',
210
				),
211
212
			),
213
			'query_type'     => 'get_var',
214
			'invoice_status' => array_keys( wpinv_get_invoice_statuses() ),
215
		);
216
217
		return absint( GetPaid_Reports_Helper::get_invoice_report_data( $args ) );
218
219
	}
220
221
	/**
222
	 * Generates content for a single row of the table
223
	 * @since 1.0.19
224
	 *
225
	 * @param int $item The user id.
226
	 */
227
	public function single_row( $item ) {
228
		$item = get_user_by( 'id', $item );
229
230
		if ( empty( $item ) ) {
231
			return;
232
		}
233
234
		echo '<tr>';
235
		$this->single_row_columns( $item );
236
		echo '</tr>';
237
	}
238
239
	/**
240
	 * Displays the customers name
241
	 *
242
	 * @param  WP_User $customer customer.
243
	 * @return string
244
	 */
245
	public function column_name( $customer ) {
246
247
		// Customer view URL.
248
		$view_url    = esc_url( add_query_arg( 'user_id', $customer->ID, admin_url( 'user-edit.php' ) ) );
249
		$row_actions = $this->row_actions(
250
			array(
251
				'view' => '<a href="' . $view_url . '#getpaid-fieldset-billing">' . __( 'Edit Details', 'invoicing' ) . '</a>',
252
			)
253
		);
254
255
		// Get user's address.
256
		$address = wpinv_get_user_address( $customer->ID );
257
258
		// Customer email address.
259
		$email       = sanitize_email( $customer->user_email );
260
261
		// Customer's avatar.
262
		$avatar = esc_url( get_avatar_url( $email ) );
0 ignored issues
show
Bug introduced by
It seems like get_avatar_url($email) can also be of type false; however, parameter $url of esc_url() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

262
		$avatar = esc_url( /** @scrutinizer ignore-type */ get_avatar_url( $email ) );
Loading history...
263
		$avatar = "<img src='$avatar' height='32' width='32'/>";
264
265
		// Customer's name.
266
		$name   = sanitize_text_field( "{$address['first_name']} {$address['last_name']}" );
267
268
		if ( ! empty( $name ) ) {
269
			$name = "<div style='overflow: hidden;height: 18px;'>$name</div>";
270
		}
271
272
		$email = "<div class='row-title'><a href='$view_url'>$email</a></div>";
273
274
		return "<div style='display: flex;'><div>$avatar</div><div style='margin-left: 10px;'>$name<strong>$email</strong>$row_actions</div></div>";
275
276
	}
277
278
	/**
279
	 * Retrieve the table columns
280
	 *
281
	 * @since 1.0.19
282
	 * @return array $columns Array of all the list table columns
283
	 */
284
	public function get_columns() {
285
286
		$columns = array(
287
			'name'     => __( 'Name', 'invoicing' ),
288
			'country'  => __( 'Country', 'invoicing' ),
289
			'state'    => __( 'State', 'invoicing' ),
290
			'city'     => __( 'City', 'invoicing' ),
291
			'zip'      => __( 'ZIP', 'invoicing' ),
292
			'address'  => __( 'Address', 'invoicing' ),
293
			'phone'    => __( 'Phone', 'invoicing' ),
294
			'company'  => __( 'Company', 'invoicing' ),
295
			'invoices' => __( 'Invoices', 'invoicing' ),
296
			'total'    => __( 'Total Spend', 'invoicing' ),
297
			'signup'   => __( 'Date created', 'invoicing' ),
298
		);
299
		return apply_filters( 'wpinv_customers_table_columns', $columns );
300
301
	}
302
303
	/**
304
	 * Retrieve the current page number
305
	 *
306
	 * @since 1.0.19
307
	 * @return int Current page number
308
	 */
309
	public function get_paged() {
310
		return isset( $_GET['paged'] ) ? absint( $_GET['paged'] ) : 1;
311
	}
312
313
	/**
314
	 * Returns bulk actions.
315
	 *
316
	 * @since 1.0.19
317
	 * @return void
318
	 */
319
	public function bulk_actions( $which = '' ) {
320
		return array();
0 ignored issues
show
Bug Best Practice introduced by
The expression return array() returns the type array which is incompatible with the documented return type void.
Loading history...
321
	}
322
323
	/**
324
	 *  Prepares the display query
325
	 */
326
	public function prepare_query() {
327
		global $wpdb;
328
329
		$post_types = '';
330
331
		foreach ( array_keys( getpaid_get_invoice_post_types() ) as $post_type ) {
332
			$post_types .= $wpdb->prepare( "post_type=%s OR ", $post_type );
333
		}
334
335
		$post_types = rtrim( $post_types, ' OR' );
336
337
		// Maybe search.
338
		if ( ! empty( $_POST['s'] ) ) {
339
			$users = get_users(
340
				array(
341
					'search'         => '*' . sanitize_text_field( urldecode( $_POST['s'] ) ) . '*',
342
					'search_columns' => array( 'user_login', 'user_email', 'display_name' ),
343
					'fields'         => 'ID',
344
				)
345
			);
346
347
			$users      = implode( ', ', $users );
348
			$post_types = "($post_types) AND ( post_author IN ( $users ) )";
349
		}
350
351
		// Users with invoices.
352
    	$customers = $wpdb->get_col(
353
			$wpdb->prepare(
354
				"SELECT DISTINCT( post_author ) FROM $wpdb->posts WHERE $post_types LIMIT %d,%d",
355
				$this->get_paged() * 10 - 10,
356
				$this->per_page
357
			)
358
		);
359
360
		$this->items = $customers;
361
		$this->total = (int) $wpdb->get_var( "SELECT COUNT( DISTINCT( post_author ) ) FROM $wpdb->posts WHERE $post_types" );
362
363
	}
364
365
	/**
366
	 * Setup the final data for the table
367
	 *
368
	 * @since 1.0.19
369
	 * @return void
370
	 */
371
	public function prepare_items() {
372
		$columns               = $this->get_columns();
373
		$hidden                = array(); // No hidden columns
374
		$sortable              = $this->get_sortable_columns();
375
		$this->_column_headers = array( $columns, $hidden, $sortable );
376
		$this->prepare_query();
377
378
		$this->set_pagination_args(
379
			array(
380
			'total_items' => $this->total,
381
			'per_page'    => $this->per_page,
382
			'total_pages' => ceil( $this->total / $this->per_page )
383
			)
384
		);
385
386
	}
387
}
388