Passed
Push — master ( 3da2df...2aa340 )
by Brian
05:09
created

WPInv_Customers_Table::get_paged()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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

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