Passed
Push — master ( c93677...8aa7be )
by Brian
10:03 queued 04:50
created
widgets/subscriptions.php 1 patch
Indentation   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -46,25 +46,25 @@
 block discarded – undo
46 46
         parent::__construct( $options );
47 47
     }
48 48
 
49
-	/**
50
-	 * The Super block output function.
51
-	 *
52
-	 * @param array $args
53
-	 * @param array $widget_args
54
-	 * @param string $content
55
-	 *
56
-	 * @return mixed|string|bool
57
-	 */
49
+    /**
50
+     * The Super block output function.
51
+     *
52
+     * @param array $args
53
+     * @param array $widget_args
54
+     * @param string $content
55
+     *
56
+     * @return mixed|string|bool
57
+     */
58 58
     public function output( $args = array(), $widget_args = array(), $content = '' ) {
59 59
 
60
-	    ob_start();
60
+        ob_start();
61 61
 
62
-	    do_action( 'wpinv_before_user_subscriptions' );
63
-	    wpinv_get_template_part( 'wpinv-subscriptions-history' );
64
-	    do_action( 'wpinv_after_user_subscriptions' );
62
+        do_action( 'wpinv_before_user_subscriptions' );
63
+        wpinv_get_template_part( 'wpinv-subscriptions-history' );
64
+        do_action( 'wpinv_after_user_subscriptions' );
65 65
 
66
-	    $output = ob_get_clean();
67
-	    return trim($output);
66
+        $output = ob_get_clean();
67
+        return trim($output);
68 68
 
69 69
     }
70 70
 
Please login to merge, or discard this patch.
includes/class-getpaid-subscriptions-query.php 1 patch
Indentation   +476 added lines, -476 removed lines patch added patch discarded remove patch
@@ -16,481 +16,481 @@
 block discarded – undo
16 16
  */
17 17
 class GetPaid_Subscriptions_Query {
18 18
 
19
-	/**
20
-	 * Query vars, after parsing
21
-	 *
22
-	 * @since 1.0.19
23
-	 * @var array
24
-	 */
25
-	public $query_vars = array();
26
-
27
-	/**
28
-	 * List of found subscriptions.
29
-	 *
30
-	 * @since 1.0.19
31
-	 * @var array
32
-	 */
33
-	private $results;
34
-
35
-	/**
36
-	 * Total number of found subscriptions for the current query
37
-	 *
38
-	 * @since 1.0.19
39
-	 * @var int
40
-	 */
41
-	private $total_subscriptions = 0;
42
-
43
-	/**
44
-	 * The SQL query used to fetch matching subscriptions.
45
-	 *
46
-	 * @since 1.0.19
47
-	 * @var string
48
-	 */
49
-	public $request;
50
-
51
-	// SQL clauses
52
-
53
-	/**
54
-	 * Contains the 'FIELDS' sql clause
55
-	 *
56
-	 * @since 1.0.19
57
-	 * @var string
58
-	 */
59
-	public $query_fields;
60
-
61
-	/**
62
-	 * Contains the 'FROM' sql clause
63
-	 *
64
-	 * @since 1.0.19
65
-	 * @var string
66
-	 */
67
-	public $query_from;
68
-
69
-	/**
70
-	 * Contains the 'WHERE' sql clause
71
-	 *
72
-	 * @since 1.0.19
73
-	 * @var string
74
-	 */
75
-	public $query_where;
76
-
77
-	/**
78
-	 * Contains the 'ORDER BY' sql clause
79
-	 *
80
-	 * @since 1.0.19
81
-	 * @var string
82
-	 */
83
-	public $query_orderby;
84
-
85
-	/**
86
-	 * Contains the 'LIMIT' sql clause
87
-	 *
88
-	 * @since 1.0.19
89
-	 * @var string
90
-	 */
91
-	public $query_limit;
92
-
93
-	/**
94
-	 * Class constructor.
95
-	 *
96
-	 * @since 1.0.19
97
-	 *
98
-	 * @param null|string|array $query Optional. The query variables.
99
-	 */
100
-	public function __construct( $query = null ) {
101
-		if ( ! is_null( $query ) ) {
102
-			$this->prepare_query( $query );
103
-			$this->query();
104
-		}
105
-	}
106
-
107
-	/**
108
-	 * Fills in missing query variables with default values.
109
-	 *
110
-	 * @since 1.0.19
111
-	 *
112
-	 * @param  string|array $args Query vars, as passed to `GetPaid_Subscriptions_Query`.
113
-	 * @return array Complete query variables with undefined ones filled in with defaults.
114
-	 */
115
-	public static function fill_query_vars( $args ) {
116
-		$defaults = array(
117
-			'status'            => 'all',
118
-			'customer_in'       => array(),
119
-			'customer_not_in'   => array(),
120
-			'product_in'        => array(),
121
-			'product_not_in'    => array(),
122
-			'include'           => array(),
123
-			'exclude'           => array(),
124
-			'orderby'           => 'id',
125
-			'order'             => 'DESC',
126
-			'offset'            => '',
127
-			'number'            => 10,
128
-			'paged'             => 1,
129
-			'count_total'       => true,
130
-			'fields'            => 'all',
131
-		);
132
-
133
-		return wp_parse_args( $args, $defaults );
134
-	}
135
-
136
-	/**
137
-	 * Prepare the query variables.
138
-	 *
139
-	 * @since 1.0.19
140
-	 *
141
-	 * @global wpdb $wpdb WordPress database abstraction object.
142
-	 *
143
-	 * @param string|array $query {
144
-	 *     Optional. Array or string of Query parameters.
145
-	 *
146
-	 *     @type string|array $status              The subscription status to filter by. Can either be a single status or an array of statuses.
147
-	 *                                             Default is all.
148
-	 *     @type int[]        $customer_in         An array of customer ids to filter by.
149
-	 *     @type int[]        $customer_not_in     An array of customer ids whose subscriptions should be excluded.
150
-	 *     @type int[]        $product_in          An array of product ids to filter by.
151
-	 *     @type int[]        $product_not_in      An array of product ids whose subscriptions should be excluded.
152
-	 *     @type array        $date_created_query  A WP_Date_Query compatible array use to filter subscriptions by their date of creation.
153
-	 *     @type array        $date_expires_query  A WP_Date_Query compatible array use to filter subscriptions by their expiration date.
154
-	 *     @type array        $include             An array of subscription IDs to include. Default empty array.
155
-	 *     @type array        $exclude             An array of subscription IDs to exclude. Default empty array.
156
-	 *     @type string|array $orderby             Field(s) to sort the retrieved subscription by. May be a single value,
157
-	 *                                             an array of values, or a multi-dimensional array with fields as
158
-	 *                                             keys and orders ('ASC' or 'DESC') as values. Accepted values are
159
-	 *                                             'id', 'customer_id', 'frequency', 'period', 'initial_amount,
160
-	 *                                             'recurring_amount', 'bill_times', 'parent_payment_id', 'created', 'expiration'
161
-	 *                                             'transaction_id', 'product_id', 'trial_period', 'include', 'status', 'profile_id'. Default array( 'id' ).
162
-	 *     @type string       $order               Designates ascending or descending order of subscriptions. Order values
163
-	 *                                             passed as part of an `$orderby` array take precedence over this
164
-	 *                                             parameter. Accepts 'ASC', 'DESC'. Default 'DESC'.
165
-	 *     @type int          $offset              Number of subscriptions to offset in retrieved results. Can be used in
166
-	 *                                             conjunction with pagination. Default 0.
167
-	 *     @type int          $number              Number of subscriptions to limit the query for. Can be used in
168
-	 *                                             conjunction with pagination. Value -1 (all) is supported, but
169
-	 *                                             should be used with caution on larger sites.
170
-	 *                                             Default 10.
171
-	 *     @type int          $paged               When used with number, defines the page of results to return.
172
-	 *                                             Default 1.
173
-	 *     @type bool         $count_total         Whether to count the total number of subscriptions found. If pagination
174
-	 *                                             is not needed, setting this to false can improve performance.
175
-	 *                                             Default true.
176
-	 *     @type string|array $fields              Which fields to return. Single or all fields (string), or array
177
-	 *                                             of fields. Accepts 'id', 'customer_id', 'frequency', 'period', 'initial_amount,
178
-	 *                                             'recurring_amount', 'bill_times', 'parent_payment_id', 'created', 'expiration'
179
-	 *                                             'transaction_id', 'product_id', 'trial_period', 'status', 'profile_id'.
180
-	 *                                             Use 'all' for all fields. Default 'all'.
181
-	 * }
182
-	 */
183
-	public function prepare_query( $query = array() ) {
184
-		global $wpdb;
185
-
186
-		if ( empty( $this->query_vars ) || ! empty( $query ) ) {
187
-			$this->query_limit = null;
188
-			$this->query_vars  = $this->fill_query_vars( $query );
189
-		}
190
-
191
-		if ( ! empty( $this->query_vars['fields'] ) && 'all' !== $this->query_vars['fields'] ) {
192
-			$this->query_vars['fields'] = wpinv_parse_list( $this->query_vars['fields'] );
193
-		}
194
-
195
-		do_action( 'getpaid_pre_get_subscriptions', array( &$this ) );
196
-
197
-		// Ensure that query vars are filled after 'getpaid_pre_get_subscriptions'.
198
-		$qv                =& $this->query_vars;
199
-		$qv                = $this->fill_query_vars( $qv );
200
-		$table             = $wpdb->prefix . 'wpinv_subscriptions';
201
-		$this->query_from  = "FROM $table";
202
-
203
-		// Prepare query fields.
204
-		$this->prepare_query_fields( $qv, $table );
205
-
206
-		// Prepare query where.
207
-		$this->prepare_query_where( $qv, $table );
208
-
209
-		// Prepare query order.
210
-		$this->prepare_query_order( $qv, $table );
211
-
212
-		// limit
213
-		if ( isset( $qv['number'] ) && $qv['number'] > 0 ) {
214
-			if ( $qv['offset'] ) {
215
-				$this->query_limit = $wpdb->prepare( 'LIMIT %d, %d', $qv['offset'], $qv['number'] );
216
-			} else {
217
-				$this->query_limit = $wpdb->prepare( 'LIMIT %d, %d', $qv['number'] * ( $qv['paged'] - 1 ), $qv['number'] );
218
-			}
219
-		}
220
-
221
-		do_action_ref_array( 'getpaid_after_subscriptions_query', array( &$this ) );
222
-	}
223
-
224
-	/**
225
-	 * Prepares the query fields.
226
-	 *
227
-	 * @since 1.0.19
228
-	 *
229
-	 * @param array $qv Query vars.
230
-	 * @param string $table Table name.
231
-	 */
232
-	protected function prepare_query_fields( &$qv, $table ) {
233
-
234
-		if ( is_array( $qv['fields'] ) ) {
235
-			$qv['fields'] = array_unique( $qv['fields'] );
236
-
237
-			$query_fields = array();
238
-			foreach ( $qv['fields'] as $field ) {
239
-				$field          = sanitize_key( $field );
240
-				$query_fields[] = "$table.`$field`";
241
-			}
242
-			$this->query_fields = implode( ',', $query_fields );
243
-		} else {
244
-			$this->query_fields = "$table.*";
245
-		}
246
-
247
-		if ( isset( $qv['count_total'] ) && $qv['count_total'] ) {
248
-			$this->query_fields = 'SQL_CALC_FOUND_ROWS ' . $this->query_fields;
249
-		}
250
-
251
-	}
252
-
253
-	/**
254
-	 * Prepares the query where.
255
-	 *
256
-	 * @since 1.0.19
257
-	 *
258
-	 * @param array $qv Query vars.
259
-	 * @param string $table Table name.
260
-	 */
261
-	protected function prepare_query_where( &$qv, $table ) {
262
-		global $wpdb;
263
-		$this->query_where = 'WHERE 1=1';
264
-
265
-		// Status.
266
-		if ( 'all' !== $qv['status'] ) {
267
-			$statuses           = wpinv_clean( wpinv_parse_list( $qv['status'] ) );
268
-			$prepared_statuses  = join( ',', array_fill( 0, count( $statuses ), '%s' ) );
269
-			$this->query_where .= $wpdb->prepare( " AND $table.`status` IN ( $prepared_statuses )", $statuses );
270
-		}
271
-
272
-		if ( ! empty( $qv['customer_in'] ) ) {
273
-			$customer_in        = implode( ',', wp_parse_id_list( $qv['customer_in'] ) );
274
-			$this->query_where .= " AND $table.`customer_id` IN ($customer_in)";
275
-		} elseif ( ! empty( $qv['customer_not_in'] ) ) {
276
-			$customer_not_in    = implode( ',', wp_parse_id_list( $qv['customer_not_in'] ) );
277
-			$this->query_where .= " AND $table.`customer_id` NOT IN ($customer_not_in)";
278
-		}
279
-
280
-		if ( ! empty( $qv['product_in'] ) ) {
281
-			$product_in         = implode( ',', wp_parse_id_list( $qv['product_in'] ) );
282
-			$this->query_where .= " AND $table.`product_id` IN ($product_in)";
283
-		} elseif ( ! empty( $qv['product_not_in'] ) ) {
284
-			$product_not_in     = implode( ',', wp_parse_id_list( $qv['product_not_in'] ) );
285
-			$this->query_where .= " AND $table.`product_id` NOT IN ($product_not_in)";
286
-		}
287
-
288
-		if ( ! empty( $qv['include'] ) ) {
289
-			$include            = implode( ',', wp_parse_id_list( $qv['include'] ) );
290
-			$this->query_where .= " AND $table.`id` IN ($include)";
291
-		} elseif ( ! empty( $qv['exclude'] ) ) {
292
-			$exclude            = implode( ',', wp_parse_id_list( $qv['exclude'] ) );
293
-			$this->query_where .= " AND $table.`id` NOT IN ($exclude)";
294
-		}
295
-
296
-		// Date queries are allowed for the subscription creation date.
297
-		if ( ! empty( $qv['date_created_query'] ) && is_array( $qv['date_created_query'] ) ) {
298
-			$date_created_query = new WP_Date_Query( $qv['date_created_query'], "$table.created" );
299
-			$this->query_where .= $date_created_query->get_sql();
300
-		}
301
-
302
-		// Date queries are also allowed for the subscription expiration date.
303
-		if ( ! empty( $qv['date_expires_query'] ) && is_array( $qv['date_expires_query'] ) ) {
304
-			$date_expires_query = new WP_Date_Query( $qv['date_expires_query'], "$table.expiration" );
305
-			$this->query_where .= $date_expires_query->get_sql();
306
-		}
307
-
308
-	}
309
-
310
-	/**
311
-	 * Prepares the query order.
312
-	 *
313
-	 * @since 1.0.19
314
-	 *
315
-	 * @param array $qv Query vars.
316
-	 * @param string $table Table name.
317
-	 */
318
-	protected function prepare_query_order( &$qv, $table ) {
319
-
320
-		// sorting.
321
-		$qv['order'] = isset( $qv['order'] ) ? strtoupper( $qv['order'] ) : '';
322
-		$order       = $this->parse_order( $qv['order'] );
323
-
324
-		// Default order is by 'id' (latest subscriptions).
325
-		if ( empty( $qv['orderby'] ) ) {
326
-			$qv['orderby'] = array( 'id' );
327
-		}
328
-
329
-		// 'orderby' values may be an array, comma- or space-separated list.
330
-		$ordersby      = array_filter( wpinv_parse_list(  $qv['orderby'] ) );
331
-
332
-		$orderby_array = array();
333
-		foreach ( $ordersby as $_key => $_value ) {
334
-
335
-			if ( is_int( $_key ) ) {
336
-				// Integer key means this is a flat array of 'orderby' fields.
337
-				$_orderby = $_value;
338
-				$_order   = $order;
339
-			} else {
340
-				// Non-integer key means that the key is the field and the value is ASC/DESC.
341
-				$_orderby = $_key;
342
-				$_order   = $_value;
343
-			}
344
-
345
-			$parsed = $this->parse_orderby( $_orderby, $table );
346
-
347
-			if ( $parsed ) {
348
-				$orderby_array[] = $parsed . ' ' . $this->parse_order( $_order );
349
-			}
350
-
351
-		}
352
-
353
-		// If no valid clauses were found, order by id.
354
-		if ( empty( $orderby_array ) ) {
355
-			$orderby_array[] = "id $order";
356
-		}
357
-
358
-		$this->query_orderby = 'ORDER BY ' . implode( ', ', $orderby_array );
359
-
360
-	}
361
-
362
-	/**
363
-	 * Execute the query, with the current variables.
364
-	 *
365
-	 * @since 1.0.19
366
-	 *
367
-	 * @global wpdb $wpdb WordPress database abstraction object.
368
-	 */
369
-	public function query() {
370
-		global $wpdb;
371
-
372
-		$qv =& $this->query_vars;
373
-
374
-		// Return a non-null value to bypass the default GetPaid subscriptions query and remember to set the
375
-		// total_subscriptions property.
376
-		$this->results = apply_filters_ref_array( 'getpaid_subscriptions_pre_query', array( null, &$this ) );
377
-
378
-		if ( null === $this->results ) {
379
-			$this->request = "SELECT $this->query_fields $this->query_from $this->query_where $this->query_orderby $this->query_limit";
380
-
381
-			if ( ( is_array( $qv['fields'] ) && 1 != count( $qv['fields'] ) ) || 'all' == $qv['fields'] ) {
382
-				$this->results = $wpdb->get_results( $this->request );
383
-			} else {
384
-				$this->results = $wpdb->get_col( $this->request );
385
-			}
386
-
387
-			if ( isset( $qv['count_total'] ) && $qv['count_total'] ) {
388
-				$found_subscriptions_query = apply_filters( 'getpaid_found_subscriptions_query', 'SELECT FOUND_ROWS()', $this );
389
-				$this->total_subscriptions   = (int) $wpdb->get_var( $found_subscriptions_query );
390
-			}
391
-		}
392
-
393
-		if ( 'all' == $qv['fields'] ) {
394
-			foreach ( $this->results as $key => $subscription ) {
395
-				$this->results[ $key ] = new WPInv_Subscription( $subscription );
396
-			}
397
-		}
398
-
399
-	}
400
-
401
-	/**
402
-	 * Retrieve query variable.
403
-	 *
404
-	 * @since 1.0.19
405
-	 *
406
-	 * @param string $query_var Query variable key.
407
-	 * @return mixed
408
-	 */
409
-	public function get( $query_var ) {
410
-		if ( isset( $this->query_vars[ $query_var ] ) ) {
411
-			return $this->query_vars[ $query_var ];
412
-		}
413
-
414
-		return null;
415
-	}
416
-
417
-	/**
418
-	 * Set query variable.
419
-	 *
420
-	 * @since 1.0.19
421
-	 *
422
-	 * @param string $query_var Query variable key.
423
-	 * @param mixed $value Query variable value.
424
-	 */
425
-	public function set( $query_var, $value ) {
426
-		$this->query_vars[ $query_var ] = $value;
427
-	}
428
-
429
-	/**
430
-	 * Return the list of subscriptions.
431
-	 *
432
-	 * @since 1.0.19
433
-	 *
434
-	 * @return WPInv_Subscription[]|array Found subscriptions.
435
-	 */
436
-	public function get_results() {
437
-		return $this->results;
438
-	}
439
-
440
-	/**
441
-	 * Return the total number of subscriptions for the current query.
442
-	 *
443
-	 * @since 1.0.19
444
-	 *
445
-	 * @return int Number of total subscriptions.
446
-	 */
447
-	public function get_total() {
448
-		return $this->total_subscriptions;
449
-	}
450
-
451
-	/**
452
-	 * Parse and sanitize 'orderby' keys passed to the subscriptions query.
453
-	 *
454
-	 * @since 1.0.19
455
-	 *
456
-	 * @param string $orderby Alias for the field to order by.
457
-	 *  @param string $table The current table.
458
-	 * @return string Value to use in the ORDER clause, if `$orderby` is valid.
459
-	 */
460
-	protected function parse_orderby( $orderby, $table ) {
461
-
462
-		$_orderby = '';
463
-		if ( in_array( $orderby, array( 'customer_id', 'frequency', 'period', 'initial_amount', 'recurring_amount', 'bill_times', 'transaction_id', 'parent_payment_id', 'product_id', 'created', 'expiration', 'trial_period', 'status', 'profile_id' ) ) ) {
464
-			$_orderby = "$table.`$orderby`";
465
-		} elseif ( 'id' === strtolower( $orderby ) ) {
466
-			$_orderby = "$table.id";
467
-		} elseif ( 'include' === $orderby && ! empty( $this->query_vars['include'] ) ) {
468
-			$include     = wp_parse_id_list( $this->query_vars['include'] );
469
-			$include_sql = implode( ',', $include );
470
-			$_orderby    = "FIELD( $table.id, $include_sql )";
471
-		}
472
-
473
-		return $_orderby;
474
-	}
475
-
476
-	/**
477
-	 * Parse an 'order' query variable and cast it to ASC or DESC as necessary.
478
-	 *
479
-	 * @since 1.0.19
480
-	 *
481
-	 * @param string $order The 'order' query variable.
482
-	 * @return string The sanitized 'order' query variable.
483
-	 */
484
-	protected function parse_order( $order ) {
485
-		if ( ! is_string( $order ) || empty( $order ) ) {
486
-			return 'DESC';
487
-		}
488
-
489
-		if ( 'ASC' === strtoupper( $order ) ) {
490
-			return 'ASC';
491
-		} else {
492
-			return 'DESC';
493
-		}
494
-	}
19
+    /**
20
+     * Query vars, after parsing
21
+     *
22
+     * @since 1.0.19
23
+     * @var array
24
+     */
25
+    public $query_vars = array();
26
+
27
+    /**
28
+     * List of found subscriptions.
29
+     *
30
+     * @since 1.0.19
31
+     * @var array
32
+     */
33
+    private $results;
34
+
35
+    /**
36
+     * Total number of found subscriptions for the current query
37
+     *
38
+     * @since 1.0.19
39
+     * @var int
40
+     */
41
+    private $total_subscriptions = 0;
42
+
43
+    /**
44
+     * The SQL query used to fetch matching subscriptions.
45
+     *
46
+     * @since 1.0.19
47
+     * @var string
48
+     */
49
+    public $request;
50
+
51
+    // SQL clauses
52
+
53
+    /**
54
+     * Contains the 'FIELDS' sql clause
55
+     *
56
+     * @since 1.0.19
57
+     * @var string
58
+     */
59
+    public $query_fields;
60
+
61
+    /**
62
+     * Contains the 'FROM' sql clause
63
+     *
64
+     * @since 1.0.19
65
+     * @var string
66
+     */
67
+    public $query_from;
68
+
69
+    /**
70
+     * Contains the 'WHERE' sql clause
71
+     *
72
+     * @since 1.0.19
73
+     * @var string
74
+     */
75
+    public $query_where;
76
+
77
+    /**
78
+     * Contains the 'ORDER BY' sql clause
79
+     *
80
+     * @since 1.0.19
81
+     * @var string
82
+     */
83
+    public $query_orderby;
84
+
85
+    /**
86
+     * Contains the 'LIMIT' sql clause
87
+     *
88
+     * @since 1.0.19
89
+     * @var string
90
+     */
91
+    public $query_limit;
92
+
93
+    /**
94
+     * Class constructor.
95
+     *
96
+     * @since 1.0.19
97
+     *
98
+     * @param null|string|array $query Optional. The query variables.
99
+     */
100
+    public function __construct( $query = null ) {
101
+        if ( ! is_null( $query ) ) {
102
+            $this->prepare_query( $query );
103
+            $this->query();
104
+        }
105
+    }
106
+
107
+    /**
108
+     * Fills in missing query variables with default values.
109
+     *
110
+     * @since 1.0.19
111
+     *
112
+     * @param  string|array $args Query vars, as passed to `GetPaid_Subscriptions_Query`.
113
+     * @return array Complete query variables with undefined ones filled in with defaults.
114
+     */
115
+    public static function fill_query_vars( $args ) {
116
+        $defaults = array(
117
+            'status'            => 'all',
118
+            'customer_in'       => array(),
119
+            'customer_not_in'   => array(),
120
+            'product_in'        => array(),
121
+            'product_not_in'    => array(),
122
+            'include'           => array(),
123
+            'exclude'           => array(),
124
+            'orderby'           => 'id',
125
+            'order'             => 'DESC',
126
+            'offset'            => '',
127
+            'number'            => 10,
128
+            'paged'             => 1,
129
+            'count_total'       => true,
130
+            'fields'            => 'all',
131
+        );
132
+
133
+        return wp_parse_args( $args, $defaults );
134
+    }
135
+
136
+    /**
137
+     * Prepare the query variables.
138
+     *
139
+     * @since 1.0.19
140
+     *
141
+     * @global wpdb $wpdb WordPress database abstraction object.
142
+     *
143
+     * @param string|array $query {
144
+     *     Optional. Array or string of Query parameters.
145
+     *
146
+     *     @type string|array $status              The subscription status to filter by. Can either be a single status or an array of statuses.
147
+     *                                             Default is all.
148
+     *     @type int[]        $customer_in         An array of customer ids to filter by.
149
+     *     @type int[]        $customer_not_in     An array of customer ids whose subscriptions should be excluded.
150
+     *     @type int[]        $product_in          An array of product ids to filter by.
151
+     *     @type int[]        $product_not_in      An array of product ids whose subscriptions should be excluded.
152
+     *     @type array        $date_created_query  A WP_Date_Query compatible array use to filter subscriptions by their date of creation.
153
+     *     @type array        $date_expires_query  A WP_Date_Query compatible array use to filter subscriptions by their expiration date.
154
+     *     @type array        $include             An array of subscription IDs to include. Default empty array.
155
+     *     @type array        $exclude             An array of subscription IDs to exclude. Default empty array.
156
+     *     @type string|array $orderby             Field(s) to sort the retrieved subscription by. May be a single value,
157
+     *                                             an array of values, or a multi-dimensional array with fields as
158
+     *                                             keys and orders ('ASC' or 'DESC') as values. Accepted values are
159
+     *                                             'id', 'customer_id', 'frequency', 'period', 'initial_amount,
160
+     *                                             'recurring_amount', 'bill_times', 'parent_payment_id', 'created', 'expiration'
161
+     *                                             'transaction_id', 'product_id', 'trial_period', 'include', 'status', 'profile_id'. Default array( 'id' ).
162
+     *     @type string       $order               Designates ascending or descending order of subscriptions. Order values
163
+     *                                             passed as part of an `$orderby` array take precedence over this
164
+     *                                             parameter. Accepts 'ASC', 'DESC'. Default 'DESC'.
165
+     *     @type int          $offset              Number of subscriptions to offset in retrieved results. Can be used in
166
+     *                                             conjunction with pagination. Default 0.
167
+     *     @type int          $number              Number of subscriptions to limit the query for. Can be used in
168
+     *                                             conjunction with pagination. Value -1 (all) is supported, but
169
+     *                                             should be used with caution on larger sites.
170
+     *                                             Default 10.
171
+     *     @type int          $paged               When used with number, defines the page of results to return.
172
+     *                                             Default 1.
173
+     *     @type bool         $count_total         Whether to count the total number of subscriptions found. If pagination
174
+     *                                             is not needed, setting this to false can improve performance.
175
+     *                                             Default true.
176
+     *     @type string|array $fields              Which fields to return. Single or all fields (string), or array
177
+     *                                             of fields. Accepts 'id', 'customer_id', 'frequency', 'period', 'initial_amount,
178
+     *                                             'recurring_amount', 'bill_times', 'parent_payment_id', 'created', 'expiration'
179
+     *                                             'transaction_id', 'product_id', 'trial_period', 'status', 'profile_id'.
180
+     *                                             Use 'all' for all fields. Default 'all'.
181
+     * }
182
+     */
183
+    public function prepare_query( $query = array() ) {
184
+        global $wpdb;
185
+
186
+        if ( empty( $this->query_vars ) || ! empty( $query ) ) {
187
+            $this->query_limit = null;
188
+            $this->query_vars  = $this->fill_query_vars( $query );
189
+        }
190
+
191
+        if ( ! empty( $this->query_vars['fields'] ) && 'all' !== $this->query_vars['fields'] ) {
192
+            $this->query_vars['fields'] = wpinv_parse_list( $this->query_vars['fields'] );
193
+        }
194
+
195
+        do_action( 'getpaid_pre_get_subscriptions', array( &$this ) );
196
+
197
+        // Ensure that query vars are filled after 'getpaid_pre_get_subscriptions'.
198
+        $qv                =& $this->query_vars;
199
+        $qv                = $this->fill_query_vars( $qv );
200
+        $table             = $wpdb->prefix . 'wpinv_subscriptions';
201
+        $this->query_from  = "FROM $table";
202
+
203
+        // Prepare query fields.
204
+        $this->prepare_query_fields( $qv, $table );
205
+
206
+        // Prepare query where.
207
+        $this->prepare_query_where( $qv, $table );
208
+
209
+        // Prepare query order.
210
+        $this->prepare_query_order( $qv, $table );
211
+
212
+        // limit
213
+        if ( isset( $qv['number'] ) && $qv['number'] > 0 ) {
214
+            if ( $qv['offset'] ) {
215
+                $this->query_limit = $wpdb->prepare( 'LIMIT %d, %d', $qv['offset'], $qv['number'] );
216
+            } else {
217
+                $this->query_limit = $wpdb->prepare( 'LIMIT %d, %d', $qv['number'] * ( $qv['paged'] - 1 ), $qv['number'] );
218
+            }
219
+        }
220
+
221
+        do_action_ref_array( 'getpaid_after_subscriptions_query', array( &$this ) );
222
+    }
223
+
224
+    /**
225
+     * Prepares the query fields.
226
+     *
227
+     * @since 1.0.19
228
+     *
229
+     * @param array $qv Query vars.
230
+     * @param string $table Table name.
231
+     */
232
+    protected function prepare_query_fields( &$qv, $table ) {
233
+
234
+        if ( is_array( $qv['fields'] ) ) {
235
+            $qv['fields'] = array_unique( $qv['fields'] );
236
+
237
+            $query_fields = array();
238
+            foreach ( $qv['fields'] as $field ) {
239
+                $field          = sanitize_key( $field );
240
+                $query_fields[] = "$table.`$field`";
241
+            }
242
+            $this->query_fields = implode( ',', $query_fields );
243
+        } else {
244
+            $this->query_fields = "$table.*";
245
+        }
246
+
247
+        if ( isset( $qv['count_total'] ) && $qv['count_total'] ) {
248
+            $this->query_fields = 'SQL_CALC_FOUND_ROWS ' . $this->query_fields;
249
+        }
250
+
251
+    }
252
+
253
+    /**
254
+     * Prepares the query where.
255
+     *
256
+     * @since 1.0.19
257
+     *
258
+     * @param array $qv Query vars.
259
+     * @param string $table Table name.
260
+     */
261
+    protected function prepare_query_where( &$qv, $table ) {
262
+        global $wpdb;
263
+        $this->query_where = 'WHERE 1=1';
264
+
265
+        // Status.
266
+        if ( 'all' !== $qv['status'] ) {
267
+            $statuses           = wpinv_clean( wpinv_parse_list( $qv['status'] ) );
268
+            $prepared_statuses  = join( ',', array_fill( 0, count( $statuses ), '%s' ) );
269
+            $this->query_where .= $wpdb->prepare( " AND $table.`status` IN ( $prepared_statuses )", $statuses );
270
+        }
271
+
272
+        if ( ! empty( $qv['customer_in'] ) ) {
273
+            $customer_in        = implode( ',', wp_parse_id_list( $qv['customer_in'] ) );
274
+            $this->query_where .= " AND $table.`customer_id` IN ($customer_in)";
275
+        } elseif ( ! empty( $qv['customer_not_in'] ) ) {
276
+            $customer_not_in    = implode( ',', wp_parse_id_list( $qv['customer_not_in'] ) );
277
+            $this->query_where .= " AND $table.`customer_id` NOT IN ($customer_not_in)";
278
+        }
279
+
280
+        if ( ! empty( $qv['product_in'] ) ) {
281
+            $product_in         = implode( ',', wp_parse_id_list( $qv['product_in'] ) );
282
+            $this->query_where .= " AND $table.`product_id` IN ($product_in)";
283
+        } elseif ( ! empty( $qv['product_not_in'] ) ) {
284
+            $product_not_in     = implode( ',', wp_parse_id_list( $qv['product_not_in'] ) );
285
+            $this->query_where .= " AND $table.`product_id` NOT IN ($product_not_in)";
286
+        }
287
+
288
+        if ( ! empty( $qv['include'] ) ) {
289
+            $include            = implode( ',', wp_parse_id_list( $qv['include'] ) );
290
+            $this->query_where .= " AND $table.`id` IN ($include)";
291
+        } elseif ( ! empty( $qv['exclude'] ) ) {
292
+            $exclude            = implode( ',', wp_parse_id_list( $qv['exclude'] ) );
293
+            $this->query_where .= " AND $table.`id` NOT IN ($exclude)";
294
+        }
295
+
296
+        // Date queries are allowed for the subscription creation date.
297
+        if ( ! empty( $qv['date_created_query'] ) && is_array( $qv['date_created_query'] ) ) {
298
+            $date_created_query = new WP_Date_Query( $qv['date_created_query'], "$table.created" );
299
+            $this->query_where .= $date_created_query->get_sql();
300
+        }
301
+
302
+        // Date queries are also allowed for the subscription expiration date.
303
+        if ( ! empty( $qv['date_expires_query'] ) && is_array( $qv['date_expires_query'] ) ) {
304
+            $date_expires_query = new WP_Date_Query( $qv['date_expires_query'], "$table.expiration" );
305
+            $this->query_where .= $date_expires_query->get_sql();
306
+        }
307
+
308
+    }
309
+
310
+    /**
311
+     * Prepares the query order.
312
+     *
313
+     * @since 1.0.19
314
+     *
315
+     * @param array $qv Query vars.
316
+     * @param string $table Table name.
317
+     */
318
+    protected function prepare_query_order( &$qv, $table ) {
319
+
320
+        // sorting.
321
+        $qv['order'] = isset( $qv['order'] ) ? strtoupper( $qv['order'] ) : '';
322
+        $order       = $this->parse_order( $qv['order'] );
323
+
324
+        // Default order is by 'id' (latest subscriptions).
325
+        if ( empty( $qv['orderby'] ) ) {
326
+            $qv['orderby'] = array( 'id' );
327
+        }
328
+
329
+        // 'orderby' values may be an array, comma- or space-separated list.
330
+        $ordersby      = array_filter( wpinv_parse_list(  $qv['orderby'] ) );
331
+
332
+        $orderby_array = array();
333
+        foreach ( $ordersby as $_key => $_value ) {
334
+
335
+            if ( is_int( $_key ) ) {
336
+                // Integer key means this is a flat array of 'orderby' fields.
337
+                $_orderby = $_value;
338
+                $_order   = $order;
339
+            } else {
340
+                // Non-integer key means that the key is the field and the value is ASC/DESC.
341
+                $_orderby = $_key;
342
+                $_order   = $_value;
343
+            }
344
+
345
+            $parsed = $this->parse_orderby( $_orderby, $table );
346
+
347
+            if ( $parsed ) {
348
+                $orderby_array[] = $parsed . ' ' . $this->parse_order( $_order );
349
+            }
350
+
351
+        }
352
+
353
+        // If no valid clauses were found, order by id.
354
+        if ( empty( $orderby_array ) ) {
355
+            $orderby_array[] = "id $order";
356
+        }
357
+
358
+        $this->query_orderby = 'ORDER BY ' . implode( ', ', $orderby_array );
359
+
360
+    }
361
+
362
+    /**
363
+     * Execute the query, with the current variables.
364
+     *
365
+     * @since 1.0.19
366
+     *
367
+     * @global wpdb $wpdb WordPress database abstraction object.
368
+     */
369
+    public function query() {
370
+        global $wpdb;
371
+
372
+        $qv =& $this->query_vars;
373
+
374
+        // Return a non-null value to bypass the default GetPaid subscriptions query and remember to set the
375
+        // total_subscriptions property.
376
+        $this->results = apply_filters_ref_array( 'getpaid_subscriptions_pre_query', array( null, &$this ) );
377
+
378
+        if ( null === $this->results ) {
379
+            $this->request = "SELECT $this->query_fields $this->query_from $this->query_where $this->query_orderby $this->query_limit";
380
+
381
+            if ( ( is_array( $qv['fields'] ) && 1 != count( $qv['fields'] ) ) || 'all' == $qv['fields'] ) {
382
+                $this->results = $wpdb->get_results( $this->request );
383
+            } else {
384
+                $this->results = $wpdb->get_col( $this->request );
385
+            }
386
+
387
+            if ( isset( $qv['count_total'] ) && $qv['count_total'] ) {
388
+                $found_subscriptions_query = apply_filters( 'getpaid_found_subscriptions_query', 'SELECT FOUND_ROWS()', $this );
389
+                $this->total_subscriptions   = (int) $wpdb->get_var( $found_subscriptions_query );
390
+            }
391
+        }
392
+
393
+        if ( 'all' == $qv['fields'] ) {
394
+            foreach ( $this->results as $key => $subscription ) {
395
+                $this->results[ $key ] = new WPInv_Subscription( $subscription );
396
+            }
397
+        }
398
+
399
+    }
400
+
401
+    /**
402
+     * Retrieve query variable.
403
+     *
404
+     * @since 1.0.19
405
+     *
406
+     * @param string $query_var Query variable key.
407
+     * @return mixed
408
+     */
409
+    public function get( $query_var ) {
410
+        if ( isset( $this->query_vars[ $query_var ] ) ) {
411
+            return $this->query_vars[ $query_var ];
412
+        }
413
+
414
+        return null;
415
+    }
416
+
417
+    /**
418
+     * Set query variable.
419
+     *
420
+     * @since 1.0.19
421
+     *
422
+     * @param string $query_var Query variable key.
423
+     * @param mixed $value Query variable value.
424
+     */
425
+    public function set( $query_var, $value ) {
426
+        $this->query_vars[ $query_var ] = $value;
427
+    }
428
+
429
+    /**
430
+     * Return the list of subscriptions.
431
+     *
432
+     * @since 1.0.19
433
+     *
434
+     * @return WPInv_Subscription[]|array Found subscriptions.
435
+     */
436
+    public function get_results() {
437
+        return $this->results;
438
+    }
439
+
440
+    /**
441
+     * Return the total number of subscriptions for the current query.
442
+     *
443
+     * @since 1.0.19
444
+     *
445
+     * @return int Number of total subscriptions.
446
+     */
447
+    public function get_total() {
448
+        return $this->total_subscriptions;
449
+    }
450
+
451
+    /**
452
+     * Parse and sanitize 'orderby' keys passed to the subscriptions query.
453
+     *
454
+     * @since 1.0.19
455
+     *
456
+     * @param string $orderby Alias for the field to order by.
457
+     *  @param string $table The current table.
458
+     * @return string Value to use in the ORDER clause, if `$orderby` is valid.
459
+     */
460
+    protected function parse_orderby( $orderby, $table ) {
461
+
462
+        $_orderby = '';
463
+        if ( in_array( $orderby, array( 'customer_id', 'frequency', 'period', 'initial_amount', 'recurring_amount', 'bill_times', 'transaction_id', 'parent_payment_id', 'product_id', 'created', 'expiration', 'trial_period', 'status', 'profile_id' ) ) ) {
464
+            $_orderby = "$table.`$orderby`";
465
+        } elseif ( 'id' === strtolower( $orderby ) ) {
466
+            $_orderby = "$table.id";
467
+        } elseif ( 'include' === $orderby && ! empty( $this->query_vars['include'] ) ) {
468
+            $include     = wp_parse_id_list( $this->query_vars['include'] );
469
+            $include_sql = implode( ',', $include );
470
+            $_orderby    = "FIELD( $table.id, $include_sql )";
471
+        }
472
+
473
+        return $_orderby;
474
+    }
475
+
476
+    /**
477
+     * Parse an 'order' query variable and cast it to ASC or DESC as necessary.
478
+     *
479
+     * @since 1.0.19
480
+     *
481
+     * @param string $order The 'order' query variable.
482
+     * @return string The sanitized 'order' query variable.
483
+     */
484
+    protected function parse_order( $order ) {
485
+        if ( ! is_string( $order ) || empty( $order ) ) {
486
+            return 'DESC';
487
+        }
488
+
489
+        if ( 'ASC' === strtoupper( $order ) ) {
490
+            return 'ASC';
491
+        } else {
492
+            return 'DESC';
493
+        }
494
+    }
495 495
 
496 496
 }
Please login to merge, or discard this patch.
includes/wpinv-subscription.php 1 patch
Indentation   +949 added lines, -949 removed lines patch added patch discarded remove patch
@@ -15,127 +15,127 @@  discard block
 block discarded – undo
15 15
  */
16 16
 class WPInv_Subscription extends GetPaid_Data {
17 17
 
18
-	/**
19
-	 * Which data store to load.
20
-	 *
21
-	 * @var string
22
-	 */
23
-	protected $data_store_name = 'subscription';
24
-
25
-	/**
26
-	 * This is the name of this object type.
27
-	 *
28
-	 * @var string
29
-	 */
30
-	protected $object_type = 'subscription';
31
-
32
-	/**
33
-	 * Item Data array. This is the core item data exposed in APIs.
34
-	 *
35
-	 * @since 1.0.19
36
-	 * @var array
37
-	 */
38
-	protected $data = array(
39
-		'customer_id'       => 0,
40
-		'frequency'         => 1,
41
-		'period'            => 'D',
42
-		'initial_amount'    => null,
43
-		'recurring_amount'  => null,
44
-		'bill_times'        => 0,
45
-		'transaction_id'    => '',
46
-		'parent_payment_id' => null,
47
-		'product_id'        => 0,
48
-		'created'           => '0000-00-00 00:00:00',
49
-		'expiration'        => '0000-00-00 00:00:00',
50
-		'trial_period'      => '',
51
-		'status'            => 'pending',
52
-		'profile_id'        => '',
53
-		'gateway'           => '',
54
-		'customer'          => '',
55
-	);
56
-
57
-	/**
58
-	 * Stores the status transition information.
59
-	 *
60
-	 * @since 1.0.19
61
-	 * @var bool
62
-	 */
63
-	protected $status_transition = false;
64
-
65
-	private $subs_db;
66
-
67
-	/**
68
-	 * Get the subscription if ID is passed, otherwise the subscription is new and empty.
69
-	 *
70
-	 * @param  int|string|object|WPInv_Subscription $subscription Subscription id, profile_id, or object to read.
71
-	 * @param  bool $deprecated
72
-	 */
73
-	function __construct( $subscription = 0, $deprecated = false ) {
74
-
75
-		parent::__construct( $subscription );
76
-
77
-		if ( ! $deprecated && ! empty( $subscription ) && is_numeric( $subscription ) ) {
78
-			$this->set_id( $subscription );
79
-		} elseif ( $subscription instanceof self ) {
80
-			$this->set_id( $subscription->get_id() );
81
-		} elseif ( ! empty( $subscription->id ) ) {
82
-			$this->set_id( $subscription->id );
83
-		} elseif ( $deprecated && $subscription_id = self::get_subscription_id_by_field( $subscription, 'profile_id' ) ) {
84
-			$this->set_id( $subscription_id );
85
-		} else {
86
-			$this->set_object_read( true );
87
-		}
88
-
89
-		// Load the datastore.
90
-		$this->data_store = GetPaid_Data_Store::load( $this->data_store_name );
91
-
92
-		if ( $this->get_id() > 0 ) {
93
-			$this->data_store->read( $this );
94
-		}
95
-
96
-	}
97
-
98
-	/**
99
-	 * Given an invoice id, profile id, transaction id, it returns the subscription's id.
100
-	 *
101
-	 *
102
-	 * @static
103
-	 * @param string $value
104
-	 * @param string $field Either invoice_id, transaction_id or profile_id.
105
-	 * @since 1.0.19
106
-	 * @return int
107
-	 */
108
-	public static function get_subscription_id_by_field( $value, $field = 'profile_id' ) {
18
+    /**
19
+     * Which data store to load.
20
+     *
21
+     * @var string
22
+     */
23
+    protected $data_store_name = 'subscription';
24
+
25
+    /**
26
+     * This is the name of this object type.
27
+     *
28
+     * @var string
29
+     */
30
+    protected $object_type = 'subscription';
31
+
32
+    /**
33
+     * Item Data array. This is the core item data exposed in APIs.
34
+     *
35
+     * @since 1.0.19
36
+     * @var array
37
+     */
38
+    protected $data = array(
39
+        'customer_id'       => 0,
40
+        'frequency'         => 1,
41
+        'period'            => 'D',
42
+        'initial_amount'    => null,
43
+        'recurring_amount'  => null,
44
+        'bill_times'        => 0,
45
+        'transaction_id'    => '',
46
+        'parent_payment_id' => null,
47
+        'product_id'        => 0,
48
+        'created'           => '0000-00-00 00:00:00',
49
+        'expiration'        => '0000-00-00 00:00:00',
50
+        'trial_period'      => '',
51
+        'status'            => 'pending',
52
+        'profile_id'        => '',
53
+        'gateway'           => '',
54
+        'customer'          => '',
55
+    );
56
+
57
+    /**
58
+     * Stores the status transition information.
59
+     *
60
+     * @since 1.0.19
61
+     * @var bool
62
+     */
63
+    protected $status_transition = false;
64
+
65
+    private $subs_db;
66
+
67
+    /**
68
+     * Get the subscription if ID is passed, otherwise the subscription is new and empty.
69
+     *
70
+     * @param  int|string|object|WPInv_Subscription $subscription Subscription id, profile_id, or object to read.
71
+     * @param  bool $deprecated
72
+     */
73
+    function __construct( $subscription = 0, $deprecated = false ) {
74
+
75
+        parent::__construct( $subscription );
76
+
77
+        if ( ! $deprecated && ! empty( $subscription ) && is_numeric( $subscription ) ) {
78
+            $this->set_id( $subscription );
79
+        } elseif ( $subscription instanceof self ) {
80
+            $this->set_id( $subscription->get_id() );
81
+        } elseif ( ! empty( $subscription->id ) ) {
82
+            $this->set_id( $subscription->id );
83
+        } elseif ( $deprecated && $subscription_id = self::get_subscription_id_by_field( $subscription, 'profile_id' ) ) {
84
+            $this->set_id( $subscription_id );
85
+        } else {
86
+            $this->set_object_read( true );
87
+        }
88
+
89
+        // Load the datastore.
90
+        $this->data_store = GetPaid_Data_Store::load( $this->data_store_name );
91
+
92
+        if ( $this->get_id() > 0 ) {
93
+            $this->data_store->read( $this );
94
+        }
95
+
96
+    }
97
+
98
+    /**
99
+     * Given an invoice id, profile id, transaction id, it returns the subscription's id.
100
+     *
101
+     *
102
+     * @static
103
+     * @param string $value
104
+     * @param string $field Either invoice_id, transaction_id or profile_id.
105
+     * @since 1.0.19
106
+     * @return int
107
+     */
108
+    public static function get_subscription_id_by_field( $value, $field = 'profile_id' ) {
109 109
         global $wpdb;
110 110
 
111
-		// Trim the value.
112
-		$value = trim( $value );
111
+        // Trim the value.
112
+        $value = trim( $value );
113 113
 
114
-		if ( empty( $value ) ) {
115
-			return 0;
116
-		}
114
+        if ( empty( $value ) ) {
115
+            return 0;
116
+        }
117 117
 
118
-		if ( 'invoice_id' == $field ) {
119
-			$field = 'parent_payment_id';
120
-		}
118
+        if ( 'invoice_id' == $field ) {
119
+            $field = 'parent_payment_id';
120
+        }
121 121
 
122 122
         // Valid fields.
123 123
         $fields = array(
124
-			'parent_payment_id',
125
-			'transaction_id',
126
-			'profile_id'
127
-		);
128
-
129
-		// Ensure a field has been passed.
130
-		if ( empty( $field ) || ! in_array( $field, $fields ) ) {
131
-			return 0;
132
-		}
133
-
134
-		// Maybe retrieve from the cache.
135
-		$subscription_id   = wp_cache_get( $value, "getpaid_subscription_{$field}s_to_subscription_ids" );
136
-		if ( ! empty( $subscription_id ) ) {
137
-			return $subscription_id;
138
-		}
124
+            'parent_payment_id',
125
+            'transaction_id',
126
+            'profile_id'
127
+        );
128
+
129
+        // Ensure a field has been passed.
130
+        if ( empty( $field ) || ! in_array( $field, $fields ) ) {
131
+            return 0;
132
+        }
133
+
134
+        // Maybe retrieve from the cache.
135
+        $subscription_id   = wp_cache_get( $value, "getpaid_subscription_{$field}s_to_subscription_ids" );
136
+        if ( ! empty( $subscription_id ) ) {
137
+            return $subscription_id;
138
+        }
139 139
 
140 140
         // Fetch from the db.
141 141
         $table            = $wpdb->prefix . 'wpinv_subscriptions';
@@ -143,34 +143,34 @@  discard block
 block discarded – undo
143 143
             $wpdb->prepare( "SELECT `id` FROM $table WHERE `$field`=%s LIMIT 1", $value )
144 144
         );
145 145
 
146
-		if ( empty( $subscription_id ) ) {
147
-			return 0;
148
-		}
146
+        if ( empty( $subscription_id ) ) {
147
+            return 0;
148
+        }
149 149
 
150
-		// Update the cache with our data.
151
-		wp_cache_set( $value, $subscription_id, "getpaid_subscription_{$field}s_to_subscription_ids" );
150
+        // Update the cache with our data.
151
+        wp_cache_set( $value, $subscription_id, "getpaid_subscription_{$field}s_to_subscription_ids" );
152 152
 
153
-		return $subscription_id;
154
-	}
153
+        return $subscription_id;
154
+    }
155 155
 
156
-	/**
156
+    /**
157 157
      * Clears the subscription's cache.
158 158
      */
159 159
     public function clear_cache() {
160
-		wp_cache_delete( $this->get_parent_payment_id(), 'getpaid_subscription_parent_payment_ids_to_subscription_ids' );
161
-		wp_cache_delete( $this->get_transaction_id(), 'getpaid_subscription_transaction_ids_to_subscription_ids' );
162
-		wp_cache_delete( $this->get_profile_id(), 'getpaid_subscription_profile_ids_to_subscription_ids' );
163
-		wp_cache_delete( $this->get_id(), 'getpaid_subscriptions' );
164
-	}
160
+        wp_cache_delete( $this->get_parent_payment_id(), 'getpaid_subscription_parent_payment_ids_to_subscription_ids' );
161
+        wp_cache_delete( $this->get_transaction_id(), 'getpaid_subscription_transaction_ids_to_subscription_ids' );
162
+        wp_cache_delete( $this->get_profile_id(), 'getpaid_subscription_profile_ids_to_subscription_ids' );
163
+        wp_cache_delete( $this->get_id(), 'getpaid_subscriptions' );
164
+    }
165 165
 
166
-	/**
166
+    /**
167 167
      * Checks if a subscription key is set.
168 168
      */
169 169
     public function _isset( $key ) {
170 170
         return isset( $this->data[$key] ) || method_exists( $this, "get_$key" );
171
-	}
171
+    }
172 172
 
173
-	/*
173
+    /*
174 174
 	|--------------------------------------------------------------------------
175 175
 	| CRUD methods
176 176
 	|--------------------------------------------------------------------------
@@ -179,57 +179,57 @@  discard block
 block discarded – undo
179 179
 	|
180 180
     */
181 181
 
182
-	/*
182
+    /*
183 183
 	|--------------------------------------------------------------------------
184 184
 	| Getters
185 185
 	|--------------------------------------------------------------------------
186 186
 	*/
187 187
 
188
-	/**
189
-	 * Get customer id.
190
-	 *
191
-	 * @since 1.0.19
192
-	 * @param  string $context View or edit context.
193
-	 * @return int
194
-	 */
195
-	public function get_customer_id( $context = 'view' ) {
196
-		return (int) $this->get_prop( 'customer_id', $context );
197
-	}
198
-
199
-	/**
200
-	 * Get customer information.
201
-	 *
202
-	 * @since 1.0.19
203
-	 * @param  string $context View or edit context.
204
-	 * @return WP_User|false WP_User object on success, false on failure.
205
-	 */
206
-	public function get_customer( $context = 'view' ) {
207
-		return get_userdata( $this->get_customer_id( $context ) );
208
-	}
209
-
210
-	/**
211
-	 * Get parent invoice id.
212
-	 *
213
-	 * @since 1.0.19
214
-	 * @param  string $context View or edit context.
215
-	 * @return int
216
-	 */
217
-	public function get_parent_invoice_id( $context = 'view' ) {
218
-		return (int) $this->get_prop( 'parent_payment_id', $context );
219
-	}
220
-
221
-	/**
222
-	 * Alias for self::get_parent_invoice_id().
223
-	 *
224
-	 * @since 1.0.19
225
-	 * @param  string $context View or edit context.
226
-	 * @return int
227
-	 */
188
+    /**
189
+     * Get customer id.
190
+     *
191
+     * @since 1.0.19
192
+     * @param  string $context View or edit context.
193
+     * @return int
194
+     */
195
+    public function get_customer_id( $context = 'view' ) {
196
+        return (int) $this->get_prop( 'customer_id', $context );
197
+    }
198
+
199
+    /**
200
+     * Get customer information.
201
+     *
202
+     * @since 1.0.19
203
+     * @param  string $context View or edit context.
204
+     * @return WP_User|false WP_User object on success, false on failure.
205
+     */
206
+    public function get_customer( $context = 'view' ) {
207
+        return get_userdata( $this->get_customer_id( $context ) );
208
+    }
209
+
210
+    /**
211
+     * Get parent invoice id.
212
+     *
213
+     * @since 1.0.19
214
+     * @param  string $context View or edit context.
215
+     * @return int
216
+     */
217
+    public function get_parent_invoice_id( $context = 'view' ) {
218
+        return (int) $this->get_prop( 'parent_payment_id', $context );
219
+    }
220
+
221
+    /**
222
+     * Alias for self::get_parent_invoice_id().
223
+     *
224
+     * @since 1.0.19
225
+     * @param  string $context View or edit context.
226
+     * @return int
227
+     */
228 228
     public function get_parent_payment_id( $context = 'view' ) {
229 229
         return $this->get_parent_invoice_id( $context );
230
-	}
230
+    }
231 231
 
232
-	/**
232
+    /**
233 233
      * Alias for self::get_parent_invoice_id().
234 234
      *
235 235
      * @since  1.0.0
@@ -239,390 +239,390 @@  discard block
 block discarded – undo
239 239
         return $this->get_parent_invoice_id( $context );
240 240
     }
241 241
 
242
-	/**
243
-	 * Get parent invoice.
244
-	 *
245
-	 * @since 1.0.19
246
-	 * @param  string $context View or edit context.
247
-	 * @return WPInv_Invoice
248
-	 */
249
-	public function get_parent_invoice( $context = 'view' ) {
250
-		return new WPInv_Invoice( $this->get_parent_invoice_id( $context ) );
251
-	}
252
-
253
-	/**
254
-	 * Alias for self::get_parent_invoice().
255
-	 *
256
-	 * @since 1.0.19
257
-	 * @param  string $context View or edit context.
258
-	 * @return WPInv_Invoice
259
-	 */
242
+    /**
243
+     * Get parent invoice.
244
+     *
245
+     * @since 1.0.19
246
+     * @param  string $context View or edit context.
247
+     * @return WPInv_Invoice
248
+     */
249
+    public function get_parent_invoice( $context = 'view' ) {
250
+        return new WPInv_Invoice( $this->get_parent_invoice_id( $context ) );
251
+    }
252
+
253
+    /**
254
+     * Alias for self::get_parent_invoice().
255
+     *
256
+     * @since 1.0.19
257
+     * @param  string $context View or edit context.
258
+     * @return WPInv_Invoice
259
+     */
260 260
     public function get_parent_payment( $context = 'view' ) {
261 261
         return $this->get_parent_invoice( $context );
262
-	}
263
-
264
-	/**
265
-	 * Get subscription's product id.
266
-	 *
267
-	 * @since 1.0.19
268
-	 * @param  string $context View or edit context.
269
-	 * @return int
270
-	 */
271
-	public function get_product_id( $context = 'view' ) {
272
-		return (int) $this->get_prop( 'product_id', $context );
273
-	}
274
-
275
-	/**
276
-	 * Get the subscription product.
277
-	 *
278
-	 * @since 1.0.19
279
-	 * @param  string $context View or edit context.
280
-	 * @return WPInv_Item
281
-	 */
282
-	public function get_product( $context = 'view' ) {
283
-		return new WPInv_Item( $this->get_product_id( $context ) );
284
-	}
285
-
286
-	/**
287
-	 * Get parent invoice's gateway.
288
-	 *
289
-	 * Here for backwards compatibility.
290
-	 *
291
-	 * @since 1.0.19
292
-	 * @param  string $context View or edit context.
293
-	 * @return string
294
-	 */
295
-	public function get_gateway( $context = 'view' ) {
296
-		return $this->get_parent_invoice( $context )->get_gateway();
297
-	}
298
-
299
-	/**
300
-	 * Get the period of a renewal.
301
-	 *
302
-	 * @since 1.0.19
303
-	 * @param  string $context View or edit context.
304
-	 * @return string
305
-	 */
306
-	public function get_period( $context = 'view' ) {
307
-		return $this->get_prop( 'period', $context );
308
-	}
309
-
310
-	/**
311
-	 * Get number of periods each renewal is valid for.
312
-	 *
313
-	 * @since 1.0.19
314
-	 * @param  string $context View or edit context.
315
-	 * @return int
316
-	 */
317
-	public function get_frequency( $context = 'view' ) {
318
-		return (int) $this->get_prop( 'frequency', $context );
319
-	}
320
-
321
-	/**
322
-	 * Get the initial amount for the subscription.
323
-	 *
324
-	 * @since 1.0.19
325
-	 * @param  string $context View or edit context.
326
-	 * @return float
327
-	 */
328
-	public function get_initial_amount( $context = 'view' ) {
329
-		return (float) wpinv_sanitize_amount( $this->get_prop( 'initial_amount', $context ) );
330
-	}
331
-
332
-	/**
333
-	 * Get the recurring amount for the subscription.
334
-	 *
335
-	 * @since 1.0.19
336
-	 * @param  string $context View or edit context.
337
-	 * @return float
338
-	 */
339
-	public function get_recurring_amount( $context = 'view' ) {
340
-		return (float) wpinv_sanitize_amount( $this->get_prop( 'recurring_amount', $context ) );
341
-	}
342
-
343
-	/**
344
-	 * Get number of times that this subscription can be renewed.
345
-	 *
346
-	 * @since 1.0.19
347
-	 * @param  string $context View or edit context.
348
-	 * @return int
349
-	 */
350
-	public function get_bill_times( $context = 'view' ) {
351
-		return (int) $this->get_prop( 'bill_times', $context );
352
-	}
353
-
354
-	/**
355
-	 * Get transaction id of this subscription's parent invoice.
356
-	 *
357
-	 * @since 1.0.19
358
-	 * @param  string $context View or edit context.
359
-	 * @return string
360
-	 */
361
-	public function get_transaction_id( $context = 'view' ) {
362
-		return $this->get_prop( 'transaction_id', $context );
363
-	}
364
-
365
-	/**
366
-	 * Get the date that the subscription was created.
367
-	 *
368
-	 * @since 1.0.19
369
-	 * @param  string $context View or edit context.
370
-	 * @return string
371
-	 */
372
-	public function get_created( $context = 'view' ) {
373
-		return $this->get_prop( 'created', $context );
374
-	}
375
-
376
-	/**
377
-	 * Alias for self::get_created().
378
-	 *
379
-	 * @since 1.0.19
380
-	 * @param  string $context View or edit context.
381
-	 * @return string
382
-	 */
383
-	public function get_date_created( $context = 'view' ) {
384
-		return $this->get_created( $context );
385
-	}
386
-
387
-	/**
388
-	 * Retrieves the creation date in a timestamp
389
-	 *
390
-	 * @since  1.0.0
391
-	 * @return int
392
-	 */
393
-	public function get_time_created() {
394
-		$created = $this->get_date_created();
395
-		return empty( $created ) ? current_time( 'timestamp' ) : strtotime( $created, current_time( 'timestamp' ) );
396
-	}
397
-
398
-	/**
399
-	 * Get GMT date when the subscription was created.
400
-	 *
401
-	 * @since 1.0.19
402
-	 * @param  string $context View or edit context.
403
-	 * @return string
404
-	 */
405
-	public function get_date_created_gmt( $context = 'view' ) {
262
+    }
263
+
264
+    /**
265
+     * Get subscription's product id.
266
+     *
267
+     * @since 1.0.19
268
+     * @param  string $context View or edit context.
269
+     * @return int
270
+     */
271
+    public function get_product_id( $context = 'view' ) {
272
+        return (int) $this->get_prop( 'product_id', $context );
273
+    }
274
+
275
+    /**
276
+     * Get the subscription product.
277
+     *
278
+     * @since 1.0.19
279
+     * @param  string $context View or edit context.
280
+     * @return WPInv_Item
281
+     */
282
+    public function get_product( $context = 'view' ) {
283
+        return new WPInv_Item( $this->get_product_id( $context ) );
284
+    }
285
+
286
+    /**
287
+     * Get parent invoice's gateway.
288
+     *
289
+     * Here for backwards compatibility.
290
+     *
291
+     * @since 1.0.19
292
+     * @param  string $context View or edit context.
293
+     * @return string
294
+     */
295
+    public function get_gateway( $context = 'view' ) {
296
+        return $this->get_parent_invoice( $context )->get_gateway();
297
+    }
298
+
299
+    /**
300
+     * Get the period of a renewal.
301
+     *
302
+     * @since 1.0.19
303
+     * @param  string $context View or edit context.
304
+     * @return string
305
+     */
306
+    public function get_period( $context = 'view' ) {
307
+        return $this->get_prop( 'period', $context );
308
+    }
309
+
310
+    /**
311
+     * Get number of periods each renewal is valid for.
312
+     *
313
+     * @since 1.0.19
314
+     * @param  string $context View or edit context.
315
+     * @return int
316
+     */
317
+    public function get_frequency( $context = 'view' ) {
318
+        return (int) $this->get_prop( 'frequency', $context );
319
+    }
320
+
321
+    /**
322
+     * Get the initial amount for the subscription.
323
+     *
324
+     * @since 1.0.19
325
+     * @param  string $context View or edit context.
326
+     * @return float
327
+     */
328
+    public function get_initial_amount( $context = 'view' ) {
329
+        return (float) wpinv_sanitize_amount( $this->get_prop( 'initial_amount', $context ) );
330
+    }
331
+
332
+    /**
333
+     * Get the recurring amount for the subscription.
334
+     *
335
+     * @since 1.0.19
336
+     * @param  string $context View or edit context.
337
+     * @return float
338
+     */
339
+    public function get_recurring_amount( $context = 'view' ) {
340
+        return (float) wpinv_sanitize_amount( $this->get_prop( 'recurring_amount', $context ) );
341
+    }
342
+
343
+    /**
344
+     * Get number of times that this subscription can be renewed.
345
+     *
346
+     * @since 1.0.19
347
+     * @param  string $context View or edit context.
348
+     * @return int
349
+     */
350
+    public function get_bill_times( $context = 'view' ) {
351
+        return (int) $this->get_prop( 'bill_times', $context );
352
+    }
353
+
354
+    /**
355
+     * Get transaction id of this subscription's parent invoice.
356
+     *
357
+     * @since 1.0.19
358
+     * @param  string $context View or edit context.
359
+     * @return string
360
+     */
361
+    public function get_transaction_id( $context = 'view' ) {
362
+        return $this->get_prop( 'transaction_id', $context );
363
+    }
364
+
365
+    /**
366
+     * Get the date that the subscription was created.
367
+     *
368
+     * @since 1.0.19
369
+     * @param  string $context View or edit context.
370
+     * @return string
371
+     */
372
+    public function get_created( $context = 'view' ) {
373
+        return $this->get_prop( 'created', $context );
374
+    }
375
+
376
+    /**
377
+     * Alias for self::get_created().
378
+     *
379
+     * @since 1.0.19
380
+     * @param  string $context View or edit context.
381
+     * @return string
382
+     */
383
+    public function get_date_created( $context = 'view' ) {
384
+        return $this->get_created( $context );
385
+    }
386
+
387
+    /**
388
+     * Retrieves the creation date in a timestamp
389
+     *
390
+     * @since  1.0.0
391
+     * @return int
392
+     */
393
+    public function get_time_created() {
394
+        $created = $this->get_date_created();
395
+        return empty( $created ) ? current_time( 'timestamp' ) : strtotime( $created, current_time( 'timestamp' ) );
396
+    }
397
+
398
+    /**
399
+     * Get GMT date when the subscription was created.
400
+     *
401
+     * @since 1.0.19
402
+     * @param  string $context View or edit context.
403
+     * @return string
404
+     */
405
+    public function get_date_created_gmt( $context = 'view' ) {
406 406
         $date = $this->get_date_created( $context );
407 407
 
408 408
         if ( $date ) {
409 409
             $date = get_gmt_from_date( $date );
410 410
         }
411
-		return $date;
412
-	}
413
-
414
-	/**
415
-	 * Get the date that the subscription will renew.
416
-	 *
417
-	 * @since 1.0.19
418
-	 * @param  string $context View or edit context.
419
-	 * @return string
420
-	 */
421
-	public function get_next_renewal_date( $context = 'view' ) {
422
-		return $this->get_prop( 'expiration', $context );
423
-	}
424
-
425
-	/**
426
-	 * Alias for self::get_next_renewal_date().
427
-	 *
428
-	 * @since 1.0.19
429
-	 * @param  string $context View or edit context.
430
-	 * @return string
431
-	 */
432
-	public function get_expiration( $context = 'view' ) {
433
-		return $this->get_next_renewal_date( $context );
434
-	}
435
-
436
-	/**
437
-	 * Retrieves the expiration date in a timestamp
438
-	 *
439
-	 * @since  1.0.0
440
-	 * @return int
441
-	 */
442
-	public function get_expiration_time() {
443
-		$expiration = $this->get_expiration();
444
-
445
-		if ( empty( $expiration ) || '0000-00-00 00:00:00' == $expiration ) {
446
-			return current_time( 'timestamp' );
447
-		}
448
-
449
-		$expiration = strtotime( $expiration, current_time( 'timestamp' ) );
450
-		return $expiration < current_time( 'timestamp' ) ? current_time( 'timestamp' ) : $expiration;
451
-	}
452
-
453
-	/**
454
-	 * Get GMT date when the subscription will renew.
455
-	 *
456
-	 * @since 1.0.19
457
-	 * @param  string $context View or edit context.
458
-	 * @return string
459
-	 */
460
-	public function get_next_renewal_date_gmt( $context = 'view' ) {
411
+        return $date;
412
+    }
413
+
414
+    /**
415
+     * Get the date that the subscription will renew.
416
+     *
417
+     * @since 1.0.19
418
+     * @param  string $context View or edit context.
419
+     * @return string
420
+     */
421
+    public function get_next_renewal_date( $context = 'view' ) {
422
+        return $this->get_prop( 'expiration', $context );
423
+    }
424
+
425
+    /**
426
+     * Alias for self::get_next_renewal_date().
427
+     *
428
+     * @since 1.0.19
429
+     * @param  string $context View or edit context.
430
+     * @return string
431
+     */
432
+    public function get_expiration( $context = 'view' ) {
433
+        return $this->get_next_renewal_date( $context );
434
+    }
435
+
436
+    /**
437
+     * Retrieves the expiration date in a timestamp
438
+     *
439
+     * @since  1.0.0
440
+     * @return int
441
+     */
442
+    public function get_expiration_time() {
443
+        $expiration = $this->get_expiration();
444
+
445
+        if ( empty( $expiration ) || '0000-00-00 00:00:00' == $expiration ) {
446
+            return current_time( 'timestamp' );
447
+        }
448
+
449
+        $expiration = strtotime( $expiration, current_time( 'timestamp' ) );
450
+        return $expiration < current_time( 'timestamp' ) ? current_time( 'timestamp' ) : $expiration;
451
+    }
452
+
453
+    /**
454
+     * Get GMT date when the subscription will renew.
455
+     *
456
+     * @since 1.0.19
457
+     * @param  string $context View or edit context.
458
+     * @return string
459
+     */
460
+    public function get_next_renewal_date_gmt( $context = 'view' ) {
461 461
         $date = $this->get_next_renewal_date( $context );
462 462
 
463 463
         if ( $date ) {
464 464
             $date = get_gmt_from_date( $date );
465 465
         }
466
-		return $date;
467
-	}
468
-
469
-	/**
470
-	 * Get the subscription's trial period.
471
-	 *
472
-	 * @since 1.0.19
473
-	 * @param  string $context View or edit context.
474
-	 * @return string
475
-	 */
476
-	public function get_trial_period( $context = 'view' ) {
477
-		return $this->get_prop( 'trial_period', $context );
478
-	}
479
-
480
-	/**
481
-	 * Get the subscription's status.
482
-	 *
483
-	 * @since 1.0.19
484
-	 * @param  string $context View or edit context.
485
-	 * @return string
486
-	 */
487
-	public function get_status( $context = 'view' ) {
488
-		return $this->get_prop( 'status', $context );
489
-	}
490
-
491
-	/**
492
-	 * Get the subscription's profile id.
493
-	 *
494
-	 * @since 1.0.19
495
-	 * @param  string $context View or edit context.
496
-	 * @return string
497
-	 */
498
-	public function get_profile_id( $context = 'view' ) {
499
-		return $this->get_prop( 'profile_id', $context );
500
-	}
501
-
502
-	/*
466
+        return $date;
467
+    }
468
+
469
+    /**
470
+     * Get the subscription's trial period.
471
+     *
472
+     * @since 1.0.19
473
+     * @param  string $context View or edit context.
474
+     * @return string
475
+     */
476
+    public function get_trial_period( $context = 'view' ) {
477
+        return $this->get_prop( 'trial_period', $context );
478
+    }
479
+
480
+    /**
481
+     * Get the subscription's status.
482
+     *
483
+     * @since 1.0.19
484
+     * @param  string $context View or edit context.
485
+     * @return string
486
+     */
487
+    public function get_status( $context = 'view' ) {
488
+        return $this->get_prop( 'status', $context );
489
+    }
490
+
491
+    /**
492
+     * Get the subscription's profile id.
493
+     *
494
+     * @since 1.0.19
495
+     * @param  string $context View or edit context.
496
+     * @return string
497
+     */
498
+    public function get_profile_id( $context = 'view' ) {
499
+        return $this->get_prop( 'profile_id', $context );
500
+    }
501
+
502
+    /*
503 503
 	|--------------------------------------------------------------------------
504 504
 	| Setters
505 505
 	|--------------------------------------------------------------------------
506 506
 	*/
507 507
 
508
-	/**
509
-	 * Set customer id.
510
-	 *
511
-	 * @since 1.0.19
512
-	 * @param  int $value The customer's id.
513
-	 */
514
-	public function set_customer_id( $value ) {
515
-		$this->set_prop( 'customer_id', (int) $value );
516
-	}
517
-
518
-	/**
519
-	 * Set parent invoice id.
520
-	 *
521
-	 * @since 1.0.19
522
-	 * @param  int $value The parent invoice id.
523
-	 */
524
-	public function set_parent_invoice_id( $value ) {
525
-		$this->set_prop( 'parent_payment_id', (int) $value );
526
-	}
527
-
528
-	/**
529
-	 * Alias for self::set_parent_invoice_id().
530
-	 *
531
-	 * @since 1.0.19
532
-	 * @param  int $value The parent invoice id.
533
-	 */
508
+    /**
509
+     * Set customer id.
510
+     *
511
+     * @since 1.0.19
512
+     * @param  int $value The customer's id.
513
+     */
514
+    public function set_customer_id( $value ) {
515
+        $this->set_prop( 'customer_id', (int) $value );
516
+    }
517
+
518
+    /**
519
+     * Set parent invoice id.
520
+     *
521
+     * @since 1.0.19
522
+     * @param  int $value The parent invoice id.
523
+     */
524
+    public function set_parent_invoice_id( $value ) {
525
+        $this->set_prop( 'parent_payment_id', (int) $value );
526
+    }
527
+
528
+    /**
529
+     * Alias for self::set_parent_invoice_id().
530
+     *
531
+     * @since 1.0.19
532
+     * @param  int $value The parent invoice id.
533
+     */
534 534
     public function set_parent_payment_id( $value ) {
535 535
         $this->set_parent_invoice_id( $value );
536
-	}
536
+    }
537 537
 
538
-	/**
538
+    /**
539 539
      * Alias for self::set_parent_invoice_id().
540 540
      *
541 541
      * @since 1.0.19
542
-	 * @param  int $value The parent invoice id.
542
+     * @param  int $value The parent invoice id.
543 543
      */
544 544
     public function set_original_payment_id( $value ) {
545 545
         $this->set_parent_invoice_id( $value );
546
-	}
547
-
548
-	/**
549
-	 * Set subscription's product id.
550
-	 *
551
-	 * @since 1.0.19
552
-	 * @param  int $value The subscription product id.
553
-	 */
554
-	public function set_product_id( $value ) {
555
-		$this->set_prop( 'product_id', (int) $value );
556
-	}
557
-
558
-	/**
559
-	 * Set the period of a renewal.
560
-	 *
561
-	 * @since 1.0.19
562
-	 * @param  string $value The renewal period.
563
-	 */
564
-	public function set_period( $value ) {
565
-		$this->set_prop( 'period', $value );
566
-	}
567
-
568
-	/**
569
-	 * Set number of periods each renewal is valid for.
570
-	 *
571
-	 * @since 1.0.19
572
-	 * @param  int $value The subscription frequency.
573
-	 */
574
-	public function set_frequency( $value ) {
575
-		$value = empty( $value ) ? 1 : (int) $value;
576
-		$this->set_prop( 'frequency', absint( $value ) );
577
-	}
578
-
579
-	/**
580
-	 * Set the initial amount for the subscription.
581
-	 *
582
-	 * @since 1.0.19
583
-	 * @param  float $value The initial subcription amount.
584
-	 */
585
-	public function set_initial_amount( $value ) {
586
-		$this->set_prop( 'initial_amount', wpinv_sanitize_amount( $value ) );
587
-	}
588
-
589
-	/**
590
-	 * Set the recurring amount for the subscription.
591
-	 *
592
-	 * @since 1.0.19
593
-	 * @param  float $value The recurring subcription amount.
594
-	 */
595
-	public function set_recurring_amount( $value ) {
596
-		$this->set_prop( 'recurring_amount', wpinv_sanitize_amount( $value ) );
597
-	}
598
-
599
-	/**
600
-	 * Set number of times that this subscription can be renewed.
601
-	 *
602
-	 * @since 1.0.19
603
-	 * @param  int $value Bill times.
604
-	 */
605
-	public function set_bill_times( $value ) {
606
-		$this->set_prop( 'bill_times', (int) $value );
607
-	}
608
-
609
-	/**
610
-	 * Get transaction id of this subscription's parent invoice.
611
-	 *
612
-	 * @since 1.0.19
613
-	 * @param string $value Bill times.
614
-	 */
615
-	public function set_transaction_id( $value ) {
616
-		$this->set_prop( 'transaction_id', sanitize_text_field( $value ) );
617
-	}
618
-
619
-	/**
620
-	 * Set date when this subscription started.
621
-	 *
622
-	 * @since 1.0.19
623
-	 * @param string $value strtotime compliant date.
624
-	 */
625
-	public function set_created( $value ) {
546
+    }
547
+
548
+    /**
549
+     * Set subscription's product id.
550
+     *
551
+     * @since 1.0.19
552
+     * @param  int $value The subscription product id.
553
+     */
554
+    public function set_product_id( $value ) {
555
+        $this->set_prop( 'product_id', (int) $value );
556
+    }
557
+
558
+    /**
559
+     * Set the period of a renewal.
560
+     *
561
+     * @since 1.0.19
562
+     * @param  string $value The renewal period.
563
+     */
564
+    public function set_period( $value ) {
565
+        $this->set_prop( 'period', $value );
566
+    }
567
+
568
+    /**
569
+     * Set number of periods each renewal is valid for.
570
+     *
571
+     * @since 1.0.19
572
+     * @param  int $value The subscription frequency.
573
+     */
574
+    public function set_frequency( $value ) {
575
+        $value = empty( $value ) ? 1 : (int) $value;
576
+        $this->set_prop( 'frequency', absint( $value ) );
577
+    }
578
+
579
+    /**
580
+     * Set the initial amount for the subscription.
581
+     *
582
+     * @since 1.0.19
583
+     * @param  float $value The initial subcription amount.
584
+     */
585
+    public function set_initial_amount( $value ) {
586
+        $this->set_prop( 'initial_amount', wpinv_sanitize_amount( $value ) );
587
+    }
588
+
589
+    /**
590
+     * Set the recurring amount for the subscription.
591
+     *
592
+     * @since 1.0.19
593
+     * @param  float $value The recurring subcription amount.
594
+     */
595
+    public function set_recurring_amount( $value ) {
596
+        $this->set_prop( 'recurring_amount', wpinv_sanitize_amount( $value ) );
597
+    }
598
+
599
+    /**
600
+     * Set number of times that this subscription can be renewed.
601
+     *
602
+     * @since 1.0.19
603
+     * @param  int $value Bill times.
604
+     */
605
+    public function set_bill_times( $value ) {
606
+        $this->set_prop( 'bill_times', (int) $value );
607
+    }
608
+
609
+    /**
610
+     * Get transaction id of this subscription's parent invoice.
611
+     *
612
+     * @since 1.0.19
613
+     * @param string $value Bill times.
614
+     */
615
+    public function set_transaction_id( $value ) {
616
+        $this->set_prop( 'transaction_id', sanitize_text_field( $value ) );
617
+    }
618
+
619
+    /**
620
+     * Set date when this subscription started.
621
+     *
622
+     * @since 1.0.19
623
+     * @param string $value strtotime compliant date.
624
+     */
625
+    public function set_created( $value ) {
626 626
         $date = strtotime( $value );
627 627
 
628 628
         if ( $date && $value !== '0000-00-00 00:00:00' ) {
@@ -630,94 +630,94 @@  discard block
 block discarded – undo
630 630
             return;
631 631
         }
632 632
 
633
-		$this->set_prop( 'created', '' );
633
+        $this->set_prop( 'created', '' );
634 634
 
635
-	}
635
+    }
636 636
 
637
-	/**
638
-	 * Alias for self::set_created().
639
-	 *
640
-	 * @since 1.0.19
641
-	 * @param string $value strtotime compliant date.
642
-	 */
643
-	public function set_date_created( $value ) {
644
-		$this->set_created( $value );
637
+    /**
638
+     * Alias for self::set_created().
639
+     *
640
+     * @since 1.0.19
641
+     * @param string $value strtotime compliant date.
642
+     */
643
+    public function set_date_created( $value ) {
644
+        $this->set_created( $value );
645 645
     }
646 646
 
647
-	/**
648
-	 * Set the date that the subscription will renew.
649
-	 *
650
-	 * @since 1.0.19
651
-	 * @param string $value strtotime compliant date.
652
-	 */
653
-	public function set_next_renewal_date( $value ) {
654
-		$date = strtotime( $value );
647
+    /**
648
+     * Set the date that the subscription will renew.
649
+     *
650
+     * @since 1.0.19
651
+     * @param string $value strtotime compliant date.
652
+     */
653
+    public function set_next_renewal_date( $value ) {
654
+        $date = strtotime( $value );
655 655
 
656 656
         if ( $date && $value !== '0000-00-00 00:00:00' ) {
657 657
             $this->set_prop( 'expiration', date( 'Y-m-d H:i:s', $date ) );
658 658
             return;
659
-		}
660
-
661
-		$this->set_prop( 'expiration', '' );
662
-
663
-	}
664
-
665
-	/**
666
-	 * Alias for self::set_next_renewal_date().
667
-	 *
668
-	 * @since 1.0.19
669
-	 * @param string $value strtotime compliant date.
670
-	 */
671
-	public function set_expiration( $value ) {
672
-		$this->set_next_renewal_date( $value );
673
-    }
674
-
675
-	/**
676
-	 * Set the subscription's trial period.
677
-	 *
678
-	 * @since 1.0.19
679
-	 * @param string $value trial period e.g 1 year.
680
-	 */
681
-	public function set_trial_period( $value ) {
682
-		$this->set_prop( 'trial_period', $value );
683
-	}
684
-
685
-	/**
686
-	 * Set the subscription's status.
687
-	 *
688
-	 * @since 1.0.19
689
-	 * @param string $new_status    New subscription status.
690
-	 */
691
-	public function set_status( $new_status ) {
692
-
693
-		// Abort if this is not a valid status;
694
-		if ( ! array_key_exists( $new_status, getpaid_get_subscription_statuses() ) ) {
695
-			return;
696
-		}
697
-
698
-		$old_status = $this->get_status();
699
-		$this->set_prop( 'status', $new_status );
700
-
701
-		if ( true === $this->object_read && $old_status !== $new_status ) {
702
-			$this->status_transition = array(
703
-				'from'   => ! empty( $this->status_transition['from'] ) ? $this->status_transition['from'] : $old_status,
704
-				'to'     => $new_status,
705
-			);
706
-		}
707
-
708
-	}
709
-
710
-	/**
711
-	 * Set the subscription's (remote) profile id.
712
-	 *
713
-	 * @since 1.0.19
714
-	 * @param  string $value the remote profile id.
715
-	 */
716
-	public function set_profile_id( $value ) {
717
-		$this->set_prop( 'profile_id', sanitize_text_field( $value ) );
718
-	}
719
-
720
-	/*
659
+        }
660
+
661
+        $this->set_prop( 'expiration', '' );
662
+
663
+    }
664
+
665
+    /**
666
+     * Alias for self::set_next_renewal_date().
667
+     *
668
+     * @since 1.0.19
669
+     * @param string $value strtotime compliant date.
670
+     */
671
+    public function set_expiration( $value ) {
672
+        $this->set_next_renewal_date( $value );
673
+    }
674
+
675
+    /**
676
+     * Set the subscription's trial period.
677
+     *
678
+     * @since 1.0.19
679
+     * @param string $value trial period e.g 1 year.
680
+     */
681
+    public function set_trial_period( $value ) {
682
+        $this->set_prop( 'trial_period', $value );
683
+    }
684
+
685
+    /**
686
+     * Set the subscription's status.
687
+     *
688
+     * @since 1.0.19
689
+     * @param string $new_status    New subscription status.
690
+     */
691
+    public function set_status( $new_status ) {
692
+
693
+        // Abort if this is not a valid status;
694
+        if ( ! array_key_exists( $new_status, getpaid_get_subscription_statuses() ) ) {
695
+            return;
696
+        }
697
+
698
+        $old_status = $this->get_status();
699
+        $this->set_prop( 'status', $new_status );
700
+
701
+        if ( true === $this->object_read && $old_status !== $new_status ) {
702
+            $this->status_transition = array(
703
+                'from'   => ! empty( $this->status_transition['from'] ) ? $this->status_transition['from'] : $old_status,
704
+                'to'     => $new_status,
705
+            );
706
+        }
707
+
708
+    }
709
+
710
+    /**
711
+     * Set the subscription's (remote) profile id.
712
+     *
713
+     * @since 1.0.19
714
+     * @param  string $value the remote profile id.
715
+     */
716
+    public function set_profile_id( $value ) {
717
+        $this->set_prop( 'profile_id', sanitize_text_field( $value ) );
718
+    }
719
+
720
+    /*
721 721
 	|--------------------------------------------------------------------------
722 722
 	| Boolean methods
723 723
 	|--------------------------------------------------------------------------
@@ -726,45 +726,45 @@  discard block
 block discarded – undo
726 726
 	|
727 727
 	*/
728 728
 
729
-	/**
729
+    /**
730 730
      * Checks if the subscription has a given status.
731
-	 *
732
-	 * @param string|array String or array of strings to check for.
733
-	 * @return bool
731
+     *
732
+     * @param string|array String or array of strings to check for.
733
+     * @return bool
734 734
      */
735 735
     public function has_status( $status ) {
736 736
         return in_array( $this->get_status(), wpinv_parse_list( $status ) );
737
-	}
737
+    }
738 738
 
739
-	/**
739
+    /**
740 740
      * Checks if the subscription has a trial period.
741
-	 *
742
-	 * @return bool
741
+     *
742
+     * @return bool
743 743
      */
744 744
     public function has_trial_period() {
745
-		$period = $this->get_trial_period();
745
+        $period = $this->get_trial_period();
746 746
         return ! empty( $period );
747
-	}
748
-
749
-	/**
750
-	 * Is the subscription active?
751
-	 *
752
-	 * @return bool
753
-	 */
754
-	public function is_active() {
755
-		return $this->has_status( 'active trialling' ) && $this->get_expiration_time() > current_time( 'mysql' );
756
-	}
757
-
758
-	/**
759
-	 * Is the subscription expired?
760
-	 *
761
-	 * @return bool
762
-	 */
763
-	public function is_expired() {
764
-		return $this->has_status( 'expired' ) || ( $this->has_status( 'active cancelled trialling' ) && $this->get_expiration_time() < current_time( 'mysql' ) );
765
-	}
766
-
767
-	/*
747
+    }
748
+
749
+    /**
750
+     * Is the subscription active?
751
+     *
752
+     * @return bool
753
+     */
754
+    public function is_active() {
755
+        return $this->has_status( 'active trialling' ) && $this->get_expiration_time() > current_time( 'mysql' );
756
+    }
757
+
758
+    /**
759
+     * Is the subscription expired?
760
+     *
761
+     * @return bool
762
+     */
763
+    public function is_expired() {
764
+        return $this->has_status( 'expired' ) || ( $this->has_status( 'active cancelled trialling' ) && $this->get_expiration_time() < current_time( 'mysql' ) );
765
+    }
766
+
767
+    /*
768 768
 	|--------------------------------------------------------------------------
769 769
 	| Additional methods
770 770
 	|--------------------------------------------------------------------------
@@ -773,27 +773,27 @@  discard block
 block discarded – undo
773 773
 	|
774 774
 	*/
775 775
 
776
-	/**
777
-	 * Backwards compatibilty.
778
-	 */
779
-	public function create( $data = array() ) {
776
+    /**
777
+     * Backwards compatibilty.
778
+     */
779
+    public function create( $data = array() ) {
780 780
 
781
-		// Set the properties.
782
-		if ( is_array( $data ) ) {
783
-			$this->set_props( $data );
784
-		}
781
+        // Set the properties.
782
+        if ( is_array( $data ) ) {
783
+            $this->set_props( $data );
784
+        }
785 785
 
786
-		// Save the item.
787
-		return $this->save();
786
+        // Save the item.
787
+        return $this->save();
788 788
 
789
-	}
789
+    }
790 790
 
791
-	/**
792
-	 * Backwards compatibilty.
793
-	 */
794
-	public function update( $args = array() ) {
795
-		return $this->create( $args );
796
-	}
791
+    /**
792
+     * Backwards compatibilty.
793
+     */
794
+    public function update( $args = array() ) {
795
+        return $this->create( $args );
796
+    }
797 797
 
798 798
     /**
799 799
      * Retrieve renewal payments for a subscription
@@ -803,15 +803,15 @@  discard block
 block discarded – undo
803 803
      */
804 804
     public function get_child_payments() {
805 805
         return get_posts(
806
-			array(
807
-            	'post_parent'    => $this->get_parent_payment_id(),
808
-            	'numberposts'    => -1,
809
-            	'post_status'    => array( 'publish', 'wpi-processing', 'wpi-renewal' ),
810
-            	'orderby'        => 'ID',
811
-            	'order'          => 'DESC',
812
-            	'post_type'      => 'wpi_invoice'
813
-			)
814
-		);
806
+            array(
807
+                'post_parent'    => $this->get_parent_payment_id(),
808
+                'numberposts'    => -1,
809
+                'post_status'    => array( 'publish', 'wpi-processing', 'wpi-renewal' ),
810
+                'orderby'        => 'ID',
811
+                'order'          => 'DESC',
812
+                'post_type'      => 'wpi_invoice'
813
+            )
814
+        );
815 815
     }
816 816
 
817 817
     /**
@@ -821,16 +821,16 @@  discard block
 block discarded – undo
821 821
      * @return int
822 822
      */
823 823
     public function get_total_payments() {
824
-		global $wpdb;
824
+        global $wpdb;
825 825
 
826
-		$count = (int) $wpdb->get_var(
827
-			$wpdb->prepare(
828
-				"SELECT COUNT(ID) FROM $wpdb->posts WHERE post_parent=%d AND post_status IN ( 'publish', 'wpi-processing', 'wpi-renewal' )",
829
-				$this->get_parent_invoice_id()
830
-			)
831
-		);
826
+        $count = (int) $wpdb->get_var(
827
+            $wpdb->prepare(
828
+                "SELECT COUNT(ID) FROM $wpdb->posts WHERE post_parent=%d AND post_status IN ( 'publish', 'wpi-processing', 'wpi-renewal' )",
829
+                $this->get_parent_invoice_id()
830
+            )
831
+        );
832 832
 
833
-		// Maybe include parent invoice.
833
+        // Maybe include parent invoice.
834 834
         if ( ! $this->has_status( 'pending' ) ) {
835 835
             $count++;
836 836
         }
@@ -859,57 +859,57 @@  discard block
 block discarded – undo
859 859
      *
860 860
      * @since  2.4
861 861
      * @param  array $args Array of values for the payment, including amount and transaction ID
862
-	 * @param  WPInv_Invoice $invoice If adding an existing invoice.
862
+     * @param  WPInv_Invoice $invoice If adding an existing invoice.
863 863
      * @return bool
864 864
      */
865 865
     public function add_payment( $args = array(), $invoice = false ) {
866 866
 
867
-		// Process each payment once.
867
+        // Process each payment once.
868 868
         if ( ! empty( $args['transaction_id'] ) && $this->payment_exists( $args['transaction_id'] ) ) {
869 869
             return false;
870 870
         }
871 871
 
872
-		// Are we creating a new invoice?
873
-		if ( empty( $invoice ) ) {
874
-			$invoice = $this->create_payment();
872
+        // Are we creating a new invoice?
873
+        if ( empty( $invoice ) ) {
874
+            $invoice = $this->create_payment();
875 875
 
876
-			if ( empty( $invoice ) ) {
877
-				return false;
878
-			}
876
+            if ( empty( $invoice ) ) {
877
+                return false;
878
+            }
879 879
 
880
-			$invoice->set_status( 'wpi-renewal' );
880
+            $invoice->set_status( 'wpi-renewal' );
881 881
 
882
-		}
882
+        }
883 883
 
884
-		// Maybe set a transaction id.
885
-		if ( ! empty( $args['transaction_id'] ) ) {
886
-			$invoice->set_transaction_id( $args['transaction_id'] );
887
-		}
884
+        // Maybe set a transaction id.
885
+        if ( ! empty( $args['transaction_id'] ) ) {
886
+            $invoice->set_transaction_id( $args['transaction_id'] );
887
+        }
888 888
 
889
-		// Set the completed date.
890
-		$invoice->set_completed_date( current_time( 'mysql' ) );
889
+        // Set the completed date.
890
+        $invoice->set_completed_date( current_time( 'mysql' ) );
891 891
 
892
-		// And the gateway.
893
-		if ( ! empty( $args['gateway'] ) ) {
894
-			$invoice->set_gateway( $args['gateway'] );
895
-		}
892
+        // And the gateway.
893
+        if ( ! empty( $args['gateway'] ) ) {
894
+            $invoice->set_gateway( $args['gateway'] );
895
+        }
896 896
 
897
-		$invoice->save();
897
+        $invoice->save();
898 898
 
899
-		if ( ! $invoice->get_id() ) {
900
-			return 0;
901
-		}
899
+        if ( ! $invoice->get_id() ) {
900
+            return 0;
901
+        }
902 902
 
903
-		do_action( 'getpaid_after_create_subscription_renewal_invoice', $invoice, $this );
904
-		do_action( 'wpinv_recurring_add_subscription_payment', $invoice, $this );
903
+        do_action( 'getpaid_after_create_subscription_renewal_invoice', $invoice, $this );
904
+        do_action( 'wpinv_recurring_add_subscription_payment', $invoice, $this );
905 905
         do_action( 'wpinv_recurring_record_payment', $invoice->get_id(), $this->get_parent_invoice_id(), $invoice->get_recurring_total(), $invoice->get_transaction_id() );
906 906
 
907 907
         update_post_meta( $invoice->get_id(), '_wpinv_subscription_id', $this->id );
908 908
 
909 909
         return $invoice->get_id();
910
-	}
910
+    }
911 911
 
912
-	/**
912
+    /**
913 913
      * Creates a new invoice and returns it.
914 914
      *
915 915
      * @since  1.0.19
@@ -917,104 +917,104 @@  discard block
 block discarded – undo
917 917
      */
918 918
     public function create_payment() {
919 919
 
920
-		$parent_invoice = $this->get_parent_payment();
921
-
922
-		if ( ! $parent_invoice->get_id() ) {
923
-			return false;
924
-		}
925
-
926
-		// Duplicate the parent invoice.
927
-		$invoice = new WPInv_Invoice();
928
-		$invoice->set_props( $parent_invoice->get_data() );
929
-		$invoice->set_id( 0 );
930
-		$invoice->set_items( $parent_invoice->get_items() );
931
-		$invoice->set_parent_id( $parent_invoice->get_id() );
932
-		$invoice->set_transaction_id( '' );
933
-		$invoice->set_key( $invoice->generate_key( 'renewal_' ) );
934
-		$invoice->set_number( '' );
935
-		$invoice->set_completed_date( '' );
936
-		$invoice->set_status( 'wpi-pending' );
937
-		$invoice->recalculate_total();
938
-		$invoice->save();
939
-
940
-		return $invoice->get_id() ? $invoice : false;
941
-    }
942
-
943
-	/**
944
-	 * Renews or completes a subscription
945
-	 *
946
-	 * @since  1.0.0
947
-	 * @return int The subscription's id
948
-	 */
949
-	public function renew() {
950
-
951
-		// Complete subscription if applicable
952
-		if ( $this->get_bill_times() > 0 && $this->get_times_billed() >= $this->get_bill_times() ) {
953
-			return $this->complete();
954
-		}
955
-
956
-		// Calculate new expiration
957
-		$frequency      = $this->get_frequency();
958
-		$period         = $this->get_period();
959
-		$new_expiration = strtotime( "+ $frequency $period", $this->get_expiration_time() );
960
-
961
-		$this->set_expiration( date( 'Y-m-d H:i:s',$new_expiration ) );
962
-		$this->set_status( 'active' );
963
-		return $this->save();
964
-
965
-		do_action( 'getpaid_subscription_renewed', $this );
966
-
967
-	}
968
-
969
-	/**
970
-	 * Marks a subscription as completed
971
-	 *
972
-	 * Subscription is completed when the number of payments matches the billing_times field
973
-	 *
974
-	 * @since  1.0.0
975
-	 * @return int|bool Subscription id or false if the subscription is cancelled.
976
-	 */
977
-	public function complete() {
978
-
979
-		// Only mark a subscription as complete if it's not already cancelled.
980
-		if ( $this->has_status( 'cancelled' ) ) {
981
-			return false;
982
-		}
983
-
984
-		$this->set_status( 'completed' );
985
-		return $this->save();
986
-
987
-	}
988
-
989
-	/**
990
-	 * Marks a subscription as expired
991
-	 *
992
-	 * @since  1.0.0
993
-	 * @param  bool $check_expiration
994
-	 * @return int|bool Subscription id or false if $check_expiration is true and expiration date is in the future.
995
-	 */
996
-	public function expire( $check_expiration = false ) {
997
-
998
-		if ( $check_expiration && $this->get_expiration_time() > current_time( 'timestamp' ) ) {
999
-			// Do not mark as expired since real expiration date is in the future
1000
-			return false;
1001
-		}
1002
-
1003
-		$this->set_status( 'expired' );
1004
-		return $this->save();
1005
-
1006
-	}
1007
-
1008
-	/**
1009
-	 * Marks a subscription as failing
1010
-	 *
1011
-	 * @since  2.4.2
1012
-	 * @return int Subscription id.
1013
-	 */
1014
-	public function failing() {
1015
-		$this->set_status( 'failing' );
1016
-		return $this->save();
1017
-	}
920
+        $parent_invoice = $this->get_parent_payment();
921
+
922
+        if ( ! $parent_invoice->get_id() ) {
923
+            return false;
924
+        }
925
+
926
+        // Duplicate the parent invoice.
927
+        $invoice = new WPInv_Invoice();
928
+        $invoice->set_props( $parent_invoice->get_data() );
929
+        $invoice->set_id( 0 );
930
+        $invoice->set_items( $parent_invoice->get_items() );
931
+        $invoice->set_parent_id( $parent_invoice->get_id() );
932
+        $invoice->set_transaction_id( '' );
933
+        $invoice->set_key( $invoice->generate_key( 'renewal_' ) );
934
+        $invoice->set_number( '' );
935
+        $invoice->set_completed_date( '' );
936
+        $invoice->set_status( 'wpi-pending' );
937
+        $invoice->recalculate_total();
938
+        $invoice->save();
939
+
940
+        return $invoice->get_id() ? $invoice : false;
941
+    }
942
+
943
+    /**
944
+     * Renews or completes a subscription
945
+     *
946
+     * @since  1.0.0
947
+     * @return int The subscription's id
948
+     */
949
+    public function renew() {
950
+
951
+        // Complete subscription if applicable
952
+        if ( $this->get_bill_times() > 0 && $this->get_times_billed() >= $this->get_bill_times() ) {
953
+            return $this->complete();
954
+        }
955
+
956
+        // Calculate new expiration
957
+        $frequency      = $this->get_frequency();
958
+        $period         = $this->get_period();
959
+        $new_expiration = strtotime( "+ $frequency $period", $this->get_expiration_time() );
960
+
961
+        $this->set_expiration( date( 'Y-m-d H:i:s',$new_expiration ) );
962
+        $this->set_status( 'active' );
963
+        return $this->save();
964
+
965
+        do_action( 'getpaid_subscription_renewed', $this );
966
+
967
+    }
968
+
969
+    /**
970
+     * Marks a subscription as completed
971
+     *
972
+     * Subscription is completed when the number of payments matches the billing_times field
973
+     *
974
+     * @since  1.0.0
975
+     * @return int|bool Subscription id or false if the subscription is cancelled.
976
+     */
977
+    public function complete() {
978
+
979
+        // Only mark a subscription as complete if it's not already cancelled.
980
+        if ( $this->has_status( 'cancelled' ) ) {
981
+            return false;
982
+        }
983
+
984
+        $this->set_status( 'completed' );
985
+        return $this->save();
986
+
987
+    }
988
+
989
+    /**
990
+     * Marks a subscription as expired
991
+     *
992
+     * @since  1.0.0
993
+     * @param  bool $check_expiration
994
+     * @return int|bool Subscription id or false if $check_expiration is true and expiration date is in the future.
995
+     */
996
+    public function expire( $check_expiration = false ) {
997
+
998
+        if ( $check_expiration && $this->get_expiration_time() > current_time( 'timestamp' ) ) {
999
+            // Do not mark as expired since real expiration date is in the future
1000
+            return false;
1001
+        }
1002
+
1003
+        $this->set_status( 'expired' );
1004
+        return $this->save();
1005
+
1006
+    }
1007
+
1008
+    /**
1009
+     * Marks a subscription as failing
1010
+     *
1011
+     * @since  2.4.2
1012
+     * @return int Subscription id.
1013
+     */
1014
+    public function failing() {
1015
+        $this->set_status( 'failing' );
1016
+        return $this->save();
1017
+    }
1018 1018
 
1019 1019
     /**
1020 1020
      * Marks a subscription as cancelled
@@ -1023,19 +1023,19 @@  discard block
 block discarded – undo
1023 1023
      * @return int Subscription id.
1024 1024
      */
1025 1025
     public function cancel() {
1026
-		$this->set_status( 'cancelled' );
1027
-		return $this->save();
1026
+        $this->set_status( 'cancelled' );
1027
+        return $this->save();
1028 1028
     }
1029 1029
 
1030
-	/**
1031
-	 * Determines if a subscription can be cancelled both locally and with a payment processor.
1032
-	 *
1033
-	 * @since  1.0.0
1034
-	 * @return bool
1035
-	 */
1036
-	public function can_cancel() {
1037
-		return apply_filters( 'wpinv_subscription_can_cancel', $this->has_status( $this->get_cancellable_statuses() ), $this );
1038
-	}
1030
+    /**
1031
+     * Determines if a subscription can be cancelled both locally and with a payment processor.
1032
+     *
1033
+     * @since  1.0.0
1034
+     * @return bool
1035
+     */
1036
+    public function can_cancel() {
1037
+        return apply_filters( 'wpinv_subscription_can_cancel', $this->has_status( $this->get_cancellable_statuses() ), $this );
1038
+    }
1039 1039
 
1040 1040
     /**
1041 1041
      * Returns an array of subscription statuses that can be cancelled
@@ -1048,82 +1048,82 @@  discard block
 block discarded – undo
1048 1048
         return apply_filters( 'wpinv_recurring_cancellable_statuses', array( 'active', 'trialling', 'failing' ) );
1049 1049
     }
1050 1050
 
1051
-	/**
1052
-	 * Retrieves the URL to cancel subscription
1053
-	 *
1054
-	 * @since  1.0.0
1055
-	 * @return string
1056
-	 */
1057
-	public function get_cancel_url() {
1058
-		$url = wp_nonce_url( add_query_arg( array( 'getpaid-action' => 'subscription_cancel', 'sub_id' => $this->get_id() ) ), 'getpaid-nonce' );
1059
-		return apply_filters( 'wpinv_subscription_cancel_url', $url, $this );
1060
-	}
1061
-
1062
-	/**
1063
-	 * Determines if subscription can be manually renewed
1064
-	 *
1065
-	 * This method is filtered by payment gateways in order to return true on subscriptions
1066
-	 * that can be renewed manually
1067
-	 *
1068
-	 * @since  2.5
1069
-	 * @return bool
1070
-	 */
1071
-	public function can_renew() {
1072
-		return apply_filters( 'wpinv_subscription_can_renew', true, $this );
1073
-	}
1074
-
1075
-	/**
1076
-	 * Retrieves the URL to renew a subscription
1077
-	 *
1078
-	 * @since  2.5
1079
-	 * @return string
1080
-	 */
1081
-	public function get_renew_url() {
1082
-		$url = wp_nonce_url( add_query_arg( array( 'getpaid-action' => 'renew_subscription', 'sub_id' => $this->get_id ) ), 'getpaid-nonce' );
1083
-		return apply_filters( 'wpinv_subscription_renew_url', $url, $this );
1084
-	}
1085
-
1086
-	/**
1087
-	 * Determines if subscription can have their payment method updated
1088
-	 *
1089
-	 * @since  1.0.0
1090
-	 * @return bool
1091
-	 */
1092
-	public function can_update() {
1093
-		return apply_filters( 'wpinv_subscription_can_update', false, $this );
1094
-	}
1095
-
1096
-	/**
1097
-	 * Retrieves the URL to update subscription
1098
-	 *
1099
-	 * @since  1.0.0
1100
-	 * @return string
1101
-	 */
1102
-	public function get_update_url() {
1103
-		$url = add_query_arg( array( 'action' => 'update', 'subscription_id' => $this->get_id() ) );
1104
-		return apply_filters( 'wpinv_subscription_update_url', $url, $this );
1105
-	}
1106
-
1107
-	/**
1108
-	 * Retrieves the subscription status label
1109
-	 *
1110
-	 * @since  1.0.0
1111
-	 * @return string
1112
-	 */
1113
-	public function get_status_label() {
1114
-		return getpaid_get_subscription_status_label( $this->get_status() );
1115
-	}
1116
-
1117
-	/**
1118
-	 * Retrieves the subscription status class
1119
-	 *
1120
-	 * @since  1.0.19
1121
-	 * @return string
1122
-	 */
1123
-	public function get_status_class() {
1124
-		$statuses = getpaid_get_subscription_status_classes();
1125
-		return isset( $statuses[ $this->get_status() ] ) ? $statuses[ $this->get_status() ] : 'text-white bg-secondary';
1126
-	}
1051
+    /**
1052
+     * Retrieves the URL to cancel subscription
1053
+     *
1054
+     * @since  1.0.0
1055
+     * @return string
1056
+     */
1057
+    public function get_cancel_url() {
1058
+        $url = wp_nonce_url( add_query_arg( array( 'getpaid-action' => 'subscription_cancel', 'sub_id' => $this->get_id() ) ), 'getpaid-nonce' );
1059
+        return apply_filters( 'wpinv_subscription_cancel_url', $url, $this );
1060
+    }
1061
+
1062
+    /**
1063
+     * Determines if subscription can be manually renewed
1064
+     *
1065
+     * This method is filtered by payment gateways in order to return true on subscriptions
1066
+     * that can be renewed manually
1067
+     *
1068
+     * @since  2.5
1069
+     * @return bool
1070
+     */
1071
+    public function can_renew() {
1072
+        return apply_filters( 'wpinv_subscription_can_renew', true, $this );
1073
+    }
1074
+
1075
+    /**
1076
+     * Retrieves the URL to renew a subscription
1077
+     *
1078
+     * @since  2.5
1079
+     * @return string
1080
+     */
1081
+    public function get_renew_url() {
1082
+        $url = wp_nonce_url( add_query_arg( array( 'getpaid-action' => 'renew_subscription', 'sub_id' => $this->get_id ) ), 'getpaid-nonce' );
1083
+        return apply_filters( 'wpinv_subscription_renew_url', $url, $this );
1084
+    }
1085
+
1086
+    /**
1087
+     * Determines if subscription can have their payment method updated
1088
+     *
1089
+     * @since  1.0.0
1090
+     * @return bool
1091
+     */
1092
+    public function can_update() {
1093
+        return apply_filters( 'wpinv_subscription_can_update', false, $this );
1094
+    }
1095
+
1096
+    /**
1097
+     * Retrieves the URL to update subscription
1098
+     *
1099
+     * @since  1.0.0
1100
+     * @return string
1101
+     */
1102
+    public function get_update_url() {
1103
+        $url = add_query_arg( array( 'action' => 'update', 'subscription_id' => $this->get_id() ) );
1104
+        return apply_filters( 'wpinv_subscription_update_url', $url, $this );
1105
+    }
1106
+
1107
+    /**
1108
+     * Retrieves the subscription status label
1109
+     *
1110
+     * @since  1.0.0
1111
+     * @return string
1112
+     */
1113
+    public function get_status_label() {
1114
+        return getpaid_get_subscription_status_label( $this->get_status() );
1115
+    }
1116
+
1117
+    /**
1118
+     * Retrieves the subscription status class
1119
+     *
1120
+     * @since  1.0.19
1121
+     * @return string
1122
+     */
1123
+    public function get_status_class() {
1124
+        $statuses = getpaid_get_subscription_status_classes();
1125
+        return isset( $statuses[ $this->get_status() ] ) ? $statuses[ $this->get_status() ] : 'text-white bg-secondary';
1126
+    }
1127 1127
 
1128 1128
     /**
1129 1129
      * Retrieves the subscription status label
@@ -1133,11 +1133,11 @@  discard block
 block discarded – undo
1133 1133
      */
1134 1134
     public function get_status_label_html() {
1135 1135
 
1136
-		$status_label = sanitize_text_field( $this->get_status_label() );
1137
-		$class        = esc_attr( $this->get_status_class() );
1138
-		$status       = sanitize_html_class( $this->get_status_label() );
1136
+        $status_label = sanitize_text_field( $this->get_status_label() );
1137
+        $class        = esc_attr( $this->get_status_class() );
1138
+        $status       = sanitize_html_class( $this->get_status_label() );
1139 1139
 
1140
-		return "<span class='bsui'><span class='d-inline-block py-2 px-3 rounded $class $status'>$status_label</span></span>";
1140
+        return "<span class='bsui'><span class='d-inline-block py-2 px-3 rounded $class $status'>$status_label</span></span>";
1141 1141
     }
1142 1142
 
1143 1143
     /**
@@ -1148,63 +1148,63 @@  discard block
 block discarded – undo
1148 1148
      * @return bool
1149 1149
      */
1150 1150
     public function payment_exists( $txn_id = '' ) {
1151
-		$invoice_id = WPInv_Invoice::get_invoice_id_by_field( $txn_id, 'transaction_id' );
1151
+        $invoice_id = WPInv_Invoice::get_invoice_id_by_field( $txn_id, 'transaction_id' );
1152 1152
         return ! empty( $invoice_id );
1153
-	}
1154
-
1155
-	/**
1156
-	 * Handle the status transition.
1157
-	 */
1158
-	protected function status_transition() {
1159
-		$status_transition = $this->status_transition;
1160
-
1161
-		// Reset status transition variable.
1162
-		$this->status_transition = false;
1163
-
1164
-		if ( $status_transition ) {
1165
-			try {
1166
-
1167
-				// Fire a hook for the status change.
1168
-				do_action( 'wpinv_subscription_' . $status_transition['to'], $this->get_id(), $this, $status_transition );
1169
-				do_action( 'getpaid_subscription_' . $status_transition['to'], $this, $status_transition );
1170
-
1171
-				if ( ! empty( $status_transition['from'] ) ) {
1172
-
1173
-					/* translators: 1: old subscription status 2: new subscription status */
1174
-					$transition_note = sprintf( __( 'Subscription status changed from %1$s to %2$s.', 'invoicing' ), getpaid_get_subscription_status_label( $status_transition['from'] ), getpaid_get_subscription_status_label( $status_transition['to'] ) );
1175
-
1176
-					// Note the transition occurred.
1177
-					$this->get_parent_payment()->add_note( $transition_note, false, false, true );
1178
-
1179
-					// Fire another hook.
1180
-					do_action( 'getpaid_subscription_status_' . $status_transition['from'] . '_to_' . $status_transition['to'], $this->get_id(), $this );
1181
-					do_action( 'getpaid_subscription_status_changed', $this, $status_transition['from'], $status_transition['to'] );
1182
-
1183
-				} else {
1184
-					/* translators: %s: new invoice status */
1185
-					$transition_note = sprintf( __( 'Subscription status set to %s.', 'invoicing' ), getpaid_get_subscription_status_label( $status_transition['to'] ) );
1186
-
1187
-					// Note the transition occurred.
1188
-					$this->get_parent_payment()->add_note( $transition_note, false, false, true );
1189
-
1190
-				}
1191
-			} catch ( Exception $e ) {
1192
-				$this->get_parent_payment()->add_note( __( 'Error during subscription status transition.', 'invoicing' ) . ' ' . $e->getMessage() );
1193
-			}
1194
-		}
1195
-
1196
-	}
1197
-
1198
-	/**
1199
-	 * Save data to the database.
1200
-	 *
1201
-	 * @since 1.0.19
1202
-	 * @return int subscription ID
1203
-	 */
1204
-	public function save() {
1205
-		parent::save();
1206
-		$this->status_transition();
1207
-		return $this->get_id();
1208
-	}
1153
+    }
1154
+
1155
+    /**
1156
+     * Handle the status transition.
1157
+     */
1158
+    protected function status_transition() {
1159
+        $status_transition = $this->status_transition;
1160
+
1161
+        // Reset status transition variable.
1162
+        $this->status_transition = false;
1163
+
1164
+        if ( $status_transition ) {
1165
+            try {
1166
+
1167
+                // Fire a hook for the status change.
1168
+                do_action( 'wpinv_subscription_' . $status_transition['to'], $this->get_id(), $this, $status_transition );
1169
+                do_action( 'getpaid_subscription_' . $status_transition['to'], $this, $status_transition );
1170
+
1171
+                if ( ! empty( $status_transition['from'] ) ) {
1172
+
1173
+                    /* translators: 1: old subscription status 2: new subscription status */
1174
+                    $transition_note = sprintf( __( 'Subscription status changed from %1$s to %2$s.', 'invoicing' ), getpaid_get_subscription_status_label( $status_transition['from'] ), getpaid_get_subscription_status_label( $status_transition['to'] ) );
1175
+
1176
+                    // Note the transition occurred.
1177
+                    $this->get_parent_payment()->add_note( $transition_note, false, false, true );
1178
+
1179
+                    // Fire another hook.
1180
+                    do_action( 'getpaid_subscription_status_' . $status_transition['from'] . '_to_' . $status_transition['to'], $this->get_id(), $this );
1181
+                    do_action( 'getpaid_subscription_status_changed', $this, $status_transition['from'], $status_transition['to'] );
1182
+
1183
+                } else {
1184
+                    /* translators: %s: new invoice status */
1185
+                    $transition_note = sprintf( __( 'Subscription status set to %s.', 'invoicing' ), getpaid_get_subscription_status_label( $status_transition['to'] ) );
1186
+
1187
+                    // Note the transition occurred.
1188
+                    $this->get_parent_payment()->add_note( $transition_note, false, false, true );
1189
+
1190
+                }
1191
+            } catch ( Exception $e ) {
1192
+                $this->get_parent_payment()->add_note( __( 'Error during subscription status transition.', 'invoicing' ) . ' ' . $e->getMessage() );
1193
+            }
1194
+        }
1195
+
1196
+    }
1197
+
1198
+    /**
1199
+     * Save data to the database.
1200
+     *
1201
+     * @since 1.0.19
1202
+     * @return int subscription ID
1203
+     */
1204
+    public function save() {
1205
+        parent::save();
1206
+        $this->status_transition();
1207
+        return $this->get_id();
1208
+    }
1209 1209
 
1210 1210
 }
Please login to merge, or discard this patch.