Passed
Push — master ( 2aa340...5b03f5 )
by Brian
05:43 queued 46s
created

WPInv_Customers_Table::column_signup()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
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
140
		$args = array(
141
			'data'             => array(
142
143
				'total'        => array(
144
					'type'     => 'invoice_data',
145
					'function' => 'SUM',
146
					'name'     => 'total_sales',
147
				)
148
149
			),
150
			'where'            => array(
151
152
				'author'       => array(
153
					'type'     => 'post_data',
154
					'value'    => absint( $user->ID ),
155
					'key'      => 'posts.post_author',
156
					'operator' => '=',
157
				),
158
159
			),
160
			'query_type'     => 'get_var',
161
			'invoice_status' => array( 'wpi-renewal', 'wpi-processing', 'publish' ),
162
		);
163
164
		return wpinv_price( (float) GetPaid_Reports_Helper::get_invoice_report_data( $args ) );
165
166
	}
167
168
	/**
169
	 * Displays the total spent column.
170
	 *
171
	 * @since 1.0.19
172
	 *
173
	 * @param WP_User $user
174
	 *
175
	 * @return string Column Name
176
	 */
177
	public function column_invoices( $user ) {
178
179
		$args = array(
180
			'data'             => array(
181
182
				'ID'           => array(
183
					'type'     => 'post_data',
184
					'function' => 'COUNT',
185
					'name'     => 'count',
186
					'distinct' => true,
187
				),
188
189
			),
190
			'where'            => array(
191
192
				'author'       => array(
193
					'type'     => 'post_data',
194
					'value'    => absint( $user->ID ),
195
					'key'      => 'posts.post_author',
196
					'operator' => '=',
197
				),
198
199
			),
200
			'query_type'     => 'get_var',
201
			'invoice_status' => array_keys( wpinv_get_invoice_statuses() ),
202
		);
203
204
		return absint( GetPaid_Reports_Helper::get_invoice_report_data( $args ) );
205
206
	}
207
208
	/**
209
	 * Generates content for a single row of the table
210
	 * @since 1.0.19
211
	 *
212
	 * @param int $item The user id.
213
	 */
214
	public function single_row( $item ) {
215
		$item = get_user_by( 'id', $item );
216
217
		if ( empty( $item ) ) {
218
			return;
219
		}
220
221
		echo '<tr>';
222
		$this->single_row_columns( $item );
223
		echo '</tr>';
224
	}
225
226
	/**
227
	 * Displays the customers name
228
	 *
229
	 * @param  WP_User $customer customer.
230
	 * @return string
231
	 */
232
	public function column_name( $customer ) {
233
234
		// Customer view URL.
235
		$view_url    = esc_url( add_query_arg( 'user_id', $customer->ID, admin_url( 'user-edit.php' ) ) );
236
		$row_actions = $this->row_actions(
237
			array(
238
				'view' => '<a href="' . $view_url . '#getpaid-fieldset-billing">' . __( 'Edit Details', 'invoicing' ) . '</a>',
239
			)
240
		);
241
242
		// Get user's address.
243
		$address = wpinv_get_user_address( $customer->ID );
244
245
		// Customer email address.
246
		$email       = sanitize_email( $customer->user_email );
247
248
		// Customer's avatar.
249
		$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

249
		$avatar = esc_url( /** @scrutinizer ignore-type */ get_avatar_url( $email ) );
Loading history...
250
		$avatar = "<img src='$avatar' height='32' width='32'/>";
251
252
		// Customer's name.
253
		$name   = sanitize_text_field( "{$address['first_name']} {$address['last_name']}" );
254
255
		if ( ! empty( $name ) ) {
256
			$name = "<div style='overflow: hidden;height: 18px;'>$name</div>";
257
		}
258
259
		$email = "<div class='row-title'><a href='$view_url'>$email</a></div>";
260
261
		return "<div style='display: flex;'><div>$avatar</div><div style='margin-left: 10px;'>$name<strong>$email</strong>$row_actions</div></div>";
262
263
	}
264
265
	/**
266
	 * Retrieve the table columns
267
	 *
268
	 * @since 1.0.19
269
	 * @return array $columns Array of all the list table columns
270
	 */
271
	public function get_columns() {
272
273
		$columns = array(
274
			'name'     => __( 'Name', 'invoicing' ),
275
			'country'  => __( 'Country', 'invoicing' ),
276
			'state'    => __( 'State', 'invoicing' ),
277
			'city'     => __( 'City', 'invoicing' ),
278
			'zip'      => __( 'ZIP', 'invoicing' ),
279
			'address'  => __( 'Address', 'invoicing' ),
280
			'phone'    => __( 'Phone', 'invoicing' ),
281
			'company'  => __( 'Company', 'invoicing' ),
282
			'invoices' => __( 'Invoices', 'invoicing' ),
283
			'total'    => __( 'Total Spend', 'invoicing' ),
284
			'signup'   => __( 'Date created', 'invoicing' ),
285
		);
286
		return apply_filters( 'wpinv_customers_table_columns', $columns );
287
288
	}
289
290
	/**
291
	 * Retrieve the current page number
292
	 *
293
	 * @since 1.0.19
294
	 * @return int Current page number
295
	 */
296
	public function get_paged() {
297
		return isset( $_GET['paged'] ) ? absint( $_GET['paged'] ) : 1;
298
	}
299
300
	/**
301
	 * Returns bulk actions.
302
	 *
303
	 * @since 1.0.19
304
	 * @return void
305
	 */
306
	public function bulk_actions( $which = '' ) {
307
		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...
308
	}
309
310
	/**
311
	 *  Prepares the display query
312
	 */
313
	public function prepare_query() {
314
		global $wpdb;
315
316
		$post_types = 'WHERE ';
317
318
		foreach ( array_keys( getpaid_get_invoice_post_types() ) as $post_type ) {
319
			$post_types .= $wpdb->prepare( "post_type=%s OR ", $post_type );
320
		}
321
322
		$post_types = rtrim( $post_types, ' OR' );
323
324
		// Users with invoices.
325
    	$customers = $wpdb->get_col(
326
			$wpdb->prepare(
327
				"SELECT DISTINCT( post_author ) FROM $wpdb->posts $post_types LIMIT %d,%d",
328
				$this->get_paged() * 10 - 10,
329
				$this->per_page
330
			)
331
		);
332
333
		$this->items = $customers;
334
		$this->total = (int) $wpdb->get_var( "SELECT COUNT( DISTINCT( post_author ) ) FROM $wpdb->posts $post_types" );
335
336
	}
337
338
	/**
339
	 * Setup the final data for the table
340
	 *
341
	 * @since 1.0.19
342
	 * @return void
343
	 */
344
	public function prepare_items() {
345
		$columns               = $this->get_columns();
346
		$hidden                = array(); // No hidden columns
347
		$sortable              = $this->get_sortable_columns();
348
		$this->_column_headers = array( $columns, $hidden, $sortable );
349
		$this->prepare_query();
350
351
		$this->set_pagination_args(
352
			array(
353
			'total_items' => $this->total,
354
			'per_page'    => $this->per_page,
355
			'total_pages' => ceil( $this->total / $this->per_page )
356
			)
357
		);
358
359
	}
360
}
361