Passed
Push — master ( 32735f...12790d )
by Brian
04:58 queued 10s
created

WPInv_Discount::is_valid_for_user()   C

Complexity

Conditions 16
Paths 36

Size

Total Lines 49
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 16
eloc 28
c 1
b 0
f 0
nc 36
nop 1
dl 0
loc 49
rs 5.5666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Contains Discount calculation class
4
 *
5
 * @since   1.0.15
6
 */
7
8
defined( 'ABSPATH' ) || exit;
9
10
/**
11
 * Discount class.
12
 * 
13
 * @since 1.0.15
14
 * @property string $code
15
 * @property string $description
16
 * @property string $type
17
 * @property string $type_name
18
 * @property string $expiration
19
 * @property string $start
20
 * @property string $status
21
 * @property string $date_modified
22
 * @property string $date_created
23
 * @property array $items
24
 * @property array $excluded_items
25
 * @property int $uses
26
 * @property int $max_uses
27
 * @property bool $is_recurring
28
 * @property bool $is_single_use
29
 * @property float $min_total
30
 * @property float $max_total
31
 * @property float $amount
32
 *
33
 */
34
class WPInv_Discount {
35
	
36
	/**
37
	 * Discount ID.
38
	 *
39
	 * @since 1.0.15
40
	 * @var integer|null
41
	 */
42
	public $ID = null;
43
44
	/**
45
	 * Old discount status.
46
	 *
47
	 * @since 1.0.15
48
	 * @var string
49
	 */
50
	public $old_status = 'draft';
51
	
52
	/**
53
	 * Data array.
54
	 *
55
	 * @since 1.0.15
56
	 * @var array
57
	 */
58
	protected $data = array();
59
60
	/**
61
	 * Discount constructor.
62
	 *
63
	 * @param int|array|string|WPInv_Discount $discount discount data, object, ID or code.
64
	 * @since 1.0.15
65
	 */
66
	public function __construct( $discount = array() ) {
67
        
68
        // If the discount is an instance of this class...
69
		if ( $discount instanceof WPInv_Discount ) {
70
			$this->init( $discount->data );
71
			return;
72
        }
73
        
74
        // If the discount is an array of discount details...
75
        if ( is_array( $discount ) ) {
76
			$this->init( $discount );
77
			return;
78
		}
79
		
80
		// Try fetching the discount by its post id.
81
		$data = false;
82
		
83
		if ( ! empty( $discount ) && is_numeric( $discount ) ) {
84
			$discount = absint( $discount );
85
			$data = self::get_data_by( 'id', $discount );
86
		}
87
88
		if ( is_array( $data ) ) {
89
			$this->init( $data );
90
			return;
91
		}
92
		
93
		// Try fetching the discount by its discount code.
94
		if ( ! empty( $discount ) && is_string( $discount ) ) {
95
			$data = self::get_data_by( 'discount_code', $discount );
96
		}
97
98
		if ( is_array( $data ) ) {
99
			$this->init( $data );
100
			return;
101
		} 
102
		
103
		// If we are here then the discount does not exist.
104
		$this->init( array() );
105
	}
106
	
107
	/**
108
	 * Sets up object properties
109
	 *
110
	 * @since 1.0.15
111
	 * @param array $data An array containing the discount's data
112
	 */
113
	public function init( $data ) {
114
		$data       	  = self::sanitize_discount_data( $data );
115
		$this->data 	  = $data;
116
		$this->old_status = $data['status'];
117
		$this->ID   	  = $data['ID'];
118
	}
119
	
120
	/**
121
	 * Fetch a discount from the db/cache
122
	 *
123
	 *
124
	 * @static
125
	 * @param string $field The field to query against: 'ID', 'discount_code'
126
	 * @param string|int $value The field value
127
	 * @since 1.0.15
128
	 * @return array|bool array of discount details on success. False otherwise.
129
	 */
130
	public static function get_data_by( $field, $value ) {
131
132
		if ( 'id' == strtolower( $field ) ) {
133
			// Make sure the value is numeric to avoid casting objects, for example,
134
			// to int 1.
135
			if ( ! is_numeric( $value ) )
136
				return false;
137
			$value = intval( $value );
138
			if ( $value < 1 )
139
				return false;
140
		}
141
142
		if ( ! $value || ! is_string( $field ) ) {
143
			return false;
144
		}
145
		
146
		$field = trim( $field );
147
148
		// prepare query args
149
		switch ( strtolower( $field ) ) {
150
			case 'id':
151
				$discount_id = $value;
152
				$args		 = array( 'include' => array( $value ) );
153
				break;
154
			case 'discount_code':
155
			case 'code':
156
				$value       = trim( $value );
157
				$discount_id = wp_cache_get( $value, 'WPInv_Discount_Codes' );
158
				$args		 = array( 'meta_key' => '_wpi_discount_code', 'meta_value' => $value );
159
				break;
160
			case 'name':
161
				$discount_id = 0;
162
				$args		 = array( 'name' => trim( $value ) );
163
				break;
164
			default:
165
				$args		 = apply_filters( "wpinv_discount_get_data_by_{$field}_args", null, $value );
166
				if ( ! is_array( $args ) ) {
167
					return apply_filters( "wpinv_discount_get_data_by_$field", false, $value );
168
				}
169
170
		}
171
172
		// Check if there is a cached value.
173
		if ( ! empty( $discount_id ) && $discount = wp_cache_get( (int) $discount_id, 'WPInv_Discounts' ) ) {
174
			return $discount;
175
		}
176
177
		$args = array_merge(
178
			$args,
179
			array(
180
				'post_type'      => 'wpi_discount',
181
				'posts_per_page' => 1,
182
				'post_status'    => array( 'publish', 'pending', 'draft', 'expired' )
183
			)
184
		);
185
186
		$discount = get_posts( $args );
187
				
188
		if( empty( $discount ) ) {
189
			return false;
190
		}
191
192
		$discount = $discount[0];
193
		
194
		// Prepare the return data.
195
		$return = array(
196
            'ID'                          => $discount->ID,
197
            'code'                        => get_post_meta( $discount->ID, '_wpi_discount_code', true ),
198
            'amount'                      => get_post_meta( $discount->ID, '_wpi_discount_amount', true ),
199
            'date_created'                => $discount->post_date,
200
			'date_modified'               => $discount->post_modified,
201
			'status'               		  => $discount->post_status,
202
			'start'                  	  => get_post_meta( $discount->ID, '_wpi_discount_start', true ),
203
            'expiration'                  => get_post_meta( $discount->ID, '_wpi_discount_expiration', true ),
204
            'type'               		  => get_post_meta( $discount->ID, '_wpi_discount_type', true ),
205
            'description'                 => $discount->post_excerpt,
206
            'uses'                 		  => get_post_meta( $discount->ID, '_wpi_discount_uses', true ),
207
            'is_single_use'               => get_post_meta( $discount->ID, '_wpi_discount_is_single_use', true ),
208
            'items'              	      => get_post_meta( $discount->ID, '_wpi_discount_items', true ),
209
            'excluded_items'              => get_post_meta( $discount->ID, '_wpi_discount_excluded_items', true ),
210
            'max_uses'                    => get_post_meta( $discount->ID, '_wpi_discount_max_uses', true ),
211
            'is_recurring'                => get_post_meta( $discount->ID, '_wpi_discount_is_recurring', true ),
212
            'min_total'                   => get_post_meta( $discount->ID, '_wpi_discount_min_total', true ),
213
            'max_total'                   => get_post_meta( $discount->ID, '_wpi_discount_max_total', true ),
214
        );
215
		
216
		$return = self::sanitize_discount_data( $return );
217
		$return = apply_filters( 'wpinv_discount_properties', $return );
218
219
		// Update the cache with our data
220
		wp_cache_add( $discount->ID, $return, 'WPInv_Discounts' );
221
		wp_cache_add( $return['code'], $discount->ID, 'WPInv_Discount_Codes' );
222
223
		return $return;
224
	}
225
	
226
	/**
227
	 * Sanitizes discount data
228
	 *
229
	 * @static
230
	 * @since 1.0.15
231
	 * @access public
232
	 *
233
	 * @return array the sanitized data
234
	 */
235
	public static function sanitize_discount_data( $data ) {
236
		
237
		$allowed_discount_types = array_keys( wpinv_get_discount_types() );
238
		
239
		$return = array(
240
            'ID'                          => null,
241
            'code'                        => '',
242
            'amount'                      => 0,
243
            'date_created'                => current_time('mysql'),
244
            'date_modified'               => current_time('mysql'),
245
			'expiration'                  => null,
246
			'start'                  	  => current_time('mysql'),
247
			'status'                  	  => 'draft',
248
            'type'               		  => 'percent',
249
            'description'                 => '',
250
            'uses'                        => 0,
251
            'is_single_use'               => false,
252
            'items'              		  => array(),
253
            'excluded_items'              => array(),
254
            'max_uses'                    => 0,
255
            'is_recurring'                => false,
256
            'min_total'                   => '',
257
			'max_total'              	  => '',
258
		);
259
		
260
				
261
		// Arrays only please.
262
		if ( ! is_array( $data ) ) {
263
            return $return;
264
        }
265
266
		// If an id is provided, ensure it is a valid discount.
267
        if ( ! empty( $data['ID'] ) && ( ! is_numeric( $data['ID'] ) || 'wpi_discount' !== get_post_type( $data['ID'] ) ) ) {
268
            return $return;
269
		}
270
271
        $return = array_merge( $return, $data );
272
273
        // Sanitize some keys.
274
        $return['amount']         = wpinv_sanitize_amount( $return['amount'] );
275
		$return['is_single_use']  = (bool) $return['is_single_use'];
276
		$return['is_recurring']   = (bool) $return['is_recurring'];
277
		$return['uses']	          = (int) $return['uses'];
278
		$return['max_uses']	      = (int) $return['max_uses'];
279
		$return['min_total'] 	  = wpinv_sanitize_amount( $return['min_total'] );
280
        $return['max_total'] 	  = wpinv_sanitize_amount( $return['max_total'] );
281
282
		// Trim all values.
283
		$return = wpinv_clean( $return );
284
		
285
		// Ensure the discount type is supported.
286
        if ( ! in_array( $return['type'], $allowed_discount_types, true ) ) {
287
            $return['type'] = 'percent';
288
		}
289
		$return['type_name'] = wpinv_get_discount_type_name( $return['type'] );
290
		
291
		// Do not offer more than a 100% discount.
292
		if ( $return['type'] == 'percent' && (float) $return['amount'] > 100 ) {
293
			$return['amount'] = 100;
294
		}
295
296
		// Format dates.
297
		foreach( wpinv_parse_list( 'date_created date_modified expiration start') as $prop ) {
298
			if( ! empty( $return[$prop] ) ) {
299
				$return[$prop]      = date_i18n( 'Y-m-d H:i:s', strtotime( $return[$prop] ) );
300
			}
301
		}
302
303
		// Formart items.
304
		foreach( array( 'excluded_items', 'items' ) as $prop ) {
305
306
			if( ! empty( $return[$prop] ) ) {
307
				// Ensure that the property is an array of non-empty integers.
308
				$return[$prop]      = array_filter( array_map( 'intval', wpinv_parse_list( $return[$prop] ) ) );
309
			} else {
310
				$return[$prop]      = array();
311
			}
312
313
		}
314
		
315
		return apply_filters( 'wpinv_sanitize_discount_data', $return, $data );
316
	}
317
	
318
	/**
319
	 * Magic method for checking the existence of a certain custom field.
320
	 *
321
	 * @since 1.0.15
322
	 * @access public
323
	 *
324
	 * @return bool Whether the given discount field is set.
325
	 */
326
	public function __isset( $key ){
327
		return isset( $this->data[$key] ) || method_exists( $this, "get_$key");
328
	}
329
	
330
	/**
331
	 * Magic method for accessing discount properties.
332
	 *
333
	 * @since 1.0.15
334
	 * @access public
335
	 *
336
	 * @param string $key Discount data to retrieve
337
	 * @return mixed Value of the given discount property (if set).
338
	 */
339
	public function __get( $key ) {
340
		return $this->get( $key );
341
	}
342
343
	/**
344
	 * Magic method for accessing discount properties.
345
	 *
346
	 * @since 1.0.15
347
	 * @access public
348
	 *
349
	 * @param string $key Discount data to retrieve
350
	 * @return mixed Value of the given discount property (if set).
351
	 */
352
	public function get( $key ) {
353
		
354
		if ( $key == 'id' ) {
355
			$key = 'ID';
356
		}
357
		
358
		if( method_exists( $this, "get_$key") ) {
359
			$value 	= call_user_func( array( $this, "get_$key" ) );
360
		} else if( isset( $this->data[$key] ) ) {
361
			$value 	= $this->data[$key];
362
		} else {
363
			$value = null;
364
		}
365
		
366
		/**
367
		 * Filters a discount's property value.
368
		 * 
369
		 * The dynamic part ($key) can be any property name e.g items, code, type etc.
370
		 * 
371
		 * @param mixed          $value    The property's value.
372
		 * @param int            $ID       The discount's ID.
373
		 * @param WPInv_Discount $discount The discount object.
374
		 * @param string         $code     The discount's discount code.
375
		 * @param array          $data     The discount's data array.
376
		 */
377
		return apply_filters( "wpinv_get_discount_{$key}", $value, $this->ID, $this, $this->data['code'], $this->data );
378
379
	}
380
	
381
	/**
382
	 * Magic method for setting discount fields.
383
	 *
384
	 * This method does not update custom fields in the database.
385
	 *
386
	 * @since 1.0.15
387
	 * @access public
388
	 *
389
	 */
390
	public function __set( $key, $value ) {
391
		
392
		if ( 'id' == strtolower( $key ) ) {
393
			
394
			$this->ID = $value;
395
			$this->data['ID'] = $value;
396
			return;
397
			
398
		}
399
		
400
		/**
401
		 * Filters a discount's property value before it is saved.
402
		 * 
403
		 * 
404
		 * 
405
		 * The dynamic part ($key) can be any property name e.g items, code, type etc.
406
		 * 
407
		 * @param mixed          $value    The property's value.
408
		 * @param int            $ID       The discount's ID.
409
		 * @param WPInv_Discount $discount The discount object.
410
		 * @param string         $code     The discount's discount code.
411
		 * @param array          $data     The discount's data array.
412
		 */
413
		$value = apply_filters( "wpinv_set_discount_{$key}", $value, $this->ID, $this, $this->code, $this->data );
414
415
		if( method_exists( $this, "set_$key") ) {
416
			call_user_func( array( $this, "set_$key" ), $value );
417
		} else {
418
			$this->data[$key] = $value;
419
		}
420
		
421
	}
422
	
423
	/**
424
	 * Saves (or updates) a discount to the database
425
	 *
426
	 * @since 1.0.15
427
	 * @access public
428
	 * @return bool
429
	 *
430
	 */
431
	public function save(){
432
		
433
		$data = self::sanitize_discount_data( $this->data );
434
435
		// Should we create a new post?
436
		if( ! $data[ 'ID' ] ) {
437
438
			$id = wp_insert_post( array(
439
				'post_status'           => $data['status'],
440
				'post_type'             => 'wpi_discount',
441
				'post_excerpt'          => $data['description'],
442
			) );
443
444
			if( empty( $id ) ) {
445
				return false;
446
			}
447
448
			$data[ 'ID' ] = (int) $id;
449
			$this->ID = $data[ 'ID' ];
450
			$this->data['ID'] = $data[ 'ID' ];
451
452
		} else {
453
			$this->update_status( $data['status'] );
454
		}
455
456
		$meta = apply_filters( 'wpinv_update_discount', $data, $this->ID, $this );
457
458
		do_action( 'wpinv_pre_update_discount', $meta, $this->ID, $this );
459
460
		foreach( wpinv_parse_list( 'ID date_created date_modified status description type_name' ) as $prop ) {
461
			if ( isset( $meta[$prop] ) ) {
462
				unset( $meta[$prop] );
463
			}
464
		}
465
466
		if( isset( $meta['uses'] ) && empty( $meta['uses'] ) ) {
467
			unset( $meta['uses'] );
468
		}
469
470
		// Save the metadata.
471
		foreach( $meta as $key => $value ) {
472
			update_post_meta( $this->ID, "_wpi_discount_$key", $value );
473
		}
474
475
		$this->refresh();
476
477
		do_action( 'wpinv_post_update_discount', $meta, $this->ID );
478
479
		return true;		
480
	}
481
482
	/**
483
	 * Refreshes the discount data.
484
	 *
485
	 * @since 1.0.15
486
	 * @access public
487
	 * @return bool
488
	 *
489
	 */
490
	public function refresh(){
491
492
		// Empty the cache for this discount.
493
		wp_cache_delete( $this->ID, 'WPInv_Discounts' );
494
		wp_cache_delete( $this->get( 'code' ), 'WPInv_Discount_Codes' );
495
496
		$data = self::get_data_by( 'id', $this->ID );
497
		if( is_array( $data ) ) {
498
			$this->init( $data );
499
		} else {
500
			$this->init( array() );
501
		}
502
503
	}
504
505
	/**
506
	 * Saves (or updates) a discount to the database
507
	 *
508
	 * @since 1.0.15
509
	 * @access public
510
	 * @return bool
511
	 *
512
	 */
513
	public function update_status( $status = 'publish' ){
514
515
516
		if ( $this->exists() && $this->old_status != $status ) {
517
518
			do_action( 'wpinv_pre_update_discount_status', $this->ID, $this->old_status, $status );
519
        	$updated = wp_update_post( array( 'ID' => $this->ID, 'post_status' => $status ) );
520
			do_action( 'wpinv_post_update_discount_status', $this->ID, $this->old_status, $status );
521
522
			$this->refresh();
523
524
			return $updated !== 0;
525
			
526
		}
527
528
		return false;		
529
	}
530
	
531
	
532
	/**
533
	 * Checks whether a discount exists in the database or not
534
	 * 
535
	 * @since 1.0.15
536
	 */
537
	public function exists(){
538
		return ! empty( $this->ID );
539
	}
540
	
541
	// Boolean methods
542
	
543
	/**
544
	 * Checks the discount type.
545
	 * 
546
	 * 
547
	 * @param  string $type the discount type to check against
548
	 * @since 1.0.15
549
	 * @return bool
550
	 */
551
	public function is_type( $type ) {
552
		return $this->type == $type;
553
	}
554
	
555
	/**
556
	 * Checks whether the discount is published or not
557
	 * 
558
	 * @since 1.0.15
559
	 * @return bool
560
	 */
561
	public function is_active() {
562
		return $this->status == 'publish';
563
	}
564
	
565
	/**
566
	 * Checks whether the discount is has exided the usage limit or not
567
	 * 
568
	 * @since 1.0.15
569
	 * @return bool
570
	 */
571
	public function has_exceeded_limit() {
572
		if( empty( $this->max_uses ) || empty( $this->uses ) ) { 
573
			return false ;
574
		}
575
		
576
		$exceeded =  $this->uses >= $this->max_uses;
577
		return apply_filters( 'wpinv_is_discount_maxed_out', $exceeded, $this->ID, $this, $this->code );
578
	}
579
	
580
	/**
581
	 * Checks if the discount is expired
582
	 * 
583
	 * @since 1.0.15
584
	 * @return bool
585
	 */
586
	public function is_expired() {
587
		$expired = empty ( $this->expiration ) ? false : current_time( 'timestamp' ) > strtotime( $this->expiration );
588
		return apply_filters( 'wpinv_is_discount_expired', $expired, $this->ID, $this, $this->code );
589
	}
590
591
	/**
592
	 * Checks the discount start date.
593
	 * 
594
	 * @since 1.0.15
595
	 * @return bool
596
	 */
597
	public function has_started() {
598
		$started = empty ( $this->start ) ? true : current_time( 'timestamp' ) > strtotime( $this->start );
599
		return apply_filters( 'wpinv_is_discount_started', $started, $this->ID, $this, $this->code );		
600
	}
601
	
602
	/**
603
	 * Check if a discount is valid for a given item id.
604
	 *
605
	 * @param  int|int[]  $item_ids
606
	 * @since 1.0.15
607
	 * @return boolean
608
	 */
609
	public function is_valid_for_items( $item_ids ) {
610
		 
611
		$item_ids = array_map( 'intval',  wpinv_parse_list( $item_ids ) );
612
		$included = array_intersect( $item_ids, $this->items );
613
		$excluded = array_intersect( $item_ids, $this->excluded_items );
614
615
		if( ! empty( $this->excluded_items ) && ! empty( $excluded ) ) {
616
			return false;
617
		}
618
619
		if( ! empty( $this->items ) && empty( $included ) ) {
620
			return false;
621
		}
622
		return true;
623
	}
624
	
625
	/**
626
	 * Check if a discount is valid for the given amount
627
	 *
628
	 * @param  float  $amount The amount to check against
629
	 * @since 1.0.15
630
	 * @return boolean
631
	 */
632
	public function is_valid_for_amount( $amount ) {
633
		return $this->is_minimum_amount_met( $amount ) && $this->is_maximum_amount_met( $amount );
634
	}
635
636
	/**
637
	 * Checks if the minimum amount is met
638
	 *
639
	 * @param  float  $amount The amount to check against
640
	 * @since 1.0.15
641
	 * @return boolean
642
	 */
643
	public function is_minimum_amount_met( $amount ) {
644
		$amount = floatval( $amount );
645
		$min_met= ! ( $this->min_total > 0 && $amount < $this->min_total );
646
		return apply_filters( 'wpinv_is_discount_min_met', $min_met, $this->ID, $this, $this->code, $amount );
647
	}
648
649
	/**
650
	 * Checks if the maximum amount is met
651
	 *
652
	 * @param  float  $amount The amount to check against
653
	 * @since 1.0.15
654
	 * @return boolean
655
	 */
656
	public function is_maximum_amount_met( $amount ) {
657
		$amount = floatval( $amount );
658
		$max_met= ! ( $this->max_total > 0 && $amount > $this->max_total );
659
		return apply_filters( 'wpinv_is_discount_max_met', $max_met, $this->ID, $this, $this->code, $amount );
660
	}
661
662
	/**
663
	 * Check if a discount is valid for the given user
664
	 *
665
	 * @param  int|string  $user
666
	 * @since 1.0.15
667
	 * @return boolean
668
	 */
669
	public function is_valid_for_user( $user ) {
670
		global $wpi_checkout_id;
671
672
		if( empty( $user ) || empty( $this->is_single_use ) ) {
673
			return true;
674
		}
675
676
		$user_id = 0;
677
        if ( is_int( $user ) ) {
678
            $user_id = absint( $user );
679
        } else if ( is_email( $user ) && $user_data = get_user_by( 'email', $user ) ) {
680
            $user_id = $user_data->ID;
681
        } else if ( $user_data = get_user_by( 'login', $user ) ) {
682
            $user_id = $user_data->ID;
683
        } else if ( absint( $user ) > 0 ) {
684
            $user_id = absint( $user );
685
		}
686
687
		if ( empty( $user_id ) ) {
688
			return true;
689
		}
690
		
691
		// Get all payments with matching user id
692
        $payments = wpinv_get_invoices( array( 'user' => $user_id, 'limit' => false ) ); 
693
		$code     = strtolower( $this->code );
694
695
		foreach ( $payments as $payment ) {
696
697
			// Don't count discount used for current invoice checkout.
698
			if ( ! empty( $wpi_checkout_id ) && $wpi_checkout_id == $payment->ID ) {
699
				continue;
700
			}
701
			
702
			if ( $payment->has_status( array( 'wpi-cancelled', 'wpi-failed' ) ) ) {
703
				continue;
704
			}
705
706
			$discounts = $payment->get_discounts( true );
707
			if ( empty( $discounts ) ) {
708
				continue;
709
			}
710
711
			$discounts = array_map( 'strtolower', wpinv_parse_list( $discounts ) );
712
			if ( ! empty( $discounts ) && in_array( $code, $discounts ) ) {
713
				return false;
714
			}
715
		}
716
717
		return true;
718
	}
719
720
	/**
721
	 * Deletes the discount from the database
722
	 *
723
	 * @since 1.0.15
724
	 * @return boolean
725
	 */
726
	public function remove() {
727
728
		if ( empty( $this->ID ) ) {
729
			return true;
730
		}
731
732
		do_action( 'wpinv_pre_delete_discount', $this->ID, $this->data );
733
		wp_cache_delete( $this->ID, 'WPInv_Discounts' );
734
    	wp_delete_post( $this->ID, true );
735
		wp_cache_delete( $this->code, 'WPInv_Discount_Codes' );
736
    	do_action( 'wpinv_post_delete_discount', $this->ID, $this->data );
737
738
		$this->ID = null;
739
		$this->data['id'] = null;
740
		return true;
741
	}
742
743
	/**
744
	 * Increases a discount's usage.
745
	 *
746
	 * @since 1.0.15
747
	 * @param int $by The number of usages to increas by.
748
	 * @return int
749
	 */
750
	public function increase_usage( $by = 1 ) {
751
752
		$this->uses = $this->uses + $by;
753
754
		if( $this->uses  < 0 ) {
755
			$this->uses = 0;
756
			update_post_meta( $this->ID, "_wpi_discount_uses", 0 );
757
		}
758
759
		$this->save();
760
761
		if( $by > 0 ) {
762
			do_action( 'wpinv_discount_increase_use_count', $this->uses, $this->ID, $this->code, $by );
763
		} else {
764
			do_action( 'wpinv_discount_decrease_use_count', $this->uses, $this->ID, $this->code, absint( $by ) );
765
		}
766
		
767
		return $this->uses;
768
	}
769
770
	/**
771
	 * Retrieves discount data
772
	 *
773
	 * @since 1.0.15
774
	 * @return array
775
	 */
776
	public function get_data() {
777
		$return = array();
778
		foreach( array_keys( $this->data ) as $key ) {
779
			$return[ $key ] = $this->get( $key );
780
		}
781
		return $return;
782
	}
783
784
	/**
785
	 * Retrieves discount data as json
786
	 *
787
	 * @since 1.0.15
788
	 * @return string|false
789
	 */
790
	public function get_data_as_json() {
791
		return wp_json_encode( $this->get_data() );
792
	}
793
794
	/**
795
	 * Checks if a discount can only be used once per user.
796
	 *
797
	 * @since 1.0.15
798
	 * @return bool
799
	 */
800
	public function get_is_single_use() {
801
		return (bool) apply_filters( 'wpinv_is_discount_single_use', $this->data['is_single_use'], $this->ID, $this, $this->code );
802
	}
803
804
	/**
805
	 * Checks if a discount is recurring.
806
	 *
807
	 * @since 1.0.15
808
	 * @return bool
809
	 */
810
	public function get_is_recurring() {
811
		return (bool) apply_filters( 'wpinv_is_discount_recurring', $this->data['is_recurring'], $this->ID, $this->code, $this );
812
	}
813
814
	/**
815
	 * Returns a discount's included items.
816
	 *
817
	 * @since 1.0.15
818
	 * @return array
819
	 */
820
	public function get_items() {
821
		return wpinv_parse_list( apply_filters( 'wpinv_get_discount_item_reqs', $this->data['items'], $this->ID, $this, $this->code ) );
822
	}
823
824
	/**
825
	 * Returns a discount's discounted amount.
826
	 *
827
	 * @since 1.0.15
828
	 * @return float
829
	 */
830
	public function get_discounted_amount( $amount ) {
831
832
		if ( $this->type == 'flat' ) {
833
            $amount = $amount - $this->amount;
834
		} else {
835
            $amount = $amount - ( $amount * ( $this->amount / 100 ) );
836
		}
837
838
		if ( $amount < 0 ) {
839
			$amount = 0;
840
		}
841
842
		return apply_filters( 'wpinv_discounted_amount', $amount, $this->ID, $this, $this->code, $this->amount );
843
	}
844
	
845
}
846