Passed
Pull Request — master (#785)
by
unknown
04:48
created

WPInv_Item::set_has_variable_pricing()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
if ( ! defined( 'ABSPATH' ) ) {
3
	exit;
4
}
5
6
/**
7
 * Item Class
8
 *
9
 */
10
class WPInv_Item extends GetPaid_Data {
11
12
    /**
13
	 * Which data store to load.
14
	 *
15
	 * @var string
16
	 */
17
    protected $data_store_name = 'item';
18
19
    /**
20
	 * This is the name of this object type.
21
	 *
22
	 * @var string
23
	 */
24
	protected $object_type = 'item';
25
26
    /**
27
	 * Item Data array. This is the core item data exposed in APIs.
28
	 *
29
	 * @since 1.0.19
30
	 * @var array
31
	 */
32
	protected $data = array(
33
		'parent_id'            => 0,
34
		'status'               => 'draft',
35
		'version'              => '',
36
		'date_created'         => null,
37
        'date_modified'        => null,
38
        'name'                 => '',
39
        'description'          => '',
40
        'author'               => 1,
41
        'price'                => 0,
42
        'vat_rule'             => 'digital',
43
        'vat_class'            => '_standard',
44
        'type'                 => 'custom',
45
        'custom_id'            => null,
46
        'custom_name'          => null,
47
        'custom_singular_name' => null,
48
        'is_editable'          => 1,
49
        'is_dynamic_pricing'   => null,
50
        'minimum_price'        => null,
51
        'is_multi_price_mode'  => null,
52
        'has_variable_pricing' => null,
53
        'default_price_id'     => null,
54
        'variable_prices'      => null,
55
        'is_recurring'         => null,
56
        'recurring_period'     => null,
57
        'recurring_interval'   => null,
58
        'recurring_limit'      => null,
59
        'is_free_trial'        => null,
60
        'trial_period'         => null,
61
        'trial_interval'       => null,
62
    );
63
64
    /**
65
	 * Stores meta in cache for future reads.
66
	 *
67
	 * A group must be set to to enable caching.
68
	 *
69
	 * @var string
70
	 */
71
	protected $cache_group = 'getpaid_items';
72
73
    /**
74
     * Stores a reference to the original WP_Post object
75
     *
76
     * @var WP_Post
77
     */
78
    protected $post = null;
79
80
    /**
81
	 * Get the item if ID is passed, otherwise the item is new and empty.
82
	 *
83
	 * @param  int|object|WPInv_Item|WP_Post $item Item to read.
84
	 */
85
	public function __construct( $item = 0 ) {
86
		parent::__construct( $item );
87
88
		if ( ! empty( $item ) && is_numeric( $item ) && 'wpi_item' == get_post_type( $item ) ) {
89
			$this->set_id( $item );
90
		} elseif ( $item instanceof self ) {
91
			$this->set_id( $item->get_id() );
92
		} elseif ( ! empty( $item->ID ) ) {
93
			$this->set_id( $item->ID );
94
		} elseif ( is_scalar( $item ) && $item_id = self::get_item_id_by_field( $item, 'custom_id' ) ) {
95
			$this->set_id( $item_id );
96
		} elseif ( is_scalar( $item ) && $item_id = self::get_item_id_by_field( $item, 'name' ) ) {
97
			$this->set_id( $item_id );
98
		} else {
99
			$this->set_object_read( true );
100
		}
101
102
        // Load the datastore.
103
		$this->data_store = GetPaid_Data_Store::load( $this->data_store_name );
104
105
		if ( $this->get_id() > 0 ) {
106
            $this->post = get_post( $this->get_id() );
0 ignored issues
show
Documentation Bug introduced by
It seems like get_post($this->get_id()) can also be of type array. However, the property $post is declared as type WP_Post. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
107
            $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...
108
			$this->data_store->read( $this );
109
        }
110
	}
111
112
    /*
113
	|--------------------------------------------------------------------------
114
	| CRUD methods
115
	|--------------------------------------------------------------------------
116
	|
117
	| Methods which create, read, update and delete items from the database.
118
	|
119
    */
120
121
    /*
122
	|--------------------------------------------------------------------------
123
	| Getters
124
	|--------------------------------------------------------------------------
125
    */
126
127
    /**
128
	 * Get parent item ID.
129
	 *
130
	 * @since 1.0.19
131
	 * @param  string $context View or edit context.
132
	 * @return int
133
	 */
134
	public function get_parent_id( $context = 'view' ) {
135
		return (int) $this->get_prop( 'parent_id', $context );
136
    }
137
138
    /**
139
	 * Get item status.
140
	 *
141
	 * @since 1.0.19
142
	 * @param  string $context View or edit context.
143
	 * @return string
144
	 */
145
	public function get_status( $context = 'view' ) {
146
		return $this->get_prop( 'status', $context );
147
    }
148
149
    /**
150
	 * Get plugin version when the item was created.
151
	 *
152
	 * @since 1.0.19
153
	 * @param  string $context View or edit context.
154
	 * @return string
155
	 */
156
	public function get_version( $context = 'view' ) {
157
		return $this->get_prop( 'version', $context );
158
    }
159
160
    /**
161
	 * Get date when the item was created.
162
	 *
163
	 * @since 1.0.19
164
	 * @param  string $context View or edit context.
165
	 * @return string
166
	 */
167
	public function get_date_created( $context = 'view' ) {
168
		return $this->get_prop( 'date_created', $context );
169
    }
170
171
    /**
172
	 * Get GMT date when the item was created.
173
	 *
174
	 * @since 1.0.19
175
	 * @param  string $context View or edit context.
176
	 * @return string
177
	 */
178
	public function get_date_created_gmt( $context = 'view' ) {
179
        $date = $this->get_date_created( $context );
180
181
        if ( $date ) {
182
            $date = get_gmt_from_date( $date );
183
        }
184
		return $date;
185
    }
186
187
    /**
188
	 * Get date when the item was last modified.
189
	 *
190
	 * @since 1.0.19
191
	 * @param  string $context View or edit context.
192
	 * @return string
193
	 */
194
	public function get_date_modified( $context = 'view' ) {
195
		return $this->get_prop( 'date_modified', $context );
196
    }
197
198
    /**
199
	 * Get GMT date when the item was last modified.
200
	 *
201
	 * @since 1.0.19
202
	 * @param  string $context View or edit context.
203
	 * @return string
204
	 */
205
	public function get_date_modified_gmt( $context = 'view' ) {
206
        $date = $this->get_date_modified( $context );
207
208
        if ( $date ) {
209
            $date = get_gmt_from_date( $date );
210
        }
211
		return $date;
212
    }
213
214
    /**
215
	 * Get the item name.
216
	 *
217
	 * @since 1.0.19
218
	 * @param  string $context View or edit context.
219
	 * @return string
220
	 */
221
	public function get_name( $context = 'view' ) {
222
		return $this->get_prop( 'name', $context );
223
    }
224
225
    /**
226
	 * Alias of self::get_name().
227
	 *
228
	 * @since 1.0.19
229
	 * @param  string $context View or edit context.
230
	 * @return string
231
	 */
232
	public function get_title( $context = 'view' ) {
233
		return $this->get_name( $context );
234
    }
235
236
    /**
237
	 * Get the item description.
238
	 *
239
	 * @since 1.0.19
240
	 * @param  string $context View or edit context.
241
	 * @return string
242
	 */
243
	public function get_description( $context = 'view' ) {
244
		return $this->get_prop( 'description', $context );
245
    }
246
247
    /**
248
	 * Alias of self::get_description().
249
	 *
250
	 * @since 1.0.19
251
	 * @param  string $context View or edit context.
252
	 * @return string
253
	 */
254
	public function get_excerpt( $context = 'view' ) {
255
		return $this->get_description( $context );
256
    }
257
258
    /**
259
	 * Alias of self::get_description().
260
	 *
261
	 * @since 1.0.19
262
	 * @param  string $context View or edit context.
263
	 * @return string
264
	 */
265
	public function get_summary( $context = 'view' ) {
266
		return $this->get_description( $context );
267
    }
268
269
    /**
270
	 * Get the owner of the item.
271
	 *
272
	 * @since 1.0.19
273
	 * @param  string $context View or edit context.
274
	 * @return int
275
	 */
276
	public function get_author( $context = 'view' ) {
277
		return (int) $this->get_prop( 'author', $context );
278
	}
279
280
	/**
281
	 * Alias of self::get_author().
282
	 *
283
	 * @since 1.0.19
284
	 * @param  string $context View or edit context.
285
	 * @return int
286
	 */
287
	public function get_owner( $context = 'view' ) {
288
		return $this->get_author( $context );
289
    }
290
291
    /**
292
	 * Get the price of the item.
293
	 *
294
	 * @since 1.0.19
295
	 * @param  string $context View or edit context.
296
	 * @return float
297
	 */
298
	public function get_price( $context = 'view' ) {
299
        return wpinv_sanitize_amount( $this->get_prop( 'price', $context ) );
300
	}
301
302
	/**
303
	 * Get the inital price of the item.
304
	 *
305
	 * @since 1.0.19
306
	 * @param  string $context View or edit context.
307
	 * @return float
308
	 */
309
	public function get_initial_price( $context = 'view', $price_id = null ) {
310
        $price = 0;
311
312
        if ( null === $price_id ) {
313
            $price = (float) $this->get_price( $context );
314
315
            if ( $this->has_free_trial() ) {
316
                $price = 0;
317
            }
318
        } else {
319
            $prices = $this->get_variable_prices();
320
321
            if ( isset( $prices[ $price_id ] ) ) {
322
                $price = (float) $prices[ $price_id ]['amount'];
323
            }
324
        }
325
326
        return wpinv_sanitize_amount( apply_filters( 'wpinv_get_initial_item_price', $price, $this ) );
327
    }
328
329
    /**
330
	 * Returns a formated price.
331
	 *
332
	 * @since 1.0.19
333
	 * @param  string $context View or edit context.
334
	 * @return string
335
	 */
336
    public function get_the_price() {
337
        return wpinv_price( $this->get_price() );
338
	}
339
340
	/**
341
	 * Returns the formated initial price.
342
	 *
343
	 * @since 1.0.19
344
	 * @param  string $context View or edit context.
345
	 * @return string
346
	 */
347
    public function get_the_initial_price() {
348
        return wpinv_price( $this->get_initial_price() );
349
    }
350
351
    /**
352
	 * Get the VAT rule of the item.
353
	 *
354
	 * @since 1.0.19
355
	 * @param  string $context View or edit context.
356
	 * @return string
357
	 */
358
	public function get_vat_rule( $context = 'view' ) {
359
        return $this->get_prop( 'vat_rule', $context );
360
    }
361
362
    /**
363
	 * Get the VAT class of the item.
364
	 *
365
	 * @since 1.0.19
366
	 * @param  string $context View or edit context.
367
	 * @return string
368
	 */
369
	public function get_vat_class( $context = 'view' ) {
370
        return $this->get_prop( 'vat_class', $context );
371
    }
372
373
    /**
374
	 * Get the type of the item.
375
	 *
376
	 * @since 1.0.19
377
	 * @param  string $context View or edit context.
378
	 * @return string
379
	 */
380
	public function get_type( $context = 'view' ) {
381
        return $this->get_prop( 'type', $context );
382
    }
383
384
    /**
385
	 * Get the custom id of the item.
386
	 *
387
	 * @since 1.0.19
388
	 * @param  string $context View or edit context.
389
	 * @return string
390
	 */
391
	public function get_custom_id( $context = 'view' ) {
392
        return $this->get_prop( 'custom_id', $context );
393
    }
394
395
    /**
396
	 * Get the custom name of the item.
397
	 *
398
	 * @since 1.0.19
399
	 * @param  string $context View or edit context.
400
	 * @return string
401
	 */
402
	public function get_custom_name( $context = 'view' ) {
403
        return $this->get_prop( 'custom_name', $context );
404
    }
405
406
    /**
407
	 * Get the custom singular name of the item.
408
	 *
409
	 * @since 1.0.19
410
	 * @param  string $context View or edit context.
411
	 * @return string
412
	 */
413
	public function get_custom_singular_name( $context = 'view' ) {
414
        return $this->get_prop( 'custom_singular_name', $context );
415
    }
416
417
    /**
418
	 * Checks if an item is editable..
419
	 *
420
	 * @since 1.0.19
421
	 * @param  string $context View or edit context.
422
	 * @return int
423
	 */
424
	public function get_is_editable( $context = 'view' ) {
425
        return (int) $this->get_prop( 'is_editable', $context );
426
    }
427
428
    /**
429
	 * Alias of self::get_is_editable().
430
	 *
431
	 * @since 1.0.19
432
	 * @param  string $context View or edit context.
433
	 * @return int
434
	 */
435
	public function get_editable( $context = 'view' ) {
436
		return $this->get_is_editable( $context );
437
    }
438
439
    /**
440
	 * Checks if dynamic pricing is enabled.
441
	 *
442
	 * @since 1.0.19
443
	 * @param  string $context View or edit context.
444
	 * @return int
445
	 */
446
	public function get_is_dynamic_pricing( $context = 'view' ) {
447
        return (int) $this->get_prop( 'is_dynamic_pricing', $context );
448
    }
449
450
    /**
451
	 * Returns the minimum price if dynamic pricing is enabled.
452
	 *
453
	 * @since 1.0.19
454
	 * @param  string $context View or edit context.
455
	 * @return float
456
	 */
457
	public function get_minimum_price( $context = 'view' ) {
458
        return wpinv_sanitize_amount( $this->get_prop( 'minimum_price', $context ) );
459
    }
460
461
    /**
462
     * Checks if multi price mode is enabled.
463
     *
464
     * @since 1.0.19
465
     * @param  string $context View or edit context.
466
     * @return int
467
     */
468
    public function get_is_multi_price_mode( $context = 'view' ) {
469
        return (bool) $this->get_prop( 'is_multi_price_mode', $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return (bool)$this->get_..._price_mode', $context) returns the type boolean which is incompatible with the documented return type integer.
Loading history...
470
    }
471
472
    /**
473
     * Checks if multi price mode is enabled.
474
     *
475
     * @since 2.8.9
476
     * @param  string $context View or edit context.
477
     * @return int
478
     */
479
    public function is_multi_price_mode() {
480
        return $this->get_is_multi_price_mode();
481
    }
482
483
    /**
484
     * Checks if variable pricing is enabled.
485
     *
486
     * @since 2.8.9
487
     * @param  string $context View or edit context.
488
     * @return int
489
     */
490
    public function get_has_variable_pricing( $context = 'view' ) {
491
        return (bool) $this->get_prop( 'has_variable_pricing', $context );
0 ignored issues
show
Bug Best Practice introduced by
The expression return (bool)$this->get_...ble_pricing', $context) returns the type boolean which is incompatible with the documented return type integer.
Loading history...
492
    }
493
494
    /**
495
     * Checks if variable pricing is enabled.
496
     *
497
     * @since 2.8.9
498
     * @param  string $context View or edit context.
499
     * @return int
500
     */
501
    public function has_variable_pricing() {
502
        return $this->get_has_variable_pricing( 'view' );
503
    }
504
505
    /**
506
     * Returns the default price ID for variable pricing, or the first
507
     * price if none is set
508
     *
509
     * @since 2.8.9
510
     * @return int              The Price ID to select by default
511
     */
512
    public function get_default_price_id( $context = 'view' ) {
513
        if ( ! $this->has_variable_pricing() ) {
514
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type integer.
Loading history...
515
        }
516
517
        $prices = $this->get_variable_prices();
518
519
        $default_price_id = (int) $this->get_prop( 'default_price_id', $context );
520
521
        if ( '' === $default_price_id || ! isset( $prices[ $default_price_id ] ) ) {
522
            $default_price_id = current( array_keys( $prices ) );
523
        }
524
525
        return  absint( $default_price_id );
526
    }
527
528
    /**
529
     * Retrieve the variable prices
530
     *
531
    * @since 2.8.9
532
     * @return array List of the variable prices
533
     */
534
    public function get_variable_prices() {
535
        $prices = array();
536
537
        if ( true === $this->has_variable_pricing() ) {
0 ignored issues
show
introduced by
The condition true === $this->has_variable_pricing() is always false.
Loading history...
538
            $prices = $this->get_prop( 'variable_prices', 'view' );
539
        }
540
541
        return $prices;
542
    }
543
544
    /**
545
	 * Checks if this is a recurring item.
546
	 *
547
	 * @since 1.0.19
548
	 * @param  string $context View or edit context.
549
	 * @return int
550
	 */
551
	public function get_is_recurring( $context = 'view' ) {
552
        return (int) $this->get_prop( 'is_recurring', $context );
553
	}
554
555
	/**
556
	 * Get the recurring price of the item.
557
	 *
558
	 * @since 1.0.19
559
	 * @param  string $context View or edit context.
560
	 * @return float
561
	 */
562
	public function get_recurring_price( $context = 'view' ) {
563
		$price = $this->get_price( $context );
564
        return wpinv_sanitize_amount( apply_filters( 'wpinv_get_recurring_item_price', $price, $this->ID ) );
565
	}
566
567
	/**
568
	 * Get the formatted recurring price of the item.
569
	 *
570
	 * @since 1.0.19
571
	 * @param  string $context View or edit context.
572
	 * @return string
573
	 */
574
    public function get_the_recurring_price() {
575
        return wpinv_price( $this->get_recurring_price() );
576
	}
577
578
	/**
579
	 * Get the first renewal date (in timestamps) of the item.
580
	 *
581
	 * @since 1.0.19
582
	 * @return int
583
	 */
584
	public function get_first_renewal_date() {
585
586
		$periods = array(
587
			'D' => 'days',
588
			'W' => 'weeks',
589
			'M' => 'months',
590
			'Y' => 'years',
591
		);
592
593
		$period   = $this->get_recurring_period();
594
		$interval = $this->get_recurring_interval();
595
596
		if ( $this->has_free_trial() ) {
597
			$period   = $this->get_trial_period();
598
			$interval = $this->get_trial_interval();
599
		}
600
601
		$period       = $periods[ $period ];
602
		$interval     = empty( $interval ) ? 1 : $interval;
603
		$next_renewal = strtotime( "+$interval $period", current_time( 'timestamp' ) );
604
        return apply_filters( 'wpinv_get_first_renewal_date', $next_renewal, $this );
605
    }
606
607
    /**
608
	 * Get the recurring period.
609
	 *
610
	 * @since 1.0.19
611
	 * @param  bool $full Return abbreviation or in full.
612
	 * @return string
613
	 */
614
	public function get_recurring_period( $full = false ) {
615
        $period = $this->get_prop( 'recurring_period', 'view' );
616
617
        if ( $full && ! is_bool( $full ) ) {
0 ignored issues
show
introduced by
The condition is_bool($full) is always true.
Loading history...
618
            $full = false;
619
        }
620
621
        return getpaid_sanitize_recurring_period( $period, $full );
622
    }
623
624
    /**
625
	 * Get the recurring interval.
626
	 *
627
	 * @since 1.0.19
628
	 * @param  string $context View or edit context.
629
	 * @return int
630
	 */
631
	public function get_recurring_interval( $context = 'view' ) {
632
		$interval = absint( $this->get_prop( 'recurring_interval', $context ) );
633
		return max( 1, $interval );
634
    }
635
636
    /**
637
	 * Get the recurring limit.
638
	 *
639
	 * @since 1.0.19
640
	 * @param  string $context View or edit context.
641
	 * @return int
642
	 */
643
	public function get_recurring_limit( $context = 'view' ) {
644
        return (int) $this->get_prop( 'recurring_limit', $context );
645
    }
646
647
    /**
648
	 * Checks if we have a free trial.
649
	 *
650
	 * @since 1.0.19
651
	 * @param  string $context View or edit context.
652
	 * @return int
653
	 */
654
	public function get_is_free_trial( $context = 'view' ) {
655
        return (int) $this->get_prop( 'is_free_trial', $context );
656
    }
657
658
    /**
659
	 * Alias for self::get_is_free_trial().
660
	 *
661
	 * @since 1.0.19
662
	 * @param  string $context View or edit context.
663
	 * @return int
664
	 */
665
	public function get_free_trial( $context = 'view' ) {
666
        return $this->get_is_free_trial( $context );
667
    }
668
669
    /**
670
	 * Get the trial period.
671
	 *
672
	 * @since 1.0.19
673
	 * @param  bool $full Return abbreviation or in full.
674
	 * @return string
675
	 */
676
	public function get_trial_period( $full = false ) {
677
        $period = $this->get_prop( 'trial_period', 'view' );
678
679
        if ( $full && ! is_bool( $full ) ) {
0 ignored issues
show
introduced by
The condition is_bool($full) is always true.
Loading history...
680
            $full = false;
681
        }
682
683
        return getpaid_sanitize_recurring_period( $period, $full );
684
    }
685
686
    /**
687
	 * Get the trial interval.
688
	 *
689
	 * @since 1.0.19
690
	 * @param  string $context View or edit context.
691
	 * @return int
692
	 */
693
	public function get_trial_interval( $context = 'view' ) {
694
        return (int) $this->get_prop( 'trial_interval', $context );
695
	}
696
697
	/**
698
	 * Get the item's edit url.
699
	 *
700
	 * @since 1.0.19
701
	 * @return string
702
	 */
703
	public function get_edit_url() {
704
        return get_edit_post_link( $this->get_id(), 'edit' );
705
	}
706
707
	/**
708
	 * Given an item's name/custom id, it returns its id.
709
	 *
710
	 *
711
	 * @static
712
	 * @param string $value The item name or custom id.
713
	 * @param string $field Either name or custom_id.
714
	 * @param string $type in case you need to search for a given type.
715
	 * @since 1.0.15
716
	 * @return int
717
	 */
718
	public static function get_item_id_by_field( $value, $field = 'custom_id', $type = '' ) {
719
720
		// Trim the value.
721
		$value = sanitize_text_field( $value );
722
		if ( empty( $value ) ) {
723
			return 0;
724
		}
725
726
        // Valid fields.
727
        $fields = array( 'custom_id', 'name', 'slug' );
728
729
		// Ensure a field has been passed.
730
		if ( empty( $field ) || ! in_array( $field, $fields ) ) {
731
			return 0;
732
		}
733
734
		if ( $field == 'name' ) {
735
			$field = 'slug';
736
		}
737
738
		// Maybe retrieve from the cache.
739
		$item_id = wp_cache_get( $value, "getpaid_{$type}_item_{$field}s_to_item_ids" );
740
		if ( ! empty( $item_id ) ) {
741
			return $item_id;
742
		}
743
744
		// Fetch from the db.
745
		$items = array();
746
		if ( $field == 'slug' ) {
747
			$items = get_posts(
748
				array(
749
					'post_type'      => 'wpi_item',
750
					'name'           => $value,
751
					'posts_per_page' => 1,
752
					'post_status'    => 'any',
753
				)
754
			);
755
		}
756
757
		if ( $field == 'custom_id' ) {
758
			$items = get_posts(
759
				array(
760
					'post_type'      => 'wpi_item',
761
					'posts_per_page' => 1,
762
					'post_status'    => 'any',
763
					'meta_query'     => array(
764
						array(
765
							'key'   => '_wpinv_type',
766
                			'value' => $type,
767
						),
768
						array(
769
							'key'   => '_wpinv_custom_id',
770
                			'value' => $value,
771
						),
772
					),
773
				)
774
			);
775
		}
776
777
		if ( empty( $items ) ) {
778
			return 0;
779
		}
780
781
		// Update the cache with our data
782
		wp_cache_set( $value, $items[0]->ID, "getpaid_{$type}_item_{$field}s_to_item_ids" );
783
784
		return $items[0]->ID;
785
    }
786
787
    /**
788
     * Margic method for retrieving a property.
789
     */
790
    public function __get( $key ) {
791
792
        // Check if we have a helper method for that.
793
        if ( method_exists( $this, 'get_' . $key ) ) {
794
            return call_user_func( array( $this, 'get_' . $key ) );
795
        }
796
797
        // Check if the key is in the associated $post object.
798
        if ( ! empty( $this->post ) && isset( $this->post->$key ) ) {
799
            return $this->post->$key;
800
        }
801
802
        return $this->get_prop( $key );
803
    }
804
805
    /*
806
	|--------------------------------------------------------------------------
807
	| Setters
808
	|--------------------------------------------------------------------------
809
	|
810
	| Functions for setting item data. These should not update anything in the
811
	| database itself and should only change what is stored in the class
812
	| object.
813
    */
814
815
    /**
816
	 * Set parent order ID.
817
	 *
818
	 * @since 1.0.19
819
	 */
820
	public function set_parent_id( $value ) {
821
		if ( $value && ( $value === $this->get_id() || ! get_post( $value ) ) ) {
822
			return;
823
		}
824
		$this->set_prop( 'parent_id', absint( $value ) );
825
	}
826
827
    /**
828
	 * Sets item status.
829
	 *
830
	 * @since 1.0.19
831
	 * @param  string $status New status.
832
	 * @return array details of change.
833
	 */
834
	public function set_status( $status ) {
835
        $old_status = $this->get_status();
836
837
        $this->set_prop( 'status', $status );
838
839
		return array(
840
			'from' => $old_status,
841
			'to'   => $status,
842
		);
843
    }
844
845
    /**
846
	 * Set plugin version when the item was created.
847
	 *
848
	 * @since 1.0.19
849
	 */
850
	public function set_version( $value ) {
851
		$this->set_prop( 'version', $value );
852
    }
853
854
    /**
855
	 * Set date when the item was created.
856
	 *
857
	 * @since 1.0.19
858
	 * @param string $value Value to set.
859
     * @return bool Whether or not the date was set.
860
	 */
861
	public function set_date_created( $value ) {
862
        $date = strtotime( $value );
863
864
        if ( $date ) {
865
            $this->set_prop( 'date_created', date( 'Y-m-d H:i:s', $date ) );
866
            return true;
867
        }
868
869
        return false;
870
    }
871
872
    /**
873
	 * Set date when the item was last modified.
874
	 *
875
	 * @since 1.0.19
876
	 * @param string $value Value to set.
877
     * @return bool Whether or not the date was set.
878
	 */
879
	public function set_date_modified( $value ) {
880
        $date = strtotime( $value );
881
882
        if ( $date ) {
883
            $this->set_prop( 'date_modified', date( 'Y-m-d H:i:s', $date ) );
884
            return true;
885
        }
886
887
        return false;
888
    }
889
890
    /**
891
	 * Set the item name.
892
	 *
893
	 * @since 1.0.19
894
	 * @param  string $value New name.
895
	 */
896
	public function set_name( $value ) {
897
        $name = sanitize_text_field( $value );
898
		$this->set_prop( 'name', $name );
899
    }
900
901
    /**
902
	 * Alias of self::set_name().
903
	 *
904
	 * @since 1.0.19
905
	 * @param  string $value New name.
906
	 */
907
	public function set_title( $value ) {
908
		$this->set_name( $value );
909
    }
910
911
    /**
912
	 * Set the item description.
913
	 *
914
	 * @since 1.0.19
915
	 * @param  string $value New description.
916
	 */
917
	public function set_description( $value ) {
918
		$description = wp_kses_post( wp_unslash( $value ) );
0 ignored issues
show
Bug introduced by
It seems like wp_unslash($value) can also be of type array; however, parameter $data of wp_kses_post() 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

918
		$description = wp_kses_post( /** @scrutinizer ignore-type */ wp_unslash( $value ) );
Loading history...
919
		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...
920
    }
921
922
    /**
923
	 * Alias of self::set_description().
924
	 *
925
	 * @since 1.0.19
926
	 * @param  string $value New description.
927
	 */
928
	public function set_excerpt( $value ) {
929
		$this->set_description( $value );
930
    }
931
932
    /**
933
	 * Alias of self::set_description().
934
	 *
935
	 * @since 1.0.19
936
	 * @param  string $value New description.
937
	 */
938
	public function set_summary( $value ) {
939
		$this->set_description( $value );
940
    }
941
942
    /**
943
	 * Set the owner of the item.
944
	 *
945
	 * @since 1.0.19
946
	 * @param  int $value New author.
947
	 */
948
	public function set_author( $value ) {
949
		$this->set_prop( 'author', (int) $value );
950
	}
951
952
	/**
953
	 * Alias of self::set_author().
954
	 *
955
	 * @since 1.0.19
956
	 * @param  int $value New author.
957
	 */
958
	public function set_owner( $value ) {
959
		$this->set_author( $value );
960
    }
961
962
    /**
963
	 * Set the price of the item.
964
	 *
965
	 * @since 1.0.19
966
	 * @param  float $value New price.
967
	 */
968
	public function set_price( $value ) {
969
        $this->set_prop( 'price', (float) wpinv_sanitize_amount( $value ) );
970
    }
971
972
    /**
973
	 * Set the VAT rule of the item.
974
	 *
975
	 * @since 1.0.19
976
	 * @param  string $value new rule.
977
	 */
978
	public function set_vat_rule( $value ) {
979
        $this->set_prop( 'vat_rule', $value );
980
    }
981
982
    /**
983
	 * Set the VAT class of the item.
984
	 *
985
	 * @since 1.0.19
986
	 * @param  string $value new class.
987
	 */
988
	public function set_vat_class( $value ) {
989
        $this->set_prop( 'vat_class', $value );
990
    }
991
992
    /**
993
	 * Set the type of the item.
994
	 *
995
	 * @since 1.0.19
996
	 * @param  string $value new item type.
997
	 * @return string
998
	 */
999
	public function set_type( $value ) {
1000
1001
        if ( empty( $value ) ) {
1002
            $value = 'custom';
1003
        }
1004
1005
        $this->set_prop( 'type', $value );
1006
    }
1007
1008
    /**
1009
	 * Set the custom id of the item.
1010
	 *
1011
	 * @since 1.0.19
1012
	 * @param  string $value new custom id.
1013
	 */
1014
	public function set_custom_id( $value ) {
1015
        $this->set_prop( 'custom_id', $value );
1016
    }
1017
1018
    /**
1019
	 * Set the custom name of the item.
1020
	 *
1021
	 * @since 1.0.19
1022
	 * @param  string $value new custom name.
1023
	 */
1024
	public function set_custom_name( $value ) {
1025
        $this->set_prop( 'custom_name', $value );
1026
    }
1027
1028
    /**
1029
	 * Set the custom singular name of the item.
1030
	 *
1031
	 * @since 1.0.19
1032
	 * @param  string $value new custom singular name.
1033
	 */
1034
	public function set_custom_singular_name( $value ) {
1035
        $this->set_prop( 'custom_singular_name', $value );
1036
    }
1037
1038
    /**
1039
	 * Sets if an item is editable..
1040
	 *
1041
	 * @since 1.0.19
1042
	 * @param  int|bool $value whether or not the item is editable.
1043
	 */
1044
	public function set_is_editable( $value ) {
1045
		$this->set_prop( 'is_editable', (int) $value );
1046
    }
1047
1048
    /**
1049
	 * Sets if dynamic pricing is enabled.
1050
	 *
1051
	 * @since 1.0.19
1052
	 * @param  int|bool $value whether or not dynamic pricing is allowed.
1053
	 */
1054
	public function set_is_dynamic_pricing( $value ) {
1055
        $this->set_prop( 'is_dynamic_pricing', (int) $value );
1056
    }
1057
1058
    /**
1059
	 * Sets the minimum price if dynamic pricing is enabled.
1060
	 *
1061
	 * @since 1.0.19
1062
	 * @param  float $value minimum price.
1063
	 */
1064
	public function set_minimum_price( $value ) {
1065
        $this->set_prop( 'minimum_price', (float) wpinv_sanitize_amount( $value ) );
1066
    }
1067
1068
    /**
1069
	 * Sets if this item has multi price mode.
1070
	 *
1071
	 * @since 1.0.19
1072
	 * @param  int|bool $value whether or not dynamic pricing is allowed.
1073
	 */
1074
	public function set_is_multi_price_mode( $value ) {
1075
        $this->set_prop( 'is_multi_price_mode', (int) $value );
1076
    }
1077
1078
    /**
1079
	 * Sets if this item has variable pricing.
1080
	 *
1081
	 * @since 1.0.19
1082
	 * @param  int|bool $value whether or not dynamic pricing is allowed.
1083
	 */
1084
	public function set_has_variable_pricing( $value ) {
1085
        $this->set_prop( 'has_variable_pricing', (int) $value );
1086
    }
1087
1088
    /**
1089
	 * Set the default price ID.
1090
	 *
1091
	 * @since 1.0.19
1092
	 * @param  int $value default price ID.
1093
	 */
1094
	public function set_default_price_id( $value ) {
1095
        return $this->set_prop( 'default_price_id', (int) $value );
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->set_prop('default_price_id', (int)$value) 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...
1096
    }
1097
1098
    /**
1099
	 * Set the variable prices.
1100
	 *
1101
	 * @since 1.0.19
1102
	 * @param  int $prices variable prices.
1103
	 */
1104
	public function set_variable_prices( $prices ) {
1105
        if ( ! is_array( $prices ) ) {
0 ignored issues
show
introduced by
The condition is_array($prices) is always false.
Loading history...
1106
            $prices = array();
1107
        }
1108
1109
        foreach ( $prices as $id => $price ) {
1110
            if ( empty( $price['amount'] ) && empty( $price['name'] ) ) {
1111
                unset( $prices[ $id ] );
1112
                continue;
1113
            } elseif ( empty( $price['amount'] ) ) {
1114
                $price['amount'] = 0;
1115
            }
1116
1117
            $prices[ $id ]['amount'] = getpaid_standardize_amount( $price['amount'] );
1118
        }
1119
1120
        return $this->set_prop( 'variable_prices', $prices );
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->set_prop('variable_prices', $prices) 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...
1121
    }
1122
1123
    /**
1124
	 * Sets if this is a recurring item.
1125
	 *
1126
	 * @since 1.0.19
1127
	 * @param  int|bool $value whether or not dynamic pricing is allowed.
1128
	 */
1129
	public function set_is_recurring( $value ) {
1130
        $this->set_prop( 'is_recurring', (int) $value );
1131
    }
1132
1133
    /**
1134
	 * Set the recurring period.
1135
	 *
1136
	 * @since 1.0.19
1137
	 * @param  string $value new period.
1138
	 */
1139
	public function set_recurring_period( $value ) {
1140
        $this->set_prop( 'recurring_period', $value );
1141
    }
1142
1143
    /**
1144
	 * Set the recurring interval.
1145
	 *
1146
	 * @since 1.0.19
1147
	 * @param  int $value recurring interval.
1148
	 */
1149
	public function set_recurring_interval( $value ) {
1150
        return $this->set_prop( 'recurring_interval', (int) $value );
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->set_prop('recurri...interval', (int)$value) 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...
1151
    }
1152
1153
    /**
1154
	 * Get the recurring limit.
1155
	 * @since 1.0.19
1156
	 * @param  int $value The recurring limit.
1157
	 * @return int
1158
	 */
1159
	public function set_recurring_limit( $value ) {
1160
        $this->set_prop( 'recurring_limit', (int) $value );
1161
    }
1162
1163
    /**
1164
	 * Checks if we have a free trial.
1165
	 *
1166
	 * @since 1.0.19
1167
	 * @param  int|bool $value whether or not it has a free trial.
1168
	 */
1169
	public function set_is_free_trial( $value ) {
1170
        $this->set_prop( 'is_free_trial', (int) $value );
1171
    }
1172
1173
    /**
1174
	 * Set the trial period.
1175
	 *
1176
	 * @since 1.0.19
1177
	 * @param  string $value trial period.
1178
	 */
1179
	public function set_trial_period( $value ) {
1180
        $this->set_prop( 'trial_period', $value );
1181
    }
1182
1183
    /**
1184
	 * Set the trial interval.
1185
	 *
1186
	 * @since 1.0.19
1187
	 * @param  int $value trial interval.
1188
	 */
1189
	public function set_trial_interval( $value ) {
1190
        $this->set_prop( 'trial_interval', $value );
1191
    }
1192
1193
    /**
1194
     * Create an item. For backwards compatibilty.
1195
     *
1196
     * @deprecated
1197
	 * @return int item id
1198
     */
1199
    public function create( $data = array() ) {
1200
1201
		// Set the properties.
1202
		if ( is_array( $data ) ) {
1203
			$this->set_props( $data );
1204
		}
1205
1206
		// Save the item.
1207
		return $this->save();
1208
    }
1209
1210
    /**
1211
     * Updates an item. For backwards compatibilty.
1212
     *
1213
     * @deprecated
1214
	 * @return int item id
1215
     */
1216
    public function update( $data = array() ) {
1217
        return $this->create( $data );
0 ignored issues
show
Deprecated Code introduced by
The function WPInv_Item::create() has been deprecated. ( Ignorable by Annotation )

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

1217
        return /** @scrutinizer ignore-deprecated */ $this->create( $data );
Loading history...
1218
    }
1219
1220
    /*
1221
	|--------------------------------------------------------------------------
1222
	| Conditionals
1223
	|--------------------------------------------------------------------------
1224
	|
1225
	| Checks if a condition is true or false.
1226
	|
1227
	*/
1228
1229
    /**
1230
	 * Checks whether the item has enabled dynamic pricing.
1231
	 *
1232
	 * @since 1.0.19
1233
	 * @return bool
1234
	 */
1235
	public function user_can_set_their_price() {
1236
        return (bool) $this->get_is_dynamic_pricing();
1237
	}
1238
1239
	/**
1240
	 * Checks whether the item is recurring.
1241
	 *
1242
	 * @since 1.0.19
1243
	 * @return bool
1244
	 */
1245
	public function is_recurring() {
1246
        return (bool) $this->get_is_recurring();
1247
    }
1248
1249
    /**
1250
	 * Checks whether the item has a free trial.
1251
	 *
1252
	 * @since 1.0.19
1253
	 * @return bool
1254
	 */
1255
    public function has_free_trial() {
1256
        $has_trial = $this->is_recurring() && (bool) $this->get_free_trial() ? true : false;
1257
        return (bool) apply_filters( 'wpinv_item_has_free_trial', $has_trial, $this->ID, $this );
1258
    }
1259
1260
    /**
1261
	 * Checks whether the item is free.
1262
	 *
1263
	 * @since 1.0.19
1264
	 * @return bool
1265
	 */
1266
    public function is_free() {
1267
        $is_free   = $this->get_price() == 0;
1268
        return (bool) apply_filters( 'wpinv_is_free_item', $is_free, $this->ID, $this );
1269
    }
1270
1271
    /**
1272
	 * Checks the item status against a passed in status.
1273
	 *
1274
	 * @param array|string $status Status to check.
1275
	 * @return bool
1276
	 */
1277
	public function has_status( $status ) {
1278
		$has_status = ( is_array( $status ) && in_array( $this->get_status(), $status, true ) ) || $this->get_status() === $status;
1279
		return (bool) apply_filters( 'getpaid_item_has_status', $has_status, $this, $status );
1280
    }
1281
1282
    /**
1283
	 * Checks the item type against a passed in types.
1284
	 *
1285
	 * @param array|string $type Type to check.
1286
	 * @return bool
1287
	 */
1288
	public function is_type( $type ) {
1289
		$is_type = ( is_array( $type ) && in_array( $this->get_type(), $type, true ) ) || $this->get_type() === $type;
1290
		return (bool) apply_filters( 'getpaid_item_is_type', $is_type, $this, $type );
1291
	}
1292
1293
    /**
1294
	 * Checks whether the item is editable.
1295
	 *
1296
	 * @since 1.0.19
1297
	 * @return bool
1298
	 */
1299
    public function is_editable() {
1300
        $is_editable = $this->get_is_editable();
1301
        return (bool) apply_filters( 'wpinv_item_is_editable', $is_editable, $this->ID, $this );
1302
	}
1303
1304
	/**
1305
	 * Returns an array of cart fees.
1306
	 */
1307
	public function get_fees() {
1308
        return array();
1309
    }
1310
1311
    /**
1312
	 * Checks whether the item is purchasable.
1313
	 *
1314
	 * @since 1.0.19
1315
	 * @return bool
1316
	 */
1317
    public function can_purchase() {
1318
        $can_purchase = $this->exists();
1319
1320
        if ( ! current_user_can( 'edit_post', $this->ID ) && $this->post_status != 'publish' ) {
0 ignored issues
show
Bug Best Practice introduced by
The property post_status does not exist on WPInv_Item. Since you implemented __get, consider adding a @property annotation.
Loading history...
1321
            $can_purchase = false;
1322
        }
1323
1324
        return (bool) apply_filters( 'wpinv_can_purchase_item', $can_purchase, $this );
1325
    }
1326
1327
    /**
1328
	 * Checks whether the item supports dynamic pricing.
1329
	 *
1330
	 * @since 1.0.19
1331
	 * @return bool
1332
	 */
1333
    public function supports_dynamic_pricing() {
1334
        return (bool) apply_filters( 'wpinv_item_supports_dynamic_pricing', true, $this );
1335
    }
1336
}
1337