Passed
Push — master ( 361a24...0a8090 )
by Brian
05:41
created

WPInv_Subscriptions_List_Table::column_amount()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * Displays a list of all subscriptions rules
4
 */
5
6
if ( ! defined( 'ABSPATH' ) ) exit;
7
8
if ( ! class_exists( 'WP_List_Table' ) ) {
9
	include_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
10
}
11
12
/**
13
 * Subscriptions table class.
14
 */
15
class WPInv_Subscriptions_List_Table extends WP_List_Table {
16
17
	/**
18
	 * URL of this page
19
	 *
20
	 * @var   string
21
	 * @since 1.0.19
22
	 */
23
	public $base_url;
24
25
	/**
26
	 * Query
27
	 *
28
	 * @var   GetPaid_Subscriptions_Query
29
	 * @since 1.0.19
30
	 */
31
	public $query;
32
33
	/**
34
	 * Total subscriptions
35
	 *
36
	 * @var   string
37
	 * @since 1.0.0
38
	 */
39
	public $total_count;
40
41
	/**
42
	 * Current status subscriptions
43
	 *
44
	 * @var   string
45
	 * @since 1.0.0
46
	 */
47
	public $current_total_count;
48
49
	/**
50
	 * Status counts
51
	 *
52
	 * @var   array
53
	 * @since 1.0.19
54
	 */
55
	public $status_counts;
56
57
	/**
58
	 * Number of results to show per page
59
	 *
60
	 * @var   int
61
	 * @since 1.0.0
62
	 */
63
	public $per_page = 10;
64
65
	/**
66
	 *  Constructor function.
67
	 */
68
	public function __construct() {
69
70
		parent::__construct(
71
			array(
72
				'singular' => 'subscription',
73
				'plural'   => 'subscriptions',
74
			)
75
		);
76
77
		$this->process_bulk_action();
78
79
		$this->prepare_query();
80
81
		$this->base_url = remove_query_arg( 'status' );
82
83
	}
84
85
	/**
86
	 *  Prepares the display query
87
	 */
88
	public function prepare_query() {
89
90
		// Prepare query args.
91
		$query = array(
92
			'number'  => $this->per_page,
93
			'paged'   => $this->get_paged(),
94
			'status'  => ( isset( $_GET['status'] ) && array_key_exists( $_GET['status'], getpaid_get_subscription_statuses() ) ) ? $_GET['status'] : 'all',
95
			'orderby' => ( isset( $_GET['orderby'] ) ) ? $_GET['orderby'] : 'id',
96
			'order'   => ( isset( $_GET['order'] ) ) ? $_GET['order'] : 'DESC',
97
			'customer_in' => $this->get_user_in(),
98
		);
99
100
		if ( is_array( $query['customer_in'] ) && empty( $query['customer_in'] ) ) {
101
			$this->total_count         = 0;
102
			$this->current_total_count = 0;
103
			$this->items               = array();
104
			$this->status_counts       = array();
105
			return;
106
		}
107
108
		// Prepare class properties.
109
		$this->query               = new GetPaid_Subscriptions_Query( $query );
110
		$this->total_count         = $this->query->get_total();
111
		$this->current_total_count = $this->query->get_total();
112
		$this->items               = $this->query->get_results();
113
		$this->status_counts       = getpaid_get_subscription_status_counts( $query );
114
115
		if ( 'all' != $query['status'] ) {
116
			unset( $query['status'] );
117
			$this->total_count   = getpaid_get_subscriptions( $query, 'count' );
118
		}
119
120
	}
121
122
	/**
123
	 * Get user in.
124
	 *
125
	 */
126
	public function get_user_in() {
127
128
		// Abort if no user.
129
		if ( empty( $_GET['s'] ) ) {
130
			return null;
131
		}
132
133
		// Or invalid user.
134
		$user = wp_unslash( sanitize_text_field( $_REQUEST['s'] ) );
135
136
		if ( empty( $user ) ) {
137
			return null;
138
		}
139
140
		// Search matching users.
141
		$user  = '*' . $user . '*';
0 ignored issues
show
Bug introduced by
Are you sure $user of type array|string can be used in concatenation? ( Ignorable by Annotation )

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

141
		$user  = '*' . /** @scrutinizer ignore-type */ $user . '*';
Loading history...
142
		$users = new WP_User_Query(
143
			array(
144
				'fields'      => 'ID',
145
				'search'      => $user,
146
				'count_total' => false,
147
			)
148
		);
149
150
		return $users->get_results();
151
	}
152
153
	/**
154
	 * Gets the list of views available on this table.
155
	 *
156
	 * The format is an associative array:
157
	 * - `'id' => 'link'`
158
	 *
159
	 * @since 1.0.0
160
	 *
161
	 * @return array
162
	 */
163
	public function get_views() {
164
165
		$current  = isset( $_GET['status'] ) ? $_GET['status'] : 'all';
166
		$views    = array(
167
168
			'all' => sprintf(
169
				'<a href="%s" %s>%s&nbsp;<span class="count">(%d)</span></a>',
170
				esc_url( add_query_arg( 'status', false, $this->base_url ) ),
171
				$current === 'all' ? ' class="current"' : '',
172
				__('All','invoicing' ),
173
				$this->total_count
174
			)
175
176
		);
177
178
		foreach ( array_filter( $this->status_counts ) as $status => $count ) {
179
180
			$views[ $status ] = sprintf(
181
				'<a href="%s" %s>%s&nbsp;<span class="count">(%d)</span></a>',
182
				esc_url( add_query_arg( 'status', urlencode( $status ), $this->base_url ) ),
183
				$current === $status ? ' class="current"' : '',
184
				esc_html( getpaid_get_subscription_status_label( $status ) ),
185
				$count
186
			);
187
188
		}
189
190
		return $views;
191
192
	}
193
194
	/**
195
	 * Render most columns
196
	 *
197
	 * @access      private
198
	 * @since       1.0.0
199
	 * @return      string
200
	 */
201
	public function column_default( $item, $column_name ) {
202
		return apply_filters( "getpaid_subscriptions_table_column_$column_name", $item->$column_name );
203
	}
204
205
	/**
206
	 * This is how checkbox column renders.
207
	 *
208
	 * @param WPInv_Subscription $item
209
	 * @return string
210
	 */
211
	public function column_cb( $item ) {
212
		return sprintf( '<input type="checkbox" name="id[]" value="%s" />', esc_html( $item->get_id() ) );
213
	}
214
215
	/**
216
	 * Status column
217
	 *
218
	 * @param WPInv_Subscription $item
219
	 * @since       1.0.0
220
	 * @return      string
221
	 */
222
	public function column_status( $item ) {
223
		return $item->get_status_label_html();
224
	}
225
226
	/**
227
	 * Subscription column
228
	 *
229
	 * @param WPInv_Subscription $item
230
	 * @since       1.0.0
231
	 * @return      string
232
	 */
233
	public function column_subscription( $item ) {
234
235
		$username = __( '(Missing User)', 'invoicing' );
236
237
		$user = get_userdata( $item->get_customer_id() );
238
		if ( $user ) {
239
240
			$username = sprintf(
241
				'<a href="user-edit.php?user_id=%s">%s</a>',
242
				absint( $user->ID ),
243
				! empty( $user->display_name ) ? esc_html( $user->display_name ) : sanitize_email( $user->user_email )
244
			);
245
246
		}
247
248
		// translators: $1: is opening link, $2: is subscription id number, $3: is closing link tag, $4: is user's name
249
		$column_content = sprintf(
250
			_x( '%1$s#%2$s%3$s for %4$s', 'Subscription title on admin table. (e.g.: #211 for John Doe)', 'invoicing' ),
251
			'<a href="' . esc_url( admin_url( 'admin.php?page=wpinv-subscriptions&id=' . absint( $item->get_id() ) ) ) . '">',
252
			'<strong>' . esc_attr( $item->get_id() ) . '</strong>', '</a>',
253
			$username
254
		);
255
256
		$row_actions = array();
257
258
		// View subscription.
259
		$view_url    = esc_url( add_query_arg( 'id', $item->get_id(), admin_url( 'admin.php?page=wpinv-subscriptions' ) ));
260
		$row_actions['view'] = '<a href="' . $view_url . '">' . __( 'View Subscription', 'invoicing' ) . '</a>';
261
262
		// View invoice.
263
		$invoice = get_post( $item->get_parent_invoice_id() );
264
265
		if ( ! empty( $invoice ) ) {
266
			$invoice_url            = get_edit_post_link( $invoice );
0 ignored issues
show
Bug introduced by
It seems like $invoice can also be of type array; however, parameter $id of get_edit_post_link() does only seem to accept WP_Post|integer, 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

266
			$invoice_url            = get_edit_post_link( /** @scrutinizer ignore-type */ $invoice );
Loading history...
267
			$row_actions['invoice'] = '<a href="' . $invoice_url . '">' . __( 'View Invoice', 'invoicing' ) . '</a>';
268
		}
269
270
		$delete_url            = esc_url(
271
			wp_nonce_url(
272
				add_query_arg(
273
					array(
274
						'getpaid-admin-action' => 'subscription_manual_delete',
275
						'id'                   => $item->get_id(),
276
					)
277
				),
278
				'getpaid-nonce',
279
				'getpaid-nonce'
280
			)
281
		);
282
		$row_actions['delete'] = '<a class="text-danger" href="' . $delete_url . '">' . __( 'Delete Subscription', 'invoicing' ) . '</a>';
283
284
		$row_actions = $this->row_actions( apply_filters( 'getpaid_subscription_table_row_actions', $row_actions, $item ) );
285
286
		return "<strong>$column_content</strong>" . $this->column_amount( $item ) . $row_actions;
287
	}
288
289
	/**
290
	 * Renewal date column
291
	 *
292
	 * @param WPInv_Subscription $item
293
	 * @since       1.0.0
294
	 * @return      string
295
	 */
296
	public function column_renewal_date( $item ) {
297
		return getpaid_format_date_value( $item->get_expiration() );
298
	}
299
300
	/**
301
	 * Start date column
302
	 *
303
	 * @param WPInv_Subscription $item
304
	 * @since       1.0.0
305
	 * @return      string
306
	 */
307
	public function column_start_date( $item ) {
308
309
		$gateway = $item->get_parent_invoice()->get_gateway_title();
310
311
		if ( empty( $gateway ) ) {
312
			return getpaid_format_date_value( $item->get_date_created() );
313
		}
314
315
		$url = apply_filters( 'getpaid_remote_subscription_profile_url', '', $item );
316
		if ( ! empty( $url ) ) {
317
318
			return getpaid_format_date_value( $item->get_date_created() ) . '<br>' . sprintf(
319
				__( 'Via %s', 'invoicing' ),
320
				'<strong><a href="' . esc_url( $url ) . '" target="_blank">' . esc_html( $item->get_parent_invoice()->get_gateway_title() ) . '</a></strong>'
321
			);
322
323
		}
324
325
		return getpaid_format_date_value( $item->get_date_created() ) . '<br>' . sprintf(
326
			__( 'Via %s', 'invoicing' ),
327
			'<strong>' . esc_html( $item->get_parent_invoice()->get_gateway_title() ) . '</strong>'
328
		);
329
330
	}
331
332
	/**
333
	 * Amount column
334
	 *
335
	 * @param WPInv_Subscription $item
336
	 * @since       1.0.19
337
	 * @return      string
338
	 */
339
	public static function column_amount( $item ) {
340
		$amount = getpaid_get_formatted_subscription_amount( $item );
341
		return "<span class='text-muted form-text mt-2 mb-2'>$amount</span>";
342
	}
343
344
	/**
345
	 * Billing Times column
346
	 *
347
	 * @param WPInv_Subscription $item
348
	 * @since       1.0.0
349
	 * @return      string
350
	 */
351
	public function column_renewals( $item ) {
352
		$max_bills = $item->get_bill_times();
353
		return $item->get_times_billed() . ' / ' . ( empty( $max_bills ) ? "&infin;" : $max_bills );
354
	}
355
356
	/**
357
	 * Product ID column
358
	 *
359
	 * @param WPInv_Subscription $item
360
	 * @since       1.0.0
361
	 * @return      string
362
	 */
363
	public function column_item( $item ) {
364
		$subscription_group = getpaid_get_invoice_subscription_group( $item->get_parent_invoice_id(), $item->get_id() );
365
366
		if ( empty( $subscription_group ) ) {
367
			return $this->generate_item_markup( $item->get_product_id() );
368
		}
369
370
		$markup = array_map( array( $this, 'generate_item_markup' ), array_keys( $subscription_group['items'] ) );
371
		return implode( ' | ', $markup );
372
373
	}
374
375
	/**
376
	 * Generates the items markup.
377
	 *
378
	 * @param int $item_id
379
	 * @since       1.0.0
380
	 * @return      string
381
	 */
382
	public static function generate_item_markup( $item_id ) {
383
		$item = get_post( $item_id );
384
385
		if ( ! empty( $item ) ) {
386
			$link = get_edit_post_link( $item );
0 ignored issues
show
Bug introduced by
It seems like $item can also be of type array; however, parameter $id of get_edit_post_link() does only seem to accept WP_Post|integer, 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

386
			$link = get_edit_post_link( /** @scrutinizer ignore-type */ $item );
Loading history...
387
			$link = esc_url( $link );
388
			$name = esc_html( get_the_title( $item ) );
0 ignored issues
show
Bug introduced by
It seems like $item can also be of type array; however, parameter $post of get_the_title() does only seem to accept WP_Post|integer, 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

388
			$name = esc_html( get_the_title( /** @scrutinizer ignore-type */ $item ) );
Loading history...
389
			return wpinv_current_user_can_manage_invoicing() ? "<a href='$link'>$name</a>" : $name;
390
		} else {
391
			return sprintf( __( 'Item #%s', 'invoicing' ), $item_id );
392
		}
393
394
	}
395
396
	/**
397
	 * Retrieve the current page number
398
	 *
399
	 * @return      int
400
	 */
401
	public function get_paged() {
402
		return isset( $_GET['paged'] ) ? absint( $_GET['paged'] ) : 1;
403
	}
404
405
	/**
406
	 * Setup the final data for the table
407
	 *
408
	 */
409
	public function prepare_items() {
410
411
		$columns  = $this->get_columns();
412
		$hidden   = array();
413
		$sortable = $this->get_sortable_columns();
414
415
		$this->_column_headers = array( $columns, $hidden, $sortable );
416
417
		$this->set_pagination_args(
418
			array(
419
			'total_items' => $this->current_total_count,
420
			'per_page'    => $this->per_page,
421
			'total_pages' => ceil( $this->current_total_count / $this->per_page )
422
			)
423
		);
424
	}
425
426
	/**
427
	 * Table columns
428
	 *
429
	 * @return array
430
	 */
431
	public function get_columns(){
432
		$columns = array(
433
			'cb'                => '<input type="checkbox" />',
434
			'subscription'      => __( 'Subscription', 'invoicing' ),
435
			'start_date'        => __( 'Start Date', 'invoicing' ),
436
			'renewal_date'      => __( 'Next Payment', 'invoicing' ),
437
			'renewals'          => __( 'Payments', 'invoicing' ),
438
			'item'              => __( 'Items', 'invoicing' ),
439
			'status'            => __( 'Status', 'invoicing' ),
440
		);
441
442
		return apply_filters( 'manage_getpaid_subscriptions_table_columns', $columns );
443
	}
444
445
	/**
446
	 * Sortable table columns.
447
	 *
448
	 * @return array
449
	 */
450
	public function get_sortable_columns() {
451
		$sortable = array(
452
			'subscription' => array( 'id', true ),
453
			'start_date'   => array( 'created', true ),
454
			'renewal_date' => array( 'expiration', true ),
455
			'renewals'     => array( 'bill_times', true ),
456
			'item'         => array( 'product_id', true ),
457
			'status'       => array( 'status', true ),
458
		);
459
460
		return apply_filters( 'manage_getpaid_subscriptions_sortable_table_columns', $sortable );
461
	}
462
463
	/**
464
	 * Whether the table has items to display or not
465
	 *
466
	 * @return bool
467
	 */
468
	public function has_items() {
469
		return ! empty( $this->current_total_count );
470
	}
471
472
	/**
473
	 * Processes bulk actions.
474
	 *
475
	 */
476
	public function process_bulk_action() {
477
478
	}
479
480
}
481