Passed
Push — master ( 96fb7a...3da2df )
by Brian
04:36
created

WPInv_Customers_Table   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 279
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 88
dl 0
loc 279
rs 10
c 1
b 0
f 0
wmc 19

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A get_primary_column_name() 0 2 1
A column_country() 0 6 2
A column_state() 0 8 2
A column_default() 0 3 1
A prepare_items() 0 12 1
A single_row() 0 10 2
A column_total() 0 27 1
A column_name() 0 30 2
A get_paged() 0 2 2
A prepare_query() 0 22 2
A bulk_actions() 0 2 1
A get_columns() 0 14 1
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
	 * Generates content for a single row of the table
157
	 * @since 1.0.19
158
	 *
159
	 * @param int $item The user id.
160
	 */
161
	public function single_row( $item ) {
162
		$item = get_user_by( 'id', $item );
163
164
		if ( empty( $item ) ) {
165
			return;
166
		}
167
168
		echo '<tr>';
169
		$this->single_row_columns( $item );
170
		echo '</tr>';
171
	}
172
173
	/**
174
	 * Displays the customers name
175
	 *
176
	 * @param  WP_User $customer customer.
177
	 * @return string
178
	 */
179
	public function column_name( $customer ) {
180
181
		// Customer view URL.
182
		$view_url    = esc_url( add_query_arg( 'user_id', $customer->ID, admin_url( 'user-edit.php' ) ) );
183
		$row_actions = $this->row_actions(
184
			array(
185
				'view' => '<a href="' . $view_url . '#getpaid-fieldset-billing">' . __( 'Edit Details', 'invoicing' ) . '</a>',
186
			)
187
		);
188
189
		// Get user's address.
190
		$address = wpinv_get_user_address( $customer->ID );
191
192
		// Customer email address.
193
		$email       = sanitize_email( $customer->user_email );
194
195
		// Customer's avatar.
196
		$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

196
		$avatar = esc_url( /** @scrutinizer ignore-type */ get_avatar_url( $email ) );
Loading history...
197
		$avatar = "<img src='$avatar' height='32' width='32'/>";
198
199
		// Customer's name.
200
		$name   = sanitize_text_field( "{$address['first_name']} {$address['last_name']}" );
201
202
		if ( ! empty( $name ) ) {
203
			$name = "<div style='overflow: hidden;height: 18px;'>$name</div>";
204
		}
205
206
		$email = "<div class='row-title'><a href='$view_url'>$email</a></div>";
207
208
		return "<div style='display: flex;'><div>$avatar</div><div style='margin-left: 10px;'>$name<strong>$email</strong>$row_actions</div></div>";
209
210
	}
211
212
	/**
213
	 * Retrieve the table columns
214
	 *
215
	 * @since 1.0.19
216
	 * @return array $columns Array of all the list table columns
217
	 */
218
	public function get_columns() {
219
220
		$columns = array(
221
			'name'     => __( 'Name', 'invoicing' ),
222
			'country'  => __( 'Country', 'invoicing' ),
223
			'state'    => __( 'State', 'invoicing' ),
224
			'city'     => __( 'City', 'invoicing' ),
225
			'zip'      => __( 'ZIP', 'invoicing' ),
226
			'address'  => __( 'Address', 'invoicing' ),
227
			'phone'    => __( 'Phone', 'invoicing' ),
228
			'company'  => __( 'Company', 'invoicing' ),
229
			'total'    => __( 'Total Spend', 'invoicing' ),
230
		);
231
		return apply_filters( 'wpinv_customers_table_columns', $columns );
232
233
	}
234
235
	/**
236
	 * Retrieve the current page number
237
	 *
238
	 * @since 1.0.19
239
	 * @return int Current page number
240
	 */
241
	public function get_paged() {
242
		return isset( $_GET['paged'] ) ? absint( $_GET['paged'] ) : 1;
243
	}
244
245
	/**
246
	 * Returns bulk actions.
247
	 *
248
	 * @since 1.0.19
249
	 * @return void
250
	 */
251
	public function bulk_actions( $which = '' ) {
252
		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...
253
	}
254
255
	/**
256
	 *  Prepares the display query
257
	 */
258
	public function prepare_query() {
259
		global $wpdb;
260
261
		$post_types = 'WHERE ';
262
263
		foreach ( array_keys( getpaid_get_invoice_post_types() ) as $post_type ) {
264
			$post_types .= $wpdb->prepare( "post_type=%s OR ", $post_type );
265
		}
266
267
		$post_types = rtrim( $post_types, ' OR' );
268
269
		// Users with invoices.
270
    	$customers = $wpdb->get_col(
271
			$wpdb->prepare(
272
				"SELECT DISTINCT( post_author ) FROM $wpdb->posts $post_types LIMIT %d,%d",
273
				$this->get_paged() * 10 - 10,
274
				$this->per_page
275
			)
276
		);
277
278
		$this->items = $customers;
279
		$this->total = (int) $wpdb->get_var( "SELECT COUNT( DISTINCT( post_author ) ) FROM $wpdb->posts $post_types" );
280
281
	}
282
283
	/**
284
	 * Setup the final data for the table
285
	 *
286
	 * @since 1.0.19
287
	 * @return void
288
	 */
289
	public function prepare_items() {
290
		$columns               = $this->get_columns();
291
		$hidden                = array(); // No hidden columns
292
		$sortable              = $this->get_sortable_columns();
293
		$this->_column_headers = array( $columns, $hidden, $sortable );
294
		$this->prepare_query();
295
296
		$this->set_pagination_args(
297
			array(
298
			'total_items' => $this->total,
299
			'per_page'    => $this->per_page,
300
			'total_pages' => ceil( $this->total / $this->per_page )
301
			)
302
		);
303
304
	}
305
}
306