Passed
Push — master ( 3b6696...7383db )
by Brian
04:13
created
includes/api/class-getpaid-rest-report-sales-controller.php 1 patch
Indentation   +659 added lines, -659 removed lines patch added patch discarded remove patch
@@ -18,664 +18,664 @@
 block discarded – undo
18 18
  */
19 19
 class GetPaid_REST_Report_Sales_Controller extends GetPaid_REST_Date_Based_Controller {
20 20
 
21
-	/**
22
-	 * Route base.
23
-	 *
24
-	 * @var string
25
-	 */
26
-	protected $rest_base = 'reports/sales';
27
-
28
-	/**
29
-	 * The report data.
30
-	 *
31
-	 * @var stdClass
32
-	 */
33
-	protected $report_data;
34
-
35
-	/**
36
-	 * The report range.
37
-	 *
38
-	 * @var array
39
-	 */
40
-	protected $report_range;
41
-
42
-	/**
43
-	 * Registers the routes for the objects of the controller.
44
-	 *
45
-	 * @since 2.0.0
46
-	 *
47
-	 * @see register_rest_route()
48
-	 */
49
-	public function register_namespace_routes( $namespace ) {
50
-
51
-		// Get sales report.
52
-		register_rest_route(
53
-			$namespace,
54
-			$this->rest_base,
55
-			array(
56
-				array(
57
-					'methods'             => WP_REST_Server::READABLE,
58
-					'callback'            => array( $this, 'get_items' ),
59
-					'permission_callback' => array( $this, 'get_items_permissions_check' ),
60
-					'args'                => $this->get_collection_params(),
61
-				),
62
-				'schema' => array( $this, 'get_public_item_schema' ),
63
-			)
64
-		);
65
-
66
-	}
67
-
68
-	/**
69
-	 * Makes sure the current user has access to READ the report APIs.
70
-	 *
71
-	 * @since  2.0.0
72
-	 * @param WP_REST_Request $request Full data about the request.
73
-	 * @return WP_Error|boolean
74
-	 */
75
-	public function get_items_permissions_check( $request ) {
76
-
77
-		if ( ! wpinv_current_user_can_manage_invoicing() ) {
78
-			return new WP_Error( 'rest_cannot_view', __( 'Sorry, you cannot list resources.', 'invoicing' ), array( 'status' => rest_authorization_required_code() ) );
79
-		}
80
-
81
-		return true;
82
-	}
83
-
84
-	/**
85
-	 * Get sales reports.
86
-	 *
87
-	 * @param WP_REST_Request $request
88
-	 * @return array|WP_Error
89
-	 */
90
-	public function get_items( $request ) {
91
-		$data   = array();
92
-		$item   = $this->prepare_item_for_response( null, $request );
93
-		$data[] = $this->prepare_response_for_collection( $item );
94
-
95
-		return rest_ensure_response( $data );
96
-	}
97
-
98
-	/**
99
-	 * Prepare a report sales object for serialization.
100
-	 *
101
-	 * @param null $_
102
-	 * @param WP_REST_Request $request Request object.
103
-	 * @return WP_REST_Response $response Response data.
104
-	 */
105
-	public function prepare_item_for_response( $_, $request ) {
106
-
107
-		// Set report range.
108
-		$this->report_range = $this->get_date_range( $request );
109
-
110
-		$report_data     = $this->get_report_data();
111
-		$period_totals   = array();
112
-
113
-		// Setup period totals by ensuring each period in the interval has data.
114
-		$start_date      = strtotime( $this->report_range['after'] ) + DAY_IN_SECONDS;
115
-
116
-		if ( 'month' === $this->groupby ) {
117
-			$start_date      = strtotime( date( 'Y-m-01', $start_date ) );
118
-		}
119
-
120
-		for ( $i = 0; $i < $this->interval; $i++ ) {
121
-
122
-			switch ( $this->groupby ) {
123
-				case 'day' :
124
-					$time = date( 'Y-m-d', strtotime( "+{$i} DAY", $start_date ) );
125
-					break;
126
-				default :
127
-					$time = date( 'Y-m', strtotime( "+{$i} MONTH", $start_date ) );
128
-					break;
129
-			}
130
-
131
-			// Set the defaults for each period.
132
-			$period_totals[ $time ] = array(
133
-				'sales'             => wpinv_round_amount( 0.00 ),
134
-				'invoices'          => 0,
135
-				'refunds'           => wpinv_round_amount( 0.00 ),
136
-				'items'             => 0,
137
-				'refunded_items'    => 0,
138
-				'tax'               => wpinv_round_amount( 0.00 ),
139
-				'refunded_tax'      => wpinv_round_amount( 0.00 ),
140
-				'subtotal'          => wpinv_round_amount( 0.00 ),
141
-				'refunded_subtotal' => wpinv_round_amount( 0.00 ),
142
-				'fees'              => wpinv_round_amount( 0.00 ),
143
-				'refunded_fees'     => wpinv_round_amount( 0.00 ),
144
-				'discount'          => wpinv_round_amount( 0.00 ),
145
-			);
146
-
147
-		}
148
-
149
-		// add total sales, total invoice count, total tax for each period
150
-		$date_format = ( 'day' === $this->groupby ) ? 'Y-m-d' : 'Y-m';
151
-		foreach ( $report_data->invoices as $invoice ) {
152
-			$time = date( $date_format, strtotime( $invoice->post_date ) );
153
-
154
-			if ( ! isset( $period_totals[ $time ] ) ) {
155
-				continue;
156
-			}
157
-
158
-			$period_totals[ $time ]['sales']    = wpinv_round_amount( $invoice->total_sales );
159
-			$period_totals[ $time ]['tax']      = wpinv_round_amount( $invoice->total_tax );
160
-			$period_totals[ $time ]['subtotal'] = wpinv_round_amount( $invoice->subtotal );
161
-			$period_totals[ $time ]['fees']     = wpinv_round_amount( $invoice->total_fees );
162
-
163
-		}
164
-
165
-		foreach ( $report_data->refunds as $invoice ) {
166
-			$time = date( $date_format, strtotime( $invoice->post_date ) );
167
-
168
-			if ( ! isset( $period_totals[ $time ] ) ) {
169
-				continue;
170
-			}
171
-
172
-			$period_totals[ $time ]['refunds']           = wpinv_round_amount( $invoice->total_sales );
173
-			$period_totals[ $time ]['refunded_tax']      = wpinv_round_amount( $invoice->total_tax );
174
-			$period_totals[ $time ]['refunded_subtotal'] = wpinv_round_amount( $invoice->subtotal );
175
-			$period_totals[ $time ]['refunded_fees']     = wpinv_round_amount( $invoice->total_fees );
176
-
177
-		}
178
-
179
-		foreach ( $report_data->invoice_counts as $invoice ) {
180
-			$time = date( $date_format, strtotime( $invoice->post_date ) );
181
-
182
-			if ( isset( $period_totals[ $time ] ) ) {
183
-				$period_totals[ $time ]['invoices']   = (int) $invoice->count;
184
-			}
185
-
186
-		}
187
-
188
-		// Add total invoice items for each period.
189
-		foreach ( $report_data->invoice_items as $invoice_item ) {
190
-			$time = ( 'day' === $this->groupby ) ? date( 'Y-m-d', strtotime( $invoice_item->post_date ) ) : date( 'Y-m', strtotime( $invoice_item->post_date ) );
191
-
192
-			if ( isset( $period_totals[ $time ] ) ) {
193
-				$period_totals[ $time ]['items'] = (int) $invoice_item->invoice_item_count;
194
-			}
195
-
196
-		}
197
-
198
-		// Add total discount for each period.
199
-		foreach ( $report_data->coupons as $discount ) {
200
-			$time = ( 'day' === $this->groupby ) ? date( 'Y-m-d', strtotime( $discount->post_date ) ) : date( 'Y-m', strtotime( $discount->post_date ) );
201
-
202
-			if ( isset( $period_totals[ $time ] ) ) {
203
-				$period_totals[ $time ]['discount'] = wpinv_round_amount( $discount->discount_amount );
204
-			}
205
-
206
-		}
207
-
208
-		$report_data->totals            = $period_totals;
209
-		$report_data->grouped_by        = $this->groupby;
210
-		$report_data->interval          = max( $this->interval, 1 );
211
-		$report_data->currency          = wpinv_get_currency();
212
-		$report_data->currency_symbol   = wpinv_currency_symbol();
213
-		$report_data->currency_position = wpinv_currency_position();
214
-		$report_data->decimal_places    = wpinv_decimals();
215
-		$report_data->thousands_sep     = wpinv_thousands_separator();
216
-		$report_data->decimals_sep      = wpinv_decimal_separator();
217
-		$report_data->start_date        = date( 'Y-m-d', strtotime( $this->report_range['after'] ) + DAY_IN_SECONDS );
218
-		$report_data->end_date          = date( 'Y-m-d', strtotime( $this->report_range['before'] ) - DAY_IN_SECONDS );
219
-		$report_data->start_date_locale = getpaid_format_date( date( 'Y-m-d', strtotime( $this->report_range['after'] ) + DAY_IN_SECONDS ) );
220
-		$report_data->end_date_locale   = getpaid_format_date( date( 'Y-m-d', strtotime( $this->report_range['before'] ) - DAY_IN_SECONDS ) );
221
-		$report_data->decimals_sep      = wpinv_decimal_separator();
222
-
223
-		$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
224
-		$data    = $report_data;
225
-		unset( $data->invoice_counts, $data->invoices, $data->coupons, $data->refunds, $data->invoice_items );
226
-		$data    = $this->add_additional_fields_to_object( (array) $data, $request );
227
-		$data    = $this->filter_response_by_context( $data, $context );
228
-
229
-		// Wrap the data in a response object.
230
-		$response = rest_ensure_response( $data );
231
-		$response->add_links( array(
232
-			'about' => array(
233
-				'href' => rest_url( sprintf( '%s/reports', $this->namespace ) ),
234
-			),
235
-		) );
236
-
237
-		return apply_filters( 'getpaid_rest_prepare_report_sales', $response, $report_data, $request );
238
-	}
239
-
240
-	/**
241
-	 * Get report data.
242
-	 *
243
-	 * @return stdClass
244
-	 */
245
-	public function get_report_data() {
246
-		if ( empty( $this->report_data ) ) {
247
-			$this->query_report_data();
248
-		}
249
-		return $this->report_data;
250
-	}
251
-
252
-	/**
253
-	 * Get all data needed for this report and store in the class.
254
-	 */
255
-	protected function query_report_data() {
256
-
257
-		// Prepare reports.
258
-		$this->report_data = (object) array(
259
-			'invoice_counts' => $this->query_invoice_counts(),//count, post_date
260
-			'coupons'        => $this->query_coupon_counts(), // discount_amount, post_date
261
-			'invoice_items'  => $this->query_item_counts(), // invoice_item_count, post_date
262
-			'refunded_items' => $this->count_refunded_items(), // invoice_item_count, post_date
263
-			'invoices'       => $this->query_invoice_totals(), // total_sales, total_tax, total_discount, total_fees, subtotal, post_date
264
-			'refunds'        => $this->query_refunded_totals(), // total_sales, total_tax, total_discount, total_fees, subtotal, post_date
265
-			'previous_range' => $this->previous_range,
266
-		);
267
-
268
-		// Calculated totals.
269
-		$this->report_data->total_tax          = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->invoices, 'total_tax' ) ) );
270
-		$this->report_data->total_sales        = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->invoices, 'total_sales' ) ) );
271
-		$this->report_data->total_discount     = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->invoices, 'total_discount' ) ) );
272
-		$this->report_data->total_fees         = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->invoices, 'total_fees' ) ) );
273
-		$this->report_data->subtotal           = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->invoices, 'subtotal' ) ) );
274
-		$this->report_data->net_sales          = wpinv_round_amount( $this->report_data->total_sales - max( 0, $this->report_data->total_tax ) );
275
-		$this->report_data->total_refunded_tax = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->refunds, 'total_tax' ) ) );
276
-		$this->report_data->total_refunds      = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->refunds, 'total_sales' ) ) );
277
-		$this->report_data->refunded_discount  = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->refunds, 'total_discount' ) ) );
278
-		$this->report_data->refunded_fees      = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->refunds, 'total_fees' ) ) );
279
-		$this->report_data->refunded_subtotal  = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->refunds, 'subtotal' ) ) );
280
-		$this->report_data->net_refunds        = wpinv_round_amount( $this->report_data->total_refunds + max( 0, $this->report_data->total_refunded_tax ) );
281
-
282
-
283
-		// Calculate average based on net.
284
-		$this->report_data->average_sales       = wpinv_round_amount( $this->report_data->net_sales / max( $this->interval, 1 ), 2 );
285
-		$this->report_data->average_total_sales = wpinv_round_amount( $this->report_data->total_sales / max( $this->interval, 1 ), 2 );
286
-
287
-		// Total invoices in this period, even if refunded.
288
-		$this->report_data->total_invoices = absint( array_sum( wp_list_pluck( $this->report_data->invoice_counts, 'count' ) ) );
289
-
290
-		// Items invoiced in this period, even if refunded.
291
-		$this->report_data->total_items = absint( array_sum( wp_list_pluck( $this->report_data->invoice_items, 'invoice_item_count' ) ) );
292
-
293
-		// 3rd party filtering of report data
294
-		$this->report_data = apply_filters( 'getpaid_rest_api_filter_report_data', $this->report_data );
295
-	}
296
-
297
-	/**
298
-	 * Prepares invoice counts.
299
-	 *
300
-	 * @return array.
301
-	 */
302
-	protected function query_invoice_counts() {
303
-
304
-		return (array) GetPaid_Reports_Helper::get_invoice_report_data(
305
-			array(
306
-				'data'         => array(
307
-					'ID'        => array(
308
-						'type'     => 'post_data',
309
-						'function' => 'COUNT',
310
-						'name'     => 'count',
311
-						'distinct' => true,
312
-					),
313
-					'post_date' => array(
314
-						'type'     => 'post_data',
315
-						'function' => '',
316
-						'name'     => 'post_date',
317
-					),
318
-				),
319
-				'group_by'       => $this->get_group_by_sql( 'posts.post_date' ),
320
-				'order_by'       => 'post_date ASC',
321
-				'query_type'     => 'get_results',
322
-				'filter_range'   => $this->report_range,
323
-				'invoice_status' => array( 'publish', 'wpi-processing', 'wpi-onhold', 'wpi-refunded', 'wpi-renewal' ),
324
-			)
325
-		);
326
-
327
-	}
328
-
329
-	/**
330
-	 * Prepares coupon counts.
331
-	 *
332
-	 * @return array.
333
-	 */
334
-	protected function query_coupon_counts() {
335
-
336
-		return (array) GetPaid_Reports_Helper::get_invoice_report_data(
337
-			array(
338
-				'data'         => array(
339
-					'discount' => array(
340
-						'type'     => 'invoice_data',
341
-						'function' => 'SUM',
342
-						'name'     => 'discount_amount',
343
-					),
344
-					'post_date'       => array(
345
-						'type'     => 'post_data',
346
-						'function' => '',
347
-						'name'     => 'post_date',
348
-					),
349
-				),
350
-				'group_by'       => $this->get_group_by_sql( 'posts.post_date' ),
351
-				'order_by'       => 'post_date ASC',
352
-				'query_type'     => 'get_results',
353
-				'filter_range'   => $this->report_range,
354
-				'invoice_status' => array( 'publish', 'wpi-processing', 'wpi-onhold', 'wpi-refunded', 'wpi-renewal' ),
355
-			)
356
-		);
357
-
358
-	}
359
-
360
-	/**
361
-	 * Prepares item counts.
362
-	 *
363
-	 * @return array.
364
-	 */
365
-	protected function query_item_counts() {
366
-
367
-		return (array) GetPaid_Reports_Helper::get_invoice_report_data(
368
-			array(
369
-				'data'         => array(
370
-					'quantity'      => array(
371
-						'type'            => 'invoice_item',
372
-						'function'        => 'SUM',
373
-						'name'            => 'invoice_item_count',
374
-					),
375
-					'post_date' => array(
376
-						'type'     => 'post_data',
377
-						'function' => '',
378
-						'name'     => 'post_date',
379
-					),
380
-				),
381
-				'group_by'       => $this->get_group_by_sql( 'posts.post_date' ),
382
-				'order_by'       => 'post_date ASC',
383
-				'query_type'     => 'get_results',
384
-				'filter_range'   => $this->report_range,
385
-				'invoice_status' => array( 'publish', 'wpi-processing', 'wpi-onhold', 'wpi-refunded', 'wpi-renewal' ),
386
-			)
387
-		);
388
-
389
-	}
390
-
391
-	/**
392
-	 * Prepares refunded item counts.
393
-	 *
394
-	 * @return array.
395
-	 */
396
-	protected function count_refunded_items() {
397
-
398
-		return (int) GetPaid_Reports_Helper::get_invoice_report_data(
399
-			array(
400
-				'data'         => array(
401
-					'quantity'      => array(
402
-						'type'            => 'invoice_item',
403
-						'function'        => 'SUM',
404
-						'name'            => 'invoice_item_count',
405
-					),
406
-				),
407
-				'query_type'     => 'get_var',
408
-				'filter_range'   => $this->report_range,
409
-				'invoice_status' => array( 'wpi-refunded' ),
410
-			)
411
-		);
412
-
413
-	}
414
-
415
-	/**
416
-	 * Prepares daily invoice totals.
417
-	 *
418
-	 * @return array.
419
-	 */
420
-	protected function query_invoice_totals() {
421
-
422
-		return (array) GetPaid_Reports_Helper::get_invoice_report_data(
423
-			array(
424
-				'data'         => array(
425
-					'total'      => array(
426
-						'type'            => 'invoice_data',
427
-						'function'        => 'SUM',
428
-						'name'            => 'total_sales',
429
-					),
430
-					'tax'      => array(
431
-						'type'            => 'invoice_data',
432
-						'function'        => 'SUM',
433
-						'name'            => 'total_tax',
434
-					),
435
-					'discount'      => array(
436
-						'type'            => 'invoice_data',
437
-						'function'        => 'SUM',
438
-						'name'            => 'total_discount',
439
-					),
440
-					'fees_total'      => array(
441
-						'type'            => 'invoice_data',
442
-						'function'        => 'SUM',
443
-						'name'            => 'total_fees',
444
-					),
445
-					'subtotal'      => array(
446
-						'type'            => 'invoice_data',
447
-						'function'        => 'SUM',
448
-						'name'            => 'subtotal',
449
-					),
450
-					'post_date' => array(
451
-						'type'     => 'post_data',
452
-						'function' => '',
453
-						'name'     => 'post_date',
454
-					),
455
-				),
456
-				'group_by'       => $this->get_group_by_sql( 'posts.post_date' ),
457
-				'order_by'       => 'post_date ASC',
458
-				'query_type'     => 'get_results',
459
-				'filter_range'   => $this->report_range,
460
-				'invoice_status' => array( 'publish', 'wpi-processing', 'wpi-onhold', 'wpi-renewal' ),
461
-			)
462
-		);
463
-
464
-	}
465
-
466
-	/**
467
-	 * Prepares daily invoice totals.
468
-	 *
469
-	 * @return array.
470
-	 */
471
-	protected function query_refunded_totals() {
472
-
473
-		return (array) GetPaid_Reports_Helper::get_invoice_report_data(
474
-			array(
475
-				'data'         => array(
476
-					'total'      => array(
477
-						'type'            => 'invoice_data',
478
-						'function'        => 'SUM',
479
-						'name'            => 'total_sales',
480
-					),
481
-					'tax'      => array(
482
-						'type'            => 'invoice_data',
483
-						'function'        => 'SUM',
484
-						'name'            => 'total_tax',
485
-					),
486
-					'discount'      => array(
487
-						'type'            => 'invoice_data',
488
-						'function'        => 'SUM',
489
-						'name'            => 'total_discount',
490
-					),
491
-					'fees_total'      => array(
492
-						'type'            => 'invoice_data',
493
-						'function'        => 'SUM',
494
-						'name'            => 'total_fees',
495
-					),
496
-					'subtotal'      => array(
497
-						'type'            => 'invoice_data',
498
-						'function'        => 'SUM',
499
-						'name'            => 'subtotal',
500
-					),
501
-					'post_date' => array(
502
-						'type'     => 'post_data',
503
-						'function' => '',
504
-						'name'     => 'post_date',
505
-					),
506
-				),
507
-				'group_by'       => $this->get_group_by_sql( 'posts.post_date' ),
508
-				'order_by'       => 'post_date ASC',
509
-				'query_type'     => 'get_results',
510
-				'filter_range'   => $this->report_range,
511
-				'invoice_status' => array( 'wpi-refunded' ),
512
-			)
513
-		);
514
-
515
-	}
516
-
517
-	/**
518
-	 * Get the Report's schema, conforming to JSON Schema.
519
-	 *
520
-	 * @return array
521
-	 */
522
-	public function get_item_schema() {
523
-
524
-		$schema = array(
525
-			'$schema'    => 'http://json-schema.org/draft-04/schema#',
526
-			'title'      => 'sales_report',
527
-			'type'       => 'object',
528
-			'properties' => array(
529
-				'total_sales' => array(
530
-					'description' => __( 'Gross sales in the period.', 'invoicing' ),
531
-					'type'        => 'string',
532
-					'context'     => array( 'view' ),
533
-					'readonly'    => true,
534
-				),
535
-				'net_sales' => array(
536
-					'description' => __( 'Net sales in the period.', 'invoicing' ),
537
-					'type'        => 'string',
538
-					'context'     => array( 'view' ),
539
-					'readonly'    => true,
540
-				),
541
-				'average_sales' => array(
542
-					'description' => __( 'Average net daily sales.', 'invoicing' ),
543
-					'type'        => 'string',
544
-					'context'     => array( 'view' ),
545
-					'readonly'    => true,
546
-				),
547
-				'average_total_sales' => array(
548
-					'description' => __( 'Average gross daily sales.', 'invoicing' ),
549
-					'type'        => 'string',
550
-					'context'     => array( 'view' ),
551
-					'readonly'    => true,
552
-				),
553
-				'total_invoices'  => array(
554
-					'description' => __( 'Number of paid invoices.', 'invoicing' ),
555
-					'type'        => 'integer',
556
-					'context'     => array( 'view' ),
557
-					'readonly'    => true,
558
-				),
559
-				'total_items' => array(
560
-					'description' => __( 'Number of items purchased.', 'invoicing' ),
561
-					'type'        => 'integer',
562
-					'context'     => array( 'view' ),
563
-					'readonly'    => true,
564
-				),
565
-				'refunded_items' => array(
566
-					'description' => __( 'Number of items refunded.', 'invoicing' ),
567
-					'type'        => 'integer',
568
-					'context'     => array( 'view' ),
569
-					'readonly'    => true,
570
-				),
571
-				'total_tax' => array(
572
-					'description' => __( 'Total charged for taxes.', 'invoicing' ),
573
-					'type'        => 'string',
574
-					'context'     => array( 'view' ),
575
-					'readonly'    => true,
576
-				),
577
-				'total_refunded_tax' => array(
578
-					'description' => __( 'Total refunded for taxes.', 'invoicing' ),
579
-					'type'        => 'string',
580
-					'context'     => array( 'view' ),
581
-					'readonly'    => true,
582
-				),
583
-				'total_fees' => array(
584
-					'description' => __( 'Total fees charged.', 'invoicing' ),
585
-					'type'        => 'string',
586
-					'context'     => array( 'view' ),
587
-					'readonly'    => true,
588
-				),
589
-				'total_refunds' => array(
590
-					'description' => __( 'Total of refunded invoices.', 'invoicing' ),
591
-					'type'        => 'integer',
592
-					'context'     => array( 'view' ),
593
-					'readonly'    => true,
594
-				),
595
-				'net_refunds' => array(
596
-					'description' => __( 'Net of refunded invoices.', 'invoicing' ),
597
-					'type'        => 'integer',
598
-					'context'     => array( 'view' ),
599
-					'readonly'    => true,
600
-				),
601
-				'total_discount' => array(
602
-					'description' => __( 'Total of discounts used.', 'invoicing' ),
603
-					'type'        => 'integer',
604
-					'context'     => array( 'view' ),
605
-					'readonly'    => true,
606
-				),
607
-				'totals' => array(
608
-					'description' => __( 'Totals.', 'invoicing' ),
609
-					'type'        => 'array',
610
-					'items'       => array(
611
-						'type'    => 'array',
612
-					),
613
-					'context'     => array( 'view' ),
614
-					'readonly'    => true,
615
-				),
616
-				'interval' => array(
617
-					'description' => __( 'Number of months/days in the report period.', 'invoicing' ),
618
-					'type'        => 'integer',
619
-					'context'     => array( 'view' ),
620
-					'readonly'    => true,
621
-				),
622
-				'previous_range'  => array(
623
-					'description' => __( 'The previous report period.', 'invoicing' ),
624
-					'type'        => 'array',
625
-					'items'       => array(
626
-						'type'    => 'string',
627
-					),
628
-					'context'     => array( 'view' ),
629
-					'readonly'    => true,
630
-				),
631
-				'grouped_by' => array(
632
-					'description' => __( 'The period used to group the totals.', 'invoicing' ),
633
-					'type'        => 'string',
634
-					'context'     => array( 'view' ),
635
-					'enum'        => array( 'day', 'month' ),
636
-					'readonly'    => true,
637
-				),
638
-				'currency' => array(
639
-					'description' => __( 'The default store currency.', 'invoicing' ),
640
-					'type'        => 'string',
641
-					'context'     => array( 'view' ),
642
-					'readonly'    => true,
643
-				),
644
-				'currency_symbol' => array(
645
-					'description' => __( 'The default store currency symbol.', 'invoicing' ),
646
-					'type'        => 'string',
647
-					'context'     => array( 'view' ),
648
-					'readonly'    => true,
649
-				),
650
-				'currency_position' => array(
651
-					'description' => __( 'The default store currency position.', 'invoicing' ),
652
-					'type'        => 'string',
653
-					'context'     => array( 'view' ),
654
-					'readonly'    => true,
655
-				),
656
-				'decimal_places' => array(
657
-					'description' => __( 'The default store decimal places.', 'invoicing' ),
658
-					'type'        => 'string',
659
-					'context'     => array( 'view' ),
660
-					'readonly'    => true,
661
-				),
662
-				'thousands_sep' => array(
663
-					'description' => __( 'The default store thousands separator.', 'invoicing' ),
664
-					'type'        => 'string',
665
-					'context'     => array( 'view' ),
666
-					'readonly'    => true,
667
-				),
668
-				'decimals_sep' => array(
669
-					'description' => __( 'The default store decimals separator.', 'invoicing' ),
670
-					'type'        => 'string',
671
-					'context'     => array( 'view' ),
672
-					'readonly'    => true,
673
-				),
674
-			),
675
-		);
676
-
677
-		return $this->add_additional_fields_schema( $schema );
678
-
679
-	}
21
+    /**
22
+     * Route base.
23
+     *
24
+     * @var string
25
+     */
26
+    protected $rest_base = 'reports/sales';
27
+
28
+    /**
29
+     * The report data.
30
+     *
31
+     * @var stdClass
32
+     */
33
+    protected $report_data;
34
+
35
+    /**
36
+     * The report range.
37
+     *
38
+     * @var array
39
+     */
40
+    protected $report_range;
41
+
42
+    /**
43
+     * Registers the routes for the objects of the controller.
44
+     *
45
+     * @since 2.0.0
46
+     *
47
+     * @see register_rest_route()
48
+     */
49
+    public function register_namespace_routes( $namespace ) {
50
+
51
+        // Get sales report.
52
+        register_rest_route(
53
+            $namespace,
54
+            $this->rest_base,
55
+            array(
56
+                array(
57
+                    'methods'             => WP_REST_Server::READABLE,
58
+                    'callback'            => array( $this, 'get_items' ),
59
+                    'permission_callback' => array( $this, 'get_items_permissions_check' ),
60
+                    'args'                => $this->get_collection_params(),
61
+                ),
62
+                'schema' => array( $this, 'get_public_item_schema' ),
63
+            )
64
+        );
65
+
66
+    }
67
+
68
+    /**
69
+     * Makes sure the current user has access to READ the report APIs.
70
+     *
71
+     * @since  2.0.0
72
+     * @param WP_REST_Request $request Full data about the request.
73
+     * @return WP_Error|boolean
74
+     */
75
+    public function get_items_permissions_check( $request ) {
76
+
77
+        if ( ! wpinv_current_user_can_manage_invoicing() ) {
78
+            return new WP_Error( 'rest_cannot_view', __( 'Sorry, you cannot list resources.', 'invoicing' ), array( 'status' => rest_authorization_required_code() ) );
79
+        }
80
+
81
+        return true;
82
+    }
83
+
84
+    /**
85
+     * Get sales reports.
86
+     *
87
+     * @param WP_REST_Request $request
88
+     * @return array|WP_Error
89
+     */
90
+    public function get_items( $request ) {
91
+        $data   = array();
92
+        $item   = $this->prepare_item_for_response( null, $request );
93
+        $data[] = $this->prepare_response_for_collection( $item );
94
+
95
+        return rest_ensure_response( $data );
96
+    }
97
+
98
+    /**
99
+     * Prepare a report sales object for serialization.
100
+     *
101
+     * @param null $_
102
+     * @param WP_REST_Request $request Request object.
103
+     * @return WP_REST_Response $response Response data.
104
+     */
105
+    public function prepare_item_for_response( $_, $request ) {
106
+
107
+        // Set report range.
108
+        $this->report_range = $this->get_date_range( $request );
109
+
110
+        $report_data     = $this->get_report_data();
111
+        $period_totals   = array();
112
+
113
+        // Setup period totals by ensuring each period in the interval has data.
114
+        $start_date      = strtotime( $this->report_range['after'] ) + DAY_IN_SECONDS;
115
+
116
+        if ( 'month' === $this->groupby ) {
117
+            $start_date      = strtotime( date( 'Y-m-01', $start_date ) );
118
+        }
119
+
120
+        for ( $i = 0; $i < $this->interval; $i++ ) {
121
+
122
+            switch ( $this->groupby ) {
123
+                case 'day' :
124
+                    $time = date( 'Y-m-d', strtotime( "+{$i} DAY", $start_date ) );
125
+                    break;
126
+                default :
127
+                    $time = date( 'Y-m', strtotime( "+{$i} MONTH", $start_date ) );
128
+                    break;
129
+            }
130
+
131
+            // Set the defaults for each period.
132
+            $period_totals[ $time ] = array(
133
+                'sales'             => wpinv_round_amount( 0.00 ),
134
+                'invoices'          => 0,
135
+                'refunds'           => wpinv_round_amount( 0.00 ),
136
+                'items'             => 0,
137
+                'refunded_items'    => 0,
138
+                'tax'               => wpinv_round_amount( 0.00 ),
139
+                'refunded_tax'      => wpinv_round_amount( 0.00 ),
140
+                'subtotal'          => wpinv_round_amount( 0.00 ),
141
+                'refunded_subtotal' => wpinv_round_amount( 0.00 ),
142
+                'fees'              => wpinv_round_amount( 0.00 ),
143
+                'refunded_fees'     => wpinv_round_amount( 0.00 ),
144
+                'discount'          => wpinv_round_amount( 0.00 ),
145
+            );
146
+
147
+        }
148
+
149
+        // add total sales, total invoice count, total tax for each period
150
+        $date_format = ( 'day' === $this->groupby ) ? 'Y-m-d' : 'Y-m';
151
+        foreach ( $report_data->invoices as $invoice ) {
152
+            $time = date( $date_format, strtotime( $invoice->post_date ) );
153
+
154
+            if ( ! isset( $period_totals[ $time ] ) ) {
155
+                continue;
156
+            }
157
+
158
+            $period_totals[ $time ]['sales']    = wpinv_round_amount( $invoice->total_sales );
159
+            $period_totals[ $time ]['tax']      = wpinv_round_amount( $invoice->total_tax );
160
+            $period_totals[ $time ]['subtotal'] = wpinv_round_amount( $invoice->subtotal );
161
+            $period_totals[ $time ]['fees']     = wpinv_round_amount( $invoice->total_fees );
162
+
163
+        }
164
+
165
+        foreach ( $report_data->refunds as $invoice ) {
166
+            $time = date( $date_format, strtotime( $invoice->post_date ) );
167
+
168
+            if ( ! isset( $period_totals[ $time ] ) ) {
169
+                continue;
170
+            }
171
+
172
+            $period_totals[ $time ]['refunds']           = wpinv_round_amount( $invoice->total_sales );
173
+            $period_totals[ $time ]['refunded_tax']      = wpinv_round_amount( $invoice->total_tax );
174
+            $period_totals[ $time ]['refunded_subtotal'] = wpinv_round_amount( $invoice->subtotal );
175
+            $period_totals[ $time ]['refunded_fees']     = wpinv_round_amount( $invoice->total_fees );
176
+
177
+        }
178
+
179
+        foreach ( $report_data->invoice_counts as $invoice ) {
180
+            $time = date( $date_format, strtotime( $invoice->post_date ) );
181
+
182
+            if ( isset( $period_totals[ $time ] ) ) {
183
+                $period_totals[ $time ]['invoices']   = (int) $invoice->count;
184
+            }
185
+
186
+        }
187
+
188
+        // Add total invoice items for each period.
189
+        foreach ( $report_data->invoice_items as $invoice_item ) {
190
+            $time = ( 'day' === $this->groupby ) ? date( 'Y-m-d', strtotime( $invoice_item->post_date ) ) : date( 'Y-m', strtotime( $invoice_item->post_date ) );
191
+
192
+            if ( isset( $period_totals[ $time ] ) ) {
193
+                $period_totals[ $time ]['items'] = (int) $invoice_item->invoice_item_count;
194
+            }
195
+
196
+        }
197
+
198
+        // Add total discount for each period.
199
+        foreach ( $report_data->coupons as $discount ) {
200
+            $time = ( 'day' === $this->groupby ) ? date( 'Y-m-d', strtotime( $discount->post_date ) ) : date( 'Y-m', strtotime( $discount->post_date ) );
201
+
202
+            if ( isset( $period_totals[ $time ] ) ) {
203
+                $period_totals[ $time ]['discount'] = wpinv_round_amount( $discount->discount_amount );
204
+            }
205
+
206
+        }
207
+
208
+        $report_data->totals            = $period_totals;
209
+        $report_data->grouped_by        = $this->groupby;
210
+        $report_data->interval          = max( $this->interval, 1 );
211
+        $report_data->currency          = wpinv_get_currency();
212
+        $report_data->currency_symbol   = wpinv_currency_symbol();
213
+        $report_data->currency_position = wpinv_currency_position();
214
+        $report_data->decimal_places    = wpinv_decimals();
215
+        $report_data->thousands_sep     = wpinv_thousands_separator();
216
+        $report_data->decimals_sep      = wpinv_decimal_separator();
217
+        $report_data->start_date        = date( 'Y-m-d', strtotime( $this->report_range['after'] ) + DAY_IN_SECONDS );
218
+        $report_data->end_date          = date( 'Y-m-d', strtotime( $this->report_range['before'] ) - DAY_IN_SECONDS );
219
+        $report_data->start_date_locale = getpaid_format_date( date( 'Y-m-d', strtotime( $this->report_range['after'] ) + DAY_IN_SECONDS ) );
220
+        $report_data->end_date_locale   = getpaid_format_date( date( 'Y-m-d', strtotime( $this->report_range['before'] ) - DAY_IN_SECONDS ) );
221
+        $report_data->decimals_sep      = wpinv_decimal_separator();
222
+
223
+        $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
224
+        $data    = $report_data;
225
+        unset( $data->invoice_counts, $data->invoices, $data->coupons, $data->refunds, $data->invoice_items );
226
+        $data    = $this->add_additional_fields_to_object( (array) $data, $request );
227
+        $data    = $this->filter_response_by_context( $data, $context );
228
+
229
+        // Wrap the data in a response object.
230
+        $response = rest_ensure_response( $data );
231
+        $response->add_links( array(
232
+            'about' => array(
233
+                'href' => rest_url( sprintf( '%s/reports', $this->namespace ) ),
234
+            ),
235
+        ) );
236
+
237
+        return apply_filters( 'getpaid_rest_prepare_report_sales', $response, $report_data, $request );
238
+    }
239
+
240
+    /**
241
+     * Get report data.
242
+     *
243
+     * @return stdClass
244
+     */
245
+    public function get_report_data() {
246
+        if ( empty( $this->report_data ) ) {
247
+            $this->query_report_data();
248
+        }
249
+        return $this->report_data;
250
+    }
251
+
252
+    /**
253
+     * Get all data needed for this report and store in the class.
254
+     */
255
+    protected function query_report_data() {
256
+
257
+        // Prepare reports.
258
+        $this->report_data = (object) array(
259
+            'invoice_counts' => $this->query_invoice_counts(),//count, post_date
260
+            'coupons'        => $this->query_coupon_counts(), // discount_amount, post_date
261
+            'invoice_items'  => $this->query_item_counts(), // invoice_item_count, post_date
262
+            'refunded_items' => $this->count_refunded_items(), // invoice_item_count, post_date
263
+            'invoices'       => $this->query_invoice_totals(), // total_sales, total_tax, total_discount, total_fees, subtotal, post_date
264
+            'refunds'        => $this->query_refunded_totals(), // total_sales, total_tax, total_discount, total_fees, subtotal, post_date
265
+            'previous_range' => $this->previous_range,
266
+        );
267
+
268
+        // Calculated totals.
269
+        $this->report_data->total_tax          = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->invoices, 'total_tax' ) ) );
270
+        $this->report_data->total_sales        = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->invoices, 'total_sales' ) ) );
271
+        $this->report_data->total_discount     = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->invoices, 'total_discount' ) ) );
272
+        $this->report_data->total_fees         = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->invoices, 'total_fees' ) ) );
273
+        $this->report_data->subtotal           = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->invoices, 'subtotal' ) ) );
274
+        $this->report_data->net_sales          = wpinv_round_amount( $this->report_data->total_sales - max( 0, $this->report_data->total_tax ) );
275
+        $this->report_data->total_refunded_tax = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->refunds, 'total_tax' ) ) );
276
+        $this->report_data->total_refunds      = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->refunds, 'total_sales' ) ) );
277
+        $this->report_data->refunded_discount  = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->refunds, 'total_discount' ) ) );
278
+        $this->report_data->refunded_fees      = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->refunds, 'total_fees' ) ) );
279
+        $this->report_data->refunded_subtotal  = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->refunds, 'subtotal' ) ) );
280
+        $this->report_data->net_refunds        = wpinv_round_amount( $this->report_data->total_refunds + max( 0, $this->report_data->total_refunded_tax ) );
281
+
282
+
283
+        // Calculate average based on net.
284
+        $this->report_data->average_sales       = wpinv_round_amount( $this->report_data->net_sales / max( $this->interval, 1 ), 2 );
285
+        $this->report_data->average_total_sales = wpinv_round_amount( $this->report_data->total_sales / max( $this->interval, 1 ), 2 );
286
+
287
+        // Total invoices in this period, even if refunded.
288
+        $this->report_data->total_invoices = absint( array_sum( wp_list_pluck( $this->report_data->invoice_counts, 'count' ) ) );
289
+
290
+        // Items invoiced in this period, even if refunded.
291
+        $this->report_data->total_items = absint( array_sum( wp_list_pluck( $this->report_data->invoice_items, 'invoice_item_count' ) ) );
292
+
293
+        // 3rd party filtering of report data
294
+        $this->report_data = apply_filters( 'getpaid_rest_api_filter_report_data', $this->report_data );
295
+    }
296
+
297
+    /**
298
+     * Prepares invoice counts.
299
+     *
300
+     * @return array.
301
+     */
302
+    protected function query_invoice_counts() {
303
+
304
+        return (array) GetPaid_Reports_Helper::get_invoice_report_data(
305
+            array(
306
+                'data'         => array(
307
+                    'ID'        => array(
308
+                        'type'     => 'post_data',
309
+                        'function' => 'COUNT',
310
+                        'name'     => 'count',
311
+                        'distinct' => true,
312
+                    ),
313
+                    'post_date' => array(
314
+                        'type'     => 'post_data',
315
+                        'function' => '',
316
+                        'name'     => 'post_date',
317
+                    ),
318
+                ),
319
+                'group_by'       => $this->get_group_by_sql( 'posts.post_date' ),
320
+                'order_by'       => 'post_date ASC',
321
+                'query_type'     => 'get_results',
322
+                'filter_range'   => $this->report_range,
323
+                'invoice_status' => array( 'publish', 'wpi-processing', 'wpi-onhold', 'wpi-refunded', 'wpi-renewal' ),
324
+            )
325
+        );
326
+
327
+    }
328
+
329
+    /**
330
+     * Prepares coupon counts.
331
+     *
332
+     * @return array.
333
+     */
334
+    protected function query_coupon_counts() {
335
+
336
+        return (array) GetPaid_Reports_Helper::get_invoice_report_data(
337
+            array(
338
+                'data'         => array(
339
+                    'discount' => array(
340
+                        'type'     => 'invoice_data',
341
+                        'function' => 'SUM',
342
+                        'name'     => 'discount_amount',
343
+                    ),
344
+                    'post_date'       => array(
345
+                        'type'     => 'post_data',
346
+                        'function' => '',
347
+                        'name'     => 'post_date',
348
+                    ),
349
+                ),
350
+                'group_by'       => $this->get_group_by_sql( 'posts.post_date' ),
351
+                'order_by'       => 'post_date ASC',
352
+                'query_type'     => 'get_results',
353
+                'filter_range'   => $this->report_range,
354
+                'invoice_status' => array( 'publish', 'wpi-processing', 'wpi-onhold', 'wpi-refunded', 'wpi-renewal' ),
355
+            )
356
+        );
357
+
358
+    }
359
+
360
+    /**
361
+     * Prepares item counts.
362
+     *
363
+     * @return array.
364
+     */
365
+    protected function query_item_counts() {
366
+
367
+        return (array) GetPaid_Reports_Helper::get_invoice_report_data(
368
+            array(
369
+                'data'         => array(
370
+                    'quantity'      => array(
371
+                        'type'            => 'invoice_item',
372
+                        'function'        => 'SUM',
373
+                        'name'            => 'invoice_item_count',
374
+                    ),
375
+                    'post_date' => array(
376
+                        'type'     => 'post_data',
377
+                        'function' => '',
378
+                        'name'     => 'post_date',
379
+                    ),
380
+                ),
381
+                'group_by'       => $this->get_group_by_sql( 'posts.post_date' ),
382
+                'order_by'       => 'post_date ASC',
383
+                'query_type'     => 'get_results',
384
+                'filter_range'   => $this->report_range,
385
+                'invoice_status' => array( 'publish', 'wpi-processing', 'wpi-onhold', 'wpi-refunded', 'wpi-renewal' ),
386
+            )
387
+        );
388
+
389
+    }
390
+
391
+    /**
392
+     * Prepares refunded item counts.
393
+     *
394
+     * @return array.
395
+     */
396
+    protected function count_refunded_items() {
397
+
398
+        return (int) GetPaid_Reports_Helper::get_invoice_report_data(
399
+            array(
400
+                'data'         => array(
401
+                    'quantity'      => array(
402
+                        'type'            => 'invoice_item',
403
+                        'function'        => 'SUM',
404
+                        'name'            => 'invoice_item_count',
405
+                    ),
406
+                ),
407
+                'query_type'     => 'get_var',
408
+                'filter_range'   => $this->report_range,
409
+                'invoice_status' => array( 'wpi-refunded' ),
410
+            )
411
+        );
412
+
413
+    }
414
+
415
+    /**
416
+     * Prepares daily invoice totals.
417
+     *
418
+     * @return array.
419
+     */
420
+    protected function query_invoice_totals() {
421
+
422
+        return (array) GetPaid_Reports_Helper::get_invoice_report_data(
423
+            array(
424
+                'data'         => array(
425
+                    'total'      => array(
426
+                        'type'            => 'invoice_data',
427
+                        'function'        => 'SUM',
428
+                        'name'            => 'total_sales',
429
+                    ),
430
+                    'tax'      => array(
431
+                        'type'            => 'invoice_data',
432
+                        'function'        => 'SUM',
433
+                        'name'            => 'total_tax',
434
+                    ),
435
+                    'discount'      => array(
436
+                        'type'            => 'invoice_data',
437
+                        'function'        => 'SUM',
438
+                        'name'            => 'total_discount',
439
+                    ),
440
+                    'fees_total'      => array(
441
+                        'type'            => 'invoice_data',
442
+                        'function'        => 'SUM',
443
+                        'name'            => 'total_fees',
444
+                    ),
445
+                    'subtotal'      => array(
446
+                        'type'            => 'invoice_data',
447
+                        'function'        => 'SUM',
448
+                        'name'            => 'subtotal',
449
+                    ),
450
+                    'post_date' => array(
451
+                        'type'     => 'post_data',
452
+                        'function' => '',
453
+                        'name'     => 'post_date',
454
+                    ),
455
+                ),
456
+                'group_by'       => $this->get_group_by_sql( 'posts.post_date' ),
457
+                'order_by'       => 'post_date ASC',
458
+                'query_type'     => 'get_results',
459
+                'filter_range'   => $this->report_range,
460
+                'invoice_status' => array( 'publish', 'wpi-processing', 'wpi-onhold', 'wpi-renewal' ),
461
+            )
462
+        );
463
+
464
+    }
465
+
466
+    /**
467
+     * Prepares daily invoice totals.
468
+     *
469
+     * @return array.
470
+     */
471
+    protected function query_refunded_totals() {
472
+
473
+        return (array) GetPaid_Reports_Helper::get_invoice_report_data(
474
+            array(
475
+                'data'         => array(
476
+                    'total'      => array(
477
+                        'type'            => 'invoice_data',
478
+                        'function'        => 'SUM',
479
+                        'name'            => 'total_sales',
480
+                    ),
481
+                    'tax'      => array(
482
+                        'type'            => 'invoice_data',
483
+                        'function'        => 'SUM',
484
+                        'name'            => 'total_tax',
485
+                    ),
486
+                    'discount'      => array(
487
+                        'type'            => 'invoice_data',
488
+                        'function'        => 'SUM',
489
+                        'name'            => 'total_discount',
490
+                    ),
491
+                    'fees_total'      => array(
492
+                        'type'            => 'invoice_data',
493
+                        'function'        => 'SUM',
494
+                        'name'            => 'total_fees',
495
+                    ),
496
+                    'subtotal'      => array(
497
+                        'type'            => 'invoice_data',
498
+                        'function'        => 'SUM',
499
+                        'name'            => 'subtotal',
500
+                    ),
501
+                    'post_date' => array(
502
+                        'type'     => 'post_data',
503
+                        'function' => '',
504
+                        'name'     => 'post_date',
505
+                    ),
506
+                ),
507
+                'group_by'       => $this->get_group_by_sql( 'posts.post_date' ),
508
+                'order_by'       => 'post_date ASC',
509
+                'query_type'     => 'get_results',
510
+                'filter_range'   => $this->report_range,
511
+                'invoice_status' => array( 'wpi-refunded' ),
512
+            )
513
+        );
514
+
515
+    }
516
+
517
+    /**
518
+     * Get the Report's schema, conforming to JSON Schema.
519
+     *
520
+     * @return array
521
+     */
522
+    public function get_item_schema() {
523
+
524
+        $schema = array(
525
+            '$schema'    => 'http://json-schema.org/draft-04/schema#',
526
+            'title'      => 'sales_report',
527
+            'type'       => 'object',
528
+            'properties' => array(
529
+                'total_sales' => array(
530
+                    'description' => __( 'Gross sales in the period.', 'invoicing' ),
531
+                    'type'        => 'string',
532
+                    'context'     => array( 'view' ),
533
+                    'readonly'    => true,
534
+                ),
535
+                'net_sales' => array(
536
+                    'description' => __( 'Net sales in the period.', 'invoicing' ),
537
+                    'type'        => 'string',
538
+                    'context'     => array( 'view' ),
539
+                    'readonly'    => true,
540
+                ),
541
+                'average_sales' => array(
542
+                    'description' => __( 'Average net daily sales.', 'invoicing' ),
543
+                    'type'        => 'string',
544
+                    'context'     => array( 'view' ),
545
+                    'readonly'    => true,
546
+                ),
547
+                'average_total_sales' => array(
548
+                    'description' => __( 'Average gross daily sales.', 'invoicing' ),
549
+                    'type'        => 'string',
550
+                    'context'     => array( 'view' ),
551
+                    'readonly'    => true,
552
+                ),
553
+                'total_invoices'  => array(
554
+                    'description' => __( 'Number of paid invoices.', 'invoicing' ),
555
+                    'type'        => 'integer',
556
+                    'context'     => array( 'view' ),
557
+                    'readonly'    => true,
558
+                ),
559
+                'total_items' => array(
560
+                    'description' => __( 'Number of items purchased.', 'invoicing' ),
561
+                    'type'        => 'integer',
562
+                    'context'     => array( 'view' ),
563
+                    'readonly'    => true,
564
+                ),
565
+                'refunded_items' => array(
566
+                    'description' => __( 'Number of items refunded.', 'invoicing' ),
567
+                    'type'        => 'integer',
568
+                    'context'     => array( 'view' ),
569
+                    'readonly'    => true,
570
+                ),
571
+                'total_tax' => array(
572
+                    'description' => __( 'Total charged for taxes.', 'invoicing' ),
573
+                    'type'        => 'string',
574
+                    'context'     => array( 'view' ),
575
+                    'readonly'    => true,
576
+                ),
577
+                'total_refunded_tax' => array(
578
+                    'description' => __( 'Total refunded for taxes.', 'invoicing' ),
579
+                    'type'        => 'string',
580
+                    'context'     => array( 'view' ),
581
+                    'readonly'    => true,
582
+                ),
583
+                'total_fees' => array(
584
+                    'description' => __( 'Total fees charged.', 'invoicing' ),
585
+                    'type'        => 'string',
586
+                    'context'     => array( 'view' ),
587
+                    'readonly'    => true,
588
+                ),
589
+                'total_refunds' => array(
590
+                    'description' => __( 'Total of refunded invoices.', 'invoicing' ),
591
+                    'type'        => 'integer',
592
+                    'context'     => array( 'view' ),
593
+                    'readonly'    => true,
594
+                ),
595
+                'net_refunds' => array(
596
+                    'description' => __( 'Net of refunded invoices.', 'invoicing' ),
597
+                    'type'        => 'integer',
598
+                    'context'     => array( 'view' ),
599
+                    'readonly'    => true,
600
+                ),
601
+                'total_discount' => array(
602
+                    'description' => __( 'Total of discounts used.', 'invoicing' ),
603
+                    'type'        => 'integer',
604
+                    'context'     => array( 'view' ),
605
+                    'readonly'    => true,
606
+                ),
607
+                'totals' => array(
608
+                    'description' => __( 'Totals.', 'invoicing' ),
609
+                    'type'        => 'array',
610
+                    'items'       => array(
611
+                        'type'    => 'array',
612
+                    ),
613
+                    'context'     => array( 'view' ),
614
+                    'readonly'    => true,
615
+                ),
616
+                'interval' => array(
617
+                    'description' => __( 'Number of months/days in the report period.', 'invoicing' ),
618
+                    'type'        => 'integer',
619
+                    'context'     => array( 'view' ),
620
+                    'readonly'    => true,
621
+                ),
622
+                'previous_range'  => array(
623
+                    'description' => __( 'The previous report period.', 'invoicing' ),
624
+                    'type'        => 'array',
625
+                    'items'       => array(
626
+                        'type'    => 'string',
627
+                    ),
628
+                    'context'     => array( 'view' ),
629
+                    'readonly'    => true,
630
+                ),
631
+                'grouped_by' => array(
632
+                    'description' => __( 'The period used to group the totals.', 'invoicing' ),
633
+                    'type'        => 'string',
634
+                    'context'     => array( 'view' ),
635
+                    'enum'        => array( 'day', 'month' ),
636
+                    'readonly'    => true,
637
+                ),
638
+                'currency' => array(
639
+                    'description' => __( 'The default store currency.', 'invoicing' ),
640
+                    'type'        => 'string',
641
+                    'context'     => array( 'view' ),
642
+                    'readonly'    => true,
643
+                ),
644
+                'currency_symbol' => array(
645
+                    'description' => __( 'The default store currency symbol.', 'invoicing' ),
646
+                    'type'        => 'string',
647
+                    'context'     => array( 'view' ),
648
+                    'readonly'    => true,
649
+                ),
650
+                'currency_position' => array(
651
+                    'description' => __( 'The default store currency position.', 'invoicing' ),
652
+                    'type'        => 'string',
653
+                    'context'     => array( 'view' ),
654
+                    'readonly'    => true,
655
+                ),
656
+                'decimal_places' => array(
657
+                    'description' => __( 'The default store decimal places.', 'invoicing' ),
658
+                    'type'        => 'string',
659
+                    'context'     => array( 'view' ),
660
+                    'readonly'    => true,
661
+                ),
662
+                'thousands_sep' => array(
663
+                    'description' => __( 'The default store thousands separator.', 'invoicing' ),
664
+                    'type'        => 'string',
665
+                    'context'     => array( 'view' ),
666
+                    'readonly'    => true,
667
+                ),
668
+                'decimals_sep' => array(
669
+                    'description' => __( 'The default store decimals separator.', 'invoicing' ),
670
+                    'type'        => 'string',
671
+                    'context'     => array( 'view' ),
672
+                    'readonly'    => true,
673
+                ),
674
+            ),
675
+        );
676
+
677
+        return $this->add_additional_fields_schema( $schema );
678
+
679
+    }
680 680
 
681 681
 }
Please login to merge, or discard this patch.
includes/api/class-getpaid-rest-date-based-controller.php 1 patch
Indentation   +573 added lines, -573 removed lines patch added patch discarded remove patch
@@ -16,577 +16,577 @@
 block discarded – undo
16 16
  */
17 17
 class GetPaid_REST_Date_Based_Controller extends GetPaid_REST_Controller {
18 18
 
19
-	/**
20
-	 * Group response items by day or month.
21
-	 *
22
-	 * @var string
23
-	 */
24
-	public $groupby = 'day';
25
-
26
-	/**
27
-	 * Returns an array with arguments to request the previous report.
28
-	 *
29
-	 * @var array
30
-	 */
31
-	public $previous_range = array();
32
-
33
-	/**
34
-	 * The period interval.
35
-	 *
36
-	 * @var int
37
-	 */
38
-	public $interval;
39
-
40
-	/**
41
-	 * Retrieves the before and after dates.
42
-	 *
43
-	 * @param WP_REST_Request $request Request object.
44
-	 * @return array The appropriate date range.
45
-	 */
46
-	public function get_date_range( $request ) {
47
-
48
-		// If not supported, assume all time.
49
-		if ( ! in_array( $request['period'], array( 'custom', 'today', 'yesterday', 'week', 'last_week', '7_days', '30_days', '60_days', '90_days', '180_days', 'month', 'last_month', 'quarter', 'last_quarter', 'year', 'last_year' ) ) ) {
50
-			$request['period'] = '7_days';
51
-		}
52
-
53
-		$date_range = call_user_func( array( $this, 'get_' . $request['period'] . '_date_range' ), $request );
54
-		$this->prepare_interval( $date_range );
55
-
56
-		return $date_range;
57
-
58
-	}
59
-
60
-	/**
61
-	 * Groups by month or days.
62
-	 *
63
-	 * @param array $range Date range.
64
-	 * @return array The appropriate date range.
65
-	 */
66
-	public function prepare_interval( $range ) {
67
-
68
-		$before = strtotime( $range['before'] ) - DAY_IN_SECONDS;
69
-		$after  = strtotime( $range['after'] ) + DAY_IN_SECONDS;
70
-		if ( 'day' === $this->groupby ) {
71
-			$difference     = max( DAY_IN_SECONDS, ( DAY_IN_SECONDS + $before - $after ) ); // Prevent division by 0;
72
-			$this->interval = absint( ceil( max( 1, $difference / DAY_IN_SECONDS ) ) );
73
-			return;
74
-		}
75
-
76
-		$this->interval = 0;
77
-		$min_date       = strtotime( date( 'Y-m-01', $after ) );
78
-
79
-		while ( $min_date <= $before ) {
80
-			$this->interval ++;
81
-			$min_date = strtotime( '+1 MONTH', $min_date );
82
-		}
83
-
84
-		$this->interval = max( 1, $this->interval );
85
-
86
-	}
87
-
88
-	/**
89
-	 * Retrieves a custom date range.
90
-	 *
91
-	 * @param WP_REST_Request $request Request object.
92
-	 * @return array The appropriate date range.
93
-	 */
94
-	public function get_custom_date_range( $request ) {
95
-
96
-		$after  = max( strtotime( '-20 years' ), strtotime( sanitize_text_field( $request['after'] ) ) );
97
-		$before = strtotime( '+1 day', current_time( 'timestamp' ) );
98
-
99
-		if ( ! empty( $request['before'] ) ) {
100
-			$before  = min( $before, strtotime( sanitize_text_field( $request['before'] ) ) );
101
-		}
102
-
103
-		// 3 months max for day view
104
-		if ( floor( ( $before - $after ) / MONTH_IN_SECONDS ) > 3 ) {
105
-			$this->groupby = 'month';
106
-		}
107
-
108
-		// Set the previous date range.
109
-		$difference           = $before - $after;
110
-		$this->previous_range = array(
111
-			'period' => 'custom',
112
-			'before' => date( 'Y-m-d', $before - $difference ),
113
-			'after'  => date( 'Y-m-d', $after - $difference ),
114
-		);
115
-
116
-		// Generate the report.
117
-		return array(
118
-			'before' => date( 'Y-m-d', $before ),
119
-			'after' => date( 'Y-m-d', $after ),
120
-		);
121
-
122
-	}
123
-
124
-	/**
125
-	 * Retrieves todays date range.
126
-	 *
127
-	 * @return array The appropriate date range.
128
-	 */
129
-	public function get_today_date_range() {
130
-
131
-		// Set the previous date range.
132
-		$this->previous_range = array(
133
-			'period' => 'yesterday',
134
-		);
135
-
136
-		// Generate the report.
137
-		return array(
138
-			'before' => date( 'Y-m-d', strtotime( '+1 day', current_time( 'timestamp' ) ) ),
139
-			'after'  => date( 'Y-m-d', strtotime( '-1 day', current_time( 'timestamp' ) ) ),
140
-		);
141
-
142
-	}
143
-
144
-	/**
145
-	 * Retrieves yesterdays date range.
146
-	 *
147
-	 * @return array The appropriate date range.
148
-	 */
149
-	public function get_yesterday_date_range() {
150
-
151
-		// Set the previous date range.
152
-		$this->previous_range = array(
153
-			'period' => 'custom',
154
-			'before' => date( 'Y-m-d', strtotime( '-1 day', current_time( 'timestamp' ) ) ),
155
-			'after'  => date( 'Y-m-d', strtotime( '-3 days', current_time( 'timestamp' ) ) ),
156
-		);
157
-
158
-		// Generate the report.
159
-		return array(
160
-			'before' => date( 'Y-m-d', current_time( 'timestamp' ) ),
161
-			'after'  => date( 'Y-m-d', strtotime( '-2 days', current_time( 'timestamp' ) ) ),
162
-		);
163
-
164
-	}
165
-
166
-	/**
167
-	 * Retrieves this week's date range.
168
-	 *
169
-	 * @return array The appropriate date range.
170
-	 */
171
-	public function get_week_date_range() {
172
-
173
-		// Set the previous date range.
174
-		$this->previous_range = array(
175
-			'period' => 'last_week',
176
-		);
177
-
178
-		// Generate the report.
179
-		return array(
180
-			'before' => date( 'Y-m-d', strtotime( 'sunday last week', current_time( 'timestamp' )  ) + 8 * DAY_IN_SECONDS ),
181
-			'after'  => date( 'Y-m-d', strtotime( 'sunday last week', current_time( 'timestamp' )  ) ),
182
-		);
183
-
184
-	}
185
-
186
-	/**
187
-	 * Retrieves last week's date range.
188
-	 *
189
-	 * @return array The appropriate date range.
190
-	 */
191
-	public function get_last_week_date_range() {
192
-
193
-		// Set the previous date range.
194
-		$this->previous_range = array(
195
-			'period' => 'custom',
196
-			'before' => date( 'Y-m-d', strtotime( 'monday last week', current_time( 'timestamp' )  ) ),
197
-			'after'  => date( 'Y-m-d', strtotime( 'monday last week', current_time( 'timestamp' )  ) - 8 * DAY_IN_SECONDS ),
198
-		);
199
-
200
-		// Generate the report.
201
-		return array(
202
-			'before' => date( 'Y-m-d', strtotime( 'monday this week', current_time( 'timestamp' )  ) ),
203
-			'after'  => date( 'Y-m-d', strtotime( 'monday last week', current_time( 'timestamp' )  ) - DAY_IN_SECONDS ),
204
-		);
205
-
206
-	}
207
-
208
-	/**
209
-	 * Retrieves last 7 days date range.
210
-	 *
211
-	 * @return array The appropriate date range.
212
-	 */
213
-	public function get_7_days_date_range() {
214
-
215
-		// Set the previous date range.
216
-		$this->previous_range = array(
217
-			'period' => 'custom',
218
-			'before' => date( 'Y-m-d', strtotime( '-7 days', current_time( 'timestamp' ) ) ),
219
-			'after'  => date( 'Y-m-d', strtotime( '-15 days', current_time( 'timestamp' ) ) ),
220
-		);
221
-
222
-		// Generate the report.
223
-		return array(
224
-			'before' => date( 'Y-m-d', current_time( 'timestamp' ) ),
225
-			'after'  => date( 'Y-m-d', strtotime( '-8 days', current_time( 'timestamp' ) ) ),
226
-		);
227
-
228
-	}
229
-
230
-	/**
231
-	 * Retrieves last 30 days date range.
232
-	 *
233
-	 * @return array The appropriate date range.
234
-	 */
235
-	public function get_30_days_date_range() {
236
-
237
-		// Set the previous date range.
238
-		$this->previous_range = array(
239
-			'period' => 'custom',
240
-			'before' => date( 'Y-m-d', strtotime( '-30 days', current_time( 'timestamp' ) ) ),
241
-			'after'  => date( 'Y-m-d', strtotime( '-61 days', current_time( 'timestamp' ) ) ),
242
-		);
243
-
244
-		// Generate the report.
245
-		return array(
246
-			'before' => date( 'Y-m-d', current_time( 'timestamp' ) ),
247
-			'after'  => date( 'Y-m-d', strtotime( '-31 days', current_time( 'timestamp' ) ) ),
248
-		);
249
-
250
-	}
251
-
252
-	/**
253
-	 * Retrieves last 90 days date range.
254
-	 *
255
-	 * @return array The appropriate date range.
256
-	 */
257
-	public function get_90_days_date_range() {
258
-
259
-		$this->groupby = 'month';
260
-
261
-		// Set the previous date range.
262
-		$this->previous_range = array(
263
-			'period' => 'custom',
264
-			'before' => date( 'Y-m-d', strtotime( '-90 days', current_time( 'timestamp' ) ) ),
265
-			'after'  => date( 'Y-m-d', strtotime( '-181 days', current_time( 'timestamp' ) ) ),
266
-		);
267
-
268
-		// Generate the report.
269
-		return array(
270
-			'before' => date( 'Y-m-d', current_time( 'timestamp' ) ),
271
-			'after'  => date( 'Y-m-d', strtotime( '-91 days', current_time( 'timestamp' ) ) ),
272
-		);
273
-
274
-	}
275
-
276
-	/**
277
-	 * Retrieves last 180 days date range.
278
-	 *
279
-	 * @return array The appropriate date range.
280
-	 */
281
-	public function get_180_days_date_range() {
282
-
283
-		$this->groupby = 'month';
284
-
285
-		// Set the previous date range.
286
-		$this->previous_range = array(
287
-			'period' => 'custom',
288
-			'before' => date( 'Y-m-d', strtotime( '-180 days', current_time( 'timestamp' ) ) ),
289
-			'after'  => date( 'Y-m-d', strtotime( '-361 days', current_time( 'timestamp' ) ) ),
290
-		);
291
-
292
-		// Generate the report.
293
-		return array(
294
-			'before' => date( 'Y-m-d', current_time( 'timestamp' ) ),
295
-			'after'  => date( 'Y-m-d', strtotime( '-181 days', current_time( 'timestamp' ) ) ),
296
-		);
297
-
298
-	}
299
-
300
-	/**
301
-	 * Retrieves last 60 days date range.
302
-	 *
303
-	 * @return array The appropriate date range.
304
-	 */
305
-	public function get_60_days_date_range() {
306
-
307
-		// Set the previous date range.
308
-		$this->previous_range = array(
309
-			'period' => 'custom',
310
-			'before' => date( 'Y-m-d', strtotime( '-60 days', current_time( 'timestamp' ) ) ),
311
-			'after'  => date( 'Y-m-d', strtotime( '-121 days', current_time( 'timestamp' ) ) ),
312
-		);
313
-
314
-		// Generate the report.
315
-		return array(
316
-			'before' => date( 'Y-m-d', current_time( 'timestamp' ) ),
317
-			'after'  => date( 'Y-m-d', strtotime( '-61 days', current_time( 'timestamp' ) ) ),
318
-		);
319
-
320
-	}
321
-
322
-	/**
323
-	 * Retrieves this month date range.
324
-	 *
325
-	 * @return array The appropriate date range.
326
-	 */
327
-	public function get_month_date_range() {
328
-
329
-		// Set the previous date range.
330
-		$this->previous_range = array(
331
-			'period' => 'last_month',
332
-		);
333
-
334
-		// Generate the report.
335
-		return array(
336
-			'before' => date( 'Y-m-01', strtotime( 'next month', current_time( 'timestamp' ) ) ),
337
-			'after'  => date( 'Y-m-t', strtotime( 'last month', current_time( 'timestamp' ) ) ),
338
-		);
339
-
340
-	}
341
-
342
-	/**
343
-	 * Retrieves last month's date range.
344
-	 *
345
-	 * @return array The appropriate date range.
346
-	 */
347
-	public function get_last_month_date_range() {
348
-
349
-		// Set the previous date range.
350
-		$this->previous_range = array(
351
-			'period' => 'custom',
352
-			'before' => date( 'Y-m-1', strtotime( 'last month', current_time( 'timestamp' ) ) ),
353
-			'after'  => date( 'Y-m-t', strtotime( "-3 months", current_time( 'timestamp' ) ) ),
354
-		);
355
-
356
-		// Generate the report.
357
-		return array(
358
-			'before' => date( 'Y-m-1', current_time( 'timestamp' ) ),
359
-			'after'  => date( 'Y-m-t', strtotime( "-2 months", current_time( 'timestamp' ) ) ),
360
-		);
361
-
362
-	}
363
-
364
-	/**
365
-	 * Retrieves this quarter date range.
366
-	 *
367
-	 * @return array The available quarters.
368
-	 */
369
-	public function get_quarters() {
370
-
371
-		$last_year = (int) date('Y') - 1;
372
-		$next_year = (int) date('Y') + 1;
373
-		$year      = (int) date('Y');
374
-		return array(
375
-
376
-			array(
377
-				'after'  => "$last_year-06-30",
378
-				'before' => "$last_year-10-01",
379
-			),
380
-
381
-			array(
382
-				'before' => "$year-01-01",
383
-				'after'  => "$last_year-09-30",
384
-			),
385
-
386
-			array(
387
-				'before' => "$year-04-01",
388
-				'after'  => "$last_year-12-31",
389
-			),
390
-
391
-			array(
392
-				'before' => "$year-07-01",
393
-				'after'  => "$year-03-31",
394
-			),
395
-
396
-			array(
397
-				'after'  => "$year-06-30",
398
-				'before' => "$year-10-01",
399
-			),
400
-
401
-			array(
402
-				'before' => "$next_year-01-01",
403
-				'after'  => "$year-09-30",
404
-			)
405
-
406
-		);
407
-
408
-	}
409
-
410
-	/**
411
-	 * Retrieves the current quater.
412
-	 *
413
-	 * @return int The current quarter.
414
-	 */
415
-	public function get_quarter() {
416
-
417
-		$month    = (int) date( 'n', current_time( 'timestamp' ) );
418
-		$quarters = array( 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4 );
419
-		return $quarters[ $month - 1 ];
420
-
421
-	}
422
-
423
-	/**
424
-	 * Retrieves this quarter date range.
425
-	 *
426
-	 * @return array The appropriate date range.
427
-	 */
428
-	public function get_quarter_date_range() {
429
-
430
-		// Set the previous date range.
431
-		$this->previous_range = array(
432
-			'period' => 'last_quarter',
433
-		);
434
-
435
-		// Generate the report.
436
-		$quarters = $this->get_quarters();
437
-		return $quarters[ $this->get_quarter() + 1 ];
438
-
439
-	}
440
-
441
-	/**
442
-	 * Retrieves last quarter's date range.
443
-	 *
444
-	 * @return array The appropriate date range.
445
-	 */
446
-	public function get_last_quarter_date_range() {
447
-
448
-		$quarters = $this->get_quarters();
449
-		$quarter  = $this->get_quarter();
450
-
451
-		// Set the previous date range.
452
-		$this->previous_range = array_merge(
453
-			$quarters[ $quarter - 1 ],
454
-			array( 'period' => 'custom' )
455
-		);
456
-
457
-		// Generate the report.
458
-		return $quarters[ $quarter ];
459
-
460
-	}
461
-
462
-	/**
463
-	 * Retrieves this year date range.
464
-	 *
465
-	 * @return array The appropriate date range.
466
-	 */
467
-	public function get_year_date_range() {
468
-
469
-		$this->groupby = 'month';
470
-
471
-		// Set the previous date range.
472
-		$this->previous_range = array(
473
-			'period' => 'last_year',
474
-		);
475
-
476
-		// Generate the report.
477
-		return array(
478
-			'before' => date( 'Y-m-d', strtotime( 'next year January 1st', current_time( 'timestamp' ) ) ),
479
-			'after'  => date( 'Y-m-d', strtotime( 'last year December 31st', current_time( 'timestamp' ) ) ),
480
-		);
481
-
482
-	}
483
-
484
-	/**
485
-	 * Retrieves last year date range.
486
-	 *
487
-	 * @return array The appropriate date range.
488
-	 */
489
-	public function get_last_year_date_range() {
490
-
491
-		$this->groupby = 'month';
492
-
493
-		// Set the previous date range.
494
-		$year          = (int) date('Y') - 3;
495
-		$this->previous_range = array(
496
-			'period' => 'custom',
497
-			'before' => date( 'Y-m-d', strtotime( 'first day of january last year', current_time( 'timestamp' ) ) ),
498
-			'after'  => "$year-12-31",
499
-		);
500
-
501
-		// Generate the report.
502
-		$year          = (int) date('Y') - 2;
503
-		return array(
504
-			'after'  => "$year-12-31",
505
-			'before' => date( 'Y-m-d', strtotime( 'first day of january this year', current_time( 'timestamp' ) ) ),
506
-		);
507
-
508
-	}
509
-
510
-	/**
511
-	 * Prepare a the request date for SQL usage.
512
-	 *
513
-	 * @param WP_REST_Request $request Request object.
514
-	 * @param string $date_field The date field.
515
-	 * @return string The appropriate SQL.
516
-	 */
517
-	public function get_date_range_sql( $request, $date_field ) {
518
-		global $wpdb;
519
-
520
-		$sql = '1=1';
521
-		$range = $this->get_date_range( $request );
522
-
523
-		if ( ! empty( $range['after'] ) ) {
524
-			$sql .= ' AND ' .  $wpdb->prepare(
525
-				"$date_field > %s",
526
-				$range['after']
527
-			);
528
-		}
529
-
530
-		if ( ! empty( $range['before'] ) ) {
531
-			$sql .= ' AND ' .  $wpdb->prepare(
532
-				"$date_field < %s",
533
-				$range['before']
534
-			);
535
-		}
536
-
537
-		return $sql;
538
-
539
-	}
540
-
541
-	/**
542
-	 * Prepares a group by query.
543
-	 *
544
-	 * @param string $date_field The date field.
545
-	 * @return string The appropriate SQL.
546
-	 */
547
-	public function get_group_by_sql( $date_field ) {
548
-
549
-		if ( 'day' === $this->groupby ) {
550
-			return "YEAR($date_field), MONTH($date_field), DAY($date_field)";
551
-		}
552
-
553
-		return "YEAR($date_field), MONTH($date_field)";
554
-	}
555
-
556
-	/**
557
-	 * Get the query params for collections.
558
-	 *
559
-	 * @return array
560
-	 */
561
-	public function get_collection_params() {
562
-		return array(
563
-			'context' => $this->get_context_param( array( 'default' => 'view' ) ),
564
-			'period' => array(
565
-				'description'       => __( 'Limit to results of a specific period.', 'invoicing' ),
566
-				'type'              => 'string',
567
-				'enum'              => array( 'custom', 'today', 'yesterday', 'week', 'last_week', '7_days', '30_days', '60_days' , '90_days', '180_days', 'month', 'last_month', 'quarter', 'last_quarter', 'year', 'last_year', 'quarter', 'last_quarter' ),
568
-				'validate_callback' => 'rest_validate_request_arg',
569
-				'sanitize_callback' => 'sanitize_text_field',
570
-				'default'           => '7_days',
571
-			),
572
-			'after' => array(
573
-				/* translators: %s: date format */
574
-				'description'       => sprintf( __( 'Limit to results after a specific date, the date needs to be in the %s format.', 'invoicing' ), 'YYYY-MM-DD' ),
575
-				'type'              => 'string',
576
-				'format'            => 'date',
577
-				'validate_callback' => 'rest_validate_request_arg',
578
-				'sanitize_callback' => 'sanitize_text_field',
579
-				'default'           => date( 'Y-m-d', strtotime( '-8 days', current_time( 'timestamp' ) ) ),
580
-			),
581
-			'before' => array(
582
-				/* translators: %s: date format */
583
-				'description'       => sprintf( __( 'Limit to results before a specific date, the date needs to be in the %s format.', 'invoicing' ), 'YYYY-MM-DD' ),
584
-				'type'              => 'string',
585
-				'format'            => 'date',
586
-				'validate_callback' => 'rest_validate_request_arg',
587
-				'sanitize_callback' => 'sanitize_text_field',
588
-				'default'           => date( 'Y-m-d', current_time( 'timestamp' ) ),
589
-			),
590
-		);
591
-	}
19
+    /**
20
+     * Group response items by day or month.
21
+     *
22
+     * @var string
23
+     */
24
+    public $groupby = 'day';
25
+
26
+    /**
27
+     * Returns an array with arguments to request the previous report.
28
+     *
29
+     * @var array
30
+     */
31
+    public $previous_range = array();
32
+
33
+    /**
34
+     * The period interval.
35
+     *
36
+     * @var int
37
+     */
38
+    public $interval;
39
+
40
+    /**
41
+     * Retrieves the before and after dates.
42
+     *
43
+     * @param WP_REST_Request $request Request object.
44
+     * @return array The appropriate date range.
45
+     */
46
+    public function get_date_range( $request ) {
47
+
48
+        // If not supported, assume all time.
49
+        if ( ! in_array( $request['period'], array( 'custom', 'today', 'yesterday', 'week', 'last_week', '7_days', '30_days', '60_days', '90_days', '180_days', 'month', 'last_month', 'quarter', 'last_quarter', 'year', 'last_year' ) ) ) {
50
+            $request['period'] = '7_days';
51
+        }
52
+
53
+        $date_range = call_user_func( array( $this, 'get_' . $request['period'] . '_date_range' ), $request );
54
+        $this->prepare_interval( $date_range );
55
+
56
+        return $date_range;
57
+
58
+    }
59
+
60
+    /**
61
+     * Groups by month or days.
62
+     *
63
+     * @param array $range Date range.
64
+     * @return array The appropriate date range.
65
+     */
66
+    public function prepare_interval( $range ) {
67
+
68
+        $before = strtotime( $range['before'] ) - DAY_IN_SECONDS;
69
+        $after  = strtotime( $range['after'] ) + DAY_IN_SECONDS;
70
+        if ( 'day' === $this->groupby ) {
71
+            $difference     = max( DAY_IN_SECONDS, ( DAY_IN_SECONDS + $before - $after ) ); // Prevent division by 0;
72
+            $this->interval = absint( ceil( max( 1, $difference / DAY_IN_SECONDS ) ) );
73
+            return;
74
+        }
75
+
76
+        $this->interval = 0;
77
+        $min_date       = strtotime( date( 'Y-m-01', $after ) );
78
+
79
+        while ( $min_date <= $before ) {
80
+            $this->interval ++;
81
+            $min_date = strtotime( '+1 MONTH', $min_date );
82
+        }
83
+
84
+        $this->interval = max( 1, $this->interval );
85
+
86
+    }
87
+
88
+    /**
89
+     * Retrieves a custom date range.
90
+     *
91
+     * @param WP_REST_Request $request Request object.
92
+     * @return array The appropriate date range.
93
+     */
94
+    public function get_custom_date_range( $request ) {
95
+
96
+        $after  = max( strtotime( '-20 years' ), strtotime( sanitize_text_field( $request['after'] ) ) );
97
+        $before = strtotime( '+1 day', current_time( 'timestamp' ) );
98
+
99
+        if ( ! empty( $request['before'] ) ) {
100
+            $before  = min( $before, strtotime( sanitize_text_field( $request['before'] ) ) );
101
+        }
102
+
103
+        // 3 months max for day view
104
+        if ( floor( ( $before - $after ) / MONTH_IN_SECONDS ) > 3 ) {
105
+            $this->groupby = 'month';
106
+        }
107
+
108
+        // Set the previous date range.
109
+        $difference           = $before - $after;
110
+        $this->previous_range = array(
111
+            'period' => 'custom',
112
+            'before' => date( 'Y-m-d', $before - $difference ),
113
+            'after'  => date( 'Y-m-d', $after - $difference ),
114
+        );
115
+
116
+        // Generate the report.
117
+        return array(
118
+            'before' => date( 'Y-m-d', $before ),
119
+            'after' => date( 'Y-m-d', $after ),
120
+        );
121
+
122
+    }
123
+
124
+    /**
125
+     * Retrieves todays date range.
126
+     *
127
+     * @return array The appropriate date range.
128
+     */
129
+    public function get_today_date_range() {
130
+
131
+        // Set the previous date range.
132
+        $this->previous_range = array(
133
+            'period' => 'yesterday',
134
+        );
135
+
136
+        // Generate the report.
137
+        return array(
138
+            'before' => date( 'Y-m-d', strtotime( '+1 day', current_time( 'timestamp' ) ) ),
139
+            'after'  => date( 'Y-m-d', strtotime( '-1 day', current_time( 'timestamp' ) ) ),
140
+        );
141
+
142
+    }
143
+
144
+    /**
145
+     * Retrieves yesterdays date range.
146
+     *
147
+     * @return array The appropriate date range.
148
+     */
149
+    public function get_yesterday_date_range() {
150
+
151
+        // Set the previous date range.
152
+        $this->previous_range = array(
153
+            'period' => 'custom',
154
+            'before' => date( 'Y-m-d', strtotime( '-1 day', current_time( 'timestamp' ) ) ),
155
+            'after'  => date( 'Y-m-d', strtotime( '-3 days', current_time( 'timestamp' ) ) ),
156
+        );
157
+
158
+        // Generate the report.
159
+        return array(
160
+            'before' => date( 'Y-m-d', current_time( 'timestamp' ) ),
161
+            'after'  => date( 'Y-m-d', strtotime( '-2 days', current_time( 'timestamp' ) ) ),
162
+        );
163
+
164
+    }
165
+
166
+    /**
167
+     * Retrieves this week's date range.
168
+     *
169
+     * @return array The appropriate date range.
170
+     */
171
+    public function get_week_date_range() {
172
+
173
+        // Set the previous date range.
174
+        $this->previous_range = array(
175
+            'period' => 'last_week',
176
+        );
177
+
178
+        // Generate the report.
179
+        return array(
180
+            'before' => date( 'Y-m-d', strtotime( 'sunday last week', current_time( 'timestamp' )  ) + 8 * DAY_IN_SECONDS ),
181
+            'after'  => date( 'Y-m-d', strtotime( 'sunday last week', current_time( 'timestamp' )  ) ),
182
+        );
183
+
184
+    }
185
+
186
+    /**
187
+     * Retrieves last week's date range.
188
+     *
189
+     * @return array The appropriate date range.
190
+     */
191
+    public function get_last_week_date_range() {
192
+
193
+        // Set the previous date range.
194
+        $this->previous_range = array(
195
+            'period' => 'custom',
196
+            'before' => date( 'Y-m-d', strtotime( 'monday last week', current_time( 'timestamp' )  ) ),
197
+            'after'  => date( 'Y-m-d', strtotime( 'monday last week', current_time( 'timestamp' )  ) - 8 * DAY_IN_SECONDS ),
198
+        );
199
+
200
+        // Generate the report.
201
+        return array(
202
+            'before' => date( 'Y-m-d', strtotime( 'monday this week', current_time( 'timestamp' )  ) ),
203
+            'after'  => date( 'Y-m-d', strtotime( 'monday last week', current_time( 'timestamp' )  ) - DAY_IN_SECONDS ),
204
+        );
205
+
206
+    }
207
+
208
+    /**
209
+     * Retrieves last 7 days date range.
210
+     *
211
+     * @return array The appropriate date range.
212
+     */
213
+    public function get_7_days_date_range() {
214
+
215
+        // Set the previous date range.
216
+        $this->previous_range = array(
217
+            'period' => 'custom',
218
+            'before' => date( 'Y-m-d', strtotime( '-7 days', current_time( 'timestamp' ) ) ),
219
+            'after'  => date( 'Y-m-d', strtotime( '-15 days', current_time( 'timestamp' ) ) ),
220
+        );
221
+
222
+        // Generate the report.
223
+        return array(
224
+            'before' => date( 'Y-m-d', current_time( 'timestamp' ) ),
225
+            'after'  => date( 'Y-m-d', strtotime( '-8 days', current_time( 'timestamp' ) ) ),
226
+        );
227
+
228
+    }
229
+
230
+    /**
231
+     * Retrieves last 30 days date range.
232
+     *
233
+     * @return array The appropriate date range.
234
+     */
235
+    public function get_30_days_date_range() {
236
+
237
+        // Set the previous date range.
238
+        $this->previous_range = array(
239
+            'period' => 'custom',
240
+            'before' => date( 'Y-m-d', strtotime( '-30 days', current_time( 'timestamp' ) ) ),
241
+            'after'  => date( 'Y-m-d', strtotime( '-61 days', current_time( 'timestamp' ) ) ),
242
+        );
243
+
244
+        // Generate the report.
245
+        return array(
246
+            'before' => date( 'Y-m-d', current_time( 'timestamp' ) ),
247
+            'after'  => date( 'Y-m-d', strtotime( '-31 days', current_time( 'timestamp' ) ) ),
248
+        );
249
+
250
+    }
251
+
252
+    /**
253
+     * Retrieves last 90 days date range.
254
+     *
255
+     * @return array The appropriate date range.
256
+     */
257
+    public function get_90_days_date_range() {
258
+
259
+        $this->groupby = 'month';
260
+
261
+        // Set the previous date range.
262
+        $this->previous_range = array(
263
+            'period' => 'custom',
264
+            'before' => date( 'Y-m-d', strtotime( '-90 days', current_time( 'timestamp' ) ) ),
265
+            'after'  => date( 'Y-m-d', strtotime( '-181 days', current_time( 'timestamp' ) ) ),
266
+        );
267
+
268
+        // Generate the report.
269
+        return array(
270
+            'before' => date( 'Y-m-d', current_time( 'timestamp' ) ),
271
+            'after'  => date( 'Y-m-d', strtotime( '-91 days', current_time( 'timestamp' ) ) ),
272
+        );
273
+
274
+    }
275
+
276
+    /**
277
+     * Retrieves last 180 days date range.
278
+     *
279
+     * @return array The appropriate date range.
280
+     */
281
+    public function get_180_days_date_range() {
282
+
283
+        $this->groupby = 'month';
284
+
285
+        // Set the previous date range.
286
+        $this->previous_range = array(
287
+            'period' => 'custom',
288
+            'before' => date( 'Y-m-d', strtotime( '-180 days', current_time( 'timestamp' ) ) ),
289
+            'after'  => date( 'Y-m-d', strtotime( '-361 days', current_time( 'timestamp' ) ) ),
290
+        );
291
+
292
+        // Generate the report.
293
+        return array(
294
+            'before' => date( 'Y-m-d', current_time( 'timestamp' ) ),
295
+            'after'  => date( 'Y-m-d', strtotime( '-181 days', current_time( 'timestamp' ) ) ),
296
+        );
297
+
298
+    }
299
+
300
+    /**
301
+     * Retrieves last 60 days date range.
302
+     *
303
+     * @return array The appropriate date range.
304
+     */
305
+    public function get_60_days_date_range() {
306
+
307
+        // Set the previous date range.
308
+        $this->previous_range = array(
309
+            'period' => 'custom',
310
+            'before' => date( 'Y-m-d', strtotime( '-60 days', current_time( 'timestamp' ) ) ),
311
+            'after'  => date( 'Y-m-d', strtotime( '-121 days', current_time( 'timestamp' ) ) ),
312
+        );
313
+
314
+        // Generate the report.
315
+        return array(
316
+            'before' => date( 'Y-m-d', current_time( 'timestamp' ) ),
317
+            'after'  => date( 'Y-m-d', strtotime( '-61 days', current_time( 'timestamp' ) ) ),
318
+        );
319
+
320
+    }
321
+
322
+    /**
323
+     * Retrieves this month date range.
324
+     *
325
+     * @return array The appropriate date range.
326
+     */
327
+    public function get_month_date_range() {
328
+
329
+        // Set the previous date range.
330
+        $this->previous_range = array(
331
+            'period' => 'last_month',
332
+        );
333
+
334
+        // Generate the report.
335
+        return array(
336
+            'before' => date( 'Y-m-01', strtotime( 'next month', current_time( 'timestamp' ) ) ),
337
+            'after'  => date( 'Y-m-t', strtotime( 'last month', current_time( 'timestamp' ) ) ),
338
+        );
339
+
340
+    }
341
+
342
+    /**
343
+     * Retrieves last month's date range.
344
+     *
345
+     * @return array The appropriate date range.
346
+     */
347
+    public function get_last_month_date_range() {
348
+
349
+        // Set the previous date range.
350
+        $this->previous_range = array(
351
+            'period' => 'custom',
352
+            'before' => date( 'Y-m-1', strtotime( 'last month', current_time( 'timestamp' ) ) ),
353
+            'after'  => date( 'Y-m-t', strtotime( "-3 months", current_time( 'timestamp' ) ) ),
354
+        );
355
+
356
+        // Generate the report.
357
+        return array(
358
+            'before' => date( 'Y-m-1', current_time( 'timestamp' ) ),
359
+            'after'  => date( 'Y-m-t', strtotime( "-2 months", current_time( 'timestamp' ) ) ),
360
+        );
361
+
362
+    }
363
+
364
+    /**
365
+     * Retrieves this quarter date range.
366
+     *
367
+     * @return array The available quarters.
368
+     */
369
+    public function get_quarters() {
370
+
371
+        $last_year = (int) date('Y') - 1;
372
+        $next_year = (int) date('Y') + 1;
373
+        $year      = (int) date('Y');
374
+        return array(
375
+
376
+            array(
377
+                'after'  => "$last_year-06-30",
378
+                'before' => "$last_year-10-01",
379
+            ),
380
+
381
+            array(
382
+                'before' => "$year-01-01",
383
+                'after'  => "$last_year-09-30",
384
+            ),
385
+
386
+            array(
387
+                'before' => "$year-04-01",
388
+                'after'  => "$last_year-12-31",
389
+            ),
390
+
391
+            array(
392
+                'before' => "$year-07-01",
393
+                'after'  => "$year-03-31",
394
+            ),
395
+
396
+            array(
397
+                'after'  => "$year-06-30",
398
+                'before' => "$year-10-01",
399
+            ),
400
+
401
+            array(
402
+                'before' => "$next_year-01-01",
403
+                'after'  => "$year-09-30",
404
+            )
405
+
406
+        );
407
+
408
+    }
409
+
410
+    /**
411
+     * Retrieves the current quater.
412
+     *
413
+     * @return int The current quarter.
414
+     */
415
+    public function get_quarter() {
416
+
417
+        $month    = (int) date( 'n', current_time( 'timestamp' ) );
418
+        $quarters = array( 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4 );
419
+        return $quarters[ $month - 1 ];
420
+
421
+    }
422
+
423
+    /**
424
+     * Retrieves this quarter date range.
425
+     *
426
+     * @return array The appropriate date range.
427
+     */
428
+    public function get_quarter_date_range() {
429
+
430
+        // Set the previous date range.
431
+        $this->previous_range = array(
432
+            'period' => 'last_quarter',
433
+        );
434
+
435
+        // Generate the report.
436
+        $quarters = $this->get_quarters();
437
+        return $quarters[ $this->get_quarter() + 1 ];
438
+
439
+    }
440
+
441
+    /**
442
+     * Retrieves last quarter's date range.
443
+     *
444
+     * @return array The appropriate date range.
445
+     */
446
+    public function get_last_quarter_date_range() {
447
+
448
+        $quarters = $this->get_quarters();
449
+        $quarter  = $this->get_quarter();
450
+
451
+        // Set the previous date range.
452
+        $this->previous_range = array_merge(
453
+            $quarters[ $quarter - 1 ],
454
+            array( 'period' => 'custom' )
455
+        );
456
+
457
+        // Generate the report.
458
+        return $quarters[ $quarter ];
459
+
460
+    }
461
+
462
+    /**
463
+     * Retrieves this year date range.
464
+     *
465
+     * @return array The appropriate date range.
466
+     */
467
+    public function get_year_date_range() {
468
+
469
+        $this->groupby = 'month';
470
+
471
+        // Set the previous date range.
472
+        $this->previous_range = array(
473
+            'period' => 'last_year',
474
+        );
475
+
476
+        // Generate the report.
477
+        return array(
478
+            'before' => date( 'Y-m-d', strtotime( 'next year January 1st', current_time( 'timestamp' ) ) ),
479
+            'after'  => date( 'Y-m-d', strtotime( 'last year December 31st', current_time( 'timestamp' ) ) ),
480
+        );
481
+
482
+    }
483
+
484
+    /**
485
+     * Retrieves last year date range.
486
+     *
487
+     * @return array The appropriate date range.
488
+     */
489
+    public function get_last_year_date_range() {
490
+
491
+        $this->groupby = 'month';
492
+
493
+        // Set the previous date range.
494
+        $year          = (int) date('Y') - 3;
495
+        $this->previous_range = array(
496
+            'period' => 'custom',
497
+            'before' => date( 'Y-m-d', strtotime( 'first day of january last year', current_time( 'timestamp' ) ) ),
498
+            'after'  => "$year-12-31",
499
+        );
500
+
501
+        // Generate the report.
502
+        $year          = (int) date('Y') - 2;
503
+        return array(
504
+            'after'  => "$year-12-31",
505
+            'before' => date( 'Y-m-d', strtotime( 'first day of january this year', current_time( 'timestamp' ) ) ),
506
+        );
507
+
508
+    }
509
+
510
+    /**
511
+     * Prepare a the request date for SQL usage.
512
+     *
513
+     * @param WP_REST_Request $request Request object.
514
+     * @param string $date_field The date field.
515
+     * @return string The appropriate SQL.
516
+     */
517
+    public function get_date_range_sql( $request, $date_field ) {
518
+        global $wpdb;
519
+
520
+        $sql = '1=1';
521
+        $range = $this->get_date_range( $request );
522
+
523
+        if ( ! empty( $range['after'] ) ) {
524
+            $sql .= ' AND ' .  $wpdb->prepare(
525
+                "$date_field > %s",
526
+                $range['after']
527
+            );
528
+        }
529
+
530
+        if ( ! empty( $range['before'] ) ) {
531
+            $sql .= ' AND ' .  $wpdb->prepare(
532
+                "$date_field < %s",
533
+                $range['before']
534
+            );
535
+        }
536
+
537
+        return $sql;
538
+
539
+    }
540
+
541
+    /**
542
+     * Prepares a group by query.
543
+     *
544
+     * @param string $date_field The date field.
545
+     * @return string The appropriate SQL.
546
+     */
547
+    public function get_group_by_sql( $date_field ) {
548
+
549
+        if ( 'day' === $this->groupby ) {
550
+            return "YEAR($date_field), MONTH($date_field), DAY($date_field)";
551
+        }
552
+
553
+        return "YEAR($date_field), MONTH($date_field)";
554
+    }
555
+
556
+    /**
557
+     * Get the query params for collections.
558
+     *
559
+     * @return array
560
+     */
561
+    public function get_collection_params() {
562
+        return array(
563
+            'context' => $this->get_context_param( array( 'default' => 'view' ) ),
564
+            'period' => array(
565
+                'description'       => __( 'Limit to results of a specific period.', 'invoicing' ),
566
+                'type'              => 'string',
567
+                'enum'              => array( 'custom', 'today', 'yesterday', 'week', 'last_week', '7_days', '30_days', '60_days' , '90_days', '180_days', 'month', 'last_month', 'quarter', 'last_quarter', 'year', 'last_year', 'quarter', 'last_quarter' ),
568
+                'validate_callback' => 'rest_validate_request_arg',
569
+                'sanitize_callback' => 'sanitize_text_field',
570
+                'default'           => '7_days',
571
+            ),
572
+            'after' => array(
573
+                /* translators: %s: date format */
574
+                'description'       => sprintf( __( 'Limit to results after a specific date, the date needs to be in the %s format.', 'invoicing' ), 'YYYY-MM-DD' ),
575
+                'type'              => 'string',
576
+                'format'            => 'date',
577
+                'validate_callback' => 'rest_validate_request_arg',
578
+                'sanitize_callback' => 'sanitize_text_field',
579
+                'default'           => date( 'Y-m-d', strtotime( '-8 days', current_time( 'timestamp' ) ) ),
580
+            ),
581
+            'before' => array(
582
+                /* translators: %s: date format */
583
+                'description'       => sprintf( __( 'Limit to results before a specific date, the date needs to be in the %s format.', 'invoicing' ), 'YYYY-MM-DD' ),
584
+                'type'              => 'string',
585
+                'format'            => 'date',
586
+                'validate_callback' => 'rest_validate_request_arg',
587
+                'sanitize_callback' => 'sanitize_text_field',
588
+                'default'           => date( 'Y-m-d', current_time( 'timestamp' ) ),
589
+            ),
590
+        );
591
+    }
592 592
 }
Please login to merge, or discard this patch.
includes/reports/class-getpaid-reports-report.php 1 patch
Indentation   +189 added lines, -189 removed lines patch added patch discarded remove patch
@@ -12,88 +12,88 @@  discard block
 block discarded – undo
12 12
  */
13 13
 class GetPaid_Reports_Report {
14 14
 
15
-	/**
16
-	 * @var array
17
-	 */
18
-	public $views;
15
+    /**
16
+     * @var array
17
+     */
18
+    public $views;
19 19
 
20
-	/**
21
-	 * Class constructor.
22
-	 *
23
-	 */
24
-	public function __construct() {
20
+    /**
21
+     * Class constructor.
22
+     *
23
+     */
24
+    public function __construct() {
25 25
 
26
-		$this->views        = array(
26
+        $this->views        = array(
27 27
 
28 28
             'items'     => array(
29
-				'label' => __( 'Items', 'invoicing' ),
30
-				'class' => 'GetPaid_Reports_Report_Items',
31
-			),
29
+                'label' => __( 'Items', 'invoicing' ),
30
+                'class' => 'GetPaid_Reports_Report_Items',
31
+            ),
32 32
 
33
-			'gateways'  => array(
34
-				'label' => __( 'Payment Methods', 'invoicing' ),
35
-				'class' => 'GetPaid_Reports_Report_Gateways',
36
-			),
33
+            'gateways'  => array(
34
+                'label' => __( 'Payment Methods', 'invoicing' ),
35
+                'class' => 'GetPaid_Reports_Report_Gateways',
36
+            ),
37 37
 
38
-			'discounts'  => array(
39
-				'label' => __( 'Discount Codes', 'invoicing' ),
40
-				'class' => 'GetPaid_Reports_Report_Discounts',
41
-			),
38
+            'discounts'  => array(
39
+                'label' => __( 'Discount Codes', 'invoicing' ),
40
+                'class' => 'GetPaid_Reports_Report_Discounts',
41
+            ),
42 42
 
43 43
         );
44 44
 
45
-		$this->views        = apply_filters( 'wpinv_report_views', $this->views );
46
-
47
-	}
48
-
49
-	/**
50
-	 * Retrieves the current range.
51
-	 *
52
-	 */
53
-	public function get_range() {
54
-		$valid_ranges = $this->get_periods();
55
-
56
-		if ( isset( $_GET['date_range'] ) && array_key_exists( $_GET['date_range'], $valid_ranges ) ) {
57
-			return sanitize_key( $_GET['date_range'] );
58
-		}
59
-
60
-		return '7_days';
61
-	}
62
-
63
-	/**
64
-	 * Returns an array of date ranges.
65
-	 *
66
-	 * @return array
67
-	 */
68
-	public function get_periods() {
69
-
70
-		$periods = array(
71
-			'today'        => __( 'Today', 'invoicing' ),
72
-			'yesterday'    => __( 'Yesterday', 'invoicing' ),
73
-			'week'         => __( 'This week', 'invoicing' ),
74
-			'last_week'    => __( 'Last week', 'invoicing' ),
75
-			'7_days'       => __( 'Last 7 days', 'invoicing' ),
76
-			'month'        => __( 'This month', 'invoicing' ),
77
-			'last_month'   => __( 'Last month', 'invoicing' ),
78
-			'30_days'      => __( 'Last 30 days', 'invoicing' ),
79
-			'quarter'      => __( 'This Quarter', 'invoicing' ),
80
-			'last_quarter' => __( 'Last Quarter', 'invoicing' ),
81
-			'year'         => __( 'This year', 'invoicing' ),
82
-			'last_year'    => __( 'Last Year', 'invoicing' ),
83
-			'custom'       => __( 'Custom Date Range', 'invoicing' ),
84
-		);
85
-
86
-		return apply_filters( 'getpaid_earning_periods', $periods );
87
-	}
88
-
89
-	/**
90
-	 * Displays the range selector.
91
-	 *
92
-	 */
93
-	public function display_range_selector() {
94
-
95
-		$range = $this->get_range();
96
-		?>
45
+        $this->views        = apply_filters( 'wpinv_report_views', $this->views );
46
+
47
+    }
48
+
49
+    /**
50
+     * Retrieves the current range.
51
+     *
52
+     */
53
+    public function get_range() {
54
+        $valid_ranges = $this->get_periods();
55
+
56
+        if ( isset( $_GET['date_range'] ) && array_key_exists( $_GET['date_range'], $valid_ranges ) ) {
57
+            return sanitize_key( $_GET['date_range'] );
58
+        }
59
+
60
+        return '7_days';
61
+    }
62
+
63
+    /**
64
+     * Returns an array of date ranges.
65
+     *
66
+     * @return array
67
+     */
68
+    public function get_periods() {
69
+
70
+        $periods = array(
71
+            'today'        => __( 'Today', 'invoicing' ),
72
+            'yesterday'    => __( 'Yesterday', 'invoicing' ),
73
+            'week'         => __( 'This week', 'invoicing' ),
74
+            'last_week'    => __( 'Last week', 'invoicing' ),
75
+            '7_days'       => __( 'Last 7 days', 'invoicing' ),
76
+            'month'        => __( 'This month', 'invoicing' ),
77
+            'last_month'   => __( 'Last month', 'invoicing' ),
78
+            '30_days'      => __( 'Last 30 days', 'invoicing' ),
79
+            'quarter'      => __( 'This Quarter', 'invoicing' ),
80
+            'last_quarter' => __( 'Last Quarter', 'invoicing' ),
81
+            'year'         => __( 'This year', 'invoicing' ),
82
+            'last_year'    => __( 'Last Year', 'invoicing' ),
83
+            'custom'       => __( 'Custom Date Range', 'invoicing' ),
84
+        );
85
+
86
+        return apply_filters( 'getpaid_earning_periods', $periods );
87
+    }
88
+
89
+    /**
90
+     * Displays the range selector.
91
+     *
92
+     */
93
+    public function display_range_selector() {
94
+
95
+        $range = $this->get_range();
96
+        ?>
97 97
 
98 98
 			<form method="get" class="getpaid-filter-earnings float-right">
99 99
 				<?php getpaid_hidden_field( 'page', 'wpinv-reports' );  ?>
@@ -115,14 +115,14 @@  discard block
 block discarded – undo
115 115
 			</form>
116 116
 
117 117
 		<?php
118
-	}
118
+    }
119 119
 
120
-	/**
121
-	 * Displays the reports tab.
122
-	 *
123
-	 */
124
-	public function display() {
125
-		?>
120
+    /**
121
+     * Displays the reports tab.
122
+     *
123
+     */
124
+    public function display() {
125
+        ?>
126 126
 
127 127
 		<div class="mt-4" style="max-width: 1200px;">
128 128
 
@@ -202,24 +202,24 @@  discard block
 block discarded – undo
202 202
 
203 203
 		<?php
204 204
 
205
-	}
206
-
207
-	/**
208
-	 * Displays the left side.
209
-	 *
210
-	 */
211
-	public function display_left() {
212
-		$graphs = array(
213
-			'sales'    => __( 'Earnings', 'invoicing' ),
214
-			'refunds'  => __( 'Refunds', 'invoicing' ),
215
-			'tax'      => __( 'Taxes', 'invoicing' ),
216
-			'fees'     => __( 'Fees', 'invoicing' ),
217
-			'discount' => __( 'Discounts', 'invoicing' ),
218
-			'invoices' => __( 'Invoices', 'invoicing' ),
219
-			'items'    => __( 'Purchased Items', 'invoicing' ),
220
-		);
221
-
222
-		?>
205
+    }
206
+
207
+    /**
208
+     * Displays the left side.
209
+     *
210
+     */
211
+    public function display_left() {
212
+        $graphs = array(
213
+            'sales'    => __( 'Earnings', 'invoicing' ),
214
+            'refunds'  => __( 'Refunds', 'invoicing' ),
215
+            'tax'      => __( 'Taxes', 'invoicing' ),
216
+            'fees'     => __( 'Fees', 'invoicing' ),
217
+            'discount' => __( 'Discounts', 'invoicing' ),
218
+            'invoices' => __( 'Invoices', 'invoicing' ),
219
+            'items'    => __( 'Purchased Items', 'invoicing' ),
220
+        );
221
+
222
+        ?>
223 223
 
224 224
 			<?php foreach ( $graphs as $key => $graph ) : ?>
225 225
 				<div class="row mb-4">
@@ -238,35 +238,35 @@  discard block
 block discarded – undo
238 238
 
239 239
 		<?php
240 240
 
241
-	}
242
-
243
-	/**
244
-	 * Retrieves the download url.
245
-	 *
246
-	 */
247
-	public function get_download_url( $graph, $file_type ) {
248
-
249
-		return wp_nonce_url(
250
-			add_query_arg(
251
-				array(
252
-					'getpaid-admin-action' => 'download_graph',
253
-					'file_type'            => urlencode( $file_type ),
254
-					'graph'                => urlencode( $graph ),
255
-				)
256
-			),
257
-			'getpaid-nonce',
258
-			'getpaid-nonce'
259
-		);
241
+    }
242
+
243
+    /**
244
+     * Retrieves the download url.
245
+     *
246
+     */
247
+    public function get_download_url( $graph, $file_type ) {
248
+
249
+        return wp_nonce_url(
250
+            add_query_arg(
251
+                array(
252
+                    'getpaid-admin-action' => 'download_graph',
253
+                    'file_type'            => urlencode( $file_type ),
254
+                    'graph'                => urlencode( $graph ),
255
+                )
256
+            ),
257
+            'getpaid-nonce',
258
+            'getpaid-nonce'
259
+        );
260 260
 
261
-	}
261
+    }
262 262
 
263
-	/**
264
-	 * Displays the right side.
265
-	 *
266
-	 */
267
-	public function display_right() {
263
+    /**
264
+     * Displays the right side.
265
+     *
266
+     */
267
+    public function display_right() {
268 268
 
269
-		?>
269
+        ?>
270 270
 
271 271
 			<?php foreach ( $this->views as $key => $view ) : ?>
272 272
 				<div class="row mb-4">
@@ -295,10 +295,10 @@  discard block
 block discarded – undo
295 295
 							</div>
296 296
 							<div class="card-body">
297 297
 								<?php
298
-									$class = $view['class'];
299
-									$class = new $class();
300
-									$class->display_stats();
301
-								?>
298
+                                    $class = $view['class'];
299
+                                    $class = new $class();
300
+                                    $class->display_stats();
301
+                                ?>
302 302
 							</div>
303 303
 						</div>
304 304
 					</div>
@@ -307,67 +307,67 @@  discard block
 block discarded – undo
307 307
 
308 308
 		<?php
309 309
 
310
-	}
311
-
312
-	/**
313
-	 * Returns a list of report cards.
314
-	 *
315
-	 */
316
-	public function get_cards() {
317
-
318
-		$cards = array(
319
-			'total_sales' => array(
320
-				'description' => __( 'Gross sales in the period.', 'invoicing' ),
321
-				'label'       => __( 'Gross Revenue', 'invoicing' ),
322
-			),
323
-			'net_sales' => array(
324
-				'description' => __( 'Net sales in the period.', 'invoicing' ),
325
-				'label'       => __( 'Net Revenue', 'invoicing' ),
326
-			),
327
-			'average_sales' => array(
328
-				'description' => __( 'Average net daily/monthly sales.', 'invoicing' ),
329
-				'label'       => __( 'Avg. Net Sales', 'invoicing' ),
330
-			),
331
-			'average_total_sales' => array(
332
-				'description' => __( 'Average gross daily/monthly sales.', 'invoicing' ),
333
-				'label'       => __( 'Avg. Gross Sales', 'invoicing' ),
334
-			),
335
-			'total_invoices'  => array(
336
-				'description' => __( 'Number of paid invoices.', 'invoicing' ),
337
-				'label'       => __( 'Paid Invoices', 'invoicing' ),
338
-			),
339
-			'total_items' => array(
340
-				'description' => __( 'Number of items purchased.', 'invoicing' ),
341
-				'label'       => __( 'Purchased Items', 'invoicing' ),
342
-			),
343
-			'refunded_items' => array(
344
-				'description' => __( 'Number of items refunded.', 'invoicing' ),
345
-				'label'       => __( 'Refunded Items', 'invoicing' ),
346
-			),
347
-			'total_tax' => array(
348
-				'description' => __( 'Total charged for taxes.', 'invoicing' ),
349
-				'label'       => __( 'Tax', 'invoicing' ),
350
-			),
351
-			'total_refunded_tax' => array(
352
-				'description' => __( 'Total refunded for taxes.', 'invoicing' ),
353
-				'label'       => __( 'Refunded Tax', 'invoicing' ),
354
-			),
355
-			'total_fees' => array(
356
-				'description' => __( 'Total fees charged.', 'invoicing' ),
357
-				'label'       => __( 'Fees', 'invoicing' ),
358
-			),
359
-			'total_refunds' => array(
360
-				'description' => __( 'Total of refunded invoices.', 'invoicing' ),
361
-				'label'       => __( 'Refunded', 'invoicing' ),
362
-			),
363
-			'total_discount'  => array(
364
-				'description' => __( 'Total of discounts used.', 'invoicing' ),
365
-				'label'       => __( 'Discounted', 'invoicing' ),
366
-			),
367
-		);
368
-
369
-		return apply_filters( 'wpinv_report_cards', $cards );
370
-	}
310
+    }
311
+
312
+    /**
313
+     * Returns a list of report cards.
314
+     *
315
+     */
316
+    public function get_cards() {
317
+
318
+        $cards = array(
319
+            'total_sales' => array(
320
+                'description' => __( 'Gross sales in the period.', 'invoicing' ),
321
+                'label'       => __( 'Gross Revenue', 'invoicing' ),
322
+            ),
323
+            'net_sales' => array(
324
+                'description' => __( 'Net sales in the period.', 'invoicing' ),
325
+                'label'       => __( 'Net Revenue', 'invoicing' ),
326
+            ),
327
+            'average_sales' => array(
328
+                'description' => __( 'Average net daily/monthly sales.', 'invoicing' ),
329
+                'label'       => __( 'Avg. Net Sales', 'invoicing' ),
330
+            ),
331
+            'average_total_sales' => array(
332
+                'description' => __( 'Average gross daily/monthly sales.', 'invoicing' ),
333
+                'label'       => __( 'Avg. Gross Sales', 'invoicing' ),
334
+            ),
335
+            'total_invoices'  => array(
336
+                'description' => __( 'Number of paid invoices.', 'invoicing' ),
337
+                'label'       => __( 'Paid Invoices', 'invoicing' ),
338
+            ),
339
+            'total_items' => array(
340
+                'description' => __( 'Number of items purchased.', 'invoicing' ),
341
+                'label'       => __( 'Purchased Items', 'invoicing' ),
342
+            ),
343
+            'refunded_items' => array(
344
+                'description' => __( 'Number of items refunded.', 'invoicing' ),
345
+                'label'       => __( 'Refunded Items', 'invoicing' ),
346
+            ),
347
+            'total_tax' => array(
348
+                'description' => __( 'Total charged for taxes.', 'invoicing' ),
349
+                'label'       => __( 'Tax', 'invoicing' ),
350
+            ),
351
+            'total_refunded_tax' => array(
352
+                'description' => __( 'Total refunded for taxes.', 'invoicing' ),
353
+                'label'       => __( 'Refunded Tax', 'invoicing' ),
354
+            ),
355
+            'total_fees' => array(
356
+                'description' => __( 'Total fees charged.', 'invoicing' ),
357
+                'label'       => __( 'Fees', 'invoicing' ),
358
+            ),
359
+            'total_refunds' => array(
360
+                'description' => __( 'Total of refunded invoices.', 'invoicing' ),
361
+                'label'       => __( 'Refunded', 'invoicing' ),
362
+            ),
363
+            'total_discount'  => array(
364
+                'description' => __( 'Total of discounts used.', 'invoicing' ),
365
+                'label'       => __( 'Discounted', 'invoicing' ),
366
+            ),
367
+        );
368
+
369
+        return apply_filters( 'wpinv_report_cards', $cards );
370
+    }
371 371
 
372 372
 	
373 373
 
Please login to merge, or discard this patch.
includes/admin/subscriptions.php 1 patch
Indentation   +203 added lines, -203 removed lines patch added patch discarded remove patch
@@ -14,7 +14,7 @@  discard block
 block discarded – undo
14 14
  */
15 15
 function wpinv_subscriptions_page() {
16 16
 
17
-	?>
17
+    ?>
18 18
 
19 19
 	<div class="wrap">
20 20
 		<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
@@ -22,27 +22,27 @@  discard block
 block discarded – undo
22 22
 
23 23
 			<?php
24 24
 
25
-				// Verify user permissions.
26
-				if ( ! wpinv_current_user_can_manage_invoicing() ) {
25
+                // Verify user permissions.
26
+                if ( ! wpinv_current_user_can_manage_invoicing() ) {
27 27
 
28
-					echo aui()->alert(
29
-						array(
30
-							'type'    => 'danger',
31
-							'content' => __( 'You are not permitted to view this page.', 'invoicing' ),
32
-						)
33
-					);
28
+                    echo aui()->alert(
29
+                        array(
30
+                            'type'    => 'danger',
31
+                            'content' => __( 'You are not permitted to view this page.', 'invoicing' ),
32
+                        )
33
+                    );
34 34
 
35
-				} else if ( ! empty( $_GET['id'] ) && is_numeric( $_GET['id'] ) ) {
35
+                } else if ( ! empty( $_GET['id'] ) && is_numeric( $_GET['id'] ) ) {
36 36
 
37
-					// Display a single subscription.
38
-					wpinv_recurring_subscription_details();
39
-				} else {
37
+                    // Display a single subscription.
38
+                    wpinv_recurring_subscription_details();
39
+                } else {
40 40
 
41
-					// Display a list of available subscriptions.
42
-					getpaid_print_subscriptions_list();
43
-				}
41
+                    // Display a list of available subscriptions.
42
+                    getpaid_print_subscriptions_list();
43
+                }
44 44
 
45
-			?>
45
+            ?>
46 46
 
47 47
 		</div>
48 48
 	</div>
@@ -59,10 +59,10 @@  discard block
 block discarded – undo
59 59
  */
60 60
 function getpaid_print_subscriptions_list() {
61 61
 
62
-	$subscribers_table = new WPInv_Subscriptions_List_Table();
63
-	$subscribers_table->prepare_items();
62
+    $subscribers_table = new WPInv_Subscriptions_List_Table();
63
+    $subscribers_table->prepare_items();
64 64
 
65
-	?>
65
+    ?>
66 66
 	<form id="subscribers-filter" class="bsui" method="get">
67 67
 		<input type="hidden" name="page" value="wpinv-subscriptions" />
68 68
 		<?php $subscribers_table->views(); ?>
@@ -80,27 +80,27 @@  discard block
 block discarded – undo
80 80
  */
81 81
 function wpinv_recurring_subscription_details() {
82 82
 
83
-	// Fetch the subscription.
84
-	$sub = new WPInv_Subscription( (int) $_GET['id'] );
85
-	if ( ! $sub->get_id() ) {
83
+    // Fetch the subscription.
84
+    $sub = new WPInv_Subscription( (int) $_GET['id'] );
85
+    if ( ! $sub->get_id() ) {
86 86
 
87
-		echo aui()->alert(
88
-			array(
89
-				'type'    => 'danger',
90
-				'content' => __( 'Subscription not found.', 'invoicing' ),
91
-			)
92
-		);
87
+        echo aui()->alert(
88
+            array(
89
+                'type'    => 'danger',
90
+                'content' => __( 'Subscription not found.', 'invoicing' ),
91
+            )
92
+        );
93 93
 
94
-		return;
95
-	}
94
+        return;
95
+    }
96 96
 
97
-	// Use metaboxes to display the subscription details.
98
-	add_meta_box( 'getpaid_admin_subscription_details_metabox', __( 'Subscription Details', 'invoicing' ), 'getpaid_admin_subscription_details_metabox', get_current_screen(), 'normal' );
99
-	add_meta_box( 'getpaid_admin_subscription_update_metabox', __( 'Change Status', 'invoicing' ), 'getpaid_admin_subscription_update_metabox', get_current_screen(), 'side' );
100
-	add_meta_box( 'getpaid_admin_subscription_invoice_details_metabox', __( 'Invoices', 'invoicing' ), 'getpaid_admin_subscription_invoice_details_metabox', get_current_screen(), 'advanced' );
101
-	do_action( 'getpaid_admin_single_subscription_register_metabox', $sub );
97
+    // Use metaboxes to display the subscription details.
98
+    add_meta_box( 'getpaid_admin_subscription_details_metabox', __( 'Subscription Details', 'invoicing' ), 'getpaid_admin_subscription_details_metabox', get_current_screen(), 'normal' );
99
+    add_meta_box( 'getpaid_admin_subscription_update_metabox', __( 'Change Status', 'invoicing' ), 'getpaid_admin_subscription_update_metabox', get_current_screen(), 'side' );
100
+    add_meta_box( 'getpaid_admin_subscription_invoice_details_metabox', __( 'Invoices', 'invoicing' ), 'getpaid_admin_subscription_invoice_details_metabox', get_current_screen(), 'advanced' );
101
+    do_action( 'getpaid_admin_single_subscription_register_metabox', $sub );
102 102
 
103
-	?>
103
+    ?>
104 104
 
105 105
 		<form method="post" action="<?php echo admin_url( 'admin.php?page=wpinv-subscriptions&id=' . absint( $sub->get_id() ) ); ?>">
106 106
 
@@ -140,41 +140,41 @@  discard block
 block discarded – undo
140 140
  */
141 141
 function getpaid_admin_subscription_details_metabox( $sub ) {
142 142
 
143
-	// Prepare subscription detail columns.
144
-	$fields = apply_filters(
145
-		'getpaid_subscription_admin_page_fields',
146
-		array(
147
-			'subscription'   => __( 'Subscription', 'invoicing' ),
148
-			'customer'       => __( 'Customer', 'invoicing' ),
149
-			'amount'         => __( 'Amount', 'invoicing' ),
150
-			'start_date'     => __( 'Start Date', 'invoicing' ),
151
-			'renews_on'      => __( 'Next Payment', 'invoicing' ),
152
-			'renewals'       => __( 'Payments', 'invoicing' ),
153
-			'item'           => __( 'Item', 'invoicing' ),
154
-			'gateway'        => __( 'Payment Method', 'invoicing' ),
155
-			'profile_id'     => __( 'Profile ID', 'invoicing' ),
156
-			'status'         => __( 'Status', 'invoicing' ),
157
-		)
158
-	);
159
-
160
-	if ( ! $sub->is_active() ) {
161
-
162
-		if ( isset( $fields['renews_on'] ) ) {
163
-			unset( $fields['renews_on'] );
164
-		}
165
-
166
-		if ( isset( $fields['gateway'] ) ) {
167
-			unset( $fields['gateway'] );
168
-		}
143
+    // Prepare subscription detail columns.
144
+    $fields = apply_filters(
145
+        'getpaid_subscription_admin_page_fields',
146
+        array(
147
+            'subscription'   => __( 'Subscription', 'invoicing' ),
148
+            'customer'       => __( 'Customer', 'invoicing' ),
149
+            'amount'         => __( 'Amount', 'invoicing' ),
150
+            'start_date'     => __( 'Start Date', 'invoicing' ),
151
+            'renews_on'      => __( 'Next Payment', 'invoicing' ),
152
+            'renewals'       => __( 'Payments', 'invoicing' ),
153
+            'item'           => __( 'Item', 'invoicing' ),
154
+            'gateway'        => __( 'Payment Method', 'invoicing' ),
155
+            'profile_id'     => __( 'Profile ID', 'invoicing' ),
156
+            'status'         => __( 'Status', 'invoicing' ),
157
+        )
158
+    );
159
+
160
+    if ( ! $sub->is_active() ) {
161
+
162
+        if ( isset( $fields['renews_on'] ) ) {
163
+            unset( $fields['renews_on'] );
164
+        }
165
+
166
+        if ( isset( $fields['gateway'] ) ) {
167
+            unset( $fields['gateway'] );
168
+        }
169 169
 		
170
-	}
170
+    }
171 171
 
172
-	$profile_id = $sub->get_profile_id();
173
-	if ( empty( $profile_id ) && isset( $fields['profile_id'] ) ) {
174
-		unset( $fields['profile_id'] );
175
-	}
172
+    $profile_id = $sub->get_profile_id();
173
+    if ( empty( $profile_id ) && isset( $fields['profile_id'] ) ) {
174
+        unset( $fields['profile_id'] );
175
+    }
176 176
 
177
-	?>
177
+    ?>
178 178
 
179 179
 		<table class="table table-borderless" style="font-size: 14px;">
180 180
 			<tbody>
@@ -208,20 +208,20 @@  discard block
 block discarded – undo
208 208
  */
209 209
 function getpaid_admin_subscription_metabox_display_customer( $subscription ) {
210 210
 
211
-	$username = __( '(Missing User)', 'invoicing' );
211
+    $username = __( '(Missing User)', 'invoicing' );
212 212
 
213
-	$user = get_userdata( $subscription->get_customer_id() );
214
-	if ( $user ) {
213
+    $user = get_userdata( $subscription->get_customer_id() );
214
+    if ( $user ) {
215 215
 
216
-		$username = sprintf(
217
-			'<a href="user-edit.php?user_id=%s">%s</a>',
218
-			absint( $user->ID ),
219
-			! empty( $user->display_name ) ? sanitize_text_field( $user->display_name ) : sanitize_email( $user->user_email )
220
-		);
216
+        $username = sprintf(
217
+            '<a href="user-edit.php?user_id=%s">%s</a>',
218
+            absint( $user->ID ),
219
+            ! empty( $user->display_name ) ? sanitize_text_field( $user->display_name ) : sanitize_email( $user->user_email )
220
+        );
221 221
 
222
-	}
222
+    }
223 223
 
224
-	echo  $username;
224
+    echo  $username;
225 225
 }
226 226
 add_action( 'getpaid_subscription_admin_display_customer', 'getpaid_admin_subscription_metabox_display_customer' );
227 227
 
@@ -231,8 +231,8 @@  discard block
 block discarded – undo
231 231
  * @param WPInv_Subscription $subscription
232 232
  */
233 233
 function getpaid_admin_subscription_metabox_display_amount( $subscription ) {
234
-	$amount    = sanitize_text_field( getpaid_get_formatted_subscription_amount( $subscription ) );
235
-	echo "<span>$amount</span>";
234
+    $amount    = sanitize_text_field( getpaid_get_formatted_subscription_amount( $subscription ) );
235
+    echo "<span>$amount</span>";
236 236
 }
237 237
 add_action( 'getpaid_subscription_admin_display_amount', 'getpaid_admin_subscription_metabox_display_amount' );
238 238
 
@@ -242,7 +242,7 @@  discard block
 block discarded – undo
242 242
  * @param WPInv_Subscription $subscription
243 243
  */
244 244
 function getpaid_admin_subscription_metabox_display_id( $subscription ) {
245
-	echo  '#' . absint( $subscription->get_id() );
245
+    echo  '#' . absint( $subscription->get_id() );
246 246
 }
247 247
 add_action( 'getpaid_subscription_admin_display_subscription', 'getpaid_admin_subscription_metabox_display_id' );
248 248
 
@@ -252,7 +252,7 @@  discard block
 block discarded – undo
252 252
  * @param WPInv_Subscription $subscription
253 253
  */
254 254
 function getpaid_admin_subscription_metabox_display_start_date( $subscription ) {
255
-	echo getpaid_format_date_value( $subscription->get_date_created() );
255
+    echo getpaid_format_date_value( $subscription->get_date_created() );
256 256
 }
257 257
 add_action( 'getpaid_subscription_admin_display_start_date', 'getpaid_admin_subscription_metabox_display_start_date' );
258 258
 
@@ -262,7 +262,7 @@  discard block
 block discarded – undo
262 262
  * @param WPInv_Subscription $subscription
263 263
  */
264 264
 function getpaid_admin_subscription_metabox_display_renews_on( $subscription ) {
265
-	echo getpaid_format_date_value( $subscription->get_expiration() );
265
+    echo getpaid_format_date_value( $subscription->get_expiration() );
266 266
 }
267 267
 add_action( 'getpaid_subscription_admin_display_renews_on', 'getpaid_admin_subscription_metabox_display_renews_on' );
268 268
 
@@ -272,8 +272,8 @@  discard block
 block discarded – undo
272 272
  * @param WPInv_Subscription $subscription
273 273
  */
274 274
 function getpaid_admin_subscription_metabox_display_renewals( $subscription ) {
275
-	$max_bills = $subscription->get_bill_times();
276
-	echo $subscription->get_times_billed() . ' / ' . ( empty( $max_bills ) ? "&infin;" : $max_bills );
275
+    $max_bills = $subscription->get_bill_times();
276
+    echo $subscription->get_times_billed() . ' / ' . ( empty( $max_bills ) ? "&infin;" : $max_bills );
277 277
 }
278 278
 add_action( 'getpaid_subscription_admin_display_renewals', 'getpaid_admin_subscription_metabox_display_renewals' );
279 279
 /**
@@ -283,16 +283,16 @@  discard block
 block discarded – undo
283 283
  */
284 284
 function getpaid_admin_subscription_metabox_display_item( $subscription ) {
285 285
 
286
-	$item = get_post( $subscription->get_product_id() );
286
+    $item = get_post( $subscription->get_product_id() );
287 287
 
288
-	if ( ! empty( $item ) ) {
289
-		$link = get_edit_post_link( $item );
290
-		$link = esc_url( $link );
291
-		$name = esc_html( get_the_title( $item ) );
292
-		echo "<a href='$link'>$name</a>";
293
-	} else {
294
-		echo sprintf( __( 'Item #%s', 'invoicing' ), $subscription->get_product_id() );
295
-	}
288
+    if ( ! empty( $item ) ) {
289
+        $link = get_edit_post_link( $item );
290
+        $link = esc_url( $link );
291
+        $name = esc_html( get_the_title( $item ) );
292
+        echo "<a href='$link'>$name</a>";
293
+    } else {
294
+        echo sprintf( __( 'Item #%s', 'invoicing' ), $subscription->get_product_id() );
295
+    }
296 296
 
297 297
 }
298 298
 add_action( 'getpaid_subscription_admin_display_item', 'getpaid_admin_subscription_metabox_display_item' );
@@ -304,13 +304,13 @@  discard block
 block discarded – undo
304 304
  */
305 305
 function getpaid_admin_subscription_metabox_display_gateway( $subscription ) {
306 306
 
307
-	$gateway = $subscription->get_gateway();
307
+    $gateway = $subscription->get_gateway();
308 308
 
309
-	if ( ! empty( $gateway ) ) {
310
-		echo sanitize_text_field( wpinv_get_gateway_admin_label( $gateway ) );
311
-	} else {
312
-		echo "&mdash;";
313
-	}
309
+    if ( ! empty( $gateway ) ) {
310
+        echo sanitize_text_field( wpinv_get_gateway_admin_label( $gateway ) );
311
+    } else {
312
+        echo "&mdash;";
313
+    }
314 314
 
315 315
 }
316 316
 add_action( 'getpaid_subscription_admin_display_gateway', 'getpaid_admin_subscription_metabox_display_gateway' );
@@ -321,7 +321,7 @@  discard block
 block discarded – undo
321 321
  * @param WPInv_Subscription $subscription
322 322
  */
323 323
 function getpaid_admin_subscription_metabox_display_status( $subscription ) {
324
-	echo $subscription->get_status_label_html();
324
+    echo $subscription->get_status_label_html();
325 325
 }
326 326
 add_action( 'getpaid_subscription_admin_display_status', 'getpaid_admin_subscription_metabox_display_status' );
327 327
 
@@ -332,14 +332,14 @@  discard block
 block discarded – undo
332 332
  */
333 333
 function getpaid_admin_subscription_metabox_display_profile_id( $subscription ) {
334 334
 
335
-	$profile_id = $subscription->get_profile_id();
335
+    $profile_id = $subscription->get_profile_id();
336 336
 
337
-	if ( ! empty( $profile_id ) ) {
338
-		$profile_id = sanitize_text_field( $profile_id );
339
-		echo apply_filters( 'getpaid_subscription_profile_id_display', $profile_id, $subscription );
340
-	} else {
341
-		echo "&mdash;";
342
-	}
337
+    if ( ! empty( $profile_id ) ) {
338
+        $profile_id = sanitize_text_field( $profile_id );
339
+        echo apply_filters( 'getpaid_subscription_profile_id_display', $profile_id, $subscription );
340
+    } else {
341
+        echo "&mdash;";
342
+    }
343 343
 
344 344
 }
345 345
 add_action( 'getpaid_subscription_admin_display_profile_id', 'getpaid_admin_subscription_metabox_display_profile_id' );
@@ -351,39 +351,39 @@  discard block
 block discarded – undo
351 351
  */
352 352
 function getpaid_admin_subscription_update_metabox( $subscription ) {
353 353
 
354
-	?>
354
+    ?>
355 355
 	<div class="mt-3">
356 356
 
357 357
 		<?php
358
-			echo aui()->select(
359
-				array(
360
-					'options'          => getpaid_get_subscription_statuses(),
361
-					'name'             => 'subscription_status',
362
-					'id'               => 'subscription_status_update_select',
363
-					'required'         => true,
364
-					'no_wrap'          => false,
365
-					'label'            => __( 'Subscription Status', 'invoicing' ),
366
-					'help_text'        => __( 'Updating the status will trigger related actions and hooks', 'invoicing' ),
367
-					'select2'          => true,
368
-					'value'            => $subscription->get_status( 'edit' ),
369
-				)
370
-			);
371
-		?>
358
+            echo aui()->select(
359
+                array(
360
+                    'options'          => getpaid_get_subscription_statuses(),
361
+                    'name'             => 'subscription_status',
362
+                    'id'               => 'subscription_status_update_select',
363
+                    'required'         => true,
364
+                    'no_wrap'          => false,
365
+                    'label'            => __( 'Subscription Status', 'invoicing' ),
366
+                    'help_text'        => __( 'Updating the status will trigger related actions and hooks', 'invoicing' ),
367
+                    'select2'          => true,
368
+                    'value'            => $subscription->get_status( 'edit' ),
369
+                )
370
+            );
371
+        ?>
372 372
 
373 373
 		<div class="mt-2 px-3 py-2 bg-light border-top" style="margin: -12px;">
374 374
 	
375 375
 		<?php
376
-			submit_button( __( 'Update', 'invoicing' ), 'primary', 'submit', false );
376
+            submit_button( __( 'Update', 'invoicing' ), 'primary', 'submit', false );
377 377
 
378
-			$url    = esc_url( wp_nonce_url( add_query_arg( 'getpaid-admin-action', 'subscription_manual_renew' ), 'getpaid-nonce', 'getpaid-nonce' ) );
379
-			$anchor = __( 'Renew Subscription', 'invoicing' );
380
-			$title  = esc_attr__( 'Are you sure you want to extend the subscription and generate a new invoice that will be automatically marked as paid?', 'invoicing' );
378
+            $url    = esc_url( wp_nonce_url( add_query_arg( 'getpaid-admin-action', 'subscription_manual_renew' ), 'getpaid-nonce', 'getpaid-nonce' ) );
379
+            $anchor = __( 'Renew Subscription', 'invoicing' );
380
+            $title  = esc_attr__( 'Are you sure you want to extend the subscription and generate a new invoice that will be automatically marked as paid?', 'invoicing' );
381 381
 
382
-			if ( $subscription->is_active() ) {
383
-				echo "<a href='$url' class='float-right text-muted' onclick='return confirm(\"$title\")'>$anchor</a>";
384
-			}
382
+            if ( $subscription->is_active() ) {
383
+                echo "<a href='$url' class='float-right text-muted' onclick='return confirm(\"$title\")'>$anchor</a>";
384
+            }
385 385
 
386
-	echo '</div></div>';
386
+    echo '</div></div>';
387 387
 }
388 388
 
389 389
 /**
@@ -393,33 +393,33 @@  discard block
 block discarded – undo
393 393
  */
394 394
 function getpaid_admin_subscription_invoice_details_metabox( $subscription ) {
395 395
 
396
-	$columns = apply_filters(
397
-		'getpaid_subscription_related_invoices_columns',
398
-		array(
399
-			'invoice'      => __( 'Invoice', 'invoicing' ),
400
-			'relationship' => __( 'Relationship', 'invoicing' ),
401
-			'date'         => __( 'Date', 'invoicing' ),
402
-			'status'       => __( 'Status', 'invoicing' ),
403
-			'total'        => __( 'Total', 'invoicing' ),
404
-		),
405
-		$subscription
406
-	);
407
-
408
-	// Prepare the invoices.
409
-	$payments = $subscription->get_child_payments( ! is_admin() );
410
-	$parent   = $subscription->get_parent_invoice();
411
-
412
-	if ( $parent->get_id() ) {
413
-		$payments = array_merge( array( $parent ), $payments );
414
-	}
396
+    $columns = apply_filters(
397
+        'getpaid_subscription_related_invoices_columns',
398
+        array(
399
+            'invoice'      => __( 'Invoice', 'invoicing' ),
400
+            'relationship' => __( 'Relationship', 'invoicing' ),
401
+            'date'         => __( 'Date', 'invoicing' ),
402
+            'status'       => __( 'Status', 'invoicing' ),
403
+            'total'        => __( 'Total', 'invoicing' ),
404
+        ),
405
+        $subscription
406
+    );
407
+
408
+    // Prepare the invoices.
409
+    $payments = $subscription->get_child_payments( ! is_admin() );
410
+    $parent   = $subscription->get_parent_invoice();
411
+
412
+    if ( $parent->get_id() ) {
413
+        $payments = array_merge( array( $parent ), $payments );
414
+    }
415 415
 	
416
-	$table_class = 'w-100 bg-white';
416
+    $table_class = 'w-100 bg-white';
417 417
 
418
-	if ( ! is_admin() ) {
419
-		$table_class = 'table table-bordered table-striped';
420
-	}
418
+    if ( ! is_admin() ) {
419
+        $table_class = 'table table-bordered table-striped';
420
+    }
421 421
 
422
-	?>
422
+    ?>
423 423
 		<div class="m-0" style="overflow: auto;">
424 424
 
425 425
 			<table class="<?php echo $table_class; ?>">
@@ -427,13 +427,13 @@  discard block
 block discarded – undo
427 427
 				<thead>
428 428
 					<tr>
429 429
 						<?php
430
-							foreach ( $columns as $key => $label ) {
431
-								$key   = esc_attr( $key );
432
-								$label = sanitize_text_field( $label );
430
+                            foreach ( $columns as $key => $label ) {
431
+                                $key   = esc_attr( $key );
432
+                                $label = sanitize_text_field( $label );
433 433
 
434
-								echo "<th class='subscription-invoice-field-$key bg-light p-2 text-left color-dark font-weight-bold'>$label</th>";
435
-							}
436
-						?>
434
+                                echo "<th class='subscription-invoice-field-$key bg-light p-2 text-left color-dark font-weight-bold'>$label</th>";
435
+                            }
436
+                        ?>
437 437
 					</tr>
438 438
 				</thead>
439 439
 
@@ -449,66 +449,66 @@  discard block
 block discarded – undo
449 449
 
450 450
 					<?php
451 451
 
452
-						foreach( $payments as $payment ) :
452
+                        foreach( $payments as $payment ) :
453 453
 
454
-							// Ensure that we have an invoice.
455
-							$payment = new WPInv_Invoice( $payment );
454
+                            // Ensure that we have an invoice.
455
+                            $payment = new WPInv_Invoice( $payment );
456 456
 
457
-							// Abort if the invoice is invalid.
458
-							if ( ! $payment->get_id() ) {
459
-								continue;
460
-							}
457
+                            // Abort if the invoice is invalid.
458
+                            if ( ! $payment->get_id() ) {
459
+                                continue;
460
+                            }
461 461
 
462
-							echo '<tr>';
462
+                            echo '<tr>';
463 463
 
464
-								foreach ( array_keys( $columns ) as $key ) {
464
+                                foreach ( array_keys( $columns ) as $key ) {
465 465
 
466
-									echo '<td class="p-2 text-left">';
466
+                                    echo '<td class="p-2 text-left">';
467 467
 
468
-										switch( $key ) {
468
+                                        switch( $key ) {
469 469
 
470
-											case 'total':
471
-												echo '<strong>' . wpinv_price( $payment->get_total(), $payment->get_currency() ) . '</strong>';
472
-												break;
470
+                                            case 'total':
471
+                                                echo '<strong>' . wpinv_price( $payment->get_total(), $payment->get_currency() ) . '</strong>';
472
+                                                break;
473 473
 
474
-											case 'relationship':
475
-												echo $payment->is_renewal() ? __( 'Renewal Invoice', 'invoicing' ) : __( 'Initial Invoice', 'invoicing' );
476
-												break;
474
+                                            case 'relationship':
475
+                                                echo $payment->is_renewal() ? __( 'Renewal Invoice', 'invoicing' ) : __( 'Initial Invoice', 'invoicing' );
476
+                                                break;
477 477
 
478
-											case 'date':
479
-												echo getpaid_format_date_value( $payment->get_date_created() );
480
-												break;
478
+                                            case 'date':
479
+                                                echo getpaid_format_date_value( $payment->get_date_created() );
480
+                                                break;
481 481
 
482
-											case 'status':
482
+                                            case 'status':
483 483
 
484
-												$status = $payment->get_status_nicename();
485
-												if ( is_admin() ) {
486
-													$status = $payment->get_status_label_html();
487
-												}
484
+                                                $status = $payment->get_status_nicename();
485
+                                                if ( is_admin() ) {
486
+                                                    $status = $payment->get_status_label_html();
487
+                                                }
488 488
 
489
-												echo $status;
490
-												break;
489
+                                                echo $status;
490
+                                                break;
491 491
 
492
-											case 'invoice':
493
-												$link    = esc_url( get_edit_post_link( $payment->get_id() ) );
492
+                                            case 'invoice':
493
+                                                $link    = esc_url( get_edit_post_link( $payment->get_id() ) );
494 494
 
495
-												if ( ! is_admin() ) {
496
-													$link = esc_url( $payment->get_view_url() );
497
-												}
495
+                                                if ( ! is_admin() ) {
496
+                                                    $link = esc_url( $payment->get_view_url() );
497
+                                                }
498 498
 
499
-												$invoice = sanitize_text_field( $payment->get_number() );
500
-												echo "<a href='$link'>$invoice</a>";
501
-												break;
502
-										}
499
+                                                $invoice = sanitize_text_field( $payment->get_number() );
500
+                                                echo "<a href='$link'>$invoice</a>";
501
+                                                break;
502
+                                        }
503 503
 
504
-									echo '</td>';
504
+                                    echo '</td>';
505 505
 
506
-								}
506
+                                }
507 507
 
508
-							echo '</tr>';
508
+                            echo '</tr>';
509 509
 
510
-						endforeach;
511
-					?>
510
+                        endforeach;
511
+                    ?>
512 512
 
513 513
 				</tbody>
514 514
 
Please login to merge, or discard this patch.
includes/subscription-functions.php 1 patch
Indentation   +146 added lines, -146 removed lines patch added patch discarded remove patch
@@ -17,28 +17,28 @@  discard block
 block discarded – undo
17 17
  */
18 18
 function getpaid_get_subscriptions( $args = array(), $return = 'results' ) {
19 19
 
20
-	// Do not retrieve all fields if we just want the count.
21
-	if ( 'count' == $return ) {
22
-		$args['fields'] = 'id';
23
-		$args['number'] = 1;
24
-	}
20
+    // Do not retrieve all fields if we just want the count.
21
+    if ( 'count' == $return ) {
22
+        $args['fields'] = 'id';
23
+        $args['number'] = 1;
24
+    }
25 25
 
26
-	// Do not count all matches if we just want the results.
27
-	if ( 'results' == $return ) {
28
-		$args['count_total'] = false;
29
-	}
26
+    // Do not count all matches if we just want the results.
27
+    if ( 'results' == $return ) {
28
+        $args['count_total'] = false;
29
+    }
30 30
 
31
-	$query = new GetPaid_Subscriptions_Query( $args );
31
+    $query = new GetPaid_Subscriptions_Query( $args );
32 32
 
33
-	if ( 'results' == $return ) {
34
-		return $query->get_results();
35
-	}
33
+    if ( 'results' == $return ) {
34
+        return $query->get_results();
35
+    }
36 36
 
37
-	if ( 'count' == $return ) {
38
-		return $query->get_total();
39
-	}
37
+    if ( 'count' == $return ) {
38
+        return $query->get_total();
39
+    }
40 40
 
41
-	return $query;
41
+    return $query;
42 42
 }
43 43
 
44 44
 /**
@@ -48,18 +48,18 @@  discard block
 block discarded – undo
48 48
  */
49 49
 function getpaid_get_subscription_statuses() {
50 50
 
51
-	return apply_filters(
52
-		'getpaid_get_subscription_statuses',
53
-		array(
54
-			'pending'    => __( 'Pending', 'invoicing' ),
55
-			'trialling'  => __( 'Trialing', 'invoicing' ),
56
-			'active'     => __( 'Active', 'invoicing' ),
57
-			'failing'    => __( 'Failing', 'invoicing' ),
58
-			'expired'    => __( 'Expired', 'invoicing' ),
59
-			'completed'  => __( 'Complete', 'invoicing' ),
60
-			'cancelled'  => __( 'Cancelled', 'invoicing' ),
61
-		)
62
-	);
51
+    return apply_filters(
52
+        'getpaid_get_subscription_statuses',
53
+        array(
54
+            'pending'    => __( 'Pending', 'invoicing' ),
55
+            'trialling'  => __( 'Trialing', 'invoicing' ),
56
+            'active'     => __( 'Active', 'invoicing' ),
57
+            'failing'    => __( 'Failing', 'invoicing' ),
58
+            'expired'    => __( 'Expired', 'invoicing' ),
59
+            'completed'  => __( 'Complete', 'invoicing' ),
60
+            'cancelled'  => __( 'Cancelled', 'invoicing' ),
61
+        )
62
+    );
63 63
 
64 64
 }
65 65
 
@@ -69,8 +69,8 @@  discard block
 block discarded – undo
69 69
  * @return string
70 70
  */
71 71
 function getpaid_get_subscription_status_label( $status ) {
72
-	$statuses = getpaid_get_subscription_statuses();
73
-	return isset( $statuses[ $status ] ) ? $statuses[ $status ] : ucfirst( sanitize_text_field( $status ) );
72
+    $statuses = getpaid_get_subscription_statuses();
73
+    return isset( $statuses[ $status ] ) ? $statuses[ $status ] : ucfirst( sanitize_text_field( $status ) );
74 74
 }
75 75
 
76 76
 /**
@@ -80,18 +80,18 @@  discard block
 block discarded – undo
80 80
  */
81 81
 function getpaid_get_subscription_status_classes() {
82 82
 
83
-	return apply_filters(
84
-		'getpaid_get_subscription_status_classes',
85
-		array(
86
-			'pending'    => 'badge-dark',
87
-			'trialling'  => 'badge-info',
88
-			'active'     => 'badge-success',
89
-			'failing'    => 'badge-warning',
90
-			'expired'    => 'badge-danger',
91
-			'completed'  => 'badge-primary',
92
-			'cancelled'  => 'badge-secondary',
93
-		)
94
-	);
83
+    return apply_filters(
84
+        'getpaid_get_subscription_status_classes',
85
+        array(
86
+            'pending'    => 'badge-dark',
87
+            'trialling'  => 'badge-info',
88
+            'active'     => 'badge-success',
89
+            'failing'    => 'badge-warning',
90
+            'expired'    => 'badge-danger',
91
+            'completed'  => 'badge-primary',
92
+            'cancelled'  => 'badge-secondary',
93
+        )
94
+    );
95 95
 
96 96
 }
97 97
 
@@ -102,15 +102,15 @@  discard block
 block discarded – undo
102 102
  */
103 103
 function getpaid_get_subscription_status_counts( $args = array() ) {
104 104
 
105
-	$statuses = array_keys( getpaid_get_subscription_statuses() );
106
-	$counts   = array();
105
+    $statuses = array_keys( getpaid_get_subscription_statuses() );
106
+    $counts   = array();
107 107
 
108
-	foreach ( $statuses as $status ) {
109
-		$_args             = wp_parse_args( "status=$status", $args );
110
-		$counts[ $status ] = getpaid_get_subscriptions( $_args, 'count' );
111
-	}
108
+    foreach ( $statuses as $status ) {
109
+        $_args             = wp_parse_args( "status=$status", $args );
110
+        $counts[ $status ] = getpaid_get_subscriptions( $_args, 'count' );
111
+    }
112 112
 
113
-	return $counts;
113
+    return $counts;
114 114
 
115 115
 }
116 116
 
@@ -121,32 +121,32 @@  discard block
 block discarded – undo
121 121
  */
122 122
 function getpaid_get_subscription_periods() {
123 123
 
124
-	return apply_filters(
125
-		'getpaid_get_subscription_periods',
126
-		array(
124
+    return apply_filters(
125
+        'getpaid_get_subscription_periods',
126
+        array(
127 127
 
128
-			'day'   => array(
129
-				'singular' => __( '%s day', 'invoicing' ),
130
-				'plural'   => __( '%d days', 'invoicing' ),
131
-			),
128
+            'day'   => array(
129
+                'singular' => __( '%s day', 'invoicing' ),
130
+                'plural'   => __( '%d days', 'invoicing' ),
131
+            ),
132 132
 
133
-			'week'   => array(
134
-				'singular' => __( '%s week', 'invoicing' ),
135
-				'plural'   => __( '%d weeks', 'invoicing' ),
136
-			),
133
+            'week'   => array(
134
+                'singular' => __( '%s week', 'invoicing' ),
135
+                'plural'   => __( '%d weeks', 'invoicing' ),
136
+            ),
137 137
 
138
-			'month'   => array(
139
-				'singular' => __( '%s month', 'invoicing' ),
140
-				'plural'   => __( '%d months', 'invoicing' ),
141
-			),
138
+            'month'   => array(
139
+                'singular' => __( '%s month', 'invoicing' ),
140
+                'plural'   => __( '%d months', 'invoicing' ),
141
+            ),
142 142
 
143
-			'year'   => array(
144
-				'singular' => __( '%s year', 'invoicing' ),
145
-				'plural'   => __( '%d years', 'invoicing' ),
146
-			),
143
+            'year'   => array(
144
+                'singular' => __( '%s year', 'invoicing' ),
145
+                'plural'   => __( '%d years', 'invoicing' ),
146
+            ),
147 147
 
148
-		)
149
-	);
148
+        )
149
+    );
150 150
 
151 151
 }
152 152
 
@@ -157,7 +157,7 @@  discard block
 block discarded – undo
157 157
  * @return int
158 158
  */
159 159
 function getpaid_get_subscription_trial_period_interval( $trial_period ) {
160
-	return (int) preg_replace( '/[^0-9]/', '', $trial_period );
160
+    return (int) preg_replace( '/[^0-9]/', '', $trial_period );
161 161
 }
162 162
 
163 163
 /**
@@ -167,7 +167,7 @@  discard block
 block discarded – undo
167 167
  * @return string
168 168
  */
169 169
 function getpaid_get_subscription_trial_period_period( $trial_period ) {
170
-	return preg_replace( '/[^a-z]/', '', strtolower( $trial_period ) );
170
+    return preg_replace( '/[^a-z]/', '', strtolower( $trial_period ) );
171 171
 }
172 172
 
173 173
 /**
@@ -178,8 +178,8 @@  discard block
 block discarded – undo
178 178
  * @return string
179 179
  */
180 180
 function getpaid_get_subscription_period_label( $period, $interval = 1, $singular_prefix = '1' ) {
181
-	$label = (int) $interval > 1 ? getpaid_get_plural_subscription_period_label(  $period, $interval ) : getpaid_get_singular_subscription_period_label( $period, $singular_prefix );
182
-	return strtolower( sanitize_text_field( $label ) );
181
+    $label = (int) $interval > 1 ? getpaid_get_plural_subscription_period_label(  $period, $interval ) : getpaid_get_singular_subscription_period_label( $period, $singular_prefix );
182
+    return strtolower( sanitize_text_field( $label ) );
183 183
 }
184 184
 
185 185
 /**
@@ -190,22 +190,22 @@  discard block
 block discarded – undo
190 190
  */
191 191
 function getpaid_get_singular_subscription_period_label( $period, $singular_prefix = '1' ) {
192 192
 
193
-	$periods = getpaid_get_subscription_periods();
194
-	$period  = strtolower( $period );
193
+    $periods = getpaid_get_subscription_periods();
194
+    $period  = strtolower( $period );
195 195
 
196
-	if ( isset( $periods[ $period ] ) ) {
197
-		return sprintf( $periods[ $period ]['singular'], $singular_prefix );
198
-	}
196
+    if ( isset( $periods[ $period ] ) ) {
197
+        return sprintf( $periods[ $period ]['singular'], $singular_prefix );
198
+    }
199 199
 
200
-	// Backwards compatibility.
201
-	foreach ( $periods as $key => $data ) {
202
-		if ( strpos( $key, $period ) === 0 ) {
203
-			return sprintf( $data['singular'], $singular_prefix );
204
-		}
205
-	}
200
+    // Backwards compatibility.
201
+    foreach ( $periods as $key => $data ) {
202
+        if ( strpos( $key, $period ) === 0 ) {
203
+            return sprintf( $data['singular'], $singular_prefix );
204
+        }
205
+    }
206 206
 
207
-	// Invalid string.
208
-	return '';
207
+    // Invalid string.
208
+    return '';
209 209
 }
210 210
 
211 211
 /**
@@ -217,22 +217,22 @@  discard block
 block discarded – undo
217 217
  */
218 218
 function getpaid_get_plural_subscription_period_label( $period, $interval ) {
219 219
 
220
-	$periods = getpaid_get_subscription_periods();
221
-	$period  = strtolower( $period );
220
+    $periods = getpaid_get_subscription_periods();
221
+    $period  = strtolower( $period );
222 222
 
223
-	if ( isset( $periods[ $period ] ) ) {
224
-		return sprintf( $periods[ $period ]['plural'], $interval );
225
-	}
223
+    if ( isset( $periods[ $period ] ) ) {
224
+        return sprintf( $periods[ $period ]['plural'], $interval );
225
+    }
226 226
 
227
-	// Backwards compatibility.
228
-	foreach ( $periods as $key => $data ) {
229
-		if ( strpos( $key, $period ) === 0 ) {
230
-			return sprintf( $data['plural'], $interval );
231
-		}
232
-	}
227
+    // Backwards compatibility.
228
+    foreach ( $periods as $key => $data ) {
229
+        if ( strpos( $key, $period ) === 0 ) {
230
+            return sprintf( $data['plural'], $interval );
231
+        }
232
+    }
233 233
 
234
-	// Invalid string.
235
-	return '';
234
+    // Invalid string.
235
+    return '';
236 236
 }
237 237
 
238 238
 /**
@@ -243,50 +243,50 @@  discard block
 block discarded – undo
243 243
  */
244 244
 function getpaid_get_formatted_subscription_amount( $subscription ) {
245 245
 
246
-	$initial   = wpinv_price( $subscription->get_initial_amount(), $subscription->get_parent_payment()->get_currency() );
247
-	$recurring = wpinv_price( $subscription->get_recurring_amount(), $subscription->get_parent_payment()->get_currency() );
248
-	$period    = getpaid_get_subscription_period_label( $subscription->get_period(), $subscription->get_frequency(), '' );
246
+    $initial   = wpinv_price( $subscription->get_initial_amount(), $subscription->get_parent_payment()->get_currency() );
247
+    $recurring = wpinv_price( $subscription->get_recurring_amount(), $subscription->get_parent_payment()->get_currency() );
248
+    $period    = getpaid_get_subscription_period_label( $subscription->get_period(), $subscription->get_frequency(), '' );
249 249
 
250
-	// Trial periods.
251
-	if ( $subscription->has_trial_period() ) {
250
+    // Trial periods.
251
+    if ( $subscription->has_trial_period() ) {
252 252
 
253
-		$trial_period   = getpaid_get_subscription_trial_period_period( $subscription->get_trial_period() );
254
-		$trial_interval = getpaid_get_subscription_trial_period_interval( $subscription->get_trial_period() );
255
-		return sprintf(
253
+        $trial_period   = getpaid_get_subscription_trial_period_period( $subscription->get_trial_period() );
254
+        $trial_interval = getpaid_get_subscription_trial_period_interval( $subscription->get_trial_period() );
255
+        return sprintf(
256 256
 
257
-			// translators: $1: is the initial amount, $2: is the trial period, $3: is the recurring amount, $4: is the recurring period
258
-			_x( '%1$s trial for %2$s then %3$s / %4$s', 'Subscription amount. (e.g.: $10 trial for 1 month then $120 / year)', 'invoicing' ),
259
-			$initial,
260
-			getpaid_get_subscription_period_label( $trial_period, $trial_interval ),
261
-			$recurring,
262
-			$period
257
+            // translators: $1: is the initial amount, $2: is the trial period, $3: is the recurring amount, $4: is the recurring period
258
+            _x( '%1$s trial for %2$s then %3$s / %4$s', 'Subscription amount. (e.g.: $10 trial for 1 month then $120 / year)', 'invoicing' ),
259
+            $initial,
260
+            getpaid_get_subscription_period_label( $trial_period, $trial_interval ),
261
+            $recurring,
262
+            $period
263 263
 
264
-		);
264
+        );
265 265
 
266
-	}
266
+    }
267 267
 
268
-	if ( $initial != $recurring ) {
268
+    if ( $initial != $recurring ) {
269 269
 
270
-		return sprintf(
270
+        return sprintf(
271 271
 
272
-			// translators: $1: is the initial amount, $2: is the recurring amount, $3: is the recurring period
273
-			_x( 'Initial payment of %1$s which renews at %2$s / %3$s', 'Subscription amount. (e.g.:Initial payment of $100 which renews at $120 / year)', 'invoicing' ),
274
-			$initial,
275
-			$recurring,
276
-			$period
272
+            // translators: $1: is the initial amount, $2: is the recurring amount, $3: is the recurring period
273
+            _x( 'Initial payment of %1$s which renews at %2$s / %3$s', 'Subscription amount. (e.g.:Initial payment of $100 which renews at $120 / year)', 'invoicing' ),
274
+            $initial,
275
+            $recurring,
276
+            $period
277 277
 
278
-		);
278
+        );
279 279
 
280
-	}
280
+    }
281 281
 
282
-	return sprintf(
282
+    return sprintf(
283 283
 
284
-		// translators: $1: is the recurring amount, $2: is the recurring period
285
-		_x( '%1$s / %2$s', 'Subscription amount. (e.g.: $120 / year)', 'invoicing' ),
286
-		$initial,
287
-		$period
284
+        // translators: $1: is the recurring amount, $2: is the recurring period
285
+        _x( '%1$s / %2$s', 'Subscription amount. (e.g.: $120 / year)', 'invoicing' ),
286
+        $initial,
287
+        $period
288 288
 
289
-	);
289
+    );
290 290
 
291 291
 }
292 292
 
@@ -297,7 +297,7 @@  discard block
 block discarded – undo
297 297
  * @return WPInv_Subscription|bool
298 298
  */
299 299
 function getpaid_get_invoice_subscription( $invoice ) {
300
-	return getpaid_subscriptions()->get_invoice_subscription( $invoice );
300
+    return getpaid_subscriptions()->get_invoice_subscription( $invoice );
301 301
 }
302 302
 
303 303
 /**
@@ -306,10 +306,10 @@  discard block
 block discarded – undo
306 306
  * @param WPInv_Invoice $invoice
307 307
  */
308 308
 function getpaid_activate_invoice_subscription( $invoice ) {
309
-	$subscription = getpaid_get_invoice_subscription( $invoice );
310
-	if ( is_a( $subscription, 'WPInv_Subscription' ) ) {
311
-		$subscription->activate();
312
-	}
309
+    $subscription = getpaid_get_invoice_subscription( $invoice );
310
+    if ( is_a( $subscription, 'WPInv_Subscription' ) ) {
311
+        $subscription->activate();
312
+    }
313 313
 }
314 314
 
315 315
 /**
@@ -318,7 +318,7 @@  discard block
 block discarded – undo
318 318
  * @return WPInv_Subscriptions
319 319
  */
320 320
 function getpaid_subscriptions() {
321
-	return getpaid()->get( 'subscriptions' );
321
+    return getpaid()->get( 'subscriptions' );
322 322
 }
323 323
 
324 324
 /**
@@ -336,14 +336,14 @@  discard block
 block discarded – undo
336 336
         return false;
337 337
     }
338 338
 
339
-	// Fetch the invoiec subscription.
340
-	$subscription = getpaid_get_subscriptions(
341
-		array(
342
-			'invoice_in' => $invoice->is_renewal() ? $invoice->get_parent_id() : $invoice->get_id(),
343
-			'number'     => 1,
344
-		)
345
-	);
339
+    // Fetch the invoiec subscription.
340
+    $subscription = getpaid_get_subscriptions(
341
+        array(
342
+            'invoice_in' => $invoice->is_renewal() ? $invoice->get_parent_id() : $invoice->get_id(),
343
+            'number'     => 1,
344
+        )
345
+    );
346 346
 
347
-	return empty( $subscription ) ? false : $subscription[0];
347
+    return empty( $subscription ) ? false : $subscription[0];
348 348
 
349 349
 }
Please login to merge, or discard this patch.
includes/class-getpaid-subscription-notification-emails.php 1 patch
Indentation   +239 added lines, -239 removed lines patch added patch discarded remove patch
@@ -13,282 +13,282 @@
 block discarded – undo
13 13
 class GetPaid_Subscription_Notification_Emails {
14 14
 
15 15
     /**
16
-	 * The array of subscription email actions.
17
-	 *
18
-	 * @param array
19
-	 */
20
-	public $subscription_actions;
16
+     * The array of subscription email actions.
17
+     *
18
+     * @param array
19
+     */
20
+    public $subscription_actions;
21 21
 
22 22
     /**
23
-	 * Class constructor
23
+     * Class constructor
24 24
      *
25
-	 */
26
-	public function __construct() {
27
-
28
-		$this->subscription_actions = apply_filters(
29
-			'getpaid_notification_email_subscription_triggers',
30
-			array(
31
-				'getpaid_subscription_trialling' => 'subscription_trial',
32
-				'getpaid_subscription_cancelled' => 'subscription_cancelled',
33
-				'getpaid_subscription_expired'   => 'subscription_expired',
34
-				'getpaid_subscription_completed' => 'subscription_complete',
35
-				'getpaid_daily_maintenance'      => 'renewal_reminder',
36
-			)
37
-		);
38
-
39
-		$this->init_hooks();
25
+     */
26
+    public function __construct() {
27
+
28
+        $this->subscription_actions = apply_filters(
29
+            'getpaid_notification_email_subscription_triggers',
30
+            array(
31
+                'getpaid_subscription_trialling' => 'subscription_trial',
32
+                'getpaid_subscription_cancelled' => 'subscription_cancelled',
33
+                'getpaid_subscription_expired'   => 'subscription_expired',
34
+                'getpaid_subscription_completed' => 'subscription_complete',
35
+                'getpaid_daily_maintenance'      => 'renewal_reminder',
36
+            )
37
+        );
38
+
39
+        $this->init_hooks();
40 40
 
41 41
     }
42 42
 
43 43
     /**
44
-	 * Registers email hooks.
45
-	 */
46
-	public function init_hooks() {
47
-
48
-		add_filter( 'getpaid_get_email_merge_tags', array( $this, 'subscription_merge_tags' ), 10, 2 );
49
-		foreach ( $this->subscription_actions as $hook => $email_type ) {
50
-
51
-			$email = new GetPaid_Notification_Email( $email_type );
52
-
53
-			if ( ! $email->is_active() ) {
54
-				continue;
55
-			}
56
-
57
-			if ( method_exists( $this, $email_type ) ) {
58
-				add_action( $hook, array( $this, $email_type ), 100, 2 );
59
-				continue;
60
-			}
61
-
62
-			do_action( 'getpaid_subscription_notification_email_register_hook', $email_type, $hook );
63
-
64
-		}
65
-
66
-	}
67
-
68
-	/**
69
-	 * Filters subscription merge tags.
70
-	 *
71
-	 * @param array $merge_tags
72
-	 * @param mixed|WPInv_Invoice|WPInv_Subscription $object
73
-	 */
74
-	public function subscription_merge_tags( $merge_tags, $object ) {
75
-
76
-		if ( is_a( $object, 'WPInv_Subscription' ) ) {
77
-			$merge_tags = array_merge(
78
-				$merge_tags,
79
-				$this->get_subscription_merge_tags( $object )
80
-			);
81
-		}
82
-
83
-		return $merge_tags;
84
-
85
-	}
86
-
87
-	/**
88
-	 * Generates subscription merge tags.
89
-	 *
90
-	 * @param WPInv_Subscription $subscription
91
-	 * @return array
92
-	 */
93
-	public function get_subscription_merge_tags( $subscription ) {
94
-
95
-		// Abort if it does not exist.
96
-		if ( ! $subscription->get_id() ) {
97
-			return array();
98
-		}
99
-
100
-		$invoice    = $subscription->get_parent_invoice();
101
-		return array(
102
-			'{subscription_renewal_date}'     => getpaid_format_date_value( $subscription->get_next_renewal_date(), __( 'Never', 'invoicing' ) ),
103
-			'{subscription_created}'          => getpaid_format_date_value( $subscription->get_date_created() ),
104
-			'{subscription_status}'           => sanitize_text_field( $subscription->get_status_label() ),
105
-			'{subscription_profile_id}'       => sanitize_text_field( $subscription->get_profile_id() ),
106
-			'{subscription_id}'               => absint( $subscription->get_id() ),
107
-			'{subscription_recurring_amount}' => sanitize_text_field( wpinv_price( $subscription->get_recurring_amount(), $invoice->get_currency() ) ),
108
-			'{subscription_initial_amount}'   => sanitize_text_field( wpinv_price( $subscription->get_initial_amount(), $invoice->get_currency() ) ),
109
-			'{subscription_recurring_period}' => getpaid_get_subscription_period_label( $subscription->get_period(), $subscription->get_frequency(), '' ),
110
-			'{subscription_bill_times}'       => $subscription->get_bill_times(),
111
-			'{subscription_url}'              => esc_url( $subscription->get_view_url() ),
112
-		);
113
-
114
-	}
115
-
116
-	/**
117
-	 * Checks if we should send a notification for a subscription.
118
-	 *
119
-	 * @param WPInv_Invoice $invoice
120
-	 * @return bool
121
-	 */
122
-	public function should_send_notification( $invoice ) {
123
-		return 0 != $invoice->get_id();
124
-	}
125
-
126
-	/**
127
-	 * Returns notification recipients.
128
-	 *
129
-	 * @param WPInv_Invoice $invoice
130
-	 * @return array
131
-	 */
132
-	public function get_recipients( $invoice ) {
133
-		$recipients = array( $invoice->get_email() );
134
-
135
-		$cc = $invoice->get_email_cc();
136
-
137
-		if ( ! empty( $cc ) ) {
138
-			$cc = array_map( 'sanitize_email', wpinv_parse_list( $cc ) );
139
-			$recipients = array_filter( array_unique( array_merge( $recipients, $cc ) ) );
140
-		}
141
-
142
-		return $recipients;
143
-	}
144
-
145
-	/**
146
-	 * Helper function to send an email.
147
-	 *
148
-	 * @param WPInv_Subscription $subscription
149
-	 * @param GetPaid_Notification_Email $email
150
-	 * @param string $type
151
-	 * @param array $extra_args Extra template args.
152
-	 */
153
-	public function send_email( $subscription, $email, $type, $extra_args = array() ) {
154
-
155
-		// Abort in case the parent invoice does not exist.
156
-		$invoice = $subscription->get_parent_invoice();
157
-		if ( ! $this->should_send_notification( $invoice ) ) {
158
-			return;
159
-		}
160
-
161
-		do_action( 'getpaid_before_send_subscription_notification', $type, $subscription, $email );
162
-
163
-		$recipients  = $this->get_recipients( $invoice );
164
-		$mailer      = new GetPaid_Notification_Email_Sender();
165
-		$merge_tags  = $email->get_merge_tags();
166
-		$content     = $email->get_content( $merge_tags, $extra_args );
167
-		$subject     = $email->add_merge_tags( $email->get_subject(), $merge_tags );
168
-		$attachments = $email->get_attachments();
169
-
170
-		$result = $mailer->send(
171
-			apply_filters( 'getpaid_subscription_email_recipients', wpinv_parse_list( $recipients ), $email ),
172
-			$subject,
173
-			$content,
174
-			$attachments
175
-		);
176
-
177
-		// Maybe send a copy to the admin.
178
-		if ( $email->include_admin_bcc() ) {
179
-			$mailer->send(
180
-				wpinv_get_admin_email(),
181
-				$subject . __( ' - ADMIN BCC COPY', 'invoicing' ),
182
-				$content,
183
-				$attachments
184
-			);
185
-		}
186
-
187
-		if ( ! $result ) {
188
-			$subscription->get_parent_invoice()->add_note( sprintf( __( 'Failed sending %s notification email.', 'invoicing' ), sanitize_key( $type ) ), false, false, true );
189
-		}
190
-
191
-		do_action( 'getpaid_after_send_subscription_notification', $type, $subscription, $email );
192
-
193
-	}
44
+     * Registers email hooks.
45
+     */
46
+    public function init_hooks() {
47
+
48
+        add_filter( 'getpaid_get_email_merge_tags', array( $this, 'subscription_merge_tags' ), 10, 2 );
49
+        foreach ( $this->subscription_actions as $hook => $email_type ) {
50
+
51
+            $email = new GetPaid_Notification_Email( $email_type );
52
+
53
+            if ( ! $email->is_active() ) {
54
+                continue;
55
+            }
56
+
57
+            if ( method_exists( $this, $email_type ) ) {
58
+                add_action( $hook, array( $this, $email_type ), 100, 2 );
59
+                continue;
60
+            }
61
+
62
+            do_action( 'getpaid_subscription_notification_email_register_hook', $email_type, $hook );
63
+
64
+        }
65
+
66
+    }
194 67
 
195 68
     /**
196
-	 * Sends a new trial notification.
197
-	 *
198
-	 * @param WPInv_Subscription $subscription
199
-	 */
200
-	public function subscription_trial( $subscription ) {
69
+     * Filters subscription merge tags.
70
+     *
71
+     * @param array $merge_tags
72
+     * @param mixed|WPInv_Invoice|WPInv_Subscription $object
73
+     */
74
+    public function subscription_merge_tags( $merge_tags, $object ) {
201 75
 
202
-		$email     = new GetPaid_Notification_Email( __FUNCTION__, $subscription );
203
-		$this->send_email( $subscription, $email, __FUNCTION__ );
76
+        if ( is_a( $object, 'WPInv_Subscription' ) ) {
77
+            $merge_tags = array_merge(
78
+                $merge_tags,
79
+                $this->get_subscription_merge_tags( $object )
80
+            );
81
+        }
204 82
 
205
-	}
83
+        return $merge_tags;
206 84
 
207
-	/**
208
-	 * Sends a cancelled subscription notification.
209
-	 *
210
-	 * @param WPInv_Subscription $subscription
211
-	 */
212
-	public function subscription_cancelled( $subscription ) {
85
+    }
213 86
 
214
-		$email     = new GetPaid_Notification_Email( __FUNCTION__, $subscription );
215
-		$this->send_email( $subscription, $email, __FUNCTION__ );
87
+    /**
88
+     * Generates subscription merge tags.
89
+     *
90
+     * @param WPInv_Subscription $subscription
91
+     * @return array
92
+     */
93
+    public function get_subscription_merge_tags( $subscription ) {
94
+
95
+        // Abort if it does not exist.
96
+        if ( ! $subscription->get_id() ) {
97
+            return array();
98
+        }
99
+
100
+        $invoice    = $subscription->get_parent_invoice();
101
+        return array(
102
+            '{subscription_renewal_date}'     => getpaid_format_date_value( $subscription->get_next_renewal_date(), __( 'Never', 'invoicing' ) ),
103
+            '{subscription_created}'          => getpaid_format_date_value( $subscription->get_date_created() ),
104
+            '{subscription_status}'           => sanitize_text_field( $subscription->get_status_label() ),
105
+            '{subscription_profile_id}'       => sanitize_text_field( $subscription->get_profile_id() ),
106
+            '{subscription_id}'               => absint( $subscription->get_id() ),
107
+            '{subscription_recurring_amount}' => sanitize_text_field( wpinv_price( $subscription->get_recurring_amount(), $invoice->get_currency() ) ),
108
+            '{subscription_initial_amount}'   => sanitize_text_field( wpinv_price( $subscription->get_initial_amount(), $invoice->get_currency() ) ),
109
+            '{subscription_recurring_period}' => getpaid_get_subscription_period_label( $subscription->get_period(), $subscription->get_frequency(), '' ),
110
+            '{subscription_bill_times}'       => $subscription->get_bill_times(),
111
+            '{subscription_url}'              => esc_url( $subscription->get_view_url() ),
112
+        );
216 113
 
217
-	}
114
+    }
218 115
 
219
-	/**
220
-	 * Sends a subscription expired notification.
221
-	 *
222
-	 * @param WPInv_Subscription $subscription
223
-	 */
224
-	public function subscription_expired( $subscription ) {
116
+    /**
117
+     * Checks if we should send a notification for a subscription.
118
+     *
119
+     * @param WPInv_Invoice $invoice
120
+     * @return bool
121
+     */
122
+    public function should_send_notification( $invoice ) {
123
+        return 0 != $invoice->get_id();
124
+    }
225 125
 
226
-		$email     = new GetPaid_Notification_Email( __FUNCTION__, $subscription );
227
-		$this->send_email( $subscription, $email, __FUNCTION__ );
126
+    /**
127
+     * Returns notification recipients.
128
+     *
129
+     * @param WPInv_Invoice $invoice
130
+     * @return array
131
+     */
132
+    public function get_recipients( $invoice ) {
133
+        $recipients = array( $invoice->get_email() );
228 134
 
229
-	}
135
+        $cc = $invoice->get_email_cc();
230 136
 
231
-	/**
232
-	 * Sends a completed subscription notification.
233
-	 *
234
-	 * @param WPInv_Subscription $subscription
235
-	 */
236
-	public function subscription_complete( $subscription ) {
137
+        if ( ! empty( $cc ) ) {
138
+            $cc = array_map( 'sanitize_email', wpinv_parse_list( $cc ) );
139
+            $recipients = array_filter( array_unique( array_merge( $recipients, $cc ) ) );
140
+        }
237 141
 
238
-		$email     = new GetPaid_Notification_Email( __FUNCTION__, $subscription );
239
-		$this->send_email( $subscription, $email, __FUNCTION__ );
142
+        return $recipients;
143
+    }
240 144
 
241
-	}
145
+    /**
146
+     * Helper function to send an email.
147
+     *
148
+     * @param WPInv_Subscription $subscription
149
+     * @param GetPaid_Notification_Email $email
150
+     * @param string $type
151
+     * @param array $extra_args Extra template args.
152
+     */
153
+    public function send_email( $subscription, $email, $type, $extra_args = array() ) {
154
+
155
+        // Abort in case the parent invoice does not exist.
156
+        $invoice = $subscription->get_parent_invoice();
157
+        if ( ! $this->should_send_notification( $invoice ) ) {
158
+            return;
159
+        }
160
+
161
+        do_action( 'getpaid_before_send_subscription_notification', $type, $subscription, $email );
162
+
163
+        $recipients  = $this->get_recipients( $invoice );
164
+        $mailer      = new GetPaid_Notification_Email_Sender();
165
+        $merge_tags  = $email->get_merge_tags();
166
+        $content     = $email->get_content( $merge_tags, $extra_args );
167
+        $subject     = $email->add_merge_tags( $email->get_subject(), $merge_tags );
168
+        $attachments = $email->get_attachments();
169
+
170
+        $result = $mailer->send(
171
+            apply_filters( 'getpaid_subscription_email_recipients', wpinv_parse_list( $recipients ), $email ),
172
+            $subject,
173
+            $content,
174
+            $attachments
175
+        );
176
+
177
+        // Maybe send a copy to the admin.
178
+        if ( $email->include_admin_bcc() ) {
179
+            $mailer->send(
180
+                wpinv_get_admin_email(),
181
+                $subject . __( ' - ADMIN BCC COPY', 'invoicing' ),
182
+                $content,
183
+                $attachments
184
+            );
185
+        }
186
+
187
+        if ( ! $result ) {
188
+            $subscription->get_parent_invoice()->add_note( sprintf( __( 'Failed sending %s notification email.', 'invoicing' ), sanitize_key( $type ) ), false, false, true );
189
+        }
190
+
191
+        do_action( 'getpaid_after_send_subscription_notification', $type, $subscription, $email );
242 192
 
243
-	/**
244
-	 * Sends a subscription renewal reminder notification.
245
-	 *
246
-	 */
247
-	public function renewal_reminder() {
193
+    }
248 194
 
249
-		$email = new GetPaid_Notification_Email( __FUNCTION__ );
195
+    /**
196
+     * Sends a new trial notification.
197
+     *
198
+     * @param WPInv_Subscription $subscription
199
+     */
200
+    public function subscription_trial( $subscription ) {
250 201
 
251
-		// Fetch reminder days.
252
-		$reminder_days = array_unique( wp_parse_id_list( $email->get_option( 'days' ) ) );
202
+        $email     = new GetPaid_Notification_Email( __FUNCTION__, $subscription );
203
+        $this->send_email( $subscription, $email, __FUNCTION__ );
253 204
 
254
-		// Abort if non is set.
255
-		if ( empty( $reminder_days ) ) {
256
-			return;
257
-		}
205
+    }
258 206
 
259
-		// Fetch matching subscriptions.
207
+    /**
208
+     * Sends a cancelled subscription notification.
209
+     *
210
+     * @param WPInv_Subscription $subscription
211
+     */
212
+    public function subscription_cancelled( $subscription ) {
213
+
214
+        $email     = new GetPaid_Notification_Email( __FUNCTION__, $subscription );
215
+        $this->send_email( $subscription, $email, __FUNCTION__ );
216
+
217
+    }
218
+
219
+    /**
220
+     * Sends a subscription expired notification.
221
+     *
222
+     * @param WPInv_Subscription $subscription
223
+     */
224
+    public function subscription_expired( $subscription ) {
225
+
226
+        $email     = new GetPaid_Notification_Email( __FUNCTION__, $subscription );
227
+        $this->send_email( $subscription, $email, __FUNCTION__ );
228
+
229
+    }
230
+
231
+    /**
232
+     * Sends a completed subscription notification.
233
+     *
234
+     * @param WPInv_Subscription $subscription
235
+     */
236
+    public function subscription_complete( $subscription ) {
237
+
238
+        $email     = new GetPaid_Notification_Email( __FUNCTION__, $subscription );
239
+        $this->send_email( $subscription, $email, __FUNCTION__ );
240
+
241
+    }
242
+
243
+    /**
244
+     * Sends a subscription renewal reminder notification.
245
+     *
246
+     */
247
+    public function renewal_reminder() {
248
+
249
+        $email = new GetPaid_Notification_Email( __FUNCTION__ );
250
+
251
+        // Fetch reminder days.
252
+        $reminder_days = array_unique( wp_parse_id_list( $email->get_option( 'days' ) ) );
253
+
254
+        // Abort if non is set.
255
+        if ( empty( $reminder_days ) ) {
256
+            return;
257
+        }
258
+
259
+        // Fetch matching subscriptions.
260 260
         $args  = array(
261 261
             'number'             => -1,
262
-			'count_total'        => false,
263
-			'status'             => 'trialling active',
262
+            'count_total'        => false,
263
+            'status'             => 'trialling active',
264 264
             'date_expires_query' => array(
265
-				'relation'  => 'OR'
265
+                'relation'  => 'OR'
266 266
             ),
267
-		);
267
+        );
268 268
 
269
-		foreach ( $reminder_days as $days ) {
270
-			$date = date_parse( date( 'Y-m-d', strtotime( "+$days days", current_time( 'timestamp' ) ) ) );
269
+        foreach ( $reminder_days as $days ) {
270
+            $date = date_parse( date( 'Y-m-d', strtotime( "+$days days", current_time( 'timestamp' ) ) ) );
271 271
 
272
-			$args['date_expires_query'][] = array(
273
-				'year'  => $date['year'],
274
-				'month' => $date['month'],
275
-				'day'   => $date['day'],
276
-			);
272
+            $args['date_expires_query'][] = array(
273
+                'year'  => $date['year'],
274
+                'month' => $date['month'],
275
+                'day'   => $date['day'],
276
+            );
277 277
 
278
-		}
278
+        }
279 279
 
280
-		$subscriptions = new GetPaid_Subscriptions_Query( $args );
280
+        $subscriptions = new GetPaid_Subscriptions_Query( $args );
281 281
 
282 282
         foreach ( $subscriptions as $subscription ) {
283 283
 
284
-			// Skip packages.
285
-			if ( get_post_meta( $subscription->get_product_id(), '_wpinv_type', true ) != 'package' ) {
286
-				$email->object = $subscription;
287
-            	$this->send_email( $subscription, $email, __FUNCTION__ );
288
-			}
284
+            // Skip packages.
285
+            if ( get_post_meta( $subscription->get_product_id(), '_wpinv_type', true ) != 'package' ) {
286
+                $email->object = $subscription;
287
+                $this->send_email( $subscription, $email, __FUNCTION__ );
288
+            }
289 289
 
290
-		}
290
+        }
291 291
 
292
-	}
292
+    }
293 293
 
294 294
 }
Please login to merge, or discard this patch.
includes/data-stores/class-getpaid-subscription-data-store.php 1 patch
Indentation   +181 added lines, -181 removed lines patch added patch discarded remove patch
@@ -5,7 +5,7 @@  discard block
 block discarded – undo
5 5
  *
6 6
  */
7 7
 if ( ! defined( 'ABSPATH' ) ) {
8
-	exit;
8
+    exit;
9 9
 }
10 10
 
11 11
 /**
@@ -15,197 +15,197 @@  discard block
 block discarded – undo
15 15
  */
16 16
 class GetPaid_Subscription_Data_Store {
17 17
 
18
-	/**
19
-	 * A map of database fields to data types.
20
-	 *
21
-	 * @since 1.0.19
22
-	 * @var array
23
-	 */
24
-	protected $database_fields_to_data_type = array(
25
-		'id'                => '%d',
26
-		'customer_id'       => '%d',
27
-		'frequency'         => '%d',
28
-		'period'            => '%s',
29
-		'initial_amount'    => '%s',
30
-		'recurring_amount'  => '%s',
31
-		'bill_times'        => '%d',
32
-		'transaction_id'    => '%s',
33
-		'parent_payment_id' => '%d',
34
-		'product_id'        => '%d',
35
-		'created'           => '%s',
36
-		'expiration'        => '%s',
37
-		'trial_period'      => '%s',
38
-		'status'            => '%s',
39
-		'profile_id'        => '%s',
40
-	);
41
-
42
-	/*
18
+    /**
19
+     * A map of database fields to data types.
20
+     *
21
+     * @since 1.0.19
22
+     * @var array
23
+     */
24
+    protected $database_fields_to_data_type = array(
25
+        'id'                => '%d',
26
+        'customer_id'       => '%d',
27
+        'frequency'         => '%d',
28
+        'period'            => '%s',
29
+        'initial_amount'    => '%s',
30
+        'recurring_amount'  => '%s',
31
+        'bill_times'        => '%d',
32
+        'transaction_id'    => '%s',
33
+        'parent_payment_id' => '%d',
34
+        'product_id'        => '%d',
35
+        'created'           => '%s',
36
+        'expiration'        => '%s',
37
+        'trial_period'      => '%s',
38
+        'status'            => '%s',
39
+        'profile_id'        => '%s',
40
+    );
41
+
42
+    /*
43 43
 	|--------------------------------------------------------------------------
44 44
 	| CRUD Methods
45 45
 	|--------------------------------------------------------------------------
46 46
 	*/
47 47
 
48
-	/**
49
-	 * Method to create a new subscription in the database.
50
-	 *
51
-	 * @param WPInv_Subscription $subscription Subscription object.
52
-	 */
53
-	public function create( &$subscription ) {
54
-		global $wpdb;
55
-
56
-		$values  = array();
57
-		$formats = array();
58
-
59
-		$fields = $this->database_fields_to_data_type;
60
-		unset( $fields['id'] );
61
-
62
-		foreach ( $fields as $key => $format ) {
63
-			$method       = "get_$key";
64
-			$values[$key] = $subscription->$method( 'edit' );
65
-			$formats[]    = $format;
66
-		}
67
-
68
-		$result = $wpdb->insert( $wpdb->prefix . 'wpinv_subscriptions', $values, $formats );
69
-
70
-		if ( $result ) {
71
-			$subscription->set_id( $wpdb->insert_id );
72
-			$subscription->apply_changes();
73
-			$subscription->clear_cache();
74
-			update_post_meta( $subscription->get_parent_invoice_id(), '_wpinv_subscription_id', $subscription->get_id() );
75
-			do_action( 'getpaid_new_subscription', $subscription );
76
-			return true;
77
-		}
78
-
79
-		return false;
80
-	}
81
-
82
-	/**
83
-	 * Method to read a subscription from the database.
84
-	 *
85
-	 * @param WPInv_Subscription $subscription Subscription object.
86
-	 *
87
-	 */
88
-	public function read( &$subscription ) {
89
-		global $wpdb;
90
-
91
-		$subscription->set_defaults();
92
-
93
-		if ( ! $subscription->get_id() ) {
94
-			$subscription->last_error = __( 'Invalid subscription ID.', 'invoicing' );
95
-			$subscription->set_id( 0 );
96
-			return false;
97
-		}
98
-
99
-		// Maybe retrieve from the cache.
100
-		$raw_subscription = wp_cache_get( $subscription->get_id(), 'getpaid_subscriptions' );
101
-
102
-		// If not found, retrieve from the db.
103
-		if ( false === $raw_subscription ) {
104
-
105
-			$raw_subscription = $wpdb->get_row(
106
-				$wpdb->prepare(
107
-					"SELECT * FROM {$wpdb->prefix}wpinv_subscriptions WHERE id = %d",
108
-					$subscription->get_id()
109
-				)
110
-			);
111
-
112
-			// Update the cache with our data
113
-			wp_cache_set( $subscription->get_id(), $raw_subscription, 'getpaid_subscriptions' );
114
-
115
-		}
116
-
117
-		if ( ! $raw_subscription ) {
118
-			$subscription->last_error = __( 'Invalid subscription ID.', 'invoicing' );
119
-			return false;
120
-		}
121
-
122
-		foreach ( array_keys( $this->database_fields_to_data_type ) as $key ) {
123
-			$method     = "set_$key";
124
-			$subscription->$method( $raw_subscription->$key );
125
-		}
126
-
127
-		$subscription->set_object_read( true );
128
-		do_action( 'getpaid_read_subscription', $subscription );
129
-
130
-	}
131
-
132
-	/**
133
-	 * Method to update a subscription in the database.
134
-	 *
135
-	 * @param WPInv_Subscription $subscription Subscription object.
136
-	 */
137
-	public function update( &$subscription ) {
138
-		global $wpdb;
139
-
140
-		$changes = $subscription->get_changes();
141
-		$values  = array();
142
-		$formats = array();
143
-
144
-		foreach ( $this->database_fields_to_data_type as $key => $format ) {
145
-			if ( array_key_exists( $key, $changes ) ) {
146
-				$method       = "get_$key";
147
-				$values[$key] = $subscription->$method( 'edit' );
148
-				$formats[]    = $format;
149
-			}
150
-		}
151
-
152
-		if ( empty( $values ) ) {
153
-			return;
154
-		}
155
-
156
-		$wpdb->update(
157
-			$wpdb->prefix . 'wpinv_subscriptions',
158
-			$values,
159
-			array(
160
-				'id' => $subscription->get_id(),
161
-			),
162
-			$formats,
163
-			'%d'
164
-		);
165
-
166
-		// Apply the changes.
167
-		$subscription->apply_changes();
168
-
169
-		// Delete cache.
170
-		$subscription->clear_cache();
171
-
172
-		update_post_meta( $subscription->get_parent_invoice_id(), '_wpinv_subscr_profile_id', $subscription->get_profile_id() );
173
-		update_post_meta( $subscription->get_parent_invoice_id(), '_wpinv_subscription_id', $subscription->get_id() );
174
-
175
-		// Fire a hook.
176
-		do_action( 'getpaid_update_subscription', $subscription );
177
-
178
-	}
179
-
180
-	/**
181
-	 * Method to delete a subscription from the database.
182
-	 *
183
-	 * @param WPInv_Subscription $subscription
184
-	 */
185
-	public function delete( &$subscription ) {
186
-		global $wpdb;
187
-
188
-		$wpdb->query(
189
-			$wpdb->prepare(
190
-				"DELETE FROM {$wpdb->prefix}wpinv_subscriptions
48
+    /**
49
+     * Method to create a new subscription in the database.
50
+     *
51
+     * @param WPInv_Subscription $subscription Subscription object.
52
+     */
53
+    public function create( &$subscription ) {
54
+        global $wpdb;
55
+
56
+        $values  = array();
57
+        $formats = array();
58
+
59
+        $fields = $this->database_fields_to_data_type;
60
+        unset( $fields['id'] );
61
+
62
+        foreach ( $fields as $key => $format ) {
63
+            $method       = "get_$key";
64
+            $values[$key] = $subscription->$method( 'edit' );
65
+            $formats[]    = $format;
66
+        }
67
+
68
+        $result = $wpdb->insert( $wpdb->prefix . 'wpinv_subscriptions', $values, $formats );
69
+
70
+        if ( $result ) {
71
+            $subscription->set_id( $wpdb->insert_id );
72
+            $subscription->apply_changes();
73
+            $subscription->clear_cache();
74
+            update_post_meta( $subscription->get_parent_invoice_id(), '_wpinv_subscription_id', $subscription->get_id() );
75
+            do_action( 'getpaid_new_subscription', $subscription );
76
+            return true;
77
+        }
78
+
79
+        return false;
80
+    }
81
+
82
+    /**
83
+     * Method to read a subscription from the database.
84
+     *
85
+     * @param WPInv_Subscription $subscription Subscription object.
86
+     *
87
+     */
88
+    public function read( &$subscription ) {
89
+        global $wpdb;
90
+
91
+        $subscription->set_defaults();
92
+
93
+        if ( ! $subscription->get_id() ) {
94
+            $subscription->last_error = __( 'Invalid subscription ID.', 'invoicing' );
95
+            $subscription->set_id( 0 );
96
+            return false;
97
+        }
98
+
99
+        // Maybe retrieve from the cache.
100
+        $raw_subscription = wp_cache_get( $subscription->get_id(), 'getpaid_subscriptions' );
101
+
102
+        // If not found, retrieve from the db.
103
+        if ( false === $raw_subscription ) {
104
+
105
+            $raw_subscription = $wpdb->get_row(
106
+                $wpdb->prepare(
107
+                    "SELECT * FROM {$wpdb->prefix}wpinv_subscriptions WHERE id = %d",
108
+                    $subscription->get_id()
109
+                )
110
+            );
111
+
112
+            // Update the cache with our data
113
+            wp_cache_set( $subscription->get_id(), $raw_subscription, 'getpaid_subscriptions' );
114
+
115
+        }
116
+
117
+        if ( ! $raw_subscription ) {
118
+            $subscription->last_error = __( 'Invalid subscription ID.', 'invoicing' );
119
+            return false;
120
+        }
121
+
122
+        foreach ( array_keys( $this->database_fields_to_data_type ) as $key ) {
123
+            $method     = "set_$key";
124
+            $subscription->$method( $raw_subscription->$key );
125
+        }
126
+
127
+        $subscription->set_object_read( true );
128
+        do_action( 'getpaid_read_subscription', $subscription );
129
+
130
+    }
131
+
132
+    /**
133
+     * Method to update a subscription in the database.
134
+     *
135
+     * @param WPInv_Subscription $subscription Subscription object.
136
+     */
137
+    public function update( &$subscription ) {
138
+        global $wpdb;
139
+
140
+        $changes = $subscription->get_changes();
141
+        $values  = array();
142
+        $formats = array();
143
+
144
+        foreach ( $this->database_fields_to_data_type as $key => $format ) {
145
+            if ( array_key_exists( $key, $changes ) ) {
146
+                $method       = "get_$key";
147
+                $values[$key] = $subscription->$method( 'edit' );
148
+                $formats[]    = $format;
149
+            }
150
+        }
151
+
152
+        if ( empty( $values ) ) {
153
+            return;
154
+        }
155
+
156
+        $wpdb->update(
157
+            $wpdb->prefix . 'wpinv_subscriptions',
158
+            $values,
159
+            array(
160
+                'id' => $subscription->get_id(),
161
+            ),
162
+            $formats,
163
+            '%d'
164
+        );
165
+
166
+        // Apply the changes.
167
+        $subscription->apply_changes();
168
+
169
+        // Delete cache.
170
+        $subscription->clear_cache();
171
+
172
+        update_post_meta( $subscription->get_parent_invoice_id(), '_wpinv_subscr_profile_id', $subscription->get_profile_id() );
173
+        update_post_meta( $subscription->get_parent_invoice_id(), '_wpinv_subscription_id', $subscription->get_id() );
174
+
175
+        // Fire a hook.
176
+        do_action( 'getpaid_update_subscription', $subscription );
177
+
178
+    }
179
+
180
+    /**
181
+     * Method to delete a subscription from the database.
182
+     *
183
+     * @param WPInv_Subscription $subscription
184
+     */
185
+    public function delete( &$subscription ) {
186
+        global $wpdb;
187
+
188
+        $wpdb->query(
189
+            $wpdb->prepare(
190
+                "DELETE FROM {$wpdb->prefix}wpinv_subscriptions
191 191
 				WHERE id = %d",
192
-				$subscription->get_id()
193
-			)
194
-		);
192
+                $subscription->get_id()
193
+            )
194
+        );
195 195
 
196
-		delete_post_meta( $subscription->get_parent_invoice_id(), '_wpinv_subscr_profile_id' );
197
-		delete_post_meta( $subscription->get_parent_invoice_id(), '_wpinv_subscription_id' );
196
+        delete_post_meta( $subscription->get_parent_invoice_id(), '_wpinv_subscr_profile_id' );
197
+        delete_post_meta( $subscription->get_parent_invoice_id(), '_wpinv_subscription_id' );
198 198
 
199
-		// Delete cache.
200
-		$subscription->clear_cache();
199
+        // Delete cache.
200
+        $subscription->clear_cache();
201 201
 
202
-		// Fire a hook.
203
-		do_action( 'getpaid_delete_subscription', $subscription );
202
+        // Fire a hook.
203
+        do_action( 'getpaid_delete_subscription', $subscription );
204 204
 
205
-		$subscription->set_id( 0 );
206
-	}
205
+        $subscription->set_id( 0 );
206
+    }
207 207
 
208
-	/*
208
+    /*
209 209
 	|--------------------------------------------------------------------------
210 210
 	| Additional Methods
211 211
 	|--------------------------------------------------------------------------
Please login to merge, or discard this patch.
includes/data-stores/class-getpaid-data.php 1 patch
Indentation   +860 added lines, -860 removed lines patch added patch discarded remove patch
@@ -9,7 +9,7 @@  discard block
 block discarded – undo
9 9
  */
10 10
 
11 11
 if ( ! defined( 'ABSPATH' ) ) {
12
-	exit;
12
+    exit;
13 13
 }
14 14
 
15 15
 /**
@@ -21,356 +21,356 @@  discard block
 block discarded – undo
21 21
  */
22 22
 abstract class GetPaid_Data {
23 23
 
24
-	/**
25
-	 * ID for this object.
26
-	 *
27
-	 * @since 1.0.19
28
-	 * @var int
29
-	 */
30
-	protected $id = 0;
31
-
32
-	/**
33
-	 * Core data for this object. Name value pairs (name + default value).
34
-	 *
35
-	 * @since 1.0.19
36
-	 * @var array
37
-	 */
38
-	protected $data = array();
39
-
40
-	/**
41
-	 * Core data changes for this object.
42
-	 *
43
-	 * @since 1.0.19
44
-	 * @var array
45
-	 */
46
-	protected $changes = array();
47
-
48
-	/**
49
-	 * This is false until the object is read from the DB.
50
-	 *
51
-	 * @since 1.0.19
52
-	 * @var bool
53
-	 */
54
-	protected $object_read = false;
55
-
56
-	/**
57
-	 * This is the name of this object type.
58
-	 *
59
-	 * @since 1.0.19
60
-	 * @var string
61
-	 */
62
-	protected $object_type = 'data';
63
-
64
-	/**
65
-	 * Extra data for this object. Name value pairs (name + default value).
66
-	 * Used as a standard way for sub classes (like item types) to add
67
-	 * additional information to an inherited class.
68
-	 *
69
-	 * @since 1.0.19
70
-	 * @var array
71
-	 */
72
-	protected $extra_data = array();
73
-
74
-	/**
75
-	 * Set to _data on construct so we can track and reset data if needed.
76
-	 *
77
-	 * @since 1.0.19
78
-	 * @var array
79
-	 */
80
-	protected $default_data = array();
81
-
82
-	/**
83
-	 * Contains a reference to the data store for this class.
84
-	 *
85
-	 * @since 1.0.19
86
-	 * @var GetPaid_Data_Store
87
-	 */
88
-	protected $data_store;
89
-
90
-	/**
91
-	 * Stores meta in cache for future reads.
92
-	 * A group must be set to to enable caching.
93
-	 *
94
-	 * @since 1.0.19
95
-	 * @var string
96
-	 */
97
-	protected $cache_group = '';
98
-
99
-	/**
100
-	 * Stores the last error.
101
-	 *
102
-	 * @since 1.0.19
103
-	 * @var string
104
-	 */
105
-	public $last_error = '';
106
-
107
-	/**
108
-	 * Stores additional meta data.
109
-	 *
110
-	 * @since 1.0.19
111
-	 * @var array
112
-	 */
113
-	protected $meta_data = null;
114
-
115
-	/**
116
-	 * Default constructor.
117
-	 *
118
-	 * @param int|object|array|string $read ID to load from the DB (optional) or already queried data.
119
-	 */
120
-	public function __construct( $read = 0 ) {
121
-		$this->data         = array_merge( $this->data, $this->extra_data );
122
-		$this->default_data = $this->data;
123
-	}
124
-
125
-	/**
126
-	 * Only store the object ID to avoid serializing the data object instance.
127
-	 *
128
-	 * @return array
129
-	 */
130
-	public function __sleep() {
131
-		return array( 'id' );
132
-	}
133
-
134
-	/**
135
-	 * Re-run the constructor with the object ID.
136
-	 *
137
-	 * If the object no longer exists, remove the ID.
138
-	 */
139
-	public function __wakeup() {
140
-		$this->__construct( absint( $this->id ) );
141
-
142
-		if ( ! empty( $this->last_error ) ) {
143
-			$this->set_id( 0 );
144
-		}
145
-
146
-	}
147
-
148
-	/**
149
-	 * When the object is cloned, make sure meta is duplicated correctly.
150
-	 *
151
-	 * @since 1.0.19
152
-	 */
153
-	public function __clone() {
154
-		$this->maybe_read_meta_data();
155
-		if ( ! empty( $this->meta_data ) ) {
156
-			foreach ( $this->meta_data as $array_key => $meta ) {
157
-				$this->meta_data[ $array_key ] = clone $meta;
158
-				if ( ! empty( $meta->id ) ) {
159
-					$this->meta_data[ $array_key ]->id = null;
160
-				}
161
-			}
162
-		}
163
-	}
164
-
165
-	/**
166
-	 * Get the data store.
167
-	 *
168
-	 * @since  1.0.19
169
-	 * @return object
170
-	 */
171
-	public function get_data_store() {
172
-		return $this->data_store;
173
-	}
174
-
175
-	/**
176
-	 * Get the object type.
177
-	 *
178
-	 * @since  1.0.19
179
-	 * @return string
180
-	 */
181
-	public function get_object_type() {
182
-		return $this->object_type;
183
-	}
184
-
185
-	/**
186
-	 * Returns the unique ID for this object.
187
-	 *
188
-	 * @since  1.0.19
189
-	 * @return int
190
-	 */
191
-	public function get_id() {
192
-		return $this->id;
193
-	}
194
-
195
-	/**
196
-	 * Get form status.
197
-	 *
198
-	 * @since 1.0.19
199
-	 * @param  string $context View or edit context.
200
-	 * @return string
201
-	 */
202
-	public function get_status( $context = 'view' ) {
203
-		return $this->get_prop( 'status', $context );
204
-    }
205
-
206
-	/**
207
-	 * Delete an object, set the ID to 0, and return result.
208
-	 *
209
-	 * @since  1.0.19
210
-	 * @param  bool $force_delete Should the data be deleted permanently.
211
-	 * @return bool result
212
-	 */
213
-	public function delete( $force_delete = false ) {
214
-		if ( $this->data_store && $this->exists() ) {
215
-			$this->data_store->delete( $this, array( 'force_delete' => $force_delete ) );
216
-			$this->set_id( 0 );
217
-			return true;
218
-		}
219
-		return false;
220
-	}
221
-
222
-	/**
223
-	 * Save should create or update based on object existence.
224
-	 *
225
-	 * @since  1.0.19
226
-	 * @return int
227
-	 */
228
-	public function save() {
229
-		if ( ! $this->data_store ) {
230
-			return $this->get_id();
231
-		}
232
-
233
-		/**
234
-		 * Trigger action before saving to the DB. Allows you to adjust object props before save.
235
-		 *
236
-		 * @param GetPaid_Data          $this The object being saved.
237
-		 * @param GetPaid_Data_Store_WP $data_store The data store persisting the data.
238
-		 */
239
-		do_action( 'getpaid_before_' . $this->object_type . '_object_save', $this, $this->data_store );
240
-
241
-		if ( $this->get_id() ) {
242
-			$this->data_store->update( $this );
243
-		} else {
244
-			$this->data_store->create( $this );
245
-		}
246
-
247
-		/**
248
-		 * Trigger action after saving to the DB.
249
-		 *
250
-		 * @param GetPaid_Data          $this The object being saved.
251
-		 * @param GetPaid_Data_Store_WP $data_store The data store persisting the data.
252
-		 */
253
-		do_action( 'getpaid_after_' . $this->object_type . '_object_save', $this, $this->data_store );
254
-
255
-		return $this->get_id();
256
-	}
257
-
258
-	/**
259
-	 * Change data to JSON format.
260
-	 *
261
-	 * @since  1.0.19
262
-	 * @return string Data in JSON format.
263
-	 */
264
-	public function __toString() {
265
-		return wp_json_encode( $this->get_data() );
266
-	}
267
-
268
-	/**
269
-	 * Returns all data for this object.
270
-	 *
271
-	 * @since  1.0.19
272
-	 * @return array
273
-	 */
274
-	public function get_data() {
275
-		return array_merge( array( 'id' => $this->get_id() ), $this->data, array( 'meta_data' => $this->get_meta_data() ) );
276
-	}
277
-
278
-	/**
279
-	 * Returns array of expected data keys for this object.
280
-	 *
281
-	 * @since   1.0.19
282
-	 * @return array
283
-	 */
284
-	public function get_data_keys() {
285
-		return array_keys( $this->data );
286
-	}
287
-
288
-	/**
289
-	 * Returns all "extra" data keys for an object (for sub objects like item types).
290
-	 *
291
-	 * @since  1.0.19
292
-	 * @return array
293
-	 */
294
-	public function get_extra_data_keys() {
295
-		return array_keys( $this->extra_data );
296
-	}
297
-
298
-	/**
299
-	 * Filter null meta values from array.
300
-	 *
301
-	 * @since  1.0.19
302
-	 * @param mixed $meta Meta value to check.
303
-	 * @return bool
304
-	 */
305
-	protected function filter_null_meta( $meta ) {
306
-		return ! is_null( $meta->value );
307
-	}
308
-
309
-	/**
310
-	 * Get All Meta Data.
311
-	 *
312
-	 * @since 1.0.19
313
-	 * @return array of objects.
314
-	 */
315
-	public function get_meta_data() {
316
-		$this->maybe_read_meta_data();
317
-		return array_values( array_filter( $this->meta_data, array( $this, 'filter_null_meta' ) ) );
318
-	}
319
-
320
-	/**
321
-	 * Check if the key is an internal one.
322
-	 *
323
-	 * @since  1.0.19
324
-	 * @param  string $key Key to check.
325
-	 * @return bool   true if it's an internal key, false otherwise
326
-	 */
327
-	protected function is_internal_meta_key( $key ) {
328
-		$internal_meta_key = ! empty( $key ) && $this->data_store && in_array( $key, $this->data_store->get_internal_meta_keys(), true );
329
-
330
-		if ( ! $internal_meta_key ) {
331
-			return false;
332
-		}
333
-
334
-		$has_setter_or_getter = is_callable( array( $this, 'set_' . $key ) ) || is_callable( array( $this, 'get_' . $key ) );
335
-
336
-		if ( ! $has_setter_or_getter ) {
337
-			return false;
338
-		}
339
-
340
-		/* translators: %s: $key Key to check */
341
-		getpaid_doing_it_wrong( __FUNCTION__, sprintf( __( 'Generic add/update/get meta methods should not be used for internal meta data, including "%s". Use getters and setters.', 'invoicing' ), $key ), '1.0.19' );
342
-
343
-		return true;
344
-	}
345
-
346
-	/**
347
-	 * Magic method for setting data fields.
348
-	 *
349
-	 * This method does not update custom fields in the database.
350
-	 *
351
-	 * @since 1.0.19
352
-	 * @access public
353
-	 *
354
-	 */
355
-	public function __set( $key, $value ) {
356
-
357
-		if ( 'id' == strtolower( $key ) ) {
358
-			return $this->set_id( $value );
359
-		}
360
-
361
-		if ( method_exists( $this, "set_$key") ) {
362
-
363
-			/* translators: %s: $key Key to set */
364
-			getpaid_doing_it_wrong( __FUNCTION__, sprintf( __( 'Object data such as "%s" should not be accessed directly. Use getters and setters.', 'invoicing' ), $key ), '1.0.19' );
365
-
366
-			call_user_func( array( $this, "set_$key" ), $value );
367
-		} else {
368
-			$this->set_prop( $key, $value );
369
-		}
370
-
371
-	}
372
-
373
-	/**
24
+    /**
25
+     * ID for this object.
26
+     *
27
+     * @since 1.0.19
28
+     * @var int
29
+     */
30
+    protected $id = 0;
31
+
32
+    /**
33
+     * Core data for this object. Name value pairs (name + default value).
34
+     *
35
+     * @since 1.0.19
36
+     * @var array
37
+     */
38
+    protected $data = array();
39
+
40
+    /**
41
+     * Core data changes for this object.
42
+     *
43
+     * @since 1.0.19
44
+     * @var array
45
+     */
46
+    protected $changes = array();
47
+
48
+    /**
49
+     * This is false until the object is read from the DB.
50
+     *
51
+     * @since 1.0.19
52
+     * @var bool
53
+     */
54
+    protected $object_read = false;
55
+
56
+    /**
57
+     * This is the name of this object type.
58
+     *
59
+     * @since 1.0.19
60
+     * @var string
61
+     */
62
+    protected $object_type = 'data';
63
+
64
+    /**
65
+     * Extra data for this object. Name value pairs (name + default value).
66
+     * Used as a standard way for sub classes (like item types) to add
67
+     * additional information to an inherited class.
68
+     *
69
+     * @since 1.0.19
70
+     * @var array
71
+     */
72
+    protected $extra_data = array();
73
+
74
+    /**
75
+     * Set to _data on construct so we can track and reset data if needed.
76
+     *
77
+     * @since 1.0.19
78
+     * @var array
79
+     */
80
+    protected $default_data = array();
81
+
82
+    /**
83
+     * Contains a reference to the data store for this class.
84
+     *
85
+     * @since 1.0.19
86
+     * @var GetPaid_Data_Store
87
+     */
88
+    protected $data_store;
89
+
90
+    /**
91
+     * Stores meta in cache for future reads.
92
+     * A group must be set to to enable caching.
93
+     *
94
+     * @since 1.0.19
95
+     * @var string
96
+     */
97
+    protected $cache_group = '';
98
+
99
+    /**
100
+     * Stores the last error.
101
+     *
102
+     * @since 1.0.19
103
+     * @var string
104
+     */
105
+    public $last_error = '';
106
+
107
+    /**
108
+     * Stores additional meta data.
109
+     *
110
+     * @since 1.0.19
111
+     * @var array
112
+     */
113
+    protected $meta_data = null;
114
+
115
+    /**
116
+     * Default constructor.
117
+     *
118
+     * @param int|object|array|string $read ID to load from the DB (optional) or already queried data.
119
+     */
120
+    public function __construct( $read = 0 ) {
121
+        $this->data         = array_merge( $this->data, $this->extra_data );
122
+        $this->default_data = $this->data;
123
+    }
124
+
125
+    /**
126
+     * Only store the object ID to avoid serializing the data object instance.
127
+     *
128
+     * @return array
129
+     */
130
+    public function __sleep() {
131
+        return array( 'id' );
132
+    }
133
+
134
+    /**
135
+     * Re-run the constructor with the object ID.
136
+     *
137
+     * If the object no longer exists, remove the ID.
138
+     */
139
+    public function __wakeup() {
140
+        $this->__construct( absint( $this->id ) );
141
+
142
+        if ( ! empty( $this->last_error ) ) {
143
+            $this->set_id( 0 );
144
+        }
145
+
146
+    }
147
+
148
+    /**
149
+     * When the object is cloned, make sure meta is duplicated correctly.
150
+     *
151
+     * @since 1.0.19
152
+     */
153
+    public function __clone() {
154
+        $this->maybe_read_meta_data();
155
+        if ( ! empty( $this->meta_data ) ) {
156
+            foreach ( $this->meta_data as $array_key => $meta ) {
157
+                $this->meta_data[ $array_key ] = clone $meta;
158
+                if ( ! empty( $meta->id ) ) {
159
+                    $this->meta_data[ $array_key ]->id = null;
160
+                }
161
+            }
162
+        }
163
+    }
164
+
165
+    /**
166
+     * Get the data store.
167
+     *
168
+     * @since  1.0.19
169
+     * @return object
170
+     */
171
+    public function get_data_store() {
172
+        return $this->data_store;
173
+    }
174
+
175
+    /**
176
+     * Get the object type.
177
+     *
178
+     * @since  1.0.19
179
+     * @return string
180
+     */
181
+    public function get_object_type() {
182
+        return $this->object_type;
183
+    }
184
+
185
+    /**
186
+     * Returns the unique ID for this object.
187
+     *
188
+     * @since  1.0.19
189
+     * @return int
190
+     */
191
+    public function get_id() {
192
+        return $this->id;
193
+    }
194
+
195
+    /**
196
+     * Get form status.
197
+     *
198
+     * @since 1.0.19
199
+     * @param  string $context View or edit context.
200
+     * @return string
201
+     */
202
+    public function get_status( $context = 'view' ) {
203
+        return $this->get_prop( 'status', $context );
204
+    }
205
+
206
+    /**
207
+     * Delete an object, set the ID to 0, and return result.
208
+     *
209
+     * @since  1.0.19
210
+     * @param  bool $force_delete Should the data be deleted permanently.
211
+     * @return bool result
212
+     */
213
+    public function delete( $force_delete = false ) {
214
+        if ( $this->data_store && $this->exists() ) {
215
+            $this->data_store->delete( $this, array( 'force_delete' => $force_delete ) );
216
+            $this->set_id( 0 );
217
+            return true;
218
+        }
219
+        return false;
220
+    }
221
+
222
+    /**
223
+     * Save should create or update based on object existence.
224
+     *
225
+     * @since  1.0.19
226
+     * @return int
227
+     */
228
+    public function save() {
229
+        if ( ! $this->data_store ) {
230
+            return $this->get_id();
231
+        }
232
+
233
+        /**
234
+         * Trigger action before saving to the DB. Allows you to adjust object props before save.
235
+         *
236
+         * @param GetPaid_Data          $this The object being saved.
237
+         * @param GetPaid_Data_Store_WP $data_store The data store persisting the data.
238
+         */
239
+        do_action( 'getpaid_before_' . $this->object_type . '_object_save', $this, $this->data_store );
240
+
241
+        if ( $this->get_id() ) {
242
+            $this->data_store->update( $this );
243
+        } else {
244
+            $this->data_store->create( $this );
245
+        }
246
+
247
+        /**
248
+         * Trigger action after saving to the DB.
249
+         *
250
+         * @param GetPaid_Data          $this The object being saved.
251
+         * @param GetPaid_Data_Store_WP $data_store The data store persisting the data.
252
+         */
253
+        do_action( 'getpaid_after_' . $this->object_type . '_object_save', $this, $this->data_store );
254
+
255
+        return $this->get_id();
256
+    }
257
+
258
+    /**
259
+     * Change data to JSON format.
260
+     *
261
+     * @since  1.0.19
262
+     * @return string Data in JSON format.
263
+     */
264
+    public function __toString() {
265
+        return wp_json_encode( $this->get_data() );
266
+    }
267
+
268
+    /**
269
+     * Returns all data for this object.
270
+     *
271
+     * @since  1.0.19
272
+     * @return array
273
+     */
274
+    public function get_data() {
275
+        return array_merge( array( 'id' => $this->get_id() ), $this->data, array( 'meta_data' => $this->get_meta_data() ) );
276
+    }
277
+
278
+    /**
279
+     * Returns array of expected data keys for this object.
280
+     *
281
+     * @since   1.0.19
282
+     * @return array
283
+     */
284
+    public function get_data_keys() {
285
+        return array_keys( $this->data );
286
+    }
287
+
288
+    /**
289
+     * Returns all "extra" data keys for an object (for sub objects like item types).
290
+     *
291
+     * @since  1.0.19
292
+     * @return array
293
+     */
294
+    public function get_extra_data_keys() {
295
+        return array_keys( $this->extra_data );
296
+    }
297
+
298
+    /**
299
+     * Filter null meta values from array.
300
+     *
301
+     * @since  1.0.19
302
+     * @param mixed $meta Meta value to check.
303
+     * @return bool
304
+     */
305
+    protected function filter_null_meta( $meta ) {
306
+        return ! is_null( $meta->value );
307
+    }
308
+
309
+    /**
310
+     * Get All Meta Data.
311
+     *
312
+     * @since 1.0.19
313
+     * @return array of objects.
314
+     */
315
+    public function get_meta_data() {
316
+        $this->maybe_read_meta_data();
317
+        return array_values( array_filter( $this->meta_data, array( $this, 'filter_null_meta' ) ) );
318
+    }
319
+
320
+    /**
321
+     * Check if the key is an internal one.
322
+     *
323
+     * @since  1.0.19
324
+     * @param  string $key Key to check.
325
+     * @return bool   true if it's an internal key, false otherwise
326
+     */
327
+    protected function is_internal_meta_key( $key ) {
328
+        $internal_meta_key = ! empty( $key ) && $this->data_store && in_array( $key, $this->data_store->get_internal_meta_keys(), true );
329
+
330
+        if ( ! $internal_meta_key ) {
331
+            return false;
332
+        }
333
+
334
+        $has_setter_or_getter = is_callable( array( $this, 'set_' . $key ) ) || is_callable( array( $this, 'get_' . $key ) );
335
+
336
+        if ( ! $has_setter_or_getter ) {
337
+            return false;
338
+        }
339
+
340
+        /* translators: %s: $key Key to check */
341
+        getpaid_doing_it_wrong( __FUNCTION__, sprintf( __( 'Generic add/update/get meta methods should not be used for internal meta data, including "%s". Use getters and setters.', 'invoicing' ), $key ), '1.0.19' );
342
+
343
+        return true;
344
+    }
345
+
346
+    /**
347
+     * Magic method for setting data fields.
348
+     *
349
+     * This method does not update custom fields in the database.
350
+     *
351
+     * @since 1.0.19
352
+     * @access public
353
+     *
354
+     */
355
+    public function __set( $key, $value ) {
356
+
357
+        if ( 'id' == strtolower( $key ) ) {
358
+            return $this->set_id( $value );
359
+        }
360
+
361
+        if ( method_exists( $this, "set_$key") ) {
362
+
363
+            /* translators: %s: $key Key to set */
364
+            getpaid_doing_it_wrong( __FUNCTION__, sprintf( __( 'Object data such as "%s" should not be accessed directly. Use getters and setters.', 'invoicing' ), $key ), '1.0.19' );
365
+
366
+            call_user_func( array( $this, "set_$key" ), $value );
367
+        } else {
368
+            $this->set_prop( $key, $value );
369
+        }
370
+
371
+    }
372
+
373
+    /**
374 374
      * Margic method for retrieving a property.
375 375
      */
376 376
     public function __get( $key ) {
@@ -378,10 +378,10 @@  discard block
 block discarded – undo
378 378
         // Check if we have a helper method for that.
379 379
         if ( method_exists( $this, 'get_' . $key ) ) {
380 380
 
381
-			if ( 'post_type' != $key ) {
382
-				/* translators: %s: $key Key to set */
383
-				getpaid_doing_it_wrong( __FUNCTION__, sprintf( __( 'Object data such as "%s" should not be accessed directly. Use getters and setters.', 'invoicing' ), $key ), '1.0.19' );
384
-			}
381
+            if ( 'post_type' != $key ) {
382
+                /* translators: %s: $key Key to set */
383
+                getpaid_doing_it_wrong( __FUNCTION__, sprintf( __( 'Object data such as "%s" should not be accessed directly. Use getters and setters.', 'invoicing' ), $key ), '1.0.19' );
384
+            }
385 385
 
386 386
             return call_user_func( array( $this, 'get_' . $key ) );
387 387
         }
@@ -391,512 +391,512 @@  discard block
 block discarded – undo
391 391
             return $this->post->$key;
392 392
         }
393 393
 
394
-		return $this->get_prop( $key );
395
-
396
-    }
397
-
398
-	/**
399
-	 * Get Meta Data by Key.
400
-	 *
401
-	 * @since  1.0.19
402
-	 * @param  string $key Meta Key.
403
-	 * @param  bool   $single return first found meta with key, or all with $key.
404
-	 * @param  string $context What the value is for. Valid values are view and edit.
405
-	 * @return mixed
406
-	 */
407
-	public function get_meta( $key = '', $single = true, $context = 'view' ) {
408
-
409
-		// Check if this is an internal meta key.
410
-		$_key = str_replace( '_wpinv', '', $key );
411
-		$_key = str_replace( 'wpinv', '', $_key );
412
-		if ( $this->is_internal_meta_key( $_key ) ) {
413
-			$function = 'get_' . $_key;
414
-
415
-			if ( is_callable( array( $this, $function ) ) ) {
416
-				return $this->{$function}();
417
-			}
418
-		}
419
-
420
-		// Read the meta data if not yet read.
421
-		$this->maybe_read_meta_data();
422
-		$meta_data  = $this->get_meta_data();
423
-		$array_keys = array_keys( wp_list_pluck( $meta_data, 'key' ), $key, true );
424
-		$value      = $single ? '' : array();
425
-
426
-		if ( ! empty( $array_keys ) ) {
427
-			// We don't use the $this->meta_data property directly here because we don't want meta with a null value (i.e. meta which has been deleted via $this->delete_meta_data()).
428
-			if ( $single ) {
429
-				$value = $meta_data[ current( $array_keys ) ]->value;
430
-			} else {
431
-				$value = array_intersect_key( $meta_data, array_flip( $array_keys ) );
432
-			}
433
-		}
434
-
435
-		if ( 'view' === $context ) {
436
-			$value = apply_filters( $this->get_hook_prefix() . $key, $value, $this );
437
-		}
438
-
439
-		return $value;
440
-	}
441
-
442
-	/**
443
-	 * See if meta data exists, since get_meta always returns a '' or array().
444
-	 *
445
-	 * @since  1.0.19
446
-	 * @param  string $key Meta Key.
447
-	 * @return boolean
448
-	 */
449
-	public function meta_exists( $key = '' ) {
450
-		$this->maybe_read_meta_data();
451
-		$array_keys = wp_list_pluck( $this->get_meta_data(), 'key' );
452
-		return in_array( $key, $array_keys, true );
453
-	}
454
-
455
-	/**
456
-	 * Set all meta data from array.
457
-	 *
458
-	 * @since 1.0.19
459
-	 * @param array $data Key/Value pairs.
460
-	 */
461
-	public function set_meta_data( $data ) {
462
-		if ( ! empty( $data ) && is_array( $data ) ) {
463
-			$this->maybe_read_meta_data();
464
-			foreach ( $data as $meta ) {
465
-				$meta = (array) $meta;
466
-				if ( isset( $meta['key'], $meta['value'], $meta['id'] ) ) {
467
-					$this->meta_data[] = new GetPaid_Meta_Data(
468
-						array(
469
-							'id'    => $meta['id'],
470
-							'key'   => $meta['key'],
471
-							'value' => $meta['value'],
472
-						)
473
-					);
474
-				}
475
-			}
476
-		}
477
-	}
478
-
479
-	/**
480
-	 * Add meta data.
481
-	 *
482
-	 * @since 1.0.19
483
-	 *
484
-	 * @param string       $key Meta key.
485
-	 * @param string|array $value Meta value.
486
-	 * @param bool         $unique Should this be a unique key?.
487
-	 */
488
-	public function add_meta_data( $key, $value, $unique = false ) {
489
-		if ( $this->is_internal_meta_key( $key ) ) {
490
-			$function = 'set_' . $key;
491
-
492
-			if ( is_callable( array( $this, $function ) ) ) {
493
-				return $this->{$function}( $value );
494
-			}
495
-		}
496
-
497
-		$this->maybe_read_meta_data();
498
-		if ( $unique ) {
499
-			$this->delete_meta_data( $key );
500
-		}
501
-		$this->meta_data[] = new GetPaid_Meta_Data(
502
-			array(
503
-				'key'   => $key,
504
-				'value' => $value,
505
-			)
506
-		);
507
-	}
508
-
509
-	/**
510
-	 * Update meta data by key or ID, if provided.
511
-	 *
512
-	 * @since  1.0.19
513
-	 *
514
-	 * @param  string       $key Meta key.
515
-	 * @param  string|array $value Meta value.
516
-	 * @param  int          $meta_id Meta ID.
517
-	 */
518
-	public function update_meta_data( $key, $value, $meta_id = 0 ) {
519
-		if ( $this->is_internal_meta_key( $key ) ) {
520
-			$function = 'set_' . $key;
521
-
522
-			if ( is_callable( array( $this, $function ) ) ) {
523
-				return $this->{$function}( $value );
524
-			}
525
-		}
526
-
527
-		$this->maybe_read_meta_data();
528
-
529
-		$array_key = false;
530
-
531
-		if ( $meta_id ) {
532
-			$array_keys = array_keys( wp_list_pluck( $this->meta_data, 'id' ), $meta_id, true );
533
-			$array_key  = $array_keys ? current( $array_keys ) : false;
534
-		} else {
535
-			// Find matches by key.
536
-			$matches = array();
537
-			foreach ( $this->meta_data as $meta_data_array_key => $meta ) {
538
-				if ( $meta->key === $key ) {
539
-					$matches[] = $meta_data_array_key;
540
-				}
541
-			}
542
-
543
-			if ( ! empty( $matches ) ) {
544
-				// Set matches to null so only one key gets the new value.
545
-				foreach ( $matches as $meta_data_array_key ) {
546
-					$this->meta_data[ $meta_data_array_key ]->value = null;
547
-				}
548
-				$array_key = current( $matches );
549
-			}
550
-		}
551
-
552
-		if ( false !== $array_key ) {
553
-			$meta        = $this->meta_data[ $array_key ];
554
-			$meta->key   = $key;
555
-			$meta->value = $value;
556
-		} else {
557
-			$this->add_meta_data( $key, $value, true );
558
-		}
559
-	}
560
-
561
-	/**
562
-	 * Delete meta data.
563
-	 *
564
-	 * @since 1.0.19
565
-	 * @param string $key Meta key.
566
-	 */
567
-	public function delete_meta_data( $key ) {
568
-		$this->maybe_read_meta_data();
569
-		$array_keys = array_keys( wp_list_pluck( $this->meta_data, 'key' ), $key, true );
570
-
571
-		if ( $array_keys ) {
572
-			foreach ( $array_keys as $array_key ) {
573
-				$this->meta_data[ $array_key ]->value = null;
574
-			}
575
-		}
576
-	}
577
-
578
-	/**
579
-	 * Delete meta data.
580
-	 *
581
-	 * @since 1.0.19
582
-	 * @param int $mid Meta ID.
583
-	 */
584
-	public function delete_meta_data_by_mid( $mid ) {
585
-		$this->maybe_read_meta_data();
586
-		$array_keys = array_keys( wp_list_pluck( $this->meta_data, 'id' ), (int) $mid, true );
587
-
588
-		if ( $array_keys ) {
589
-			foreach ( $array_keys as $array_key ) {
590
-				$this->meta_data[ $array_key ]->value = null;
591
-			}
592
-		}
593
-	}
594
-
595
-	/**
596
-	 * Read meta data if null.
597
-	 *
598
-	 * @since 1.0.19
599
-	 */
600
-	protected function maybe_read_meta_data() {
601
-		if ( is_null( $this->meta_data ) ) {
602
-			$this->read_meta_data();
603
-		}
604
-	}
605
-
606
-	/**
607
-	 * Read Meta Data from the database. Ignore any internal properties.
608
-	 * Uses it's own caches because get_metadata does not provide meta_ids.
609
-	 *
610
-	 * @since 1.0.19
611
-	 * @param bool $force_read True to force a new DB read (and update cache).
612
-	 */
613
-	public function read_meta_data( $force_read = false ) {
614
-
615
-		// Reset meta data.
616
-		$this->meta_data = array();
617
-
618
-		// Maybe abort early.
619
-		if ( ! $this->get_id() || ! $this->data_store ) {
620
-			return;
621
-		}
622
-
623
-		// Only read from cache if the cache key is set.
624
-		$cache_key = null;
625
-		if ( ! $force_read && ! empty( $this->cache_group ) ) {
626
-			$cache_key     = GetPaid_Cache_Helper::get_cache_prefix( $this->cache_group ) . GetPaid_Cache_Helper::get_cache_prefix( 'object_' . $this->get_id() ) . 'object_meta_' . $this->get_id();
627
-			$raw_meta_data = wp_cache_get( $cache_key, $this->cache_group );
628
-		}
629
-
630
-		// Should we force read?
631
-		if ( empty( $raw_meta_data ) ) {
632
-			$raw_meta_data = $this->data_store->read_meta( $this );
633
-
634
-			if ( ! empty( $cache_key ) ) {
635
-				wp_cache_set( $cache_key, $raw_meta_data, $this->cache_group );
636
-			}
637
-
638
-		}
639
-
640
-		// Set meta data.
641
-		if ( is_array( $raw_meta_data ) ) {
642
-
643
-			foreach ( $raw_meta_data as $meta ) {
644
-				$this->meta_data[] = new GetPaid_Meta_Data(
645
-					array(
646
-						'id'    => (int) $meta->meta_id,
647
-						'key'   => $meta->meta_key,
648
-						'value' => maybe_unserialize( $meta->meta_value ),
649
-					)
650
-				);
651
-			}
652
-
653
-		}
654
-
655
-	}
656
-
657
-	/**
658
-	 * Update Meta Data in the database.
659
-	 *
660
-	 * @since 1.0.19
661
-	 */
662
-	public function save_meta_data() {
663
-		if ( ! $this->data_store || is_null( $this->meta_data ) ) {
664
-			return;
665
-		}
666
-		foreach ( $this->meta_data as $array_key => $meta ) {
667
-			if ( is_null( $meta->value ) ) {
668
-				if ( ! empty( $meta->id ) ) {
669
-					$this->data_store->delete_meta( $this, $meta );
670
-					unset( $this->meta_data[ $array_key ] );
671
-				}
672
-			} elseif ( empty( $meta->id ) ) {
673
-				$meta->id = $this->data_store->add_meta( $this, $meta );
674
-				$meta->apply_changes();
675
-			} else {
676
-				if ( $meta->get_changes() ) {
677
-					$this->data_store->update_meta( $this, $meta );
678
-					$meta->apply_changes();
679
-				}
680
-			}
681
-		}
682
-		if ( ! empty( $this->cache_group ) ) {
683
-			$cache_key = GetPaid_Cache_Helper::get_cache_prefix( $this->cache_group ) . GetPaid_Cache_Helper::get_cache_prefix( 'object_' . $this->get_id() ) . 'object_meta_' . $this->get_id();
684
-			wp_cache_delete( $cache_key, $this->cache_group );
685
-		}
686
-	}
687
-
688
-	/**
689
-	 * Set ID.
690
-	 *
691
-	 * @since 1.0.19
692
-	 * @param int $id ID.
693
-	 */
694
-	public function set_id( $id ) {
695
-		$this->id = absint( $id );
696
-	}
697
-
698
-	/**
699
-	 * Sets item status.
700
-	 *
701
-	 * @since 1.0.19
702
-	 * @param string $status New status.
703
-	 * @return array details of change.
704
-	 */
705
-	public function set_status( $status ) {
394
+        return $this->get_prop( $key );
395
+
396
+    }
397
+
398
+    /**
399
+     * Get Meta Data by Key.
400
+     *
401
+     * @since  1.0.19
402
+     * @param  string $key Meta Key.
403
+     * @param  bool   $single return first found meta with key, or all with $key.
404
+     * @param  string $context What the value is for. Valid values are view and edit.
405
+     * @return mixed
406
+     */
407
+    public function get_meta( $key = '', $single = true, $context = 'view' ) {
408
+
409
+        // Check if this is an internal meta key.
410
+        $_key = str_replace( '_wpinv', '', $key );
411
+        $_key = str_replace( 'wpinv', '', $_key );
412
+        if ( $this->is_internal_meta_key( $_key ) ) {
413
+            $function = 'get_' . $_key;
414
+
415
+            if ( is_callable( array( $this, $function ) ) ) {
416
+                return $this->{$function}();
417
+            }
418
+        }
419
+
420
+        // Read the meta data if not yet read.
421
+        $this->maybe_read_meta_data();
422
+        $meta_data  = $this->get_meta_data();
423
+        $array_keys = array_keys( wp_list_pluck( $meta_data, 'key' ), $key, true );
424
+        $value      = $single ? '' : array();
425
+
426
+        if ( ! empty( $array_keys ) ) {
427
+            // We don't use the $this->meta_data property directly here because we don't want meta with a null value (i.e. meta which has been deleted via $this->delete_meta_data()).
428
+            if ( $single ) {
429
+                $value = $meta_data[ current( $array_keys ) ]->value;
430
+            } else {
431
+                $value = array_intersect_key( $meta_data, array_flip( $array_keys ) );
432
+            }
433
+        }
434
+
435
+        if ( 'view' === $context ) {
436
+            $value = apply_filters( $this->get_hook_prefix() . $key, $value, $this );
437
+        }
438
+
439
+        return $value;
440
+    }
441
+
442
+    /**
443
+     * See if meta data exists, since get_meta always returns a '' or array().
444
+     *
445
+     * @since  1.0.19
446
+     * @param  string $key Meta Key.
447
+     * @return boolean
448
+     */
449
+    public function meta_exists( $key = '' ) {
450
+        $this->maybe_read_meta_data();
451
+        $array_keys = wp_list_pluck( $this->get_meta_data(), 'key' );
452
+        return in_array( $key, $array_keys, true );
453
+    }
454
+
455
+    /**
456
+     * Set all meta data from array.
457
+     *
458
+     * @since 1.0.19
459
+     * @param array $data Key/Value pairs.
460
+     */
461
+    public function set_meta_data( $data ) {
462
+        if ( ! empty( $data ) && is_array( $data ) ) {
463
+            $this->maybe_read_meta_data();
464
+            foreach ( $data as $meta ) {
465
+                $meta = (array) $meta;
466
+                if ( isset( $meta['key'], $meta['value'], $meta['id'] ) ) {
467
+                    $this->meta_data[] = new GetPaid_Meta_Data(
468
+                        array(
469
+                            'id'    => $meta['id'],
470
+                            'key'   => $meta['key'],
471
+                            'value' => $meta['value'],
472
+                        )
473
+                    );
474
+                }
475
+            }
476
+        }
477
+    }
478
+
479
+    /**
480
+     * Add meta data.
481
+     *
482
+     * @since 1.0.19
483
+     *
484
+     * @param string       $key Meta key.
485
+     * @param string|array $value Meta value.
486
+     * @param bool         $unique Should this be a unique key?.
487
+     */
488
+    public function add_meta_data( $key, $value, $unique = false ) {
489
+        if ( $this->is_internal_meta_key( $key ) ) {
490
+            $function = 'set_' . $key;
491
+
492
+            if ( is_callable( array( $this, $function ) ) ) {
493
+                return $this->{$function}( $value );
494
+            }
495
+        }
496
+
497
+        $this->maybe_read_meta_data();
498
+        if ( $unique ) {
499
+            $this->delete_meta_data( $key );
500
+        }
501
+        $this->meta_data[] = new GetPaid_Meta_Data(
502
+            array(
503
+                'key'   => $key,
504
+                'value' => $value,
505
+            )
506
+        );
507
+    }
508
+
509
+    /**
510
+     * Update meta data by key or ID, if provided.
511
+     *
512
+     * @since  1.0.19
513
+     *
514
+     * @param  string       $key Meta key.
515
+     * @param  string|array $value Meta value.
516
+     * @param  int          $meta_id Meta ID.
517
+     */
518
+    public function update_meta_data( $key, $value, $meta_id = 0 ) {
519
+        if ( $this->is_internal_meta_key( $key ) ) {
520
+            $function = 'set_' . $key;
521
+
522
+            if ( is_callable( array( $this, $function ) ) ) {
523
+                return $this->{$function}( $value );
524
+            }
525
+        }
526
+
527
+        $this->maybe_read_meta_data();
528
+
529
+        $array_key = false;
530
+
531
+        if ( $meta_id ) {
532
+            $array_keys = array_keys( wp_list_pluck( $this->meta_data, 'id' ), $meta_id, true );
533
+            $array_key  = $array_keys ? current( $array_keys ) : false;
534
+        } else {
535
+            // Find matches by key.
536
+            $matches = array();
537
+            foreach ( $this->meta_data as $meta_data_array_key => $meta ) {
538
+                if ( $meta->key === $key ) {
539
+                    $matches[] = $meta_data_array_key;
540
+                }
541
+            }
542
+
543
+            if ( ! empty( $matches ) ) {
544
+                // Set matches to null so only one key gets the new value.
545
+                foreach ( $matches as $meta_data_array_key ) {
546
+                    $this->meta_data[ $meta_data_array_key ]->value = null;
547
+                }
548
+                $array_key = current( $matches );
549
+            }
550
+        }
551
+
552
+        if ( false !== $array_key ) {
553
+            $meta        = $this->meta_data[ $array_key ];
554
+            $meta->key   = $key;
555
+            $meta->value = $value;
556
+        } else {
557
+            $this->add_meta_data( $key, $value, true );
558
+        }
559
+    }
560
+
561
+    /**
562
+     * Delete meta data.
563
+     *
564
+     * @since 1.0.19
565
+     * @param string $key Meta key.
566
+     */
567
+    public function delete_meta_data( $key ) {
568
+        $this->maybe_read_meta_data();
569
+        $array_keys = array_keys( wp_list_pluck( $this->meta_data, 'key' ), $key, true );
570
+
571
+        if ( $array_keys ) {
572
+            foreach ( $array_keys as $array_key ) {
573
+                $this->meta_data[ $array_key ]->value = null;
574
+            }
575
+        }
576
+    }
577
+
578
+    /**
579
+     * Delete meta data.
580
+     *
581
+     * @since 1.0.19
582
+     * @param int $mid Meta ID.
583
+     */
584
+    public function delete_meta_data_by_mid( $mid ) {
585
+        $this->maybe_read_meta_data();
586
+        $array_keys = array_keys( wp_list_pluck( $this->meta_data, 'id' ), (int) $mid, true );
587
+
588
+        if ( $array_keys ) {
589
+            foreach ( $array_keys as $array_key ) {
590
+                $this->meta_data[ $array_key ]->value = null;
591
+            }
592
+        }
593
+    }
594
+
595
+    /**
596
+     * Read meta data if null.
597
+     *
598
+     * @since 1.0.19
599
+     */
600
+    protected function maybe_read_meta_data() {
601
+        if ( is_null( $this->meta_data ) ) {
602
+            $this->read_meta_data();
603
+        }
604
+    }
605
+
606
+    /**
607
+     * Read Meta Data from the database. Ignore any internal properties.
608
+     * Uses it's own caches because get_metadata does not provide meta_ids.
609
+     *
610
+     * @since 1.0.19
611
+     * @param bool $force_read True to force a new DB read (and update cache).
612
+     */
613
+    public function read_meta_data( $force_read = false ) {
614
+
615
+        // Reset meta data.
616
+        $this->meta_data = array();
617
+
618
+        // Maybe abort early.
619
+        if ( ! $this->get_id() || ! $this->data_store ) {
620
+            return;
621
+        }
622
+
623
+        // Only read from cache if the cache key is set.
624
+        $cache_key = null;
625
+        if ( ! $force_read && ! empty( $this->cache_group ) ) {
626
+            $cache_key     = GetPaid_Cache_Helper::get_cache_prefix( $this->cache_group ) . GetPaid_Cache_Helper::get_cache_prefix( 'object_' . $this->get_id() ) . 'object_meta_' . $this->get_id();
627
+            $raw_meta_data = wp_cache_get( $cache_key, $this->cache_group );
628
+        }
629
+
630
+        // Should we force read?
631
+        if ( empty( $raw_meta_data ) ) {
632
+            $raw_meta_data = $this->data_store->read_meta( $this );
633
+
634
+            if ( ! empty( $cache_key ) ) {
635
+                wp_cache_set( $cache_key, $raw_meta_data, $this->cache_group );
636
+            }
637
+
638
+        }
639
+
640
+        // Set meta data.
641
+        if ( is_array( $raw_meta_data ) ) {
642
+
643
+            foreach ( $raw_meta_data as $meta ) {
644
+                $this->meta_data[] = new GetPaid_Meta_Data(
645
+                    array(
646
+                        'id'    => (int) $meta->meta_id,
647
+                        'key'   => $meta->meta_key,
648
+                        'value' => maybe_unserialize( $meta->meta_value ),
649
+                    )
650
+                );
651
+            }
652
+
653
+        }
654
+
655
+    }
656
+
657
+    /**
658
+     * Update Meta Data in the database.
659
+     *
660
+     * @since 1.0.19
661
+     */
662
+    public function save_meta_data() {
663
+        if ( ! $this->data_store || is_null( $this->meta_data ) ) {
664
+            return;
665
+        }
666
+        foreach ( $this->meta_data as $array_key => $meta ) {
667
+            if ( is_null( $meta->value ) ) {
668
+                if ( ! empty( $meta->id ) ) {
669
+                    $this->data_store->delete_meta( $this, $meta );
670
+                    unset( $this->meta_data[ $array_key ] );
671
+                }
672
+            } elseif ( empty( $meta->id ) ) {
673
+                $meta->id = $this->data_store->add_meta( $this, $meta );
674
+                $meta->apply_changes();
675
+            } else {
676
+                if ( $meta->get_changes() ) {
677
+                    $this->data_store->update_meta( $this, $meta );
678
+                    $meta->apply_changes();
679
+                }
680
+            }
681
+        }
682
+        if ( ! empty( $this->cache_group ) ) {
683
+            $cache_key = GetPaid_Cache_Helper::get_cache_prefix( $this->cache_group ) . GetPaid_Cache_Helper::get_cache_prefix( 'object_' . $this->get_id() ) . 'object_meta_' . $this->get_id();
684
+            wp_cache_delete( $cache_key, $this->cache_group );
685
+        }
686
+    }
687
+
688
+    /**
689
+     * Set ID.
690
+     *
691
+     * @since 1.0.19
692
+     * @param int $id ID.
693
+     */
694
+    public function set_id( $id ) {
695
+        $this->id = absint( $id );
696
+    }
697
+
698
+    /**
699
+     * Sets item status.
700
+     *
701
+     * @since 1.0.19
702
+     * @param string $status New status.
703
+     * @return array details of change.
704
+     */
705
+    public function set_status( $status ) {
706 706
         $old_status = $this->get_status();
707 707
 
708
-		$this->set_prop( 'status', $status );
709
-
710
-		return array(
711
-			'from' => $old_status,
712
-			'to'   => $status,
713
-		);
714
-    }
715
-
716
-	/**
717
-	 * Set all props to default values.
718
-	 *
719
-	 * @since 1.0.19
720
-	 */
721
-	public function set_defaults() {
722
-		$this->data    = $this->default_data;
723
-		$this->changes = array();
724
-		$this->set_object_read( false );
725
-	}
726
-
727
-	/**
728
-	 * Set object read property.
729
-	 *
730
-	 * @since 1.0.19
731
-	 * @param boolean $read Should read?.
732
-	 */
733
-	public function set_object_read( $read = true ) {
734
-		$this->object_read = (bool) $read;
735
-	}
736
-
737
-	/**
738
-	 * Get object read property.
739
-	 *
740
-	 * @since  1.0.19
741
-	 * @return boolean
742
-	 */
743
-	public function get_object_read() {
744
-		return (bool) $this->object_read;
745
-	}
746
-
747
-	/**
748
-	 * Set a collection of props in one go, collect any errors, and return the result.
749
-	 * Only sets using public methods.
750
-	 *
751
-	 * @since  1.0.19
752
-	 *
753
-	 * @param array  $props Key value pairs to set. Key is the prop and should map to a setter function name.
754
-	 * @param string $context In what context to run this.
755
-	 *
756
-	 * @return bool|WP_Error
757
-	 */
758
-	public function set_props( $props, $context = 'set' ) {
759
-		$errors = false;
760
-
761
-		foreach ( $props as $prop => $value ) {
762
-			try {
763
-				/**
764
-				 * Checks if the prop being set is allowed, and the value is not null.
765
-				 */
766
-				if ( is_null( $value ) || in_array( $prop, array( 'prop', 'date_prop', 'meta_data' ), true ) ) {
767
-					continue;
768
-				}
769
-				$setter = "set_$prop";
770
-
771
-				if ( is_callable( array( $this, $setter ) ) ) {
772
-					$this->{$setter}( $value );
773
-				}
774
-			} catch ( Exception $e ) {
775
-				if ( ! $errors ) {
776
-					$errors = new WP_Error();
777
-				}
778
-				$errors->add( $e->getCode(), $e->getMessage() );
779
-				$this->last_error = $e->getMessage();
780
-			}
781
-		}
782
-
783
-		return $errors && count( $errors->get_error_codes() ) ? $errors : true;
784
-	}
785
-
786
-	/**
787
-	 * Sets a prop for a setter method.
788
-	 *
789
-	 * This stores changes in a special array so we can track what needs saving
790
-	 * the the DB later.
791
-	 *
792
-	 * @since 1.0.19
793
-	 * @param string $prop Name of prop to set.
794
-	 * @param mixed  $value Value of the prop.
795
-	 */
796
-	protected function set_prop( $prop, $value ) {
797
-		if ( array_key_exists( $prop, $this->data ) ) {
798
-			if ( true === $this->object_read ) {
799
-				if ( $value !== $this->data[ $prop ] || array_key_exists( $prop, $this->changes ) ) {
800
-					$this->changes[ $prop ] = $value;
801
-				}
802
-			} else {
803
-				$this->data[ $prop ] = $value;
804
-			}
805
-		}
806
-	}
807
-
808
-	/**
809
-	 * Return data changes only.
810
-	 *
811
-	 * @since 1.0.19
812
-	 * @return array
813
-	 */
814
-	public function get_changes() {
815
-		return $this->changes;
816
-	}
817
-
818
-	/**
819
-	 * Merge changes with data and clear.
820
-	 *
821
-	 * @since 1.0.19
822
-	 */
823
-	public function apply_changes() {
824
-		$this->data    = array_replace_recursive( $this->data, $this->changes );
825
-		$this->changes = array();
826
-	}
827
-
828
-	/**
829
-	 * Prefix for action and filter hooks on data.
830
-	 *
831
-	 * @since  1.0.19
832
-	 * @return string
833
-	 */
834
-	protected function get_hook_prefix() {
835
-		return 'wpinv_get_' . $this->object_type . '_';
836
-	}
837
-
838
-	/**
839
-	 * Gets a prop for a getter method.
840
-	 *
841
-	 * Gets the value from either current pending changes, or the data itself.
842
-	 * Context controls what happens to the value before it's returned.
843
-	 *
844
-	 * @since  1.0.19
845
-	 * @param  string $prop Name of prop to get.
846
-	 * @param  string $context What the value is for. Valid values are view and edit.
847
-	 * @return mixed
848
-	 */
849
-	protected function get_prop( $prop, $context = 'view' ) {
850
-		$value = null;
851
-
852
-		if ( array_key_exists( $prop, $this->data ) ) {
853
-			$value = array_key_exists( $prop, $this->changes ) ? $this->changes[ $prop ] : $this->data[ $prop ];
854
-
855
-			if ( 'view' === $context ) {
856
-				$value = apply_filters( $this->get_hook_prefix() . $prop, $value, $this );
857
-			}
858
-		}
859
-
860
-		return $value;
861
-	}
862
-
863
-	/**
864
-	 * Sets a date prop whilst handling formatting and datetime objects.
865
-	 *
866
-	 * @since 1.0.19
867
-	 * @param string         $prop Name of prop to set.
868
-	 * @param string|integer $value Value of the prop.
869
-	 */
870
-	protected function set_date_prop( $prop, $value ) {
871
-
872
-		if ( empty( $value ) ) {
873
-			$this->set_prop( $prop, null );
874
-			return;
875
-		}
876
-		$this->set_prop( $prop, $value );
877
-
878
-	}
879
-
880
-	/**
881
-	 * When invalid data is found, throw an exception unless reading from the DB.
882
-	 *
883
-	 * @since 1.0.19
884
-	 * @param string $code             Error code.
885
-	 * @param string $message          Error message.
886
-	 */
887
-	protected function error( $code, $message ) {
888
-		$this->last_error = $message;
889
-	}
890
-
891
-	/**
892
-	 * Checks if the object is saved in the database
893
-	 *
894
-	 * @since 1.0.19
895
-	 * @return bool
896
-	 */
897
-	public function exists() {
898
-		$id = $this->get_id();
899
-		return ! empty( $id );
900
-	}
708
+        $this->set_prop( 'status', $status );
709
+
710
+        return array(
711
+            'from' => $old_status,
712
+            'to'   => $status,
713
+        );
714
+    }
715
+
716
+    /**
717
+     * Set all props to default values.
718
+     *
719
+     * @since 1.0.19
720
+     */
721
+    public function set_defaults() {
722
+        $this->data    = $this->default_data;
723
+        $this->changes = array();
724
+        $this->set_object_read( false );
725
+    }
726
+
727
+    /**
728
+     * Set object read property.
729
+     *
730
+     * @since 1.0.19
731
+     * @param boolean $read Should read?.
732
+     */
733
+    public function set_object_read( $read = true ) {
734
+        $this->object_read = (bool) $read;
735
+    }
736
+
737
+    /**
738
+     * Get object read property.
739
+     *
740
+     * @since  1.0.19
741
+     * @return boolean
742
+     */
743
+    public function get_object_read() {
744
+        return (bool) $this->object_read;
745
+    }
746
+
747
+    /**
748
+     * Set a collection of props in one go, collect any errors, and return the result.
749
+     * Only sets using public methods.
750
+     *
751
+     * @since  1.0.19
752
+     *
753
+     * @param array  $props Key value pairs to set. Key is the prop and should map to a setter function name.
754
+     * @param string $context In what context to run this.
755
+     *
756
+     * @return bool|WP_Error
757
+     */
758
+    public function set_props( $props, $context = 'set' ) {
759
+        $errors = false;
760
+
761
+        foreach ( $props as $prop => $value ) {
762
+            try {
763
+                /**
764
+                 * Checks if the prop being set is allowed, and the value is not null.
765
+                 */
766
+                if ( is_null( $value ) || in_array( $prop, array( 'prop', 'date_prop', 'meta_data' ), true ) ) {
767
+                    continue;
768
+                }
769
+                $setter = "set_$prop";
770
+
771
+                if ( is_callable( array( $this, $setter ) ) ) {
772
+                    $this->{$setter}( $value );
773
+                }
774
+            } catch ( Exception $e ) {
775
+                if ( ! $errors ) {
776
+                    $errors = new WP_Error();
777
+                }
778
+                $errors->add( $e->getCode(), $e->getMessage() );
779
+                $this->last_error = $e->getMessage();
780
+            }
781
+        }
782
+
783
+        return $errors && count( $errors->get_error_codes() ) ? $errors : true;
784
+    }
785
+
786
+    /**
787
+     * Sets a prop for a setter method.
788
+     *
789
+     * This stores changes in a special array so we can track what needs saving
790
+     * the the DB later.
791
+     *
792
+     * @since 1.0.19
793
+     * @param string $prop Name of prop to set.
794
+     * @param mixed  $value Value of the prop.
795
+     */
796
+    protected function set_prop( $prop, $value ) {
797
+        if ( array_key_exists( $prop, $this->data ) ) {
798
+            if ( true === $this->object_read ) {
799
+                if ( $value !== $this->data[ $prop ] || array_key_exists( $prop, $this->changes ) ) {
800
+                    $this->changes[ $prop ] = $value;
801
+                }
802
+            } else {
803
+                $this->data[ $prop ] = $value;
804
+            }
805
+        }
806
+    }
807
+
808
+    /**
809
+     * Return data changes only.
810
+     *
811
+     * @since 1.0.19
812
+     * @return array
813
+     */
814
+    public function get_changes() {
815
+        return $this->changes;
816
+    }
817
+
818
+    /**
819
+     * Merge changes with data and clear.
820
+     *
821
+     * @since 1.0.19
822
+     */
823
+    public function apply_changes() {
824
+        $this->data    = array_replace_recursive( $this->data, $this->changes );
825
+        $this->changes = array();
826
+    }
827
+
828
+    /**
829
+     * Prefix for action and filter hooks on data.
830
+     *
831
+     * @since  1.0.19
832
+     * @return string
833
+     */
834
+    protected function get_hook_prefix() {
835
+        return 'wpinv_get_' . $this->object_type . '_';
836
+    }
837
+
838
+    /**
839
+     * Gets a prop for a getter method.
840
+     *
841
+     * Gets the value from either current pending changes, or the data itself.
842
+     * Context controls what happens to the value before it's returned.
843
+     *
844
+     * @since  1.0.19
845
+     * @param  string $prop Name of prop to get.
846
+     * @param  string $context What the value is for. Valid values are view and edit.
847
+     * @return mixed
848
+     */
849
+    protected function get_prop( $prop, $context = 'view' ) {
850
+        $value = null;
851
+
852
+        if ( array_key_exists( $prop, $this->data ) ) {
853
+            $value = array_key_exists( $prop, $this->changes ) ? $this->changes[ $prop ] : $this->data[ $prop ];
854
+
855
+            if ( 'view' === $context ) {
856
+                $value = apply_filters( $this->get_hook_prefix() . $prop, $value, $this );
857
+            }
858
+        }
859
+
860
+        return $value;
861
+    }
862
+
863
+    /**
864
+     * Sets a date prop whilst handling formatting and datetime objects.
865
+     *
866
+     * @since 1.0.19
867
+     * @param string         $prop Name of prop to set.
868
+     * @param string|integer $value Value of the prop.
869
+     */
870
+    protected function set_date_prop( $prop, $value ) {
871
+
872
+        if ( empty( $value ) ) {
873
+            $this->set_prop( $prop, null );
874
+            return;
875
+        }
876
+        $this->set_prop( $prop, $value );
877
+
878
+    }
879
+
880
+    /**
881
+     * When invalid data is found, throw an exception unless reading from the DB.
882
+     *
883
+     * @since 1.0.19
884
+     * @param string $code             Error code.
885
+     * @param string $message          Error message.
886
+     */
887
+    protected function error( $code, $message ) {
888
+        $this->last_error = $message;
889
+    }
890
+
891
+    /**
892
+     * Checks if the object is saved in the database
893
+     *
894
+     * @since 1.0.19
895
+     * @return bool
896
+     */
897
+    public function exists() {
898
+        $id = $this->get_id();
899
+        return ! empty( $id );
900
+    }
901 901
 
902 902
 }
Please login to merge, or discard this patch.
includes/data-stores/class-getpaid-invoice-data-store.php 1 patch
Indentation   +469 added lines, -469 removed lines patch added patch discarded remove patch
@@ -5,7 +5,7 @@  discard block
 block discarded – undo
5 5
  *
6 6
  */
7 7
 if ( ! defined( 'ABSPATH' ) ) {
8
-	exit;
8
+    exit;
9 9
 }
10 10
 
11 11
 /**
@@ -15,539 +15,539 @@  discard block
 block discarded – undo
15 15
  */
16 16
 class GetPaid_Invoice_Data_Store extends GetPaid_Data_Store_WP {
17 17
 
18
-	/**
19
-	 * Data stored in meta keys, but not considered "meta" for a discount.
20
-	 *
21
-	 * @since 1.0.19
22
-	 * @var array
23
-	 */
24
-	protected $internal_meta_keys = array(
25
-		'_wpinv_subscr_profile_id',
26
-		'_wpinv_subscription_id',
27
-		'_wpinv_taxes',
28
-		'_wpinv_fees',
29
-		'_wpinv_discounts',
30
-		'_wpinv_submission_id',
31
-		'_wpinv_payment_form',
32
-		'_wpinv_is_viewed',
33
-		'_wpinv_phone',
34
-		'wpinv_email_cc',
35
-		'wpinv_template',
36
-		'wpinv_created_via'
37
-	);
38
-
39
-	/**
40
-	 * A map of meta keys to data props.
41
-	 *
42
-	 * @since 1.0.19
43
-	 *
44
-	 * @var array
45
-	 */
46
-	protected $meta_key_to_props = array(
47
-		'_wpinv_subscr_profile_id' => 'remote_subscription_id',
48
-		'_wpinv_subscription_id'   => 'subscription_id',
49
-		'_wpinv_taxes'             => 'taxes',
50
-		'_wpinv_fees'              => 'fees',
51
-		'_wpinv_discounts'         => 'discounts',
52
-		'_wpinv_submission_id'     => 'submission_id',
53
-		'_wpinv_payment_form'      => 'payment_form',
54
-		'_wpinv_is_viewed'         => 'is_viewed',
55
-		'wpinv_email_cc'           => 'email_cc',
56
-		'wpinv_template'           => 'template',
57
-		'wpinv_created_via'        => 'created_via',
58
-		'_wpinv_phone'             => 'phone',
59
-	);
60
-
61
-	/**
62
-	 * A map of database fields to data props.
63
-	 *
64
-	 * @since 1.0.19
65
-	 *
66
-	 * @var array
67
-	 */
68
-	protected $database_fields_to_props = array(
69
-		'post_id'            => 'id',
70
-		'number'             => 'number',
71
-		'currency'           => 'currency',
72
-		'key'                => 'key',
73
-		'type'               => 'type',
74
-		'mode'               => 'mode',
75
-		'user_ip'            => 'user_ip',
76
-		'first_name'         => 'first_name',
77
-		'last_name'          => 'last_name',
78
-		'address'            => 'address',
79
-		'city'               => 'city',
80
-		'state'              => 'state',
81
-		'country'            => 'country',
82
-		'zip'                => 'zip',
83
-		'zip'                => 'zip',
84
-		'adddress_confirmed' => 'address_confirmed',
85
-		'gateway'            => 'gateway',
86
-		'transaction_id'     => 'transaction_id',
87
-		'currency'           => 'currency',
88
-		'subtotal'           => 'subtotal',
89
-		'tax'                => 'total_tax',
90
-		'fees_total'         => 'total_fees',
91
-		'discount'           => 'total_discount',
92
-		'total'              => 'total',
93
-		'discount_code'      => 'discount_code',
94
-		'disable_taxes'      => 'disable_taxes',
95
-		'due_date'           => 'due_date',
96
-		'completed_date'     => 'completed_date',
97
-		'company'            => 'company',
98
-		'vat_number'         => 'vat_number',
99
-		'vat_rate'           => 'vat_rate',
100
-	);
101
-
102
-	/*
18
+    /**
19
+     * Data stored in meta keys, but not considered "meta" for a discount.
20
+     *
21
+     * @since 1.0.19
22
+     * @var array
23
+     */
24
+    protected $internal_meta_keys = array(
25
+        '_wpinv_subscr_profile_id',
26
+        '_wpinv_subscription_id',
27
+        '_wpinv_taxes',
28
+        '_wpinv_fees',
29
+        '_wpinv_discounts',
30
+        '_wpinv_submission_id',
31
+        '_wpinv_payment_form',
32
+        '_wpinv_is_viewed',
33
+        '_wpinv_phone',
34
+        'wpinv_email_cc',
35
+        'wpinv_template',
36
+        'wpinv_created_via'
37
+    );
38
+
39
+    /**
40
+     * A map of meta keys to data props.
41
+     *
42
+     * @since 1.0.19
43
+     *
44
+     * @var array
45
+     */
46
+    protected $meta_key_to_props = array(
47
+        '_wpinv_subscr_profile_id' => 'remote_subscription_id',
48
+        '_wpinv_subscription_id'   => 'subscription_id',
49
+        '_wpinv_taxes'             => 'taxes',
50
+        '_wpinv_fees'              => 'fees',
51
+        '_wpinv_discounts'         => 'discounts',
52
+        '_wpinv_submission_id'     => 'submission_id',
53
+        '_wpinv_payment_form'      => 'payment_form',
54
+        '_wpinv_is_viewed'         => 'is_viewed',
55
+        'wpinv_email_cc'           => 'email_cc',
56
+        'wpinv_template'           => 'template',
57
+        'wpinv_created_via'        => 'created_via',
58
+        '_wpinv_phone'             => 'phone',
59
+    );
60
+
61
+    /**
62
+     * A map of database fields to data props.
63
+     *
64
+     * @since 1.0.19
65
+     *
66
+     * @var array
67
+     */
68
+    protected $database_fields_to_props = array(
69
+        'post_id'            => 'id',
70
+        'number'             => 'number',
71
+        'currency'           => 'currency',
72
+        'key'                => 'key',
73
+        'type'               => 'type',
74
+        'mode'               => 'mode',
75
+        'user_ip'            => 'user_ip',
76
+        'first_name'         => 'first_name',
77
+        'last_name'          => 'last_name',
78
+        'address'            => 'address',
79
+        'city'               => 'city',
80
+        'state'              => 'state',
81
+        'country'            => 'country',
82
+        'zip'                => 'zip',
83
+        'zip'                => 'zip',
84
+        'adddress_confirmed' => 'address_confirmed',
85
+        'gateway'            => 'gateway',
86
+        'transaction_id'     => 'transaction_id',
87
+        'currency'           => 'currency',
88
+        'subtotal'           => 'subtotal',
89
+        'tax'                => 'total_tax',
90
+        'fees_total'         => 'total_fees',
91
+        'discount'           => 'total_discount',
92
+        'total'              => 'total',
93
+        'discount_code'      => 'discount_code',
94
+        'disable_taxes'      => 'disable_taxes',
95
+        'due_date'           => 'due_date',
96
+        'completed_date'     => 'completed_date',
97
+        'company'            => 'company',
98
+        'vat_number'         => 'vat_number',
99
+        'vat_rate'           => 'vat_rate',
100
+    );
101
+
102
+    /*
103 103
 	|--------------------------------------------------------------------------
104 104
 	| CRUD Methods
105 105
 	|--------------------------------------------------------------------------
106 106
 	*/
107 107
 
108
-	/**
109
-	 * Method to create a new invoice in the database.
110
-	 *
111
-	 * @param WPInv_Invoice $invoice Invoice object.
112
-	 */
113
-	public function create( &$invoice ) {
114
-		$invoice->set_version( WPINV_VERSION );
115
-		$invoice->set_date_created( current_time('mysql') );
116
-
117
-		// Create a new post.
118
-		$id = wp_insert_post(
119
-			apply_filters(
120
-				'getpaid_new_invoice_data',
121
-				array(
122
-					'post_date'     => $invoice->get_date_created( 'edit' ),
123
-					'post_type'     => $invoice->get_post_type( 'edit' ),
124
-					'post_status'   => $this->get_post_status( $invoice ),
125
-					'ping_status'   => 'closed',
126
-					'post_author'   => $invoice->get_user_id( 'edit' ),
127
-					'post_title'    => $invoice->get_title( 'edit' ),
128
-					'post_excerpt'  => $invoice->get_description( 'edit' ),
129
-					'post_parent'   => $invoice->get_parent_id( 'edit' ),
130
-				)
131
-			),
132
-			true
133
-		);
134
-
135
-		if ( $id && ! is_wp_error( $id ) ) {
136
-
137
-			// Update the new id and regenerate a title.
138
-			$invoice->set_id( $id );
139
-
140
-			$invoice->maybe_set_number();
141
-
142
-			wp_update_post(
143
-				array(
144
-					'ID'         => $invoice->get_id(),
145
-					'post_title' => $invoice->get_number( 'edit' ),
146
-					'post_name'  => $invoice->get_path( 'edit' )
147
-				)
148
-			);
149
-
150
-			// Save special fields and items.
151
-			$this->save_special_fields( $invoice );
152
-			$this->save_items( $invoice );
153
-
154
-			// Update meta data.
155
-			$this->update_post_meta( $invoice );
156
-			$invoice->save_meta_data();
157
-
158
-			// Apply changes.
159
-			$invoice->apply_changes();
160
-			$this->clear_caches( $invoice );
161
-
162
-			// Fires after a new invoice is created.
163
-			do_action( 'getpaid_new_invoice', $invoice );
164
-			return true;
165
-		}
166
-
167
-		if ( is_wp_error( $id ) ) {
168
-			$invoice->last_error = $id->get_error_message();
169
-		}
170
-
171
-		return false;
172
-	}
173
-
174
-	/**
175
-	 * Method to read an invoice from the database.
176
-	 *
177
-	 * @param WPInv_Invoice $invoice Invoice object.
178
-	 *
179
-	 */
180
-	public function read( &$invoice ) {
181
-
182
-		$invoice->set_defaults();
183
-		$invoice_object = get_post( $invoice->get_id() );
184
-
185
-		if ( ! $invoice->get_id() || ! $invoice_object || ! getpaid_is_invoice_post_type( $invoice_object->post_type ) ) {
186
-			$invoice->last_error = __( 'Invalid invoice.', 'invoicing' );
187
-			$invoice->set_id( 0 );
188
-			return false;
189
-		}
190
-
191
-		$invoice->set_props(
192
-			array(
193
-				'date_created'  => 0 < $invoice_object->post_date ? $invoice_object->post_date : null,
194
-				'date_modified' => 0 < $invoice_object->post_modified ? $invoice_object->post_modified : null,
195
-				'status'        => $invoice_object->post_status,
196
-				'author'        => $invoice_object->post_author,
197
-				'description'   => $invoice_object->post_excerpt,
198
-				'parent_id'     => $invoice_object->post_parent,
199
-				'name'          => $invoice_object->post_title,
200
-				'path'          => $invoice_object->post_name,
201
-				'post_type'     => $invoice_object->post_type,
202
-			)
203
-		);
204
-
205
-		$invoice->set_type( $invoice_object->post_type );
206
-
207
-		$this->read_object_data( $invoice, $invoice_object );
208
-		$this->add_special_fields( $invoice );
209
-		$this->add_items( $invoice );
210
-		$invoice->read_meta_data();
211
-		$invoice->set_object_read( true );
212
-		do_action( 'getpaid_read_invoice', $invoice );
213
-
214
-	}
215
-
216
-	/**
217
-	 * Method to update an invoice in the database.
218
-	 *
219
-	 * @param WPInv_Invoice $invoice Invoice object.
220
-	 */
221
-	public function update( &$invoice ) {
222
-		$invoice->save_meta_data();
223
-		$invoice->set_version( WPINV_VERSION );
224
-
225
-		if ( null === $invoice->get_date_created( 'edit' ) ) {
226
-			$invoice->set_date_created(  current_time('mysql') );
227
-		}
228
-
229
-		// Ensure both the key and number are set.
230
-		$invoice->get_path();
231
-
232
-		// Grab the current status so we can compare.
233
-		$previous_status = get_post_status( $invoice->get_id() );
234
-
235
-		$changes = $invoice->get_changes();
236
-
237
-		// Only update the post when the post data changes.
238
-		if ( array_intersect( array( 'date_created', 'date_modified', 'status', 'name', 'author', 'description', 'parent_id', 'post_excerpt', 'path' ), array_keys( $changes ) ) ) {
239
-			$post_data = array(
240
-				'post_date'         => $invoice->get_date_created( 'edit' ),
241
-				'post_date_gmt'     => $invoice->get_date_created_gmt( 'edit' ),
242
-				'post_status'       => $invoice->get_status( 'edit' ),
243
-				'post_title'        => $invoice->get_name( 'edit' ),
244
-				'post_author'       => $invoice->get_user_id( 'edit' ),
245
-				'post_modified'     => $invoice->get_date_modified( 'edit' ),
246
-				'post_excerpt'      => $invoice->get_description( 'edit' ),
247
-				'post_parent'       => $invoice->get_parent_id( 'edit' ),
248
-				'post_name'         => $invoice->get_path( 'edit' ),
249
-				'post_type'         => $invoice->get_post_type( 'edit' ),
250
-			);
251
-
252
-			/**
253
-			 * When updating this object, to prevent infinite loops, use $wpdb
254
-			 * to update data, since wp_update_post spawns more calls to the
255
-			 * save_post action.
256
-			 *
257
-			 * This ensures hooks are fired by either WP itself (admin screen save),
258
-			 * or an update purely from CRUD.
259
-			 */
260
-			if ( doing_action( 'save_post' ) ) {
261
-				$GLOBALS['wpdb']->update( $GLOBALS['wpdb']->posts, $post_data, array( 'ID' => $invoice->get_id() ) );
262
-				clean_post_cache( $invoice->get_id() );
263
-			} else {
264
-				wp_update_post( array_merge( array( 'ID' => $invoice->get_id() ), $post_data ) );
265
-			}
266
-			$invoice->read_meta_data( true ); // Refresh internal meta data, in case things were hooked into `save_post` or another WP hook.
267
-		}
268
-
269
-		// Update meta data.
270
-		$this->update_post_meta( $invoice );
271
-
272
-		// Save special fields and items.
273
-		$this->save_special_fields( $invoice );
274
-		$this->save_items( $invoice );
275
-
276
-		// Apply the changes.
277
-		$invoice->apply_changes();
278
-
279
-		// Clear caches.
280
-		$this->clear_caches( $invoice );
281
-
282
-		// Fire a hook depending on the status - this should be considered a creation if it was previously draft status.
283
-		$new_status = $invoice->get_status( 'edit' );
284
-
285
-		if ( $new_status !== $previous_status && in_array( $previous_status, array( 'new', 'auto-draft', 'draft' ), true ) ) {
286
-			do_action( 'getpaid_new_invoice', $invoice );
287
-		} else {
288
-			do_action( 'getpaid_update_invoice', $invoice );
289
-		}
290
-
291
-	}
292
-
293
-	/*
108
+    /**
109
+     * Method to create a new invoice in the database.
110
+     *
111
+     * @param WPInv_Invoice $invoice Invoice object.
112
+     */
113
+    public function create( &$invoice ) {
114
+        $invoice->set_version( WPINV_VERSION );
115
+        $invoice->set_date_created( current_time('mysql') );
116
+
117
+        // Create a new post.
118
+        $id = wp_insert_post(
119
+            apply_filters(
120
+                'getpaid_new_invoice_data',
121
+                array(
122
+                    'post_date'     => $invoice->get_date_created( 'edit' ),
123
+                    'post_type'     => $invoice->get_post_type( 'edit' ),
124
+                    'post_status'   => $this->get_post_status( $invoice ),
125
+                    'ping_status'   => 'closed',
126
+                    'post_author'   => $invoice->get_user_id( 'edit' ),
127
+                    'post_title'    => $invoice->get_title( 'edit' ),
128
+                    'post_excerpt'  => $invoice->get_description( 'edit' ),
129
+                    'post_parent'   => $invoice->get_parent_id( 'edit' ),
130
+                )
131
+            ),
132
+            true
133
+        );
134
+
135
+        if ( $id && ! is_wp_error( $id ) ) {
136
+
137
+            // Update the new id and regenerate a title.
138
+            $invoice->set_id( $id );
139
+
140
+            $invoice->maybe_set_number();
141
+
142
+            wp_update_post(
143
+                array(
144
+                    'ID'         => $invoice->get_id(),
145
+                    'post_title' => $invoice->get_number( 'edit' ),
146
+                    'post_name'  => $invoice->get_path( 'edit' )
147
+                )
148
+            );
149
+
150
+            // Save special fields and items.
151
+            $this->save_special_fields( $invoice );
152
+            $this->save_items( $invoice );
153
+
154
+            // Update meta data.
155
+            $this->update_post_meta( $invoice );
156
+            $invoice->save_meta_data();
157
+
158
+            // Apply changes.
159
+            $invoice->apply_changes();
160
+            $this->clear_caches( $invoice );
161
+
162
+            // Fires after a new invoice is created.
163
+            do_action( 'getpaid_new_invoice', $invoice );
164
+            return true;
165
+        }
166
+
167
+        if ( is_wp_error( $id ) ) {
168
+            $invoice->last_error = $id->get_error_message();
169
+        }
170
+
171
+        return false;
172
+    }
173
+
174
+    /**
175
+     * Method to read an invoice from the database.
176
+     *
177
+     * @param WPInv_Invoice $invoice Invoice object.
178
+     *
179
+     */
180
+    public function read( &$invoice ) {
181
+
182
+        $invoice->set_defaults();
183
+        $invoice_object = get_post( $invoice->get_id() );
184
+
185
+        if ( ! $invoice->get_id() || ! $invoice_object || ! getpaid_is_invoice_post_type( $invoice_object->post_type ) ) {
186
+            $invoice->last_error = __( 'Invalid invoice.', 'invoicing' );
187
+            $invoice->set_id( 0 );
188
+            return false;
189
+        }
190
+
191
+        $invoice->set_props(
192
+            array(
193
+                'date_created'  => 0 < $invoice_object->post_date ? $invoice_object->post_date : null,
194
+                'date_modified' => 0 < $invoice_object->post_modified ? $invoice_object->post_modified : null,
195
+                'status'        => $invoice_object->post_status,
196
+                'author'        => $invoice_object->post_author,
197
+                'description'   => $invoice_object->post_excerpt,
198
+                'parent_id'     => $invoice_object->post_parent,
199
+                'name'          => $invoice_object->post_title,
200
+                'path'          => $invoice_object->post_name,
201
+                'post_type'     => $invoice_object->post_type,
202
+            )
203
+        );
204
+
205
+        $invoice->set_type( $invoice_object->post_type );
206
+
207
+        $this->read_object_data( $invoice, $invoice_object );
208
+        $this->add_special_fields( $invoice );
209
+        $this->add_items( $invoice );
210
+        $invoice->read_meta_data();
211
+        $invoice->set_object_read( true );
212
+        do_action( 'getpaid_read_invoice', $invoice );
213
+
214
+    }
215
+
216
+    /**
217
+     * Method to update an invoice in the database.
218
+     *
219
+     * @param WPInv_Invoice $invoice Invoice object.
220
+     */
221
+    public function update( &$invoice ) {
222
+        $invoice->save_meta_data();
223
+        $invoice->set_version( WPINV_VERSION );
224
+
225
+        if ( null === $invoice->get_date_created( 'edit' ) ) {
226
+            $invoice->set_date_created(  current_time('mysql') );
227
+        }
228
+
229
+        // Ensure both the key and number are set.
230
+        $invoice->get_path();
231
+
232
+        // Grab the current status so we can compare.
233
+        $previous_status = get_post_status( $invoice->get_id() );
234
+
235
+        $changes = $invoice->get_changes();
236
+
237
+        // Only update the post when the post data changes.
238
+        if ( array_intersect( array( 'date_created', 'date_modified', 'status', 'name', 'author', 'description', 'parent_id', 'post_excerpt', 'path' ), array_keys( $changes ) ) ) {
239
+            $post_data = array(
240
+                'post_date'         => $invoice->get_date_created( 'edit' ),
241
+                'post_date_gmt'     => $invoice->get_date_created_gmt( 'edit' ),
242
+                'post_status'       => $invoice->get_status( 'edit' ),
243
+                'post_title'        => $invoice->get_name( 'edit' ),
244
+                'post_author'       => $invoice->get_user_id( 'edit' ),
245
+                'post_modified'     => $invoice->get_date_modified( 'edit' ),
246
+                'post_excerpt'      => $invoice->get_description( 'edit' ),
247
+                'post_parent'       => $invoice->get_parent_id( 'edit' ),
248
+                'post_name'         => $invoice->get_path( 'edit' ),
249
+                'post_type'         => $invoice->get_post_type( 'edit' ),
250
+            );
251
+
252
+            /**
253
+             * When updating this object, to prevent infinite loops, use $wpdb
254
+             * to update data, since wp_update_post spawns more calls to the
255
+             * save_post action.
256
+             *
257
+             * This ensures hooks are fired by either WP itself (admin screen save),
258
+             * or an update purely from CRUD.
259
+             */
260
+            if ( doing_action( 'save_post' ) ) {
261
+                $GLOBALS['wpdb']->update( $GLOBALS['wpdb']->posts, $post_data, array( 'ID' => $invoice->get_id() ) );
262
+                clean_post_cache( $invoice->get_id() );
263
+            } else {
264
+                wp_update_post( array_merge( array( 'ID' => $invoice->get_id() ), $post_data ) );
265
+            }
266
+            $invoice->read_meta_data( true ); // Refresh internal meta data, in case things were hooked into `save_post` or another WP hook.
267
+        }
268
+
269
+        // Update meta data.
270
+        $this->update_post_meta( $invoice );
271
+
272
+        // Save special fields and items.
273
+        $this->save_special_fields( $invoice );
274
+        $this->save_items( $invoice );
275
+
276
+        // Apply the changes.
277
+        $invoice->apply_changes();
278
+
279
+        // Clear caches.
280
+        $this->clear_caches( $invoice );
281
+
282
+        // Fire a hook depending on the status - this should be considered a creation if it was previously draft status.
283
+        $new_status = $invoice->get_status( 'edit' );
284
+
285
+        if ( $new_status !== $previous_status && in_array( $previous_status, array( 'new', 'auto-draft', 'draft' ), true ) ) {
286
+            do_action( 'getpaid_new_invoice', $invoice );
287
+        } else {
288
+            do_action( 'getpaid_update_invoice', $invoice );
289
+        }
290
+
291
+    }
292
+
293
+    /*
294 294
 	|--------------------------------------------------------------------------
295 295
 	| Additional Methods
296 296
 	|--------------------------------------------------------------------------
297 297
 	*/
298 298
 
299
-	/**
299
+    /**
300 300
      * Retrieves special fields and adds to the invoice.
301
-	 *
302
-	 * @param WPInv_Invoice $invoice Invoice object.
301
+     *
302
+     * @param WPInv_Invoice $invoice Invoice object.
303 303
      */
304 304
     public function add_special_fields( &$invoice ) {
305
-		global $wpdb;
305
+        global $wpdb;
306 306
 
307
-		// Maybe retrieve from the cache.
308
-		$data   = wp_cache_get( $invoice->get_id(), 'getpaid_invoice_special_fields' );
307
+        // Maybe retrieve from the cache.
308
+        $data   = wp_cache_get( $invoice->get_id(), 'getpaid_invoice_special_fields' );
309 309
 
310
-		// If not found, retrieve from the db.
311
-		if ( false === $data ) {
312
-			$table =  $wpdb->prefix . 'getpaid_invoices';
310
+        // If not found, retrieve from the db.
311
+        if ( false === $data ) {
312
+            $table =  $wpdb->prefix . 'getpaid_invoices';
313 313
 
314
-			$data  = $wpdb->get_row(
315
-				$wpdb->prepare( "SELECT * FROM $table WHERE `post_id`=%d LIMIT 1", $invoice->get_id() ),
316
-				ARRAY_A
317
-			);
314
+            $data  = $wpdb->get_row(
315
+                $wpdb->prepare( "SELECT * FROM $table WHERE `post_id`=%d LIMIT 1", $invoice->get_id() ),
316
+                ARRAY_A
317
+            );
318 318
 
319
-			// Update the cache with our data
320
-			wp_cache_set( $invoice->get_id(), $data, 'getpaid_invoice_special_fields' );
319
+            // Update the cache with our data
320
+            wp_cache_set( $invoice->get_id(), $data, 'getpaid_invoice_special_fields' );
321 321
 
322
-		}
322
+        }
323 323
 
324
-		// Abort if the data does not exist.
325
-		if ( empty( $data ) ) {
326
-			$invoice->set_object_read( true );
327
-			$invoice->set_props( wpinv_get_user_address( $invoice->get_user_id() ) );
328
-			return;
329
-		}
324
+        // Abort if the data does not exist.
325
+        if ( empty( $data ) ) {
326
+            $invoice->set_object_read( true );
327
+            $invoice->set_props( wpinv_get_user_address( $invoice->get_user_id() ) );
328
+            return;
329
+        }
330 330
 
331
-		$props = array();
331
+        $props = array();
332 332
 
333
-		foreach ( $this->database_fields_to_props as $db_field => $prop ) {
333
+        foreach ( $this->database_fields_to_props as $db_field => $prop ) {
334 334
 			
335
-			if ( $db_field == 'post_id' ) {
336
-				continue;
337
-			}
338
-
339
-			$props[ $prop ] = $data[ $db_field ];
340
-		}
341
-
342
-		$invoice->set_props( $props );
343
-
344
-	}
345
-
346
-	/**
347
-	 * Gets a list of special fields that need updated based on change state
348
-	 * or if they are present in the database or not.
349
-	 *
350
-	 * @param  WPInv_Invoice $invoice       The Invoice object.
351
-	 * @return array                        A mapping of field keys => prop names, filtered by ones that should be updated.
352
-	 */
353
-	protected function get_special_fields_to_update( $invoice ) {
354
-		$fields_to_update = array();
355
-		$changed_props   = $invoice->get_changes();
356
-
357
-		// Props should be updated if they are a part of the $changed array or don't exist yet.
358
-		foreach ( $this->database_fields_to_props as $database_field => $prop ) {
359
-			if ( array_key_exists( $prop, $changed_props ) ) {
360
-				$fields_to_update[ $database_field ] = $prop;
361
-			}
362
-		}
363
-
364
-		return $fields_to_update;
365
-	}
366
-
367
-	/**
368
-	 * Helper method that updates all the database fields for an invoice based on it's settings in the WPInv_Invoice class.
369
-	 *
370
-	 * @param WPInv_Invoice $invoice WPInv_Invoice object.
371
-	 * @since 1.0.19
372
-	 */
373
-	protected function update_special_fields( &$invoice ) {
374
-		global $wpdb;
375
-
376
-		$updated_props    = array();
377
-		$fields_to_update = $this->get_special_fields_to_update( $invoice );
378
-
379
-		foreach ( $fields_to_update as $database_field => $prop ) {
380
-			$value = $invoice->{"get_$prop"}( 'edit' );
381
-			$value = is_string( $value ) ? wp_slash( $value ) : $value;
382
-			$value = is_bool( $value ) ? ( int ) $value : $value;
383
-			$updated_props[ $database_field ] = maybe_serialize( $value );
384
-		}
385
-
386
-		if ( ! empty( $updated_props ) ) {
387
-
388
-			$table = $wpdb->prefix . 'getpaid_invoices';
389
-			$wpdb->update( $table, $updated_props, array( 'post_id' => $invoice->get_id() ) );
390
-			wp_cache_delete( $invoice->get_id(), 'getpaid_invoice_special_fields' );
391
-			do_action( "getpaid_invoice_update_database_fields", $invoice, $updated_props );
392
-
393
-		}
394
-
395
-	}
396
-
397
-	/**
398
-	 * Helper method that inserts special fields to the database.
399
-	 *
400
-	 * @param WPInv_Invoice $invoice WPInv_Invoice object.
401
-	 * @since 1.0.19
402
-	 */
403
-	protected function insert_special_fields( &$invoice ) {
404
-		global $wpdb;
405
-
406
-		$updated_props   = array();
407
-
408
-		foreach ( $this->database_fields_to_props as $database_field => $prop ) {
409
-			$value = $invoice->{"get_$prop"}( 'edit' );
410
-			$value = is_string( $value ) ? wp_slash( $value ) : $value;
411
-			$value = is_bool( $value ) ? ( int ) $value : $value;
412
-			$updated_props[ $database_field ] = maybe_serialize( $value );
413
-		}
414
-
415
-		$table = $wpdb->prefix . 'getpaid_invoices';
416
-		$wpdb->insert( $table, $updated_props );
417
-		wp_cache_delete( $invoice->get_id(), 'getpaid_invoice_special_fields' );
418
-		do_action( "getpaid_invoice_insert_database_fields", $invoice, $updated_props );
419
-
420
-	}
421
-
422
-	/**
335
+            if ( $db_field == 'post_id' ) {
336
+                continue;
337
+            }
338
+
339
+            $props[ $prop ] = $data[ $db_field ];
340
+        }
341
+
342
+        $invoice->set_props( $props );
343
+
344
+    }
345
+
346
+    /**
347
+     * Gets a list of special fields that need updated based on change state
348
+     * or if they are present in the database or not.
349
+     *
350
+     * @param  WPInv_Invoice $invoice       The Invoice object.
351
+     * @return array                        A mapping of field keys => prop names, filtered by ones that should be updated.
352
+     */
353
+    protected function get_special_fields_to_update( $invoice ) {
354
+        $fields_to_update = array();
355
+        $changed_props   = $invoice->get_changes();
356
+
357
+        // Props should be updated if they are a part of the $changed array or don't exist yet.
358
+        foreach ( $this->database_fields_to_props as $database_field => $prop ) {
359
+            if ( array_key_exists( $prop, $changed_props ) ) {
360
+                $fields_to_update[ $database_field ] = $prop;
361
+            }
362
+        }
363
+
364
+        return $fields_to_update;
365
+    }
366
+
367
+    /**
368
+     * Helper method that updates all the database fields for an invoice based on it's settings in the WPInv_Invoice class.
369
+     *
370
+     * @param WPInv_Invoice $invoice WPInv_Invoice object.
371
+     * @since 1.0.19
372
+     */
373
+    protected function update_special_fields( &$invoice ) {
374
+        global $wpdb;
375
+
376
+        $updated_props    = array();
377
+        $fields_to_update = $this->get_special_fields_to_update( $invoice );
378
+
379
+        foreach ( $fields_to_update as $database_field => $prop ) {
380
+            $value = $invoice->{"get_$prop"}( 'edit' );
381
+            $value = is_string( $value ) ? wp_slash( $value ) : $value;
382
+            $value = is_bool( $value ) ? ( int ) $value : $value;
383
+            $updated_props[ $database_field ] = maybe_serialize( $value );
384
+        }
385
+
386
+        if ( ! empty( $updated_props ) ) {
387
+
388
+            $table = $wpdb->prefix . 'getpaid_invoices';
389
+            $wpdb->update( $table, $updated_props, array( 'post_id' => $invoice->get_id() ) );
390
+            wp_cache_delete( $invoice->get_id(), 'getpaid_invoice_special_fields' );
391
+            do_action( "getpaid_invoice_update_database_fields", $invoice, $updated_props );
392
+
393
+        }
394
+
395
+    }
396
+
397
+    /**
398
+     * Helper method that inserts special fields to the database.
399
+     *
400
+     * @param WPInv_Invoice $invoice WPInv_Invoice object.
401
+     * @since 1.0.19
402
+     */
403
+    protected function insert_special_fields( &$invoice ) {
404
+        global $wpdb;
405
+
406
+        $updated_props   = array();
407
+
408
+        foreach ( $this->database_fields_to_props as $database_field => $prop ) {
409
+            $value = $invoice->{"get_$prop"}( 'edit' );
410
+            $value = is_string( $value ) ? wp_slash( $value ) : $value;
411
+            $value = is_bool( $value ) ? ( int ) $value : $value;
412
+            $updated_props[ $database_field ] = maybe_serialize( $value );
413
+        }
414
+
415
+        $table = $wpdb->prefix . 'getpaid_invoices';
416
+        $wpdb->insert( $table, $updated_props );
417
+        wp_cache_delete( $invoice->get_id(), 'getpaid_invoice_special_fields' );
418
+        do_action( "getpaid_invoice_insert_database_fields", $invoice, $updated_props );
419
+
420
+    }
421
+
422
+    /**
423 423
      * Saves all special fields.
424
-	 *
425
-	 * @param WPInv_Invoice $invoice Invoice object.
424
+     *
425
+     * @param WPInv_Invoice $invoice Invoice object.
426 426
      */
427 427
     public function save_special_fields( & $invoice ) {
428
-		global $wpdb;
428
+        global $wpdb;
429 429
 
430
-		// The invoices table.
431
-		$table = $wpdb->prefix . 'getpaid_invoices';
432
-		$id    = (int) $invoice->get_id();
433
-		$invoice->maybe_set_key();
430
+        // The invoices table.
431
+        $table = $wpdb->prefix . 'getpaid_invoices';
432
+        $id    = (int) $invoice->get_id();
433
+        $invoice->maybe_set_key();
434 434
 
435
-		if ( $wpdb->get_var( "SELECT `post_id` FROM $table WHERE `post_id`= $id" ) ) {
435
+        if ( $wpdb->get_var( "SELECT `post_id` FROM $table WHERE `post_id`= $id" ) ) {
436 436
 
437
-			$this->update_special_fields( $invoice );
437
+            $this->update_special_fields( $invoice );
438 438
 
439
-		} else {
439
+        } else {
440 440
 
441
-			$this->insert_special_fields( $invoice );
441
+            $this->insert_special_fields( $invoice );
442 442
 
443
-		}
443
+        }
444 444
 
445
-	}
445
+    }
446 446
 
447
-	/**
447
+    /**
448 448
      * Set's up cart details.
449
-	 *
450
-	 * @param WPInv_Invoice $invoice Invoice object.
449
+     *
450
+     * @param WPInv_Invoice $invoice Invoice object.
451 451
      */
452 452
     public function add_items( &$invoice ) {
453
-		global $wpdb;
453
+        global $wpdb;
454 454
 
455
-		// Maybe retrieve from the cache.
456
-		$items = wp_cache_get( $invoice->get_id(), 'getpaid_invoice_cart_details' );
455
+        // Maybe retrieve from the cache.
456
+        $items = wp_cache_get( $invoice->get_id(), 'getpaid_invoice_cart_details' );
457 457
 
458
-		// If not found, retrieve from the db.
459
-		if ( false === $items ) {
460
-			$table =  $wpdb->prefix . 'getpaid_invoice_items';
458
+        // If not found, retrieve from the db.
459
+        if ( false === $items ) {
460
+            $table =  $wpdb->prefix . 'getpaid_invoice_items';
461 461
 
462
-			$items = $wpdb->get_results(
463
-				$wpdb->prepare( "SELECT * FROM $table WHERE `post_id`=%d", $invoice->get_id() )
464
-			);
462
+            $items = $wpdb->get_results(
463
+                $wpdb->prepare( "SELECT * FROM $table WHERE `post_id`=%d", $invoice->get_id() )
464
+            );
465 465
 
466
-			// Update the cache with our data
467
-			wp_cache_set( $invoice->get_id(), $items, 'getpaid_invoice_cart_details' );
466
+            // Update the cache with our data
467
+            wp_cache_set( $invoice->get_id(), $items, 'getpaid_invoice_cart_details' );
468 468
 
469
-		}
469
+        }
470 470
 
471
-		// Abort if no items found.
471
+        // Abort if no items found.
472 472
         if ( empty( $items ) ) {
473 473
             return;
474
-		}
474
+        }
475 475
 
476
-		foreach ( $items as $item_data ) {
477
-			$item = new GetPaid_Form_Item( $item_data->item_id );
476
+        foreach ( $items as $item_data ) {
477
+            $item = new GetPaid_Form_Item( $item_data->item_id );
478 478
 
479
-			// Set item data.
480
-			$item->item_tax      = wpinv_sanitize_amount( $item_data->tax );
481
-			$item->item_discount = wpinv_sanitize_amount( $item_data->discount );
482
-			$item->set_name( $item_data->item_name );
483
-			$item->set_description( $item_data->item_description );
484
-			$item->set_price( $item_data->item_price );
485
-			$item->set_quantity( $item_data->quantity );
486
-			$item->set_item_meta( $item_data->meta );
479
+            // Set item data.
480
+            $item->item_tax      = wpinv_sanitize_amount( $item_data->tax );
481
+            $item->item_discount = wpinv_sanitize_amount( $item_data->discount );
482
+            $item->set_name( $item_data->item_name );
483
+            $item->set_description( $item_data->item_description );
484
+            $item->set_price( $item_data->item_price );
485
+            $item->set_quantity( $item_data->quantity );
486
+            $item->set_item_meta( $item_data->meta );
487 487
 
488
-			$invoice->add_item( $item );
489
-		}
488
+            $invoice->add_item( $item );
489
+        }
490 490
 
491
-	}
491
+    }
492 492
 
493
-	/**
493
+    /**
494 494
      * Saves cart details.
495
-	 *
496
-	 * @param WPInv_Invoice $invoice Invoice object.
495
+     *
496
+     * @param WPInv_Invoice $invoice Invoice object.
497 497
      */
498 498
     public function save_items( $invoice ) {
499 499
 
500
-		// Delete previously existing items.
501
-		$this->delete_items( $invoice );
500
+        // Delete previously existing items.
501
+        $this->delete_items( $invoice );
502 502
 
503
-		$table   =  $GLOBALS['wpdb']->prefix . 'getpaid_invoice_items';
503
+        $table   =  $GLOBALS['wpdb']->prefix . 'getpaid_invoice_items';
504 504
 
505
-		foreach ( $invoice->get_cart_details() as $item_data ) {
506
-			$item_data = array_map( 'maybe_serialize', $item_data );
507
-			$GLOBALS['wpdb']->insert( $table, $item_data );
508
-		}
505
+        foreach ( $invoice->get_cart_details() as $item_data ) {
506
+            $item_data = array_map( 'maybe_serialize', $item_data );
507
+            $GLOBALS['wpdb']->insert( $table, $item_data );
508
+        }
509 509
 
510
-		wp_cache_delete( $invoice->get_id(), 'getpaid_invoice_cart_details' );
511
-		do_action( "getpaid_invoice_save_items", $invoice );
510
+        wp_cache_delete( $invoice->get_id(), 'getpaid_invoice_cart_details' );
511
+        do_action( "getpaid_invoice_save_items", $invoice );
512 512
 
513
-	}
513
+    }
514 514
 
515
-	/**
515
+    /**
516 516
      * Deletes an invoice's cart details from the database.
517
-	 *
518
-	 * @param WPInv_Invoice $invoice Invoice object.
517
+     *
518
+     * @param WPInv_Invoice $invoice Invoice object.
519 519
      */
520 520
     public function delete_items( $invoice ) {
521
-		$table =  $GLOBALS['wpdb']->prefix . 'getpaid_invoice_items';
522
-		return $GLOBALS['wpdb']->delete( $table, array( 'post_id' => $invoice->get_id() ) );
523
-	}
521
+        $table =  $GLOBALS['wpdb']->prefix . 'getpaid_invoice_items';
522
+        return $GLOBALS['wpdb']->delete( $table, array( 'post_id' => $invoice->get_id() ) );
523
+    }
524 524
 
525
-	/**
525
+    /**
526 526
      * Deletes an invoice's special fields from the database.
527
-	 *
528
-	 * @param WPInv_Invoice $invoice Invoice object.
527
+     *
528
+     * @param WPInv_Invoice $invoice Invoice object.
529 529
      */
530 530
     public function delete_special_fields( $invoice ) {
531
-		$table =  $GLOBALS['wpdb']->prefix . 'getpaid_invoices';
532
-		return $GLOBALS['wpdb']->delete( $table, array( 'post_id' => $invoice->get_id() ) );
533
-	}
531
+        $table =  $GLOBALS['wpdb']->prefix . 'getpaid_invoices';
532
+        return $GLOBALS['wpdb']->delete( $table, array( 'post_id' => $invoice->get_id() ) );
533
+    }
534 534
 	
535
-	/**
536
-	 * Get the status to save to the post object.
537
-	 *
538
-	 *
539
-	 * @since 1.0.19
540
-	 * @param  WPInv_Invoice $object GetPaid_Data object.
541
-	 * @return string
542
-	 */
543
-	protected function get_post_status( $object ) {
544
-		$object_status = $object->get_status( 'edit' );
545
-
546
-		if ( ! $object_status ) {
547
-			$object_status = $object->get_default_status();
548
-		}
549
-
550
-		return $object_status;
551
-	}
535
+    /**
536
+     * Get the status to save to the post object.
537
+     *
538
+     *
539
+     * @since 1.0.19
540
+     * @param  WPInv_Invoice $object GetPaid_Data object.
541
+     * @return string
542
+     */
543
+    protected function get_post_status( $object ) {
544
+        $object_status = $object->get_status( 'edit' );
545
+
546
+        if ( ! $object_status ) {
547
+            $object_status = $object->get_default_status();
548
+        }
549
+
550
+        return $object_status;
551
+    }
552 552
 
553 553
 }
Please login to merge, or discard this patch.