Passed
Pull Request — master (#377)
by Brian
05:21
created

WPInv_Invoice::remove_item()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 10
rs 10
cc 3
nc 4
nop 1
1
<?php
2
3
// MUST have WordPress.
4
if ( !defined( 'WPINC' ) ) {
5
    exit( 'Do NOT access this file directly: ' . basename( __FILE__ ) );
6
}
7
8
/**
9
 * Invoice class.
10
 */
11
class WPInv_Invoice extends GetPaid_Data {
12
13
    /**
14
	 * Which data store to load.
15
	 *
16
	 * @var string
17
	 */
18
    protected $data_store_name = 'invoice';
19
20
    /**
21
	 * This is the name of this object type.
22
	 *
23
	 * @var string
24
	 */
25
    protected $object_type = 'invoice';
26
27
    /**
28
	 * Item Data array. This is the core item data exposed in APIs.
29
	 *
30
	 * @since 1.0.19
31
	 * @var array
32
	 */
33
	protected $data = array(
34
		'parent_id'            => 0,
35
		'status'               => 'wpi-pending',
36
		'version'              => '',
37
		'date_created'         => null,
38
        'date_modified'        => null,
39
        'due_date'             => null,
40
        'completed_date'       => null,
41
        'number'               => '',
42
        'title'                => '',
43
        'path'                 => '',
44
        'key'                  => '',
45
        'description'          => '',
46
        'author'               => 1,
47
        'type'                 => 'invoice',
48
        'post_type'            => 'wpi_invoice',
49
        'mode'                 => 'live',
50
        'user_ip'              => null,
51
        'first_name'           => null,
52
        'last_name'            => null,
53
        'phone'                => null,
54
        'email'                => null,
55
        'country'              => null,
56
        'city'                 => null,
57
        'state'                => null,
58
        'zip'                  => null,
59
        'company'              => null,
60
        'vat_number'           => null,
61
        'vat_rate'             => null,
62
        'address'              => null,
63
        'address_confirmed'    => false,
64
        'subtotal'             => 0,
65
        'total_discount'       => 0,
66
        'total_tax'            => 0,
67
        'total_fees'           => 0,
68
        'fees'                 => array(),
69
        'discounts'            => array(),
70
        'taxes'                => array(),
71
        'items'                => array(),
72
        'payment_form'         => 1,
73
        'submission_id'        => null,
74
        'discount_code'        => null,
75
        'gateway'              => 'none',
76
        'transaction_id'       => '',
77
        'currency'             => '',
78
        'disable_taxes'        => 0,
79
        'subscription_id'      => null,
80
    );
81
82
    /**
83
	 * Stores meta in cache for future reads.
84
	 *
85
	 * A group must be set to to enable caching.
86
	 *
87
	 * @var string
88
	 */
89
	protected $cache_group = 'getpaid_invoices';
90
91
    /**
92
     * Stores a reference to the original WP_Post object
93
     * 
94
     * @var WP_Post
95
     */
96
    protected $post = null;
97
98
    /**
99
     * Stores a reference to the recurring item id instead of looping through the items.
100
     * 
101
     * @var int
102
     */
103
    protected $recurring_item = null;
104
105
    /**
106
	 * Get the invoice if ID is passed, otherwise the invoice is new and empty.
107
	 *
108
	 * @param  int/string|object|WPInv_Invoice|WPInv_Legacy_Invoice|WP_Post $invoice Invoice id, key, number or object to read.
0 ignored issues
show
Documentation Bug introduced by
The doc comment int/string|object|WPInv_..._Legacy_Invoice|WP_Post at position 0 could not be parsed: Unknown type name 'int/string' at position 0 in int/string|object|WPInv_Invoice|WPInv_Legacy_Invoice|WP_Post.
Loading history...
109
	 */
110
    public function __construct( $invoice = false ) {
111
112
        parent::__construct( $invoice );
113
114
		if ( is_numeric( $invoice ) && getpaid_is_invoice_post_type( get_post_type( $invoice ) ) ) {
115
			$this->set_id( $invoice );
116
		} elseif ( $invoice instanceof self ) {
117
			$this->set_id( $invoice->get_id() );
118
		} elseif ( ! empty( $invoice->ID ) ) {
119
			$this->set_id( $invoice->ID );
120
		} elseif ( is_array( $invoice ) ) {
121
			$this->set_props( $invoice );
122
123
			if ( isset( $invoice['ID'] ) ) {
124
				$this->set_id( $invoice['ID'] );
125
			}
126
127
		} elseif ( is_scalar( $invoice ) && $invoice_id = self::get_discount_id_by_code( $invoice, 'key' ) ) {
128
			$this->set_id( $invoice_id );
129
		} elseif ( is_scalar( $invoice ) && $invoice_id = self::get_discount_id_by_code( $invoice, 'number' ) ) {
130
			$this->set_id( $invoice_id );
131
		} else {
132
			$this->set_object_read( true );
133
		}
134
135
        // Load the datastore.
136
		$this->data_store = GetPaid_Data_Store::load( $this->data_store_name );
137
138
		if ( $this->get_id() > 0 ) {
139
            $this->post = get_post( $this->get_id() );
140
            $this->ID   = $this->get_id();
0 ignored issues
show
Bug Best Practice introduced by
The property ID does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
141
			$this->data_store->read( $this );
142
        }
143
144
    }
145
146
    /**
147
	 * Given a discount code, it returns a discount id.
148
	 *
149
	 *
150
	 * @static
151
	 * @param string $discount_code
152
	 * @since 1.0.15
153
	 * @return int
154
	 */
155
	public static function get_discount_id_by_code( $invoice_key_or_number, $field = 'key' ) {
156
        global $wpdb;
157
158
		// Trim the code.
159
        $key = trim( $invoice_key_or_number );
160
        
161
        // Valid fields.
162
        $fields = array( 'key', 'number' );
163
164
		// Ensure a value has been passed.
165
		if ( empty( $key ) || ! in_array( $field, $fields ) ) {
166
			return 0;
167
		}
168
169
		// Maybe retrieve from the cache.
170
		$invoice_id   = wp_cache_get( $key, 'getpaid_invoice_keys_' . $field );
171
		if ( ! empty( $invoice_id ) ) {
172
			return $invoice_id;
173
		}
174
175
        // Fetch from the db.
176
        $table       = $wpdb->prefix . 'getpaid_invoices';
177
        $invoice_id  = $wpdb->get_var(
178
            $wpdb->prepare( "SELECT `post_id` FROM $table WHERE $field=%s LIMIT 1", $key )
179
        );
180
181
		if ( empty( $invoice_id ) ) {
182
			return 0;
183
		}
184
185
		// Update the cache with our data
186
		wp_cache_add( $key, $invoice_id, 'getpaid_invoice_keys_' . $field );
187
188
		return $invoice_id;
189
    }
190
191
    /**
192
     * Checks if an invoice key is set.
193
     */
194
    public function _isset( $key ) {
195
        return isset( $this->data[$key] ) || method_exists( $this, "get_$key" );
196
    }
197
    
198
    /*
199
	|--------------------------------------------------------------------------
200
	| CRUD methods
201
	|--------------------------------------------------------------------------
202
	|
203
	| Methods which create, read, update and delete items from the database.
204
	|
205
    */
206
207
    /*
208
	|--------------------------------------------------------------------------
209
	| Getters
210
	|--------------------------------------------------------------------------
211
    */
212
213
    /**
214
	 * Get parent invoice ID.
215
	 *
216
	 * @since 1.0.19
217
	 * @param  string $context View or edit context.
218
	 * @return int
219
	 */
220
	public function get_parent_id( $context = 'view' ) {
221
		return (int) $this->get_prop( 'parent_id', $context );
222
    }
223
224
    /**
225
	 * Get parent invoice.
226
	 *
227
	 * @since 1.0.19
228
	 * @return WPInv_Invoice
229
	 */
230
    public function get_parent_payment() {
231
        return new WPInv_Invoice( $this->get_parent_id() );
232
    }
233
234
    /**
235
	 * Alias for self::get_parent_payment().
236
	 *
237
	 * @since 1.0.19
238
	 * @return WPInv_Invoice
239
	 */
240
    public function get_parent() {
241
        return $this->get_parent_payment();
242
    }
243
244
    /**
245
	 * Get invoice status.
246
	 *
247
	 * @since 1.0.19
248
	 * @param  string $context View or edit context.
249
	 * @return string
250
	 */
251
	public function get_status( $context = 'view' ) {
252
		return $this->get_prop( 'status', $context );
253
    }
254
255
    /**
256
	 * Get invoice status nice name.
257
	 *
258
	 * @since 1.0.19
259
	 * @return string
260
	 */
261
    public function get_status_nicename() {
262
        $statuses = wpinv_get_invoice_statuses( true, true, $this );
263
264
        if ( $this->is_quote() && class_exists( 'Wpinv_Quotes_Shared' ) ) {
265
            $statuses = Wpinv_Quotes_Shared::wpinv_get_quote_statuses();
0 ignored issues
show
Bug introduced by
The type Wpinv_Quotes_Shared was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
266
        }
267
268
        $status = isset( $statuses[ $this->get_status() ] ) ? $statuses[ $this->get_status() ] : $this->get_status();
269
270
        return apply_filters( 'wpinv_get_invoice_status_nicename', $status );
271
    }
272
273
    /**
274
	 * Get plugin version when the invoice was created.
275
	 *
276
	 * @since 1.0.19
277
	 * @param  string $context View or edit context.
278
	 * @return string
279
	 */
280
	public function get_version( $context = 'view' ) {
281
		return $this->get_prop( 'version', $context );
282
    }
283
284
    /**
285
	 * Get date when the invoice was created.
286
	 *
287
	 * @since 1.0.19
288
	 * @param  string $context View or edit context.
289
	 * @return string
290
	 */
291
	public function get_date_created( $context = 'view' ) {
292
		return $this->get_prop( 'date_created', $context );
293
    }
294
295
    /**
296
	 * Get GMT date when the invoice was created.
297
	 *
298
	 * @since 1.0.19
299
	 * @param  string $context View or edit context.
300
	 * @return string
301
	 */
302
	public function get_date_created_gmt( $context = 'view' ) {
303
        $date = $this->get_date_created( $context );
304
305
        if ( $date ) {
306
            $date = get_gmt_from_date( $date );
307
        }
308
		return $date;
309
    }
310
311
    /**
312
	 * Get date when the invoice was last modified.
313
	 *
314
	 * @since 1.0.19
315
	 * @param  string $context View or edit context.
316
	 * @return string
317
	 */
318
	public function get_date_modified( $context = 'view' ) {
319
		return $this->get_prop( 'date_modified', $context );
320
    }
321
322
    /**
323
	 * Get GMT date when the invoice was last modified.
324
	 *
325
	 * @since 1.0.19
326
	 * @param  string $context View or edit context.
327
	 * @return string
328
	 */
329
	public function get_date_modified_gmt( $context = 'view' ) {
330
        $date = $this->get_date_modified( $context );
331
332
        if ( $date ) {
333
            $date = get_gmt_from_date( $date );
334
        }
335
		return $date;
336
    }
337
338
    /**
339
	 * Get the invoice due date.
340
	 *
341
	 * @since 1.0.19
342
	 * @param  string $context View or edit context.
343
	 * @return string
344
	 */
345
	public function get_due_date( $context = 'view' ) {
346
		return $this->get_prop( 'due_date', $context );
347
    }
348
349
    /**
350
	 * Alias for self::get_due_date().
351
	 *
352
	 * @since 1.0.19
353
	 * @param  string $context View or edit context.
354
	 * @return string
355
	 */
356
	public function get_date_due( $context = 'view' ) {
357
		return $this->get_due_date( $context );
358
    }
359
360
    /**
361
	 * Get the invoice GMT due date.
362
	 *
363
	 * @since 1.0.19
364
	 * @param  string $context View or edit context.
365
	 * @return string
366
	 */
367
	public function get_due_date_gmt( $context = 'view' ) {
368
        $date = $this->get_due_date( $context );
369
370
        if ( $date ) {
371
            $date = get_gmt_from_date( $date );
372
        }
373
		return $date;
374
    }
375
376
    /**
377
	 * Alias for self::get_due_date_gmt().
378
	 *
379
	 * @since 1.0.19
380
	 * @param  string $context View or edit context.
381
	 * @return string
382
	 */
383
	public function get_gmt_date_due( $context = 'view' ) {
384
		return $this->get_due_date_gmt( $context );
385
    }
386
387
    /**
388
	 * Get date when the invoice was completed.
389
	 *
390
	 * @since 1.0.19
391
	 * @param  string $context View or edit context.
392
	 * @return string
393
	 */
394
	public function get_completed_date( $context = 'view' ) {
395
		return $this->get_prop( 'completed_date', $context );
396
    }
397
398
    /**
399
	 * Alias for self::get_completed_date().
400
	 *
401
	 * @since 1.0.19
402
	 * @param  string $context View or edit context.
403
	 * @return string
404
	 */
405
	public function get_date_completed( $context = 'view' ) {
406
		return $this->get_completed_date( $context );
407
    }
408
409
    /**
410
	 * Get GMT date when the invoice was was completed.
411
	 *
412
	 * @since 1.0.19
413
	 * @param  string $context View or edit context.
414
	 * @return string
415
	 */
416
	public function get_completed_date_gmt( $context = 'view' ) {
417
        $date = $this->get_completed_date( $context );
418
419
        if ( $date ) {
420
            $date = get_gmt_from_date( $date );
421
        }
422
		return $date;
423
    }
424
425
    /**
426
	 * Alias for self::get_completed_date_gmt().
427
	 *
428
	 * @since 1.0.19
429
	 * @param  string $context View or edit context.
430
	 * @return string
431
	 */
432
	public function get_gmt_completed_date( $context = 'view' ) {
433
		return $this->get_completed_date_gmt( $context );
434
    }
435
436
    /**
437
	 * Get the invoice number.
438
	 *
439
	 * @since 1.0.19
440
	 * @param  string $context View or edit context.
441
	 * @return string
442
	 */
443
	public function get_number( $context = 'view' ) {
444
        $number = $this->get_prop( 'number', $context );
445
446
        if ( empty( $number ) ) {
447
            $number = $this->generate_number();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $number is correct as $this->generate_number() targeting WPInv_Invoice::generate_number() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
448
            $this->set_number( $number );
449
        }
450
451
		return $number;
452
    }
453
454
    /**
455
	 * Get the invoice key.
456
	 *
457
	 * @since 1.0.19
458
	 * @param  string $context View or edit context.
459
	 * @return string
460
	 */
461
	public function get_key( $context = 'view' ) {
462
        $key = $this->get_prop( 'key', $context );
463
464
        if ( empty( $key ) ) {
465
            $key = $this->generate_key( $this->post_type );
0 ignored issues
show
Bug Best Practice introduced by
The property post_type does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
466
            $this->set_key( $key );
467
        }
468
469
		return $key;
470
    }
471
472
    /**
473
	 * Get the invoice type.
474
	 *
475
	 * @since 1.0.19
476
	 * @param  string $context View or edit context.
477
	 * @return string
478
	 */
479
	public function get_type( $context = 'view' ) {
480
        return $this->get_prop( 'type', $context );
481
    }
482
483
    /**
484
	 * Get the invoice post type.
485
	 *
486
	 * @since 1.0.19
487
	 * @param  string $context View or edit context.
488
	 * @return string
489
	 */
490
	public function get_post_type( $context = 'view' ) {
491
        return $this->get_prop( 'post_type', $context );
492
    }
493
494
    /**
495
	 * Get the invoice mode.
496
	 *
497
	 * @since 1.0.19
498
	 * @param  string $context View or edit context.
499
	 * @return string
500
	 */
501
	public function get_mode( $context = 'view' ) {
502
        return $this->get_prop( 'mode', $context );
503
    }
504
505
    /**
506
	 * Get the invoice path.
507
	 *
508
	 * @since 1.0.19
509
	 * @param  string $context View or edit context.
510
	 * @return string
511
	 */
512
	public function get_path( $context = 'view' ) {
513
        $path = $this->get_prop( 'path', $context );
514
515
        if ( empty( $path ) ) {
516
            $prefix = apply_filters( 'wpinv_post_name_prefix', 'inv-', $this->post_type );
0 ignored issues
show
Bug Best Practice introduced by
The property post_type does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
517
            $path   = sanitize_title( $prefix . $this->get_id() );
518
        }
519
520
		return $path;
521
    }
522
523
    /**
524
	 * Get the invoice name/title.
525
	 *
526
	 * @since 1.0.19
527
	 * @param  string $context View or edit context.
528
	 * @return string
529
	 */
530
	public function get_name( $context = 'view' ) {
531
        $name = $this->get_prop( 'title', $context );
532
533
		return empty( $name ) ? $this->get_number( $context ) : $name;
534
    }
535
536
    /**
537
	 * Alias of self::get_name().
538
	 *
539
	 * @since 1.0.19
540
	 * @param  string $context View or edit context.
541
	 * @return string
542
	 */
543
	public function get_title( $context = 'view' ) {
544
		return $this->get_name( $context );
545
    }
546
547
    /**
548
	 * Get the invoice description.
549
	 *
550
	 * @since 1.0.19
551
	 * @param  string $context View or edit context.
552
	 * @return string
553
	 */
554
	public function get_description( $context = 'view' ) {
555
		return $this->get_prop( 'description', $context );
556
    }
557
558
    /**
559
	 * Alias of self::get_description().
560
	 *
561
	 * @since 1.0.19
562
	 * @param  string $context View or edit context.
563
	 * @return string
564
	 */
565
	public function get_excerpt( $context = 'view' ) {
566
		return $this->get_description( $context );
567
    }
568
569
    /**
570
	 * Alias of self::get_description().
571
	 *
572
	 * @since 1.0.19
573
	 * @param  string $context View or edit context.
574
	 * @return string
575
	 */
576
	public function get_summary( $context = 'view' ) {
577
		return $this->get_description( $context );
578
    }
579
580
    /**
581
	 * Returns the user info.
582
	 *
583
	 * @since 1.0.19
584
     * @param  string $context View or edit context.
585
	 * @return array
586
	 */
587
    public function get_user_info( $context = 'view' ) {
588
        $user_info = array(
589
            'user_id'    => $this->get_user_id( $context ),
590
            'email'      => $this->get_email( $context ),
591
            'first_name' => $this->get_first_name( $context ),
592
            'last_name'  => $this->get_last_name( $context ),
593
            'address'    => $this->get_address( $context ),
594
            'phone'      => $this->get_phone( $context ),
595
            'city'       => $this->get_city( $context ),
596
            'country'    => $this->get_country( $context ),
597
            'state'      => $this->get_state( $context ),
598
            'zip'        => $this->get_zip( $context ),
599
            'company'    => $this->get_company( $context ),
600
            'vat_number' => $this->get_vat_number( $context ),
601
            'discount'   => $this->get_discount_code( $context ),
602
        );
603
        return apply_filters( 'wpinv_user_info', $user_info, $this->ID, $this );
604
    }
605
606
    /**
607
	 * Get the customer id.
608
	 *
609
	 * @since 1.0.19
610
	 * @param  string $context View or edit context.
611
	 * @return int
612
	 */
613
	public function get_author( $context = 'view' ) {
614
		return (int) $this->get_prop( 'author', $context );
615
    }
616
617
    /**
618
	 * Alias of self::get_author().
619
	 *
620
	 * @since 1.0.19
621
	 * @param  string $context View or edit context.
622
	 * @return int
623
	 */
624
	public function get_user_id( $context = 'view' ) {
625
		return $this->get_author( $context );
626
    }
627
628
     /**
629
	 * Alias of self::get_author().
630
	 *
631
	 * @since 1.0.19
632
	 * @param  string $context View or edit context.
633
	 * @return int
634
	 */
635
	public function get_customer_id( $context = 'view' ) {
636
		return $this->get_author( $context );
637
    }
638
639
    /**
640
	 * Get the customer's ip.
641
	 *
642
	 * @since 1.0.19
643
	 * @param  string $context View or edit context.
644
	 * @return string
645
	 */
646
	public function get_ip( $context = 'view' ) {
647
		return $this->get_prop( 'user_ip', $context );
648
    }
649
650
    /**
651
	 * Alias of self::get_ip().
652
	 *
653
	 * @since 1.0.19
654
	 * @param  string $context View or edit context.
655
	 * @return string
656
	 */
657
	public function get_user_ip( $context = 'view' ) {
658
		return $this->get_ip( $context );
0 ignored issues
show
Unused Code introduced by
The call to WPInv_Invoice::get_ip() has too many arguments starting with $context. ( Ignorable by Annotation )

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

658
		return $this->/** @scrutinizer ignore-call */ get_ip( $context );

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
659
    }
660
661
     /**
662
	 * Alias of self::get_ip().
663
	 *
664
	 * @since 1.0.19
665
	 * @param  string $context View or edit context.
666
	 * @return string
667
	 */
668
	public function get_customer_ip( $context = 'view' ) {
669
		return $this->get_ip( $context );
0 ignored issues
show
Unused Code introduced by
The call to WPInv_Invoice::get_ip() has too many arguments starting with $context. ( Ignorable by Annotation )

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

669
		return $this->/** @scrutinizer ignore-call */ get_ip( $context );

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
670
    }
671
672
    /**
673
	 * Get the customer's first name.
674
	 *
675
	 * @since 1.0.19
676
	 * @param  string $context View or edit context.
677
	 * @return string
678
	 */
679
	public function get_first_name( $context = 'view' ) {
680
		return $this->get_prop( 'first_name', $context );
681
    }
682
683
    /**
684
	 * Alias of self::get_first_name().
685
	 *
686
	 * @since 1.0.19
687
	 * @param  string $context View or edit context.
688
	 * @return int
689
	 */
690
	public function get_user_first_name( $context = 'view' ) {
691
		return $this->get_first_name( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_first_name($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
692
    }
693
694
     /**
695
	 * Alias of self::get_first_name().
696
	 *
697
	 * @since 1.0.19
698
	 * @param  string $context View or edit context.
699
	 * @return int
700
	 */
701
	public function get_customer_first_name( $context = 'view' ) {
702
		return $this->get_first_name( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_first_name($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
703
    }
704
705
    /**
706
	 * Get the customer's last name.
707
	 *
708
	 * @since 1.0.19
709
	 * @param  string $context View or edit context.
710
	 * @return string
711
	 */
712
	public function get_last_name( $context = 'view' ) {
713
		return $this->get_prop( 'last_name', $context );
714
    }
715
    
716
    /**
717
	 * Alias of self::get_last_name().
718
	 *
719
	 * @since 1.0.19
720
	 * @param  string $context View or edit context.
721
	 * @return int
722
	 */
723
	public function get_user_last_name( $context = 'view' ) {
724
		return $this->get_last_name( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_last_name($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
725
    }
726
727
    /**
728
	 * Alias of self::get_last_name().
729
	 *
730
	 * @since 1.0.19
731
	 * @param  string $context View or edit context.
732
	 * @return int
733
	 */
734
	public function get_customer_last_name( $context = 'view' ) {
735
		return $this->get_last_name( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_last_name($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
736
    }
737
738
    /**
739
	 * Get the customer's full name.
740
	 *
741
	 * @since 1.0.19
742
	 * @param  string $context View or edit context.
743
	 * @return string
744
	 */
745
	public function get_full_name( $context = 'view' ) {
746
		return trim( $this->get_first_name( $context ) . ' ' . $this->get_last_name( $context ) );
747
    }
748
749
    /**
750
	 * Alias of self::get_full_name().
751
	 *
752
	 * @since 1.0.19
753
	 * @param  string $context View or edit context.
754
	 * @return int
755
	 */
756
	public function get_user_full_name( $context = 'view' ) {
757
		return $this->get_full_name( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_full_name($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
758
    }
759
760
    /**
761
	 * Alias of self::get_full_name().
762
	 *
763
	 * @since 1.0.19
764
	 * @param  string $context View or edit context.
765
	 * @return int
766
	 */
767
	public function get_customer_full_name( $context = 'view' ) {
768
		return $this->get_full_name( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_full_name($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
769
    }
770
771
    /**
772
	 * Get the customer's phone number.
773
	 *
774
	 * @since 1.0.19
775
	 * @param  string $context View or edit context.
776
	 * @return string
777
	 */
778
	public function get_phone( $context = 'view' ) {
779
		return $this->get_prop( 'phone', $context );
780
    }
781
782
    /**
783
	 * Alias of self::get_phone().
784
	 *
785
	 * @since 1.0.19
786
	 * @param  string $context View or edit context.
787
	 * @return int
788
	 */
789
	public function get_phone_number( $context = 'view' ) {
790
		return $this->get_phone( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_phone($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
791
    }
792
793
    /**
794
	 * Alias of self::get_phone().
795
	 *
796
	 * @since 1.0.19
797
	 * @param  string $context View or edit context.
798
	 * @return int
799
	 */
800
	public function get_user_phone( $context = 'view' ) {
801
		return $this->get_phone( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_phone($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
802
    }
803
804
    /**
805
	 * Alias of self::get_phone().
806
	 *
807
	 * @since 1.0.19
808
	 * @param  string $context View or edit context.
809
	 * @return int
810
	 */
811
	public function get_customer_phone( $context = 'view' ) {
812
		return $this->get_phone( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_phone($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
813
    }
814
815
    /**
816
	 * Get the customer's email address.
817
	 *
818
	 * @since 1.0.19
819
	 * @param  string $context View or edit context.
820
	 * @return string
821
	 */
822
	public function get_email( $context = 'view' ) {
823
		return $this->get_prop( 'email', $context );
824
    }
825
826
    /**
827
	 * Alias of self::get_email().
828
	 *
829
	 * @since 1.0.19
830
	 * @param  string $context View or edit context.
831
	 * @return string
832
	 */
833
	public function get_email_address( $context = 'view' ) {
834
		return $this->get_email( $context );
835
    }
836
837
    /**
838
	 * Alias of self::get_email().
839
	 *
840
	 * @since 1.0.19
841
	 * @param  string $context View or edit context.
842
	 * @return int
843
	 */
844
	public function get_user_email( $context = 'view' ) {
845
		return $this->get_email( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_email($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
846
    }
847
848
    /**
849
	 * Alias of self::get_email().
850
	 *
851
	 * @since 1.0.19
852
	 * @param  string $context View or edit context.
853
	 * @return int
854
	 */
855
	public function get_customer_email( $context = 'view' ) {
856
		return $this->get_email( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_email($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
857
    }
858
859
    /**
860
	 * Get the customer's country.
861
	 *
862
	 * @since 1.0.19
863
	 * @param  string $context View or edit context.
864
	 * @return string
865
	 */
866
	public function get_country( $context = 'view' ) {
867
		return $this->get_prop( 'country', $context );
868
    }
869
870
    /**
871
	 * Alias of self::get_country().
872
	 *
873
	 * @since 1.0.19
874
	 * @param  string $context View or edit context.
875
	 * @return int
876
	 */
877
	public function get_user_country( $context = 'view' ) {
878
		return $this->get_country( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_country($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
879
    }
880
881
    /**
882
	 * Alias of self::get_country().
883
	 *
884
	 * @since 1.0.19
885
	 * @param  string $context View or edit context.
886
	 * @return int
887
	 */
888
	public function get_customer_country( $context = 'view' ) {
889
		return $this->get_country( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_country($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
890
    }
891
892
    /**
893
	 * Get the customer's state.
894
	 *
895
	 * @since 1.0.19
896
	 * @param  string $context View or edit context.
897
	 * @return string
898
	 */
899
	public function get_state( $context = 'view' ) {
900
		return $this->get_prop( 'state', $context );
901
    }
902
903
    /**
904
	 * Alias of self::get_state().
905
	 *
906
	 * @since 1.0.19
907
	 * @param  string $context View or edit context.
908
	 * @return int
909
	 */
910
	public function get_user_state( $context = 'view' ) {
911
		return $this->get_state( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_state($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
912
    }
913
914
    /**
915
	 * Alias of self::get_state().
916
	 *
917
	 * @since 1.0.19
918
	 * @param  string $context View or edit context.
919
	 * @return int
920
	 */
921
	public function get_customer_state( $context = 'view' ) {
922
		return $this->get_state( $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get_state($context) returns the type string which is incompatible with the documented return type integer.
Loading history...
923
    }
924
925
    /**
926
	 * Get the customer's city.
927
	 *
928
	 * @since 1.0.19
929
	 * @param  string $context View or edit context.
930
	 * @return string
931
	 */
932
	public function get_city( $context = 'view' ) {
933
		return $this->get_prop( 'city', $context );
934
    }
935
936
    /**
937
	 * Alias of self::get_city().
938
	 *
939
	 * @since 1.0.19
940
	 * @param  string $context View or edit context.
941
	 * @return string
942
	 */
943
	public function get_user_city( $context = 'view' ) {
944
		return $this->get_city( $context );
945
    }
946
947
    /**
948
	 * Alias of self::get_city().
949
	 *
950
	 * @since 1.0.19
951
	 * @param  string $context View or edit context.
952
	 * @return string
953
	 */
954
	public function get_customer_city( $context = 'view' ) {
955
		return $this->get_city( $context );
956
    }
957
958
    /**
959
	 * Get the customer's zip.
960
	 *
961
	 * @since 1.0.19
962
	 * @param  string $context View or edit context.
963
	 * @return string
964
	 */
965
	public function get_zip( $context = 'view' ) {
966
		return $this->get_prop( 'zip', $context );
967
    }
968
969
    /**
970
	 * Alias of self::get_zip().
971
	 *
972
	 * @since 1.0.19
973
	 * @param  string $context View or edit context.
974
	 * @return string
975
	 */
976
	public function get_user_zip( $context = 'view' ) {
977
		return $this->get_zip( $context );
978
    }
979
980
    /**
981
	 * Alias of self::get_zip().
982
	 *
983
	 * @since 1.0.19
984
	 * @param  string $context View or edit context.
985
	 * @return string
986
	 */
987
	public function get_customer_zip( $context = 'view' ) {
988
		return $this->get_zip( $context );
989
    }
990
991
    /**
992
	 * Get the customer's company.
993
	 *
994
	 * @since 1.0.19
995
	 * @param  string $context View or edit context.
996
	 * @return string
997
	 */
998
	public function get_company( $context = 'view' ) {
999
		return $this->get_prop( 'company', $context );
1000
    }
1001
1002
    /**
1003
	 * Alias of self::get_company().
1004
	 *
1005
	 * @since 1.0.19
1006
	 * @param  string $context View or edit context.
1007
	 * @return string
1008
	 */
1009
	public function get_user_company( $context = 'view' ) {
1010
		return $this->get_company( $context );
1011
    }
1012
1013
    /**
1014
	 * Alias of self::get_company().
1015
	 *
1016
	 * @since 1.0.19
1017
	 * @param  string $context View or edit context.
1018
	 * @return string
1019
	 */
1020
	public function get_customer_company( $context = 'view' ) {
1021
		return $this->get_company( $context );
1022
    }
1023
1024
    /**
1025
	 * Get the customer's vat number.
1026
	 *
1027
	 * @since 1.0.19
1028
	 * @param  string $context View or edit context.
1029
	 * @return string
1030
	 */
1031
	public function get_vat_number( $context = 'view' ) {
1032
		return $this->get_prop( 'vat_number', $context );
1033
    }
1034
1035
    /**
1036
	 * Alias of self::get_vat_number().
1037
	 *
1038
	 * @since 1.0.19
1039
	 * @param  string $context View or edit context.
1040
	 * @return string
1041
	 */
1042
	public function get_user_vat_number( $context = 'view' ) {
1043
		return $this->get_vat_number( $context );
1044
    }
1045
1046
    /**
1047
	 * Alias of self::get_vat_number().
1048
	 *
1049
	 * @since 1.0.19
1050
	 * @param  string $context View or edit context.
1051
	 * @return string
1052
	 */
1053
	public function get_customer_vat_number( $context = 'view' ) {
1054
		return $this->get_vat_number( $context );
1055
    }
1056
1057
    /**
1058
	 * Get the customer's vat rate.
1059
	 *
1060
	 * @since 1.0.19
1061
	 * @param  string $context View or edit context.
1062
	 * @return string
1063
	 */
1064
	public function get_vat_rate( $context = 'view' ) {
1065
		return $this->get_prop( 'vat_rate', $context );
1066
    }
1067
1068
    /**
1069
	 * Alias of self::get_vat_rate().
1070
	 *
1071
	 * @since 1.0.19
1072
	 * @param  string $context View or edit context.
1073
	 * @return string
1074
	 */
1075
	public function get_user_vat_rate( $context = 'view' ) {
1076
		return $this->get_vat_rate( $context );
1077
    }
1078
1079
    /**
1080
	 * Alias of self::get_vat_rate().
1081
	 *
1082
	 * @since 1.0.19
1083
	 * @param  string $context View or edit context.
1084
	 * @return string
1085
	 */
1086
	public function get_customer_vat_rate( $context = 'view' ) {
1087
		return $this->get_vat_rate( $context );
1088
    }
1089
1090
    /**
1091
	 * Get the customer's address.
1092
	 *
1093
	 * @since 1.0.19
1094
	 * @param  string $context View or edit context.
1095
	 * @return string
1096
	 */
1097
	public function get_address( $context = 'view' ) {
1098
		return $this->get_prop( 'address', $context );
1099
    }
1100
1101
    /**
1102
	 * Alias of self::get_address().
1103
	 *
1104
	 * @since 1.0.19
1105
	 * @param  string $context View or edit context.
1106
	 * @return string
1107
	 */
1108
	public function get_user_address( $context = 'view' ) {
1109
		return $this->get_address( $context );
1110
    }
1111
1112
    /**
1113
	 * Alias of self::get_address().
1114
	 *
1115
	 * @since 1.0.19
1116
	 * @param  string $context View or edit context.
1117
	 * @return string
1118
	 */
1119
	public function get_customer_address( $context = 'view' ) {
1120
		return $this->get_address( $context );
1121
    }
1122
1123
    /**
1124
	 * Get whether the customer has confirmed their address.
1125
	 *
1126
	 * @since 1.0.19
1127
	 * @param  string $context View or edit context.
1128
	 * @return bool
1129
	 */
1130
	public function get_address_confirmed( $context = 'view' ) {
1131
		return (bool) $this->get_prop( 'address_confirmed', $context );
1132
    }
1133
1134
    /**
1135
	 * Alias of self::get_address_confirmed().
1136
	 *
1137
	 * @since 1.0.19
1138
	 * @param  string $context View or edit context.
1139
	 * @return bool
1140
	 */
1141
	public function get_user_address_confirmed( $context = 'view' ) {
1142
		return $this->get_address_confirmed( $context );
1143
    }
1144
1145
    /**
1146
	 * Alias of self::get_address().
1147
	 *
1148
	 * @since 1.0.19
1149
	 * @param  string $context View or edit context.
1150
	 * @return bool
1151
	 */
1152
	public function get_customer_address_confirmed( $context = 'view' ) {
1153
		return $this->get_address_confirmed( $context );
1154
    }
1155
1156
    /**
1157
	 * Get the invoice subtotal.
1158
	 *
1159
	 * @since 1.0.19
1160
	 * @param  string $context View or edit context.
1161
	 * @return float
1162
	 */
1163
	public function get_subtotal( $context = 'view' ) {
1164
        $subtotal = (float) $this->get_prop( 'subtotal', $context );
1165
        
1166
        // Backwards compatibility.
1167
        if ( is_bool( $context ) && $context ) {
0 ignored issues
show
introduced by
The condition is_bool($context) is always false.
Loading history...
1168
            return wpinv_price( wpinv_format_amount( $subtotal ), $this->get_currency() );
1169
        }
1170
1171
        return $subtotal;
1172
    }
1173
1174
    /**
1175
	 * Get the invoice discount total.
1176
	 *
1177
	 * @since 1.0.19
1178
	 * @param  string $context View or edit context.
1179
	 * @return float
1180
	 */
1181
	public function get_total_discount( $context = 'view' ) {
1182
		return (float) $this->get_prop( 'total_discount', $context );
1183
    }
1184
1185
    /**
1186
	 * Get the invoice tax total.
1187
	 *
1188
	 * @since 1.0.19
1189
	 * @param  string $context View or edit context.
1190
	 * @return float
1191
	 */
1192
	public function get_total_tax( $context = 'view' ) {
1193
		return (float) $this->get_prop( 'total_tax', $context );
1194
    }
1195
1196
    /**
1197
	 * Get the invoice fees total.
1198
	 *
1199
	 * @since 1.0.19
1200
	 * @param  string $context View or edit context.
1201
	 * @return float
1202
	 */
1203
	public function get_total_fees( $context = 'view' ) {
1204
		return (float) $this->get_prop( 'total_fees', $context );
1205
    }
1206
1207
    /**
1208
	 * Alias for self::get_total_fees().
1209
	 *
1210
	 * @since 1.0.19
1211
	 * @param  string $context View or edit context.
1212
	 * @return float
1213
	 */
1214
	public function get_fees_total( $context = 'view' ) {
1215
		return $this->get_total_fees( $context );
1216
    }
1217
1218
    /**
1219
	 * Get the invoice total.
1220
	 *
1221
	 * @since 1.0.19
1222
     * @param  string $context View or edit context.
1223
     * @return float
1224
	 */
1225
	public function get_total( $context = 'view' ) {
1226
		$total = $this->get_subtotal( $context ) + $this->get_total_fees( $context ) - $this->get_total_discount(  $context  ) + $this->get_total_tax(  $context  );
1227
		$total = apply_filters( 'getpaid_get_invoice_total_amount', $total, $this  );
1228
		return (float) wpinv_sanitize_amount( $total );
1229
    }
1230
1231
    /**
1232
     * Calculates the initial total.
1233
     */
1234
    public function get_initial_total( $currency = false ) {        
1235
        if ( $this->is_free_trial() ) {
1236
            $total = wpinv_round_amount( 0 );
1237
        } else {
1238
            $total = wpinv_round_amount( $this->total );
0 ignored issues
show
Bug Best Practice introduced by
The property total does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
1239
        }
1240
        if ( $currency ) {
1241
            $total = wpinv_price( wpinv_format_amount( $total, NULL, !$currency ), $this->get_currency() );
1242
        }
1243
        
1244
        return apply_filters( 'wpinv_get_invoice_total', $total, $this->ID, $this, $currency );
1245
    }
1246
1247
    /**
1248
	 * Get the invoice fees.
1249
	 *
1250
	 * @since 1.0.19
1251
	 * @param  string $context View or edit context.
1252
	 * @return array
1253
	 */
1254
	public function get_fees( $context = 'view' ) {
1255
		return wpinv_parse_list( $this->get_prop( 'fees', $context ) );
1256
    }
1257
1258
    /**
1259
	 * Get the invoice discounts.
1260
	 *
1261
	 * @since 1.0.19
1262
	 * @param  string $context View or edit context.
1263
	 * @return array
1264
	 */
1265
	public function get_discounts( $context = 'view' ) {
1266
		return wpinv_parse_list( $this->get_prop( 'discounts', $context ) );
1267
    }
1268
1269
    /**
1270
	 * Get the invoice taxes.
1271
	 *
1272
	 * @since 1.0.19
1273
	 * @param  string $context View or edit context.
1274
	 * @return array
1275
	 */
1276
	public function get_taxes( $context = 'view' ) {
1277
		return wpinv_parse_list( $this->get_prop( 'taxes', $context ) );
1278
    }
1279
1280
    /**
1281
	 * Get the invoice items.
1282
	 *
1283
	 * @since 1.0.19
1284
	 * @param  string $context View or edit context.
1285
	 * @return GetPaid_Form_Item[]
1286
	 */
1287
	public function get_items( $context = 'view' ) {
1288
        return $this->get_prop( 'items', $context );
1289
    }
1290
1291
    /**
1292
	 * Get the invoice's payment form.
1293
	 *
1294
	 * @since 1.0.19
1295
	 * @param  string $context View or edit context.
1296
	 * @return int
1297
	 */
1298
	public function get_payment_form( $context = 'view' ) {
1299
		return intval( $this->get_prop( 'payment_form', $context ) );
1300
    }
1301
1302
    /**
1303
	 * Get the invoice's submission id.
1304
	 *
1305
	 * @since 1.0.19
1306
	 * @param  string $context View or edit context.
1307
	 * @return string
1308
	 */
1309
	public function get_submission_id( $context = 'view' ) {
1310
		return $this->get_prop( 'submission_id', $context );
1311
    }
1312
1313
    /**
1314
	 * Get the invoice's discount code.
1315
	 *
1316
	 * @since 1.0.19
1317
	 * @param  string $context View or edit context.
1318
	 * @return string
1319
	 */
1320
	public function get_discount_code( $context = 'view' ) {
1321
		return $this->get_prop( 'discount_code', $context );
1322
    }
1323
1324
    /**
1325
	 * Get the invoice's gateway.
1326
	 *
1327
	 * @since 1.0.19
1328
	 * @param  string $context View or edit context.
1329
	 * @return string
1330
	 */
1331
	public function get_gateway( $context = 'view' ) {
1332
		return $this->get_prop( 'gateway', $context );
1333
    }
1334
1335
    /**
1336
	 * Get the invoice's gateway display title.
1337
	 *
1338
	 * @since 1.0.19
1339
	 * @return string
1340
	 */
1341
    public function get_gateway_title() {
1342
        $title =  wpinv_get_gateway_checkout_label( $this->get_gateway() );
1343
        return apply_filters( 'wpinv_gateway_title', $title, $this->ID, $this );
1344
    }
1345
1346
    /**
1347
	 * Get the invoice's transaction id.
1348
	 *
1349
	 * @since 1.0.19
1350
	 * @param  string $context View or edit context.
1351
	 * @return string
1352
	 */
1353
	public function get_transaction_id( $context = 'view' ) {
1354
		return $this->get_prop( 'transaction_id', $context );
1355
    }
1356
1357
    /**
1358
	 * Get the invoice's currency.
1359
	 *
1360
	 * @since 1.0.19
1361
	 * @param  string $context View or edit context.
1362
	 * @return string
1363
	 */
1364
	public function get_currency( $context = 'view' ) {
1365
        $currency = $this->get_prop( 'currency', $context );
1366
        return empty( $currency ) ? wpinv_get_currency() : $currency;
1367
    }
1368
1369
    /**
1370
	 * Checks if we are charging taxes for this invoice.
1371
	 *
1372
	 * @since 1.0.19
1373
	 * @param  string $context View or edit context.
1374
	 * @return bool
1375
	 */
1376
	public function get_disable_taxes( $context = 'view' ) {
1377
        return (bool) $this->get_prop( 'disable_taxes', $context );
1378
    }
1379
1380
    /**
1381
	 * Retrieves the subscription id for an invoice.
1382
	 *
1383
	 * @since 1.0.19
1384
	 * @param  string $context View or edit context.
1385
	 * @return int
1386
	 */
1387
    public function get_subscription_id( $context = 'view' ) {
1388
        $subscription_id = $this->get_prop( 'subscription_id', $context );
1389
1390
        if ( empty( $subscription_id ) && $this->is_renewal() ) {
1391
            $parent = $this->get_parent();
1392
            return $parent->get_subscription_id( $context );
1393
        }
1394
1395
        return $subscription_id;
1396
    }
1397
1398
    /**
1399
	 * Retrieves the payment meta for an invoice.
1400
	 *
1401
	 * @since 1.0.19
1402
	 * @param  string $context View or edit context.
1403
	 * @return array
1404
	 */
1405
    public function get_payment_meta( $context = 'view' ) {
1406
1407
        return array(
1408
            'price'        => $this->get_total( $context ),
1409
            'date'         => $this->get_date_created( $context ),
1410
            'user_email'   => $this->get_email( $context ),
1411
            'invoice_key'  => $this->get_key( $context ),
1412
            'currency'     => $this->get_currency( $context ),
1413
            'items'        => $this->get_items( $context ),
1414
            'user_info'    => $this->get_user_info( $context ),
1415
            'cart_details' => $this->get_cart_details(),
1416
            'status'       => $this->get_status( $context ),
1417
            'fees'         => $this->get_fees( $context ),
1418
            'taxes'        => $this->get_taxes( $context ),
1419
        );
1420
1421
    }
1422
1423
    /**
1424
	 * Retrieves the cart details for an invoice.
1425
	 *
1426
	 * @since 1.0.19
1427
	 * @return array
1428
	 */
1429
    public function get_cart_details() {
1430
        $items        = $this->get_items();
1431
        $cart_details = array();
1432
1433
        foreach ( $items as $item_id => $item ) {
1434
            $cart_details[] = $item->prepare_data_for_saving();
1435
        }
1436
1437
        return $cart_details;
1438
    }
1439
1440
    /**
1441
	 * Magic method for accessing invoice properties.
1442
	 *
1443
	 * @since 1.0.15
1444
	 * @access public
1445
	 *
1446
	 * @param string $key Discount data to retrieve
1447
	 * @param  string $context View or edit context.
1448
	 * @return mixed Value of the given invoice property (if set).
1449
	 */
1450
	public function get( $key, $context = 'view' ) {
1451
        return $this->get_prop( $key, $context );
1452
	}
1453
1454
    /*
1455
	|--------------------------------------------------------------------------
1456
	| Setters
1457
	|--------------------------------------------------------------------------
1458
	|
1459
	| Functions for setting item data. These should not update anything in the
1460
	| database itself and should only change what is stored in the class
1461
	| object.
1462
    */
1463
1464
    /**
1465
	 * Set parent invoice ID.
1466
	 *
1467
	 * @since 1.0.19
1468
	 */
1469
	public function set_parent_id( $value ) {
1470
		if ( $value && ( $value === $this->get_id() || ! get_post( $value ) ) ) {
1471
			return;
1472
		}
1473
		$this->set_prop( 'parent_id', absint( $value ) );
1474
    }
1475
    
1476
    /**
1477
	 * Sets invoice status.
1478
	 *
1479
	 * @since 1.0.19
1480
	 * @param  string $status New status.
1481
	 * @return array details of change.
1482
	 */
1483
	public function set_status( $status ) {
1484
        $old_status = $this->get_status();
1485
1486
        $this->set_prop( 'status', $status );
1487
1488
		return array(
1489
			'from' => $old_status,
1490
			'to'   => $status,
1491
		);
1492
    }
1493
1494
    /**
1495
	 * Set plugin version when the invoice was created.
1496
	 *
1497
	 * @since 1.0.19
1498
	 */
1499
	public function set_version( $value ) {
1500
		$this->set_prop( 'version', $value );
1501
    }
1502
1503
    /**
1504
	 * Set date when the invoice was created.
1505
	 *
1506
	 * @since 1.0.19
1507
	 * @param string $value Value to set.
1508
     * @return bool Whether or not the date was set.
1509
	 */
1510
	public function set_date_created( $value ) {
1511
        $date = strtotime( $value );
1512
1513
        if ( $date ) {
1514
            $this->set_prop( 'date_created', date( 'Y-m-d H:i:s', $date ) );
1515
            return true;
1516
        }
1517
1518
        return false;
1519
1520
    }
1521
1522
    /**
1523
	 * Set date invoice due date.
1524
	 *
1525
	 * @since 1.0.19
1526
	 * @param string $value Value to set.
1527
     * @return bool Whether or not the date was set.
1528
	 */
1529
	public function set_due_date( $value ) {
1530
        $date = strtotime( $value );
1531
1532
        if ( $date ) {
1533
            $this->set_prop( 'due_date', date( 'Y-m-d H:i:s', $date ) );
1534
            return true;
1535
        }
1536
1537
        return false;
1538
1539
    }
1540
1541
    /**
1542
	 * Alias of self::set_due_date().
1543
	 *
1544
	 * @since 1.0.19
1545
	 * @param  string $value New name.
1546
	 */
1547
	public function set_date_due( $value ) {
1548
		$this->set_due_date( $value );
1549
    }
1550
1551
    /**
1552
	 * Set date invoice was completed.
1553
	 *
1554
	 * @since 1.0.19
1555
	 * @param string $value Value to set.
1556
     * @return bool Whether or not the date was set.
1557
	 */
1558
	public function set_completed_date( $value ) {
1559
        $date = strtotime( $value );
1560
1561
        if ( $date ) {
1562
            $this->set_prop( 'completed_date', date( 'Y-m-d H:i:s', $date ) );
1563
            return true;
1564
        }
1565
1566
        return false;
1567
1568
    }
1569
1570
    /**
1571
	 * Alias of self::set_completed_date().
1572
	 *
1573
	 * @since 1.0.19
1574
	 * @param  string $value New name.
1575
	 */
1576
	public function set_date_completed( $value ) {
1577
		$this->set_completed_date( $value );
1578
    }
1579
1580
    /**
1581
	 * Set date when the invoice was last modified.
1582
	 *
1583
	 * @since 1.0.19
1584
	 * @param string $value Value to set.
1585
     * @return bool Whether or not the date was set.
1586
	 */
1587
	public function set_date_modified( $value ) {
1588
        $date = strtotime( $value );
1589
1590
        if ( $date ) {
1591
            $this->set_prop( 'date_modified', date( 'Y-m-d H:i:s', $date ) );
1592
            return true;
1593
        }
1594
1595
        return false;
1596
1597
    }
1598
1599
    /**
1600
	 * Set the invoice number.
1601
	 *
1602
	 * @since 1.0.19
1603
	 * @param  string $value New number.
1604
	 */
1605
	public function set_number( $value ) {
1606
        $number = sanitize_text_field( $value );
1607
		$this->set_prop( 'number', $number );
1608
    }
1609
1610
    /**
1611
	 * Set the invoice type.
1612
	 *
1613
	 * @since 1.0.19
1614
	 * @param  string $value Type.
1615
	 */
1616
	public function set_type( $value ) {
1617
        $type = sanitize_text_field( str_replace( 'wpi_', '', $value ) );
1618
		$this->set_prop( 'type', $type );
1619
    }
1620
1621
    /**
1622
	 * Set the invoice post type.
1623
	 *
1624
	 * @since 1.0.19
1625
	 * @param  string $value Post type.
1626
	 */
1627
	public function set_post_type( $value ) {
1628
        if ( getpaid_is_invoice_post_type( $value ) ) {
1629
            $this->set_prop( 'post_type', $value );
1630
        }
1631
    }
1632
1633
    /**
1634
	 * Set the invoice key.
1635
	 *
1636
	 * @since 1.0.19
1637
	 * @param  string $value New key.
1638
	 */
1639
	public function set_key( $value ) {
1640
        $key = sanitize_text_field( $value );
1641
		$this->set_prop( 'key', $key );
1642
    }
1643
1644
    /**
1645
	 * Set the invoice mode.
1646
	 *
1647
	 * @since 1.0.19
1648
	 * @param  string $value mode.
1649
	 */
1650
	public function set_mode( $value ) {
1651
        if ( ! in_array( $value, array( 'live', 'test' ) ) ) {
1652
            $this->set_prop( 'value', $value );
1653
        }
1654
    }
1655
1656
    /**
1657
	 * Set the invoice path.
1658
	 *
1659
	 * @since 1.0.19
1660
	 * @param  string $value path.
1661
	 */
1662
	public function set_path( $value ) {
1663
        $this->set_prop( 'path', $value );
1664
    }
1665
1666
    /**
1667
	 * Set the invoice name.
1668
	 *
1669
	 * @since 1.0.19
1670
	 * @param  string $value New name.
1671
	 */
1672
	public function set_name( $value ) {
1673
        $name = sanitize_text_field( $value );
1674
		$this->set_prop( 'name', $name );
1675
    }
1676
1677
    /**
1678
	 * Alias of self::set_name().
1679
	 *
1680
	 * @since 1.0.19
1681
	 * @param  string $value New name.
1682
	 */
1683
	public function set_title( $value ) {
1684
		$this->set_name( $value );
1685
    }
1686
1687
    /**
1688
	 * Set the invoice description.
1689
	 *
1690
	 * @since 1.0.19
1691
	 * @param  string $value New description.
1692
	 */
1693
	public function set_description( $value ) {
1694
        $description = wp_kses_post( $value );
1695
		return $this->set_prop( 'description', $description );
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->set_prop('description', $description) targeting GetPaid_Data::set_prop() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
1696
    }
1697
1698
    /**
1699
	 * Alias of self::set_description().
1700
	 *
1701
	 * @since 1.0.19
1702
	 * @param  string $value New description.
1703
	 */
1704
	public function set_excerpt( $value ) {
1705
		$this->set_description( $value );
1706
    }
1707
1708
    /**
1709
	 * Alias of self::set_description().
1710
	 *
1711
	 * @since 1.0.19
1712
	 * @param  string $value New description.
1713
	 */
1714
	public function set_summary( $value ) {
1715
		$this->set_description( $value );
1716
    }
1717
1718
    /**
1719
	 * Set the receiver of the invoice.
1720
	 *
1721
	 * @since 1.0.19
1722
	 * @param  int $value New author.
1723
	 */
1724
	public function set_author( $value ) {
1725
		$this->set_prop( 'author', (int) $value );
1726
    }
1727
1728
    /**
1729
	 * Alias of self::set_author().
1730
	 *
1731
	 * @since 1.0.19
1732
	 * @param  int $value New user id.
1733
	 */
1734
	public function set_user_id( $value ) {
1735
		$this->set_author( $value );
1736
    }
1737
1738
    /**
1739
	 * Alias of self::set_author().
1740
	 *
1741
	 * @since 1.0.19
1742
	 * @param  int $value New user id.
1743
	 */
1744
	public function set_customer_id( $value ) {
1745
		$this->set_author( $value );
1746
    }
1747
1748
    /**
1749
	 * Set the customer's ip.
1750
	 *
1751
	 * @since 1.0.19
1752
	 * @param  string $value ip address.
1753
	 */
1754
	public function set_ip( $value ) {
1755
		$this->set_prop( 'ip', $value );
1756
    }
1757
1758
    /**
1759
	 * Alias of self::set_ip().
1760
	 *
1761
	 * @since 1.0.19
1762
	 * @param  string $value ip address.
1763
	 */
1764
	public function set_user_ip( $value ) {
1765
		$this->set_ip( $value );
1766
    }
1767
1768
    /**
1769
	 * Set the customer's first name.
1770
	 *
1771
	 * @since 1.0.19
1772
	 * @param  string $value first name.
1773
	 */
1774
	public function set_first_name( $value ) {
1775
		$this->set_prop( 'first_name', $value );
1776
    }
1777
1778
    /**
1779
	 * Alias of self::set_first_name().
1780
	 *
1781
	 * @since 1.0.19
1782
	 * @param  string $value first name.
1783
	 */
1784
	public function set_user_first_name( $value ) {
1785
		$this->set_first_name( $value );
1786
    }
1787
1788
    /**
1789
	 * Alias of self::set_first_name().
1790
	 *
1791
	 * @since 1.0.19
1792
	 * @param  string $value first name.
1793
	 */
1794
	public function set_customer_first_name( $value ) {
1795
		$this->set_first_name( $value );
1796
    }
1797
1798
    /**
1799
	 * Set the customer's last name.
1800
	 *
1801
	 * @since 1.0.19
1802
	 * @param  string $value last name.
1803
	 */
1804
	public function set_last_name( $value ) {
1805
		$this->set_prop( 'last_name', $value );
1806
    }
1807
1808
    /**
1809
	 * Alias of self::set_last_name().
1810
	 *
1811
	 * @since 1.0.19
1812
	 * @param  string $value last name.
1813
	 */
1814
	public function set_user_last_name( $value ) {
1815
		$this->set_last_name( $value );
1816
    }
1817
1818
    /**
1819
	 * Alias of self::set_last_name().
1820
	 *
1821
	 * @since 1.0.19
1822
	 * @param  string $value last name.
1823
	 */
1824
	public function set_customer_last_name( $value ) {
1825
		$this->set_last_name( $value );
1826
    }
1827
1828
    /**
1829
	 * Set the customer's phone number.
1830
	 *
1831
	 * @since 1.0.19
1832
	 * @param  string $value phone.
1833
	 */
1834
	public function set_phone( $value ) {
1835
		$this->set_prop( 'phone', $value );
1836
    }
1837
1838
    /**
1839
	 * Alias of self::set_phone().
1840
	 *
1841
	 * @since 1.0.19
1842
	 * @param  string $value phone.
1843
	 */
1844
	public function set_user_phone( $value ) {
1845
		$this->set_phone( $value );
1846
    }
1847
1848
    /**
1849
	 * Alias of self::set_phone().
1850
	 *
1851
	 * @since 1.0.19
1852
	 * @param  string $value phone.
1853
	 */
1854
	public function set_customer_phone( $value ) {
1855
		$this->set_phone( $value );
1856
    }
1857
1858
    /**
1859
	 * Alias of self::set_phone().
1860
	 *
1861
	 * @since 1.0.19
1862
	 * @param  string $value phone.
1863
	 */
1864
	public function set_phone_number( $value ) {
1865
		$this->set_phone( $value );
1866
    }
1867
1868
    /**
1869
	 * Set the customer's email address.
1870
	 *
1871
	 * @since 1.0.19
1872
	 * @param  string $value email address.
1873
	 */
1874
	public function set_email( $value ) {
1875
		$this->set_prop( 'email', $value );
1876
    }
1877
1878
    /**
1879
	 * Alias of self::set_email().
1880
	 *
1881
	 * @since 1.0.19
1882
	 * @param  string $value email address.
1883
	 */
1884
	public function set_user_email( $value ) {
1885
		$this->set_email( $value );
1886
    }
1887
1888
    /**
1889
	 * Alias of self::set_email().
1890
	 *
1891
	 * @since 1.0.19
1892
	 * @param  string $value email address.
1893
	 */
1894
	public function set_email_address( $value ) {
1895
		$this->set_email( $value );
1896
    }
1897
1898
    /**
1899
	 * Alias of self::set_email().
1900
	 *
1901
	 * @since 1.0.19
1902
	 * @param  string $value email address.
1903
	 */
1904
	public function set_customer_email( $value ) {
1905
		$this->set_email( $value );
1906
    }
1907
1908
    /**
1909
	 * Set the customer's country.
1910
	 *
1911
	 * @since 1.0.19
1912
	 * @param  string $value country.
1913
	 */
1914
	public function set_country( $value ) {
1915
		$this->set_prop( 'country', $value );
1916
    }
1917
1918
    /**
1919
	 * Alias of self::set_country().
1920
	 *
1921
	 * @since 1.0.19
1922
	 * @param  string $value country.
1923
	 */
1924
	public function set_user_country( $value ) {
1925
		$this->set_country( $value );
1926
    }
1927
1928
    /**
1929
	 * Alias of self::set_country().
1930
	 *
1931
	 * @since 1.0.19
1932
	 * @param  string $value country.
1933
	 */
1934
	public function set_customer_country( $value ) {
1935
		$this->set_country( $value );
1936
    }
1937
1938
    /**
1939
	 * Set the customer's state.
1940
	 *
1941
	 * @since 1.0.19
1942
	 * @param  string $value state.
1943
	 */
1944
	public function set_state( $value ) {
1945
		$this->set_prop( 'state', $value );
1946
    }
1947
1948
    /**
1949
	 * Alias of self::set_state().
1950
	 *
1951
	 * @since 1.0.19
1952
	 * @param  string $value state.
1953
	 */
1954
	public function set_user_state( $value ) {
1955
		$this->set_state( $value );
1956
    }
1957
1958
    /**
1959
	 * Alias of self::set_state().
1960
	 *
1961
	 * @since 1.0.19
1962
	 * @param  string $value state.
1963
	 */
1964
	public function set_customer_state( $value ) {
1965
		$this->set_state( $value );
1966
    }
1967
1968
    /**
1969
	 * Set the customer's city.
1970
	 *
1971
	 * @since 1.0.19
1972
	 * @param  string $value city.
1973
	 */
1974
	public function set_city( $value ) {
1975
		$this->set_prop( 'city', $value );
1976
    }
1977
1978
    /**
1979
	 * Alias of self::set_city().
1980
	 *
1981
	 * @since 1.0.19
1982
	 * @param  string $value city.
1983
	 */
1984
	public function set_user_city( $value ) {
1985
		$this->set_city( $value );
1986
    }
1987
1988
    /**
1989
	 * Alias of self::set_city().
1990
	 *
1991
	 * @since 1.0.19
1992
	 * @param  string $value city.
1993
	 */
1994
	public function set_customer_city( $value ) {
1995
		$this->set_city( $value );
1996
    }
1997
1998
    /**
1999
	 * Set the customer's zip code.
2000
	 *
2001
	 * @since 1.0.19
2002
	 * @param  string $value zip.
2003
	 */
2004
	public function set_zip( $value ) {
2005
		$this->set_prop( 'zip', $value );
2006
    }
2007
2008
    /**
2009
	 * Alias of self::set_zip().
2010
	 *
2011
	 * @since 1.0.19
2012
	 * @param  string $value zip.
2013
	 */
2014
	public function set_user_zip( $value ) {
2015
		$this->set_zip( $value );
2016
    }
2017
2018
    /**
2019
	 * Alias of self::set_zip().
2020
	 *
2021
	 * @since 1.0.19
2022
	 * @param  string $value zip.
2023
	 */
2024
	public function set_customer_zip( $value ) {
2025
		$this->set_zip( $value );
2026
    }
2027
2028
    /**
2029
	 * Set the customer's company.
2030
	 *
2031
	 * @since 1.0.19
2032
	 * @param  string $value company.
2033
	 */
2034
	public function set_company( $value ) {
2035
		$this->set_prop( 'company', $value );
2036
    }
2037
2038
    /**
2039
	 * Alias of self::set_company().
2040
	 *
2041
	 * @since 1.0.19
2042
	 * @param  string $value company.
2043
	 */
2044
	public function set_user_company( $value ) {
2045
		$this->set_company( $value );
2046
    }
2047
2048
    /**
2049
	 * Alias of self::set_company().
2050
	 *
2051
	 * @since 1.0.19
2052
	 * @param  string $value company.
2053
	 */
2054
	public function set_customer_company( $value ) {
2055
		$this->set_company( $value );
2056
    }
2057
2058
    /**
2059
	 * Set the customer's var number.
2060
	 *
2061
	 * @since 1.0.19
2062
	 * @param  string $value var number.
2063
	 */
2064
	public function set_vat_number( $value ) {
2065
		$this->set_prop( 'vat_number', $value );
2066
    }
2067
2068
    /**
2069
	 * Alias of self::set_vat_number().
2070
	 *
2071
	 * @since 1.0.19
2072
	 * @param  string $value var number.
2073
	 */
2074
	public function set_user_vat_number( $value ) {
2075
		$this->set_vat_number( $value );
2076
    }
2077
2078
    /**
2079
	 * Alias of self::set_vat_number().
2080
	 *
2081
	 * @since 1.0.19
2082
	 * @param  string $value var number.
2083
	 */
2084
	public function set_customer_vat_number( $value ) {
2085
		$this->set_vat_number( $value );
2086
    }
2087
2088
    /**
2089
	 * Set the customer's vat rate.
2090
	 *
2091
	 * @since 1.0.19
2092
	 * @param  string $value var rate.
2093
	 */
2094
	public function set_vat_rate( $value ) {
2095
		$this->set_prop( 'vat_rate', $value );
2096
    }
2097
2098
    /**
2099
	 * Alias of self::set_vat_rate().
2100
	 *
2101
	 * @since 1.0.19
2102
	 * @param  string $value var number.
2103
	 */
2104
	public function set_user_vat_rate( $value ) {
2105
		$this->set_vat_rate( $value );
2106
    }
2107
2108
    /**
2109
	 * Alias of self::set_vat_rate().
2110
	 *
2111
	 * @since 1.0.19
2112
	 * @param  string $value var number.
2113
	 */
2114
	public function set_customer_vat_rate( $value ) {
2115
		$this->set_vat_rate( $value );
2116
    }
2117
2118
    /**
2119
	 * Set the customer's address.
2120
	 *
2121
	 * @since 1.0.19
2122
	 * @param  string $value address.
2123
	 */
2124
	public function set_address( $value ) {
2125
		$this->set_prop( 'address', $value );
2126
    }
2127
2128
    /**
2129
	 * Alias of self::set_address().
2130
	 *
2131
	 * @since 1.0.19
2132
	 * @param  string $value address.
2133
	 */
2134
	public function set_user_address( $value ) {
2135
		$this->set_address( $value );
2136
    }
2137
2138
    /**
2139
	 * Alias of self::set_address().
2140
	 *
2141
	 * @since 1.0.19
2142
	 * @param  string $value address.
2143
	 */
2144
	public function set_customer_address( $value ) {
2145
		$this->set_address( $value );
2146
    }
2147
2148
    /**
2149
	 * Set the customer's address confirmed status.
2150
	 *
2151
	 * @since 1.0.19
2152
	 * @param  int|bool $value confirmed.
2153
	 */
2154
	public function set_address_confirmed( $value ) {
2155
		$this->set_prop( 'address_confirmed', $value );
2156
    }
2157
2158
    /**
2159
	 * Alias of self::set_address_confirmed().
2160
	 *
2161
	 * @since 1.0.19
2162
	 * @param  int|bool $value confirmed.
2163
	 */
2164
	public function set_user_address_confirmed( $value ) {
2165
		$this->set_address_confirmed( $value );
2166
    }
2167
2168
    /**
2169
	 * Alias of self::set_address_confirmed().
2170
	 *
2171
	 * @since 1.0.19
2172
	 * @param  int|bool $value confirmed.
2173
	 */
2174
	public function set_customer_address_confirmed( $value ) {
2175
		$this->set_address_confirmed( $value );
2176
    }
2177
2178
    /**
2179
	 * Set the invoice sub total.
2180
	 *
2181
	 * @since 1.0.19
2182
	 * @param  float $value sub total.
2183
	 */
2184
	public function set_subtotal( $value ) {
2185
		$this->set_prop( 'subtotal', $value );
2186
    }
2187
2188
    /**
2189
	 * Set the invoice discount amount.
2190
	 *
2191
	 * @since 1.0.19
2192
	 * @param  float $value discount total.
2193
	 */
2194
	public function set_total_discount( $value ) {
2195
		$this->set_prop( 'total_discount', $value );
2196
    }
2197
2198
    /**
2199
	 * Alias of self::set_total_discount().
2200
	 *
2201
	 * @since 1.0.19
2202
	 * @param  float $value discount total.
2203
	 */
2204
	public function set_discount( $value ) {
2205
		$this->set_total_discount( $value );
2206
    }
2207
2208
    /**
2209
	 * Set the invoice tax amount.
2210
	 *
2211
	 * @since 1.0.19
2212
	 * @param  float $value tax total.
2213
	 */
2214
	public function set_total_tax( $value ) {
2215
		$this->set_prop( 'total_tax', $value );
2216
    }
2217
2218
    /**
2219
	 * Alias of self::set_total_tax().
2220
	 *
2221
	 * @since 1.0.19
2222
	 * @param  float $value tax total.
2223
	 */
2224
	public function set_tax_total( $value ) {
2225
		$this->set_total_tax( $value );
2226
    }
2227
2228
    /**
2229
	 * Set the invoice fees amount.
2230
	 *
2231
	 * @since 1.0.19
2232
	 * @param  float $value fees total.
2233
	 */
2234
	public function set_total_fees( $value ) {
2235
		$this->set_prop( 'total_fees', $value );
2236
    }
2237
2238
    /**
2239
	 * Alias of self::set_total_fees().
2240
	 *
2241
	 * @since 1.0.19
2242
	 * @param  float $value fees total.
2243
	 */
2244
	public function set_fees_total( $value ) {
2245
		$this->set_total_fees( $value );
2246
    }
2247
2248
    /**
2249
	 * Set the invoice fees.
2250
	 *
2251
	 * @since 1.0.19
2252
	 * @param  array $value fees.
2253
	 */
2254
	public function set_fees( $value ) {
2255
2256
        $this->set_prop( 'fees', array() );
2257
2258
        // Ensure that we have an array.
2259
        if ( ! is_array( $value ) ) {
0 ignored issues
show
introduced by
The condition is_array($value) is always true.
Loading history...
2260
            return;
2261
        }
2262
2263
        foreach ( $value as $name => $data ) {
2264
            if ( isset( $data['amount'] ) ) {
2265
                $this->add_fee( $name, $data['amount'], $data['recurring'] );
2266
            }
2267
        }
2268
2269
    }
2270
2271
    /**
2272
	 * Set the invoice taxes.
2273
	 *
2274
	 * @since 1.0.19
2275
	 * @param  array $value taxes.
2276
	 */
2277
	public function set_taxes( $value ) {
2278
		$this->set_prop( 'taxes', $value );
2279
    }
2280
2281
    /**
2282
	 * Set the invoice discounts.
2283
	 *
2284
	 * @since 1.0.19
2285
	 * @param  array $value discounts.
2286
	 */
2287
	public function set_discounts( $value ) {
2288
		$this->set_prop( 'discounts', array() );
2289
2290
        // Ensure that we have an array.
2291
        if ( ! is_array( $value ) ) {
0 ignored issues
show
introduced by
The condition is_array($value) is always true.
Loading history...
2292
            return;
2293
        }
2294
2295
        foreach ( $value as $name => $data ) {
2296
            if ( isset( $data['amount'] ) ) {
2297
                $this->add_discount( $name, $data['amount'], $data['recurring'] );
2298
            }
2299
        }
2300
    }
2301
2302
    /**
2303
	 * Set the invoice items.
2304
	 *
2305
	 * @since 1.0.19
2306
	 * @param  GetPaid_Form_Item[] $value items.
2307
	 */
2308
	public function set_items( $value ) {
2309
2310
        // Remove existing items.
2311
        $this->set_prop( 'items', array() );
2312
2313
        // Ensure that we have an array.
2314
        if ( ! is_array( $value ) ) {
0 ignored issues
show
introduced by
The condition is_array($value) is always true.
Loading history...
2315
            return;
2316
        }
2317
2318
        foreach ( $value as $item ) {
2319
            $this->add_item( $item );
2320
        }
2321
2322
    }
2323
2324
    /**
2325
	 * Set the payment form.
2326
	 *
2327
	 * @since 1.0.19
2328
	 * @param  int $value payment form.
2329
	 */
2330
	public function set_payment_form( $value ) {
2331
		$this->set_prop( 'payment_form', $value );
2332
    }
2333
2334
    /**
2335
	 * Set the submission id.
2336
	 *
2337
	 * @since 1.0.19
2338
	 * @param  string $value submission id.
2339
	 */
2340
	public function set_submission_id( $value ) {
2341
		$this->set_prop( 'submission_id', $value );
2342
    }
2343
2344
    /**
2345
	 * Set the discount code.
2346
	 *
2347
	 * @since 1.0.19
2348
	 * @param  string $value discount code.
2349
	 */
2350
	public function set_discount_code( $value ) {
2351
		$this->set_prop( 'discount_code', $value );
2352
    }
2353
2354
    /**
2355
	 * Set the gateway.
2356
	 *
2357
	 * @since 1.0.19
2358
	 * @param  string $value gateway.
2359
	 */
2360
	public function set_gateway( $value ) {
2361
		$this->set_prop( 'gateway', $value );
2362
    }
2363
2364
    /**
2365
	 * Set the transaction id.
2366
	 *
2367
	 * @since 1.0.19
2368
	 * @param  string $value transaction id.
2369
	 */
2370
	public function set_transaction_id( $value ) {
2371
		$this->set_prop( 'transaction_id', $value );
2372
    }
2373
2374
    /**
2375
	 * Set the currency id.
2376
	 *
2377
	 * @since 1.0.19
2378
	 * @param  string $value currency id.
2379
	 */
2380
	public function set_currency( $value ) {
2381
		$this->set_prop( 'currency', $value );
2382
    }
2383
2384
    /**
2385
	 * Set the subscription id.
2386
	 *
2387
	 * @since 1.0.19
2388
	 * @param  string $value subscription id.
2389
	 */
2390
	public function set_subscription_id( $value ) {
2391
		$this->set_prop( 'subscription_id', $value );
2392
    }
2393
2394
    public function update_status( $new_status = false, $note = '', $manual = false ) {
2395
        $old_status = ! empty( $this->old_status ) ? $this->old_status : get_post_status( $this->ID );
2396
2397
        if ( $old_status === $new_status && in_array( $new_status, array_keys( wpinv_get_invoice_statuses( true ) ) ) ) {
2398
            return false; // Don't permit status changes that aren't changes
2399
        }
2400
2401
        $do_change = apply_filters( 'wpinv_should_update_invoice_status', true, $this->ID, $new_status, $old_status );
2402
        $updated = false;
2403
2404
        if ( $do_change ) {
2405
            do_action( 'wpinv_before_invoice_status_change', $this->ID, $new_status, $old_status );
2406
2407
            $update_post_data                   = array();
2408
            $update_post_data['ID']             = $this->ID;
2409
            $update_post_data['post_status']    = $new_status;
2410
            $update_post_data['edit_date']      = current_time( 'mysql', 0 );
2411
            $update_post_data['edit_date_gmt']  = current_time( 'mysql', 1 );
2412
            
2413
            $update_post_data = apply_filters( 'wpinv_update_invoice_status_fields', $update_post_data, $this->ID );
2414
2415
            $updated = wp_update_post( $update_post_data );     
2416
           
2417
            // Process any specific status functions
2418
            switch( $new_status ) {
2419
                case 'wpi-refunded':
2420
                    $this->process_refund();
2421
                    break;
2422
                case 'wpi-failed':
2423
                    $this->process_failure();
2424
                    break;
2425
                case 'wpi-pending':
2426
                    $this->process_pending();
2427
                    break;
2428
            }
2429
            
2430
            // Status was changed.
2431
            do_action( 'wpinv_status_' . $new_status, $this->ID, $old_status );
2432
            do_action( 'wpinv_status_' . $old_status . '_to_' . $new_status, $this->ID, $old_status );
0 ignored issues
show
Bug introduced by
Are you sure $old_status of type false|mixed|string can be used in concatenation? ( Ignorable by Annotation )

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

2432
            do_action( 'wpinv_status_' . /** @scrutinizer ignore-type */ $old_status . '_to_' . $new_status, $this->ID, $old_status );
Loading history...
2433
            do_action( 'wpinv_update_status', $this->ID, $new_status, $old_status );
2434
        }
2435
2436
        return $updated;
2437
    }
2438
2439
    public function refund() {
2440
        $this->old_status        = $this->status;
0 ignored issues
show
Bug Best Practice introduced by
The property old_status does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
2441
        $this->status            = 'wpi-refunded';
0 ignored issues
show
Bug Best Practice introduced by
The property status does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
2442
        $this->pending['status'] = $this->status;
0 ignored issues
show
Bug Best Practice introduced by
The property pending does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
2443
2444
        $this->save();
2445
    }
2446
2447
    private function process_refund() {
2448
        $process_refund = true;
2449
2450
        // If the payment was not in publish, don't decrement stats as they were never incremented
2451
        if ( 'publish' != $this->old_status || 'wpi-refunded' != $this->status ) {
2452
            $process_refund = false;
2453
        }
2454
2455
        // Allow extensions to filter for their own payment types, Example: Recurring Payments
2456
        $process_refund = apply_filters( 'wpinv_should_process_refund', $process_refund, $this );
2457
2458
        if ( false === $process_refund ) {
2459
            return;
2460
        }
2461
2462
        do_action( 'wpinv_pre_refund_invoice', $this );
2463
        
2464
        $decrease_store_earnings = apply_filters( 'wpinv_decrease_store_earnings_on_refund', true, $this );
0 ignored issues
show
Unused Code introduced by
The assignment to $decrease_store_earnings is dead and can be removed.
Loading history...
2465
        $decrease_customer_value = apply_filters( 'wpinv_decrease_customer_value_on_refund', true, $this );
0 ignored issues
show
Unused Code introduced by
The assignment to $decrease_customer_value is dead and can be removed.
Loading history...
2466
        $decrease_purchase_count = apply_filters( 'wpinv_decrease_customer_purchase_count_on_refund', true, $this );
0 ignored issues
show
Unused Code introduced by
The assignment to $decrease_purchase_count is dead and can be removed.
Loading history...
2467
        
2468
        do_action( 'wpinv_post_refund_invoice', $this );
2469
    }
2470
2471
    private function process_failure() {
2472
        $discounts = $this->discounts;
0 ignored issues
show
Bug Best Practice introduced by
The property discounts does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
2473
        if ( empty( $discounts ) ) {
2474
            return;
2475
        }
2476
2477
        if ( ! is_array( $discounts ) ) {
2478
            $discounts = array_map( 'trim', explode( ',', $discounts ) );
2479
        }
2480
2481
        foreach ( $discounts as $discount ) {
2482
            wpinv_decrease_discount_usage( $discount );
2483
        }
2484
    }
2485
    
2486
    private function process_pending() {
2487
        $process_pending = true;
2488
2489
        // If the payment was not in publish or revoked status, don't decrement stats as they were never incremented
2490
        if ( ( 'publish' != $this->old_status && 'revoked' != $this->old_status ) || 'wpi-pending' != $this->status ) {
2491
            $process_pending = false;
2492
        }
2493
2494
        // Allow extensions to filter for their own payment types, Example: Recurring Payments
2495
        $process_pending = apply_filters( 'wpinv_should_process_pending', $process_pending, $this );
2496
2497
        if ( false === $process_pending ) {
2498
            return;
2499
        }
2500
2501
        $decrease_store_earnings = apply_filters( 'wpinv_decrease_store_earnings_on_pending', true, $this );
0 ignored issues
show
Unused Code introduced by
The assignment to $decrease_store_earnings is dead and can be removed.
Loading history...
2502
        $decrease_customer_value = apply_filters( 'wpinv_decrease_customer_value_on_pending', true, $this );
0 ignored issues
show
Unused Code introduced by
The assignment to $decrease_customer_value is dead and can be removed.
Loading history...
2503
        $decrease_purchase_count = apply_filters( 'wpinv_decrease_customer_purchase_count_on_pending', true, $this );
0 ignored issues
show
Unused Code introduced by
The assignment to $decrease_purchase_count is dead and can be removed.
Loading history...
2504
2505
        $this->completed_date = '';
0 ignored issues
show
Bug Best Practice introduced by
The property completed_date does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
2506
        $this->update_meta( '_wpinv_completed_date', '' );
0 ignored issues
show
Bug introduced by
The method update_meta() does not exist on WPInv_Invoice. Did you maybe mean update_meta_data()? ( Ignorable by Annotation )

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

2506
        $this->/** @scrutinizer ignore-call */ 
2507
               update_meta( '_wpinv_completed_date', '' );

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
2507
    }
2508
2509
    /**
2510
     * Returns recurring payment details.
2511
     */
2512
    public function get_recurring_details( $field = '', $currency = false ) {        
2513
        $data                 = array();
2514
        $data['cart_details'] = $this->cart_details;
2515
        $data['subtotal']     = $this->get_subtotal();
2516
        $data['discount']     = $this->get_discount();
0 ignored issues
show
Bug introduced by
The call to WPInv_Invoice::get_discount() has too few arguments starting with discount. ( Ignorable by Annotation )

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

2516
        /** @scrutinizer ignore-call */ 
2517
        $data['discount']     = $this->get_discount();

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
2517
        $data['tax']          = $this->get_tax();
0 ignored issues
show
Bug introduced by
The call to WPInv_Invoice::get_tax() has too few arguments starting with tax. ( Ignorable by Annotation )

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

2517
        /** @scrutinizer ignore-call */ 
2518
        $data['tax']          = $this->get_tax();

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
2518
        $data['total']        = $this->get_total();
2519
2520
        if ( $this->is_parent() || $this->is_renewal() ) {
2521
2522
            // Use the parent to calculate recurring details.
2523
            if ( $this->is_renewal() ){
2524
                $parent = $this->get_parent_payment();
2525
            } else {
2526
                $parent = $this;
2527
            }
2528
2529
            if ( empty( $parent ) ) {
2530
                $parent = $this;
2531
            }
2532
2533
            // Subtotal.
2534
            $data['subtotal'] = wpinv_round_amount( $parent->subtotal );
2535
            $data['tax']      = wpinv_round_amount( $parent->tax );
2536
            $data['discount'] = wpinv_round_amount( $parent->discount );
2537
2538
            if ( $data['discount'] > 0 && $parent->discount_first_payment_only() ) {
2539
                $data['discount'] = wpinv_round_amount( 0 );
2540
            }
2541
2542
            $data['total'] = wpinv_round_amount( $data['subtotal'] + $data['tax'] - $data['discount'] );
2543
2544
        }
2545
        
2546
        $data = apply_filters( 'wpinv_get_invoice_recurring_details', $data, $this, $field, $currency );
2547
2548
        if ( $data['total'] < 0 ) {
2549
            $data['total'] = 0;
2550
        }
2551
2552
        if ( isset( $data[$field] ) ) {
2553
            return ( $currency ? wpinv_price( $data[$field], $this->get_currency() ) : $data[$field] );
2554
        }
2555
        
2556
        return $data;
2557
    }
2558
    
2559
    public function get_final_tax( $currency = false ) {        
2560
        $final_total = wpinv_round_amount( $this->tax );
2561
        if ( $currency ) {
2562
            $final_total = wpinv_price( wpinv_format_amount( $final_total, NULL, !$currency ), $this->get_currency() );
2563
        }
2564
        
2565
        return apply_filters( 'wpinv_get_invoice_final_total', $final_total, $this, $currency );
2566
    }
2567
    
2568
    public function get_discounts( $array = false ) {
2569
        $discounts = $this->discounts;
0 ignored issues
show
Bug Best Practice introduced by
The property discounts does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
2570
2571
        if ( ! is_array( $discounts ) ) {
2572
            $discounts = explode( ',', $discounts );
2573
        }
2574
2575
        $discounts = array_filter( $discounts );
2576
2577
        if ( ! $array ) {
2578
            $discounts = implode( ',', $discounts );
2579
        }
2580
2581
        return apply_filters( 'wpinv_payment_discounts', $discounts, $this->ID, $this, $array );
2582
    }
2583
    
2584
    
2585
    
2586
    
2587
    public function get_invoice_date( $formatted = true ) {
2588
        $date_completed = $this->completed_date;
2589
        $invoice_date   = $date_completed != '' && $date_completed != '0000-00-00 00:00:00' ? $date_completed : '';
2590
        
2591
        if ( $invoice_date == '' ) {
2592
            $date_created   = $this->date;
0 ignored issues
show
Bug Best Practice introduced by
The property date does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
2593
            $invoice_date   = $date_created != '' && $date_created != '0000-00-00 00:00:00' ? $date_created : '';
2594
        }
2595
        
2596
        if ( $formatted && $invoice_date ) {
2597
            $invoice_date   = date_i18n( get_option( 'date_format' ), strtotime( $invoice_date ) );
0 ignored issues
show
Bug introduced by
It seems like get_option('date_format') can also be of type false; however, parameter $format of date_i18n() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

2597
            $invoice_date   = date_i18n( /** @scrutinizer ignore-type */ get_option( 'date_format' ), strtotime( $invoice_date ) );
Loading history...
2598
        }
2599
2600
        return apply_filters( 'wpinv_get_invoice_date', $invoice_date, $formatted, $this->ID, $this );
2601
    }
2602
    
2603
    public function get_ip() {
2604
        return apply_filters( 'wpinv_user_ip', $this->ip, $this->ID, $this );
0 ignored issues
show
Bug Best Practice introduced by
The property ip does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
2605
    }
2606
2607
    public function update_items($temp = false) {
2608
        global $wpinv_euvat, $wpi_current_id, $wpi_item_id, $wpi_nosave;
2609
2610
        if ( ! empty( $this->cart_details ) ) {
2611
            $wpi_nosave             = $temp;
2612
            $cart_subtotal          = 0;
2613
            $cart_discount          = 0;
2614
            $cart_tax               = 0;
2615
            $cart_details           = array();
2616
2617
            $_POST['wpinv_country'] = $this->country;
0 ignored issues
show
Bug Best Practice introduced by
The property country does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
2618
            $_POST['wpinv_state']   = $this->state;
0 ignored issues
show
Bug Best Practice introduced by
The property state does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
2619
2620
            foreach ( $this->cart_details as $item ) {
2621
                $item_price = $item['item_price'];
2622
                $quantity   = wpinv_item_quantities_enabled() && $item['quantity'] > 0 ? absint( $item['quantity'] ) : 1;
2623
                $amount     = wpinv_round_amount( $item_price * $quantity );
0 ignored issues
show
Unused Code introduced by
The assignment to $amount is dead and can be removed.
Loading history...
2624
                $subtotal   = $item_price * $quantity;
2625
2626
                $wpi_current_id         = $this->ID;
2627
                $wpi_item_id            = $item['id'];
2628
2629
                $discount   = wpinv_get_cart_item_discount_amount( $item, $this->get_discounts() );
2630
2631
                $tax_rate   = wpinv_get_tax_rate( $this->country, $this->state, $wpi_item_id );
2632
                $tax_class  = $wpinv_euvat->get_item_class( $wpi_item_id );
2633
                $tax        = $item_price > 0 ? ( ( $subtotal - $discount ) * 0.01 * (float)$tax_rate ) : 0;
2634
2635
                if ( ! $this->is_taxable() ) {
2636
                    $tax = 0;
2637
                }
2638
2639
                if ( wpinv_prices_include_tax() ) {
2640
                    $subtotal -= wpinv_round_amount( $tax );
2641
                }
2642
2643
                $total      = $subtotal - $discount + $tax;
2644
2645
                // Do not allow totals to go negative
2646
                if( $total < 0 ) {
2647
                    $total = 0;
2648
                }
2649
2650
                $cart_details[] = array(
2651
                    'id'          => $item['id'],
2652
                    'name'        => $item['name'],
2653
                    'item_price'  => wpinv_round_amount( $item_price ),
2654
                    'custom_price'=> ( isset( $item['custom_price'] ) ? $item['custom_price'] : '' ),
2655
                    'quantity'    => $quantity,
2656
                    'discount'    => $discount,
2657
                    'subtotal'    => wpinv_round_amount( $subtotal ),
2658
                    'tax'         => wpinv_round_amount( $tax ),
2659
                    'price'       => wpinv_round_amount( $total ),
2660
                    'vat_rate'    => $tax_rate,
2661
                    'vat_class'   => $tax_class,
2662
                    'meta'        => isset($item['meta']) ? $item['meta'] : array(),
2663
                    'fees'        => isset($item['fees']) ? $item['fees'] : array(),
2664
                );
2665
2666
                $cart_subtotal  += (float) $subtotal;
2667
                $cart_discount  += (float) $discount;
2668
                $cart_tax       += (float) $tax;
2669
            }
2670
2671
            if ( $cart_subtotal < 0 ) {
2672
                $cart_subtotal = 0;
2673
            }
2674
2675
            if ( $cart_discount < 0 ) {
2676
                $cart_discount = 0;
2677
            }
2678
2679
            if ( $cart_tax < 0 ) {
2680
                $cart_tax = 0;
2681
            }
2682
2683
            $this->subtotal = wpinv_round_amount( $cart_subtotal );
0 ignored issues
show
Bug Best Practice introduced by
The property subtotal does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
2684
            $this->tax      = wpinv_round_amount( $cart_tax );
0 ignored issues
show
Bug Best Practice introduced by
The property tax does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
2685
            $this->discount = wpinv_round_amount( $cart_discount );
0 ignored issues
show
Bug Best Practice introduced by
The property discount does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
2686
2687
            $this->recalculate_total();
2688
            
2689
            $this->cart_details = $cart_details;
0 ignored issues
show
Bug Best Practice introduced by
The property cart_details does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
2690
        }
2691
2692
        return $this;
2693
    }
2694
2695
    /**
2696
     * Validates a whether the discount is valid.
2697
     */
2698
    public function validate_discount() {    
2699
        
2700
        $discounts = $this->get_discounts( true );
2701
2702
        if ( empty( $discounts ) ) {
2703
            return false;
2704
        }
2705
2706
        $discount = wpinv_get_discount_obj( $discounts[0] );
2707
2708
        // Ensure it is active.
2709
        return $discount->exists();
2710
2711
    }
2712
    
2713
    public function recalculate_totals($temp = false) {        
2714
        $this->update_items($temp);
2715
        $this->save( true );
0 ignored issues
show
Unused Code introduced by
The call to GetPaid_Data::save() has too many arguments starting with true. ( Ignorable by Annotation )

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

2715
        $this->/** @scrutinizer ignore-call */ 
2716
               save( true );

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
2716
        
2717
        return $this;
2718
    }
2719
    
2720
    public function needs_payment() {
2721
        $valid_invoice_statuses = apply_filters( 'wpinv_valid_invoice_statuses_for_payment', array( 'wpi-pending' ), $this );
2722
2723
        if ( $this->has_status( $valid_invoice_statuses ) && ( $this->get_total() > 0 || $this->is_free_trial() || $this->is_free() || $this->is_initial_free() ) ) {
2724
            $needs_payment = true;
2725
        } else {
2726
            $needs_payment = false;
2727
        }
2728
2729
        return apply_filters( 'wpinv_needs_payment', $needs_payment, $this, $valid_invoice_statuses );
2730
    }
2731
    
2732
    public function get_checkout_payment_url( $with_key = false, $secret = false ) {
2733
        $pay_url = wpinv_get_checkout_uri();
2734
2735
        if ( is_ssl() ) {
2736
            $pay_url = str_replace( 'http:', 'https:', $pay_url );
2737
        }
2738
        
2739
        $key = $this->get_key();
2740
2741
        if ( $with_key ) {
2742
            $pay_url = add_query_arg( 'invoice_key', $key, $pay_url );
2743
        } else {
2744
            $pay_url = add_query_arg( array( 'wpi_action' => 'pay_for_invoice', 'invoice_key' => $key ), $pay_url );
2745
        }
2746
        
2747
        if ( $secret ) {
2748
            $pay_url = add_query_arg( array( '_wpipay' => md5( $this->get_user_id() . '::' . $this->get_email() . '::' . $key ) ), $pay_url );
2749
        }
2750
2751
        return apply_filters( 'wpinv_get_checkout_payment_url', $pay_url, $this, $with_key, $secret );
2752
    }
2753
    
2754
    public function get_view_url( $with_key = false ) {
2755
        $invoice_url = get_permalink( $this->ID );
2756
2757
        if ( $with_key ) {
2758
            $invoice_url = add_query_arg( 'invoice_key', $this->get_key(), $invoice_url );
2759
        }
2760
2761
        return apply_filters( 'wpinv_get_view_url', $invoice_url, $this, $with_key );
2762
    }
2763
2764
    /**
2765
     * Generates a unique key for the invoice.
2766
     */
2767
    public function generate_key( $string = '' ) {
2768
        $auth_key  = defined( 'AUTH_KEY' ) ? AUTH_KEY : '';
2769
        return strtolower(
2770
            md5( $this->get_id() . $string . date( 'Y-m-d H:i:s' ) . $auth_key . uniqid( 'wpinv', true ) )
2771
        );
2772
    }
2773
2774
    /**
2775
     * Generates a new number for the invoice.
2776
     */
2777
    public function generate_number() {
2778
        $number = $this->get_id();
2779
2780
        if ( $this->has_status( 'auto-draft' ) && wpinv_sequential_number_active( $this->post_type ) ) {
0 ignored issues
show
Bug Best Practice introduced by
The property post_type does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
2781
            $next_number = wpinv_get_next_invoice_number( $this->post_type );
2782
            $number      = $next_number;
2783
        }
2784
2785
        $number = wpinv_format_invoice_number( $number, $this->post_type );
0 ignored issues
show
Unused Code introduced by
The assignment to $number is dead and can be removed.
Loading history...
2786
    }
2787
2788
    /**
2789
     * Check if the free trial is a result of a discount.
2790
     */
2791
    public function is_free_trial_from_discount() {
2792
2793
        $parent = $this;
2794
2795
        if ( $this->is_renewal() ) {
2796
            $parent = $this->get_parent_payment();
2797
        }
2798
    
2799
        if ( $parent && $item = $parent->get_recurring( true ) ) {
2800
            return ! ( ! empty( $item ) && $item->has_free_trial() );
2801
        }
2802
        return false;
2803
2804
    }
2805
2806
    /**
2807
     * Check if a discount is only applicable to the first payment.
2808
     */
2809
    public function discount_first_payment_only() {
2810
2811
        if ( empty( $this->discounts ) || ! $this->is_recurring() ) {
0 ignored issues
show
Bug Best Practice introduced by
The property discounts does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
2812
            return true;
2813
        }
2814
2815
        $discount = wpinv_get_discount_obj( $this->discounts[0] );
2816
2817
        if ( ! $discount || ! $discount->exists() ) {
0 ignored issues
show
introduced by
$discount is of type WPInv_Discount, thus it always evaluated to true.
Loading history...
2818
            return true;
2819
        }
2820
2821
        return ! $discount->get_is_recurring();
2822
    }
2823
2824
    public function is_initial_free() {
2825
        $is_initial_free = false;
2826
        
2827
        if ( ! ( (float)wpinv_round_amount( $this->get_total() ) > 0 ) && $this->is_parent() && $this->is_recurring() && ! $this->is_free_trial() && ! $this->is_free() ) {
2828
            $is_initial_free = true;
2829
        }
2830
2831
        return apply_filters( 'wpinv_invoice_is_initial_free', $is_initial_free, $this->cart_details );
2832
    }
2833
2834
    public function get_recurring( $object = false ) {
2835
        $item = NULL;
2836
        
2837
        if ( empty( $this->cart_details ) ) {
2838
            return $item;
2839
        }
2840
2841
        foreach( $this->cart_details as $cart_item ) {
2842
            if ( !empty( $cart_item['id'] ) && wpinv_is_recurring_item( $cart_item['id'] )  ) {
2843
                $item = $cart_item['id'];
2844
                break;
2845
            }
2846
        }
2847
2848
        if ( $object ) {
2849
            $item = $item ? new WPInv_Item( $item ) : NULL;
2850
            
2851
            apply_filters( 'wpinv_invoice_get_recurring_item', $item, $this );
2852
        }
2853
2854
        return apply_filters( 'wpinv_invoice_get_recurring_item_id', $item, $this );
2855
    }
2856
2857
    public function get_subscription_name() {
2858
        $item = $this->get_recurring( true );
2859
2860
        if ( empty( $item ) ) {
2861
            return NULL;
2862
        }
2863
2864
        if ( !($name = $item->get_name()) ) {
2865
            $name = $item->post_name;
0 ignored issues
show
Bug Best Practice introduced by
The property post_name does not exist on WPInv_Item. Since you implemented __get, consider adding a @property annotation.
Loading history...
2866
        }
2867
2868
        return apply_filters( 'wpinv_invoice_get_subscription_name', $name, $this );
2869
    }
2870
    
2871
    public function is_refunded() {
2872
        $is_refunded = $this->has_status( array( 'wpi-refunded' ) );
2873
2874
        return apply_filters( 'wpinv_invoice_is_refunded', $is_refunded, $this );
2875
    }
2876
    
2877
    public function is_free() {
2878
        $is_free = false;
2879
2880
        if ( !( (float)wpinv_round_amount( $this->get_total() ) > 0 ) ) {
2881
            if ( $this->is_parent() && $this->is_recurring() ) {
2882
                $is_free = (float)wpinv_round_amount( $this->get_recurring_details( 'total' ) ) > 0 ? false : true;
2883
            } else {
2884
                $is_free = true;
2885
            }
2886
        }
2887
2888
        return apply_filters( 'wpinv_invoice_is_free', $is_free, $this );
2889
    }
2890
    
2891
    public function has_vat() {
2892
        global $wpinv_euvat, $wpi_country;
2893
        
2894
        $requires_vat = false;
2895
        
2896
        if ( $this->country ) {
0 ignored issues
show
Bug Best Practice introduced by
The property country does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
2897
            $wpi_country        = $this->country;
2898
            
2899
            $requires_vat       = $wpinv_euvat->requires_vat( $requires_vat, $this->get_user_id(), $wpinv_euvat->invoice_has_digital_rule( $this ) );
2900
        }
2901
        
2902
        return apply_filters( 'wpinv_invoice_has_vat', $requires_vat, $this );
2903
    }
2904
2905
    public function refresh_item_ids() {
2906
        $item_ids = array();
2907
        
2908
        if ( ! empty( $this->cart_details ) ) {
2909
            foreach ( array_keys( $this->cart_details ) as $item ) {
2910
                if ( ! empty( $item['id'] ) ) {
2911
                    $item_ids[] = $item['id'];
2912
                }
2913
            }
2914
        }
2915
        
2916
        $item_ids = !empty( $item_ids ) ? implode( ',', array_unique( $item_ids ) ) : '';
2917
        
2918
        update_post_meta( $this->ID, '_wpinv_item_ids', $item_ids );
2919
    }
2920
    
2921
    public function get_invoice_quote_type( $post_id ) {
2922
        if ( empty( $post_id ) ) {
2923
            return '';
2924
        }
2925
2926
        $type = get_post_type( $post_id );
2927
2928
        if ( 'wpi_invoice' === $type ) {
2929
            $post_type = __('Invoice', 'invoicing');
2930
        } else{
2931
            $post_type = __('Quote', 'invoicing');
2932
        }
2933
2934
        return apply_filters('get_invoice_type_label', $post_type, $post_id);
2935
    }
2936
2937
    /*
2938
	|--------------------------------------------------------------------------
2939
	| Boolean methods
2940
	|--------------------------------------------------------------------------
2941
	|
2942
	| Return true or false.
2943
	|
2944
    */
2945
2946
    /**
2947
     * Checks if this is a parent invoice.
2948
     */
2949
    public function is_parent() {
2950
        $parent = $this->get_parent_id();
2951
        return apply_filters( 'wpinv_invoice_is_parent', empty( $parent ), $this );
2952
    }
2953
2954
    /**
2955
     * Checks if this is a renewal invoice.
2956
     */
2957
    public function is_renewal() {
2958
        return ! $this->is_parent();
2959
    }
2960
2961
    /**
2962
     * Checks if this is a recurring invoice.
2963
     */
2964
    public function is_recurring() {
2965
        return ! empty( $this->recurring_item );
2966
    }
2967
2968
    /**
2969
     * Checks if this is a taxable invoice.
2970
     */
2971
    public function is_taxable() {
2972
        return (int) $this->disable_taxes === 0;
0 ignored issues
show
Bug Best Practice introduced by
The property disable_taxes does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
2973
    }
2974
2975
    /**
2976
     * Checks if the invoice is paid.
2977
     */
2978
    public function is_paid() {
2979
        $is_paid = $this->has_status( array( 'publish', 'wpi-processing', 'wpi-renewal' ) );
2980
        return apply_filters( 'wpinv_invoice_is_paid', $is_paid, $this );
2981
    }
2982
2983
    /**
2984
     * Checks if the invoice has a given status.
2985
     */
2986
    public function has_status( $status ) {
2987
        $status = wpinv_parse_list( $status );
2988
        return apply_filters( 'wpinv_has_status', in_array( $this->get_status(), $status ), $status );
2989
    }
2990
2991
    /**
2992
     * Checks if this is a quote object.
2993
     * 
2994
     * @since 1.0.15
2995
     */
2996
    public function is_quote() {
2997
        return $this->has_status( 'wpi_quote' );
2998
    }
2999
3000
    /**
3001
     * Check if the invoice (or it's parent has a free trial).
3002
     * 
3003
     */
3004
    public function has_free_trial() {
3005
3006
        // Ensure we have a recurring item.
3007
        if ( ! $this->is_recurring() ) {
3008
            return;
3009
        }
3010
3011
        $item = new WPInv_Item( $this->recurring_item );
3012
        return $item->has_free_trial();
3013
    }
3014
3015
    /**
3016
     * Check if we are offering a free trial.
3017
     * 
3018
     * Returns true if it has a 100% discount for the first period.
3019
     */
3020
    public function is_free_trial() {
3021
        $is_free_trial = false;
3022
3023
        if ( $this->is_parent() && $item = $this->get_recurring( true ) ) {
3024
            if ( ! empty( $item ) && ( $item->has_free_trial() || ( $this->total == 0 && $this->discount_first_payment_only() ) ) ) {
0 ignored issues
show
Bug Best Practice introduced by
The property total does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
3025
                $is_free_trial = true;
3026
            }
3027
        }
3028
3029
        return apply_filters( 'wpinv_invoice_is_free_trial', $is_free_trial, $this->cart_details, $this );
3030
    }
3031
3032
    /*
3033
	|--------------------------------------------------------------------------
3034
	| Cart related methods
3035
	|--------------------------------------------------------------------------
3036
	|
3037
	| Do not forget to recalculate totals after calling the following methods.
3038
	|
3039
    */
3040
3041
    /**
3042
     * Adds an item to the invoice.
3043
     *
3044
     * @param GetPaid_Form_Item $item
3045
     * @return WP_Error|Bool
3046
     */
3047
    public function add_item( $item ) {
3048
3049
        // Make sure that it is available for purchase.
3050
		if ( $item->get_id() > 0 && ! $item->can_purchase() ) {
3051
			return new WP_Error( 'invalid_item', __( 'This item is not available for purchase', 'invoicing' ) );
3052
        }
3053
3054
        // Do we have a recurring item?
3055
		if ( $item->is_recurring() ) {
3056
			$this->recurring_item = $item->get_id();
3057
        }
3058
3059
        // Invoice id.
3060
        $item->invoice_id = $this->get_id();
3061
3062
        // Retrieve all items.
3063
        $items = $this->get_items();
3064
        $items[ $item->get_id() ] = $item;
3065
3066
        $this->set_prop( 'items', $items );
3067
3068
    }
3069
3070
    /**
3071
	 * Retrieves a specific item.
3072
	 *
3073
	 * @since 1.0.19
3074
	 */
3075
	public function get_item( $item_id ) {
3076
        $items = $this->get_items();
3077
		return isset( $items[ $item_id ] ) ? $items[ $item_id ] : null;
3078
    }
3079
3080
    /**
3081
	 * Removes a specific item.
3082
	 *
3083
	 * @since 1.0.19
3084
	 */
3085
	public function remove_item( $item_id ) {
3086
        $items = $this->get_items();
3087
3088
        if ( $item_id == $this->recurring_item ) {
3089
            $this->recurring_item = null;
3090
        }
3091
3092
        if ( isset( $items[ $item_id ] ) ) {
3093
            unset( $items[ $item_id ] );
3094
            $this->set_prop( 'items', $items );
3095
        }
3096
    }
3097
3098
    /**
3099
     * Adds a fee to the invoice.
3100
     *
3101
     * @param string $fee
3102
     * @param float $value
3103
     * @return WP_Error|Bool
3104
     */
3105
    public function add_fee( $fee, $value, $recurring = false ) {
3106
3107
        $amount = wpinv_sanitize_amount( $value );
3108
        $fees   = $this->get_fees();
3109
3110
        if ( isset( $fees[ $fee ] ) && isset( $fees[ $fee ]['amount'] ) ) {
3111
3112
            $amount = $fees[ $fee ]['amount'] += $amount;
3113
			$fees[ $fee ] = array(
3114
                'amount'    => $amount,
3115
                'recurring' => $recurring,
3116
            );
3117
3118
		} else {
3119
			$fees[ $fee ] = array(
3120
                'amount'    => $amount,
3121
                'recurring' => $recurring,
3122
            );
3123
		}
3124
3125
        $this->set_prop( 'fees', $fee );
3126
3127
    }
3128
3129
    /**
3130
	 * Retrieves a specific fee.
3131
	 *
3132
	 * @since 1.0.19
3133
	 */
3134
	public function get_fee( $fee ) {
3135
        $fees = $this->get_fees();
3136
		return isset( $fees[ $fee ] ) ? $fees[ $fee ] : null;
3137
    }
3138
3139
    /**
3140
	 * Removes a specific fee.
3141
	 *
3142
	 * @since 1.0.19
3143
	 */
3144
	public function remove_fee( $fee ) {
3145
        $fees = $this->get_fees();
3146
        if ( isset( $fees[ $fee ] ) ) {
3147
            unset( $fees[ $fee ] );
3148
            $this->set_prop( 'fees', $fees );
3149
        }
3150
    }
3151
3152
    /**
3153
     * Adds a discount to the invoice.
3154
     *
3155
     * @param string $discount
3156
     * @param float $value
3157
     * @return WP_Error|Bool
3158
     */
3159
    public function add_discount( $discount, $value, $recurring = false ) {
3160
3161
        $amount    = wpinv_sanitize_amount( $value );
3162
        $discounts = $this->get_discounts();
3163
3164
        if ( isset( $discounts[ $discount ] ) && isset( $discounts[ $discount ]['amount'] ) ) {
3165
3166
            $amount = $discounts[ $discount ]['amount'] += $amount;
3167
			$discounts[ $discount ] = array(
3168
                'amount'    => $amount,
3169
                'recurring' => $recurring,
3170
            );
3171
3172
		} else {
3173
			$discounts[ $discount ] = array(
3174
                'amount'    => $amount,
3175
                'recurring' => $recurring,
3176
            );
3177
		}
3178
3179
        $this->set_prop( 'discounts', $discount );
3180
3181
    }
3182
3183
    /**
3184
	 * Retrieves a specific discount.
3185
	 *
3186
	 * @since 1.0.19
3187
	 */
3188
	public function get_discount( $discount ) {
3189
        $discounts = $this->get_discounts();
3190
		return isset( $discounts[ $discount ] ) ? $discounts[ $discount ] : null;
3191
    }
3192
3193
    /**
3194
	 * Removes a specific discount.
3195
	 *
3196
	 * @since 1.0.19
3197
	 */
3198
	public function remove_discount( $discount ) {
3199
        $discounts = $this->get_discounts();
3200
        if ( isset( $discounts[ $discount ] ) ) {
3201
            unset( $discounts[ $discount ] );
3202
            $this->set_prop( 'discounts', $discounts );
3203
        }
3204
    }
3205
3206
    /**
3207
     * Adds a tax to the invoice.
3208
     *
3209
     * @param string $tax
3210
     * @param float $value
3211
     */
3212
    public function add_tax( $tax, $value, $recurring = true ) {
3213
3214
        if ( ! $this->is_taxable() ) {
3215
            return;
3216
        }
3217
3218
        $amount    = wpinv_sanitize_amount( $value );
3219
        $taxes     = $this->get_taxes();
3220
3221
        if ( isset( $taxes[ $tax ] ) && isset( $taxes[ $tax ]['amount'] ) ) {
3222
3223
            $amount = $taxes[ $tax ]['amount'] += $amount;
3224
			$taxes[ $tax ] = array(
3225
                'amount'    => $amount,
3226
                'recurring' => $recurring,
3227
            );
3228
3229
		} else {
3230
			$taxes[ $tax ] = array(
3231
                'amount'    => $amount,
3232
                'recurring' => $recurring,
3233
            );
3234
		}
3235
3236
        $this->set_prop( 'taxes', $tax );
3237
3238
    }
3239
3240
    /**
3241
	 * Retrieves a specific tax.
3242
	 *
3243
	 * @since 1.0.19
3244
	 */
3245
	public function get_tax( $tax ) {
3246
        $taxes = $this->get_taxes();
3247
		return isset( $taxes[ $tax ] ) ? $taxes[ $tax ] : null;
3248
    }
3249
3250
    /**
3251
	 * Removes a specific tax.
3252
	 *
3253
	 * @since 1.0.19
3254
	 */
3255
	public function remove_tax( $tax ) {
3256
        $taxes = $this->get_discounts();
3257
        if ( isset( $taxes[ $tax ] ) ) {
3258
            unset( $taxes[ $tax ] );
3259
            $this->set_prop( 'taxes', $taxes );
3260
        }
3261
    }
3262
3263
    /**
3264
	 * Recalculates the invoice subtotal.
3265
	 *
3266
	 * @since 1.0.19
3267
	 * @return float The recalculated subtotal
3268
	 */
3269
	public function recalculate_subtotal() {
3270
        $items    = $this->get_items();
3271
        $subtotal = 0;
3272
3273
        foreach ( $items as $item ) {
3274
            $subtotal += $item->get_sub_total();
3275
        }
3276
3277
        $this->set_subtotal( $subtotal );
3278
        return $subtotal;
3279
    }
3280
3281
    /**
3282
	 * Recalculates the invoice discount total.
3283
	 *
3284
	 * @since 1.0.19
3285
	 * @return float The recalculated discount
3286
	 */
3287
	public function recalculate_total_discount() {
3288
        $discounts = $this->get_discounts();
3289
        $discount  = 0;
3290
3291
        foreach ( $discounts as $amount ) {
3292
            $discount += $amount;
3293
        }
3294
3295
        $this->set_total_discount( $discount );
3296
        return $discount;
3297
3298
    }
3299
3300
    /**
3301
	 * Recalculates the invoice tax total.
3302
	 *
3303
	 * @since 1.0.19
3304
	 * @return float The recalculated tax
3305
	 */
3306
	public function recalculate_total_tax() {
3307
        $taxes = $this->get_taxes();
3308
        $tax   = 0;
3309
3310
        foreach ( $taxes as $amount ) {
3311
            $tax += $amount;
3312
        }
3313
3314
        $this->set_total_tax( $tax );
3315
        return $tax;
3316
3317
    }
3318
3319
    /**
3320
	 * Recalculates the invoice fees total.
3321
	 *
3322
	 * @since 1.0.19
3323
	 * @return float The recalculated fee
3324
	 */
3325
	public function recalculate_total_fees() {
3326
		$fees = $this->get_fees();
3327
        $fee  = 0;
3328
3329
        foreach ( $fees as $amount ) {
3330
            $fee += $amount;
3331
        }
3332
3333
        $this->set_total_fees( $fee );
3334
        return $fee;
3335
    }
3336
3337
    /**
3338
	 * Recalculates the invoice total.
3339
	 *
3340
	 * @since 1.0.19
3341
     * @return float The invoice total
3342
	 */
3343
	public function recalculate_total() {
3344
        $this->recalculate_subtotal();
3345
        $this->recalculate_total_fees();
3346
        $this->recalculate_total_discount();
3347
        $this->recalculate_total_tax();
3348
		return $this->get_total();
3349
    }
3350
3351
    /**
3352
     * Convert this to an array.
3353
     */
3354
    public function array_convert() {
3355
        return $this->get_data();
3356
    }
3357
3358
    /**
3359
     * Adds a note to an invoice.
3360
     * 
3361
     * @param string $note The note being added.
3362
     * 
3363
     */
3364
    public function add_note( $note = '', $customer_type = false, $added_by_user = false, $system = false ) {
3365
3366
        // Bail if no note specified or this invoice is not yet saved.
3367
        if ( ! $note || $this->get_id() == 0 ) {
3368
            return false;
3369
        }
3370
        
3371
        if ( ( ( is_user_logged_in() && wpinv_current_user_can_manage_invoicing() ) || $added_by_user ) && !$system ) {
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: (is_user_logged_in() && ...d_by_user) && ! $system, Probably Intended Meaning: is_user_logged_in() && w...d_by_user && ! $system)
Loading history...
3372
            $user                 = get_user_by( 'id', get_current_user_id() );
3373
            $comment_author       = $user->display_name;
3374
            $comment_author_email = $user->user_email;
3375
        } else {
3376
            $comment_author       = 'System';
3377
            $comment_author_email = 'system@';
3378
            $comment_author_email .= isset( $_SERVER['HTTP_HOST'] ) ? str_replace( 'www.', '', $_SERVER['HTTP_HOST'] ) : 'noreply.com';
3379
            $comment_author_email = sanitize_email( $comment_author_email );
3380
        }
3381
3382
        do_action( 'wpinv_pre_insert_invoice_note', $this->get_id(), $note, $customer_type );
3383
3384
        $note_id = wp_insert_comment( wp_filter_comment( array(
3385
            'comment_post_ID'      => $this->get_id(),
3386
            'comment_content'      => $note,
3387
            'comment_agent'        => 'GetPaid',
3388
            'user_id'              => is_admin() ? get_current_user_id() : 0,
3389
            'comment_date'         => current_time( 'mysql' ),
3390
            'comment_date_gmt'     => current_time( 'mysql', 1 ),
3391
            'comment_approved'     => 1,
3392
            'comment_parent'       => 0,
3393
            'comment_author'       => $comment_author,
3394
            'comment_author_IP'    => wpinv_get_ip(),
3395
            'comment_author_url'   => '',
3396
            'comment_author_email' => $comment_author_email,
3397
            'comment_type'         => 'wpinv_note'
3398
        ) ) );
3399
3400
        do_action( 'wpinv_insert_payment_note', $note_id, $this->get_id(), $note );
3401
3402
        if ( $customer_type ) {
3403
            add_comment_meta( $note_id, '_wpi_customer_note', 1 );
0 ignored issues
show
Bug introduced by
$note_id of type false is incompatible with the type integer expected by parameter $comment_id of add_comment_meta(). ( Ignorable by Annotation )

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

3403
            add_comment_meta( /** @scrutinizer ignore-type */ $note_id, '_wpi_customer_note', 1 );
Loading history...
3404
            do_action( 'wpinv_new_customer_note', array( 'invoice_id' => $this->get_id(), 'user_note' => $note ) );
3405
        }
3406
3407
        return $note_id;
3408
    }
3409
3410
}
3411