Passed
Pull Request — master (#405)
by Brian
05:03
created

WPInv_Subscription_Reports_Table::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 11
rs 10
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_Subscription_Lists_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();
0 ignored issues
show
Bug introduced by
The method process_bulk_action() does not exist on WPInv_Subscription_Lists_Table. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

77
		$this->/** @scrutinizer ignore-call */ 
78
         process_bulk_action();
Loading history...
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
		);
98
99
		// Prepare class properties.
100
		$this->query               = new GetPaid_Subscriptions_Query( $query );
101
		$this->total_count         = $this->query->get_total();
102
		$this->current_total_count = $this->query->get_total();
103
		$this->items               = $this->query->get_results();
104
		$this->status_counts       = getpaid_get_subscription_status_counts( $query );
0 ignored issues
show
Documentation Bug introduced by
It seems like getpaid_get_subscription_status_counts($query) of type integer is incompatible with the declared type array of property $status_counts.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
105
106
		if ( 'all' != $query['status'] ) {
107
			unset( $query['status'] );
108
			$this->total_count   = getpaid_get_subscriptions( $query, 'count' );
109
		}
110
111
	}
112
113
	/**
114
	 * Gets the list of views available on this table.
115
	 *
116
	 * The format is an associative array:
117
	 * - `'id' => 'link'`
118
	 *
119
	 * @since 1.0.0
120
	 *
121
	 * @return array
122
	 */
123
	protected function get_views() {
124
125
		$current  = isset( $_GET['status'] ) ? $_GET['status'] : 'all';
126
		$views    = array(
127
128
			'all' => sprintf(
129
				'<a href="%s" %s>%s&nbsp;<span class="count">(%d)</span></a>',
130
				esc_url( add_query_arg( 'status', false, $this->base_url ) ),
131
				$current === 'all' ? ' class="current"' : '',
132
				__('All','invoicing' ),
133
				$this->total_count
134
			)
135
136
		);
137
138
		foreach ( array_filter( $this->status_counts ) as $status => $count ) {
139
140
			$views[ $status ] = sprintf(
141
				'<a href="%s" %s>%s&nbsp;<span class="count">(%d)</span></a>',
142
				esc_url( add_query_arg( 'status', urlencode( $status ), $this->base_url ) ),
143
				$current === $status ? ' class="current"' : '',
144
				sanitize_text_field( getpaid_get_subscription_status_label( $status ) ),
145
				$count
146
			);
147
148
		}
149
150
		return $views;
151
152
	}
153
154
	/**
155
	 * Render most columns
156
	 *
157
	 * @access      private
158
	 * @since       1.0.0
159
	 * @return      string
160
	 */
161
	public function column_default( $item, $column_name ) {
162
		return apply_filters( "getpaid_subscriptions_table_column_$column_name", $item->$column_name );
163
	}
164
165
	/**
166
	 * This is how checkbox column renders.
167
	 *
168
	 * @param WPInv_Subscription $item
169
	 * @return string
170
	 */
171
	public function column_cb( $item ) {
172
		return sprintf( '<input type="checkbox" name="id[]" value="%s" />', esc_html( $item->get_id() ) );
173
	}
174
175
	/**
176
	 * Status column
177
	 *
178
	 * @param WPInv_Subscription $item
179
	 * @since       1.0.0
180
	 * @return      string
181
	 */
182
	public function column_status( $item ) {
183
		return $item->get_status_label_html();
184
	}
185
186
	/**
187
	 * Subscription column
188
	 *
189
	 * @param WPInv_Subscription $item
190
	 * @since       1.0.0
191
	 * @return      string
192
	 */
193
	public function column_subscription( $item ) {
194
195
		$username = __( '(Missing User)', 'invoicing' );
196
197
		$user = get_userdata( $item->get_customer_id() );
198
		if ( $user ) {
199
200
			$username = sprintf(
201
				'<a href="user-edit.php?user_id=%s">%s</a>',
202
				absint( $user->ID ),
203
				! empty( $user->display_name ) ? sanitize_text_field( $user->display_name ) : sanitize_email( $user->user_email )
204
			);
205
206
		}
207
208
		// translators: $1: is opening link, $2: is subscription id number, $3: is closing link tag, $4: is user's name
209
		$column_content = sprintf(
210
			_x( '%1$s#%2$s%3$s for %4$s', 'Subscription title on admin table. (e.g.: #211 for John Doe)', 'invoicing' ),
211
			'<a href="' . esc_url( admin_url( 'admin.php?page=wpinv-subscriptions&id=' . absint( $item->get_id() ) ) ) . '">',
212
			'<strong>' . esc_attr( $item->get_id() ) . '</strong>', '</a>',
213
			$username
214
		);
215
216
		$row_actions = array();
217
218
		// View subscription.
219
		$view_url    = esc_url( add_query_arg( 'id', $item->get_id(), admin_url( 'admin.php?page=wpinv-subscriptions' ) ));
220
		$row_actions['view'] = '<a href="' . $view_url . '">' . __( 'View Subscription', 'invoicing' ) . '</a>';
221
222
		// View invoice.
223
		$invoice = get_post( $item->get_product_id() );
224
225
		if ( ! empty( $invoice ) ) {
226
			$view_url    = get_edit_post_link( $invoice );
227
			$row_actions['invoice'] = '<a href="' . $view_url . '">' . __( 'View Invoice', 'invoicing' ) . '</a>';
228
		}
229
230
		$row_actions = $this->row_actions( apply_filters( 'getpaid_subscription_table_row_actions', $row_actions, $item ) );
231
232
		return "<strong>$column_content</strong>" . $this->column_amount( $item ) . $row_actions;
233
	}
234
235
	/**
236
	 * Renewal date column
237
	 *
238
	 * @param WPInv_Subscription $item
239
	 * @since       1.0.0
240
	 * @return      string
241
	 */
242
	public function column_renewal_date( $item ) {
243
244
		$expiration = $item->get_expiration();
245
		if ( ! $item->is_active() || empty( $expiration ) || '0000-00-00 00:00:00' == $expiration ) {
246
			return "&mdash;";
247
		}
248
249
		return date_i18n( get_option( 'date_format' ), strtotime( $expiration ) );
0 ignored issues
show
Bug introduced by
It seems like get_option('date_format') can also be of type false; however, parameter $format of date_i18n() 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
		return date_i18n( /** @scrutinizer ignore-type */ get_option( 'date_format' ), strtotime( $expiration ) );
Loading history...
250
		
251
	}
252
253
	/**
254
	 * Start date column
255
	 *
256
	 * @param WPInv_Subscription $item
257
	 * @since       1.0.0
258
	 * @return      string
259
	 */
260
	public function column_start_date( $item ) {
261
262
		$created = $item->get_date_created();
263
		if ( empty( $created ) || '0000-00-00 00:00:00' == $created ) {
264
			return "&mdash;";
265
		}
266
267
		return date_i18n( get_option( 'date_format' ), strtotime( $created ) );
0 ignored issues
show
Bug introduced by
It seems like get_option('date_format') can also be of type false; however, parameter $format of date_i18n() 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

267
		return date_i18n( /** @scrutinizer ignore-type */ get_option( 'date_format' ), strtotime( $created ) );
Loading history...
268
269
	}
270
271
	/**
272
	 * Amount column
273
	 *
274
	 * @param WPInv_Subscription $item
275
	 * @since       1.0.19
276
	 * @return      string
277
	 */
278
	public function column_amount( $item ) {
279
280
		$initial   = wpinv_price( wpinv_format_amount( wpinv_sanitize_amount( $item->get_initial_amount() ) ), $item->get_parent_payment()->get_currency() );
281
		$recurring = wpinv_price( wpinv_format_amount( wpinv_sanitize_amount( $item->get_recurring_amount() ) ), $item->get_parent_payment()->get_currency() );
282
		$period    = 1 == $item->get_frequency() ? getpaid_get_subscription_period_label( $item->get_period() ) : WPInv_Subscriptions::wpinv_get_pretty_subscription_frequency( $item->get_period(),$item->get_frequency() );
283
284
		if ( $item->has_trial_period() ) {
285
286
			// translators: $1: is the initial amount, $2: is the trial period, $3: is the recurring amount, $4: is the recurring period
287
			$amount = sprintf(
288
				_x( '%1$s trial for %2$s(s) then %3$s / %4$s', 'Subscription amount on admin table. (e.g.: $10 trial for 1 month then $120 / year)', 'invoicing' ),
289
				$initial,
290
				sanitize_text_field( $item->get_trial_period() ),
291
				$recurring,
292
				sanitize_text_field( strtolower( $period ) )
0 ignored issues
show
Bug introduced by
It seems like $period can also be of type array; however, parameter $str of strtolower() 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

292
				sanitize_text_field( strtolower( /** @scrutinizer ignore-type */ $period ) )
Loading history...
293
			);
294
295
		} else if ( $initial != $recurring ) {
296
			
297
			// translators: $1: is the initial amount, $2: is the recurring amount, $3: is the recurring perio
298
			$amount = sprintf(
299
				_x( 'Initial payment of %1$s then %2$s / %3$s', 'Subscription amount on admin table. (e.g.:Initial payment of $100 then $120 / year)', 'invoicing' ),
300
				$initial,
301
				$recurring,
302
				sanitize_text_field( strtolower( $period ) )
303
			);
304
305
		} else {
306
307
			// translators: $1: is the recurring amount, $2: is the recurring period
308
			$amount = sprintf(
309
				_x( '%1$s / %2$s', 'Subscription amount on admin table. (e.g.: $120 / year)', 'invoicing' ),
310
				$initial,
311
				sanitize_text_field( strtolower( $period ) )
312
			);
313
314
		}
315
316
		return "<span class='text-muted form-text mt-2 mb-2'>$amount</span>";
317
	}
318
319
	/**
320
	 * Billing Times column
321
	 *
322
	 * @param WPInv_Subscription $item
323
	 * @since       1.0.0
324
	 * @return      string
325
	 */
326
	public function column_renewals( $item ) {
327
		$max_bills = $item->get_bill_times();
328
		return $item->get_times_billed() . ' / ' . ( empty( $max_bills ) ? "&infin;" : $max_bills );
329
	}
330
331
	/**
332
	 * Product ID column
333
	 *
334
	 * @param WPInv_Subscription $item
335
	 * @since       1.0.0
336
	 * @return      string
337
	 */
338
	function column_item( $item ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
339
		$_item = get_post( $item->get_product_id() );
340
341
		if ( ! empty( $_item ) ) {
342
			$link = get_edit_post_link( $_item );
343
			$link = esc_url( $link );
344
			$name = esc_html( get_the_title( $_item ) );
345
			return "<a href='$link'>$name</a>";
346
		} else {
347
			return sprintf( __( 'Item #%s', 'invoicing' ), $item->get_product_id() );
348
		}
349
350
	}
351
352
	/**
353
	 * Retrieve the current page number
354
	 *
355
	 * @return      int
356
	 */
357
	public function get_paged() {
358
		return isset( $_GET['paged'] ) ? absint( $_GET['paged'] ) : 1;
359
	}
360
361
	/**
362
	 * Setup the final data for the table
363
	 *
364
	 */
365
	public function prepare_items() {
366
367
		$columns  = $this->get_columns();
368
		$hidden   = array();
369
		$sortable = $this->get_sortable_columns();
370
371
		$this->_column_headers = array( $columns, $hidden, $sortable );
372
373
		$this->set_pagination_args(
374
			array(
375
			'total_items' => $this->current_total_count,
376
			'per_page'    => $this->per_page,
377
			'total_pages' => ceil( $this->current_total_count / $this->per_page )
378
			)
379
		);
380
	}
381
382
	/**
383
	 * Table columns
384
	 *
385
	 * @return array
386
	 */
387
	public function get_columns(){
388
		$columns = array(
389
			'cb'                => '<input type="checkbox" />',
390
			'subscription'      => __( 'Subscription', 'invoicing' ),
391
			'start_date'        => __( 'Start Date', 'invoicing' ),
392
			'renewal_date'      => __( 'Next Payment', 'invoicing' ),
393
			'renewals'          => __( 'Renewals', 'invoicing' ),
394
			'item'              => __( 'Item', 'invoicing' ),
395
			'status'            => __( 'Status', 'invoicing' ),
396
		);
397
398
		return apply_filters( 'manage_getpaid_subscriptions_table_columns', $columns );
399
	}
400
401
	/**
402
	 * Sortable table columns.
403
	 *
404
	 * @return array
405
	 */
406
	public function get_sortable_columns() {
407
		$sortable = array(
408
			'subscription' => array( 'id', true ),
409
			'start_date'   => array( 'created', true ),
410
			'renewal_date' => array( 'expiration', true ),
411
			'renewals'     => array( 'bill_times', true ),
412
			'item'         => array( 'product_id', true ),
413
			'status'       => array( 'status', true ),
414
		);
415
416
		return apply_filters( 'manage_getpaid_subscriptions_sortable_table_columns', $sortable );
417
	}
418
419
	/**
420
	 * Whether the table has items to display or not
421
	 *
422
	 * @return bool
423
	 */
424
	public function has_items() {
425
		return ! empty( $this->current_total_count );
426
	}
427
428
}
429