Completed
Push — issues/611 ( 661115...758b1c )
by Ravinder
21:11
created

Give_Donate_Form   D

Complexity

Total Complexity 77

Size/Duplication

Total Lines 1064
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
dl 0
loc 1064
rs 4.9374
c 0
b 0
f 0
wmc 77
lcom 1
cbo 0

27 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
B setup_donation_form() 0 29 5
A __get() 0 14 2
B create() 0 36 2
A get_ID() 0 3 1
A get_name() 0 3 1
B get_price() 0 28 3
A get_minimum_price() 0 21 4
A get_prices() 0 19 2
A get_goal() 0 21 3
A is_single_price_mode() 0 20 3
A is_custom_price_mode() 0 20 2
A has_variable_prices() 0 18 2
A get_type() 0 15 3
A get_form_classes() 0 19 2
A get_form_wrap_classes() 0 20 4
A is_set_type_donation_form() 0 5 2
A is_multi_type_donation_form() 0 6 2
A get_sales() 0 20 4
A increase_sales() 0 16 2
A decrease_sales() 0 23 3
A get_earnings() 0 20 4
A increase_earnings() 0 16 2
A decrease_earnings() 0 22 3
B is_free() 0 18 7
A is_close_donation_form() 0 19 3
B update_meta() 0 30 5

How to fix   Complexity   

Complex Class

Complex classes like Give_Donate_Form often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Give_Donate_Form, and based on these observations, apply Extract Interface, too.

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 32 and the first side effect is on line 14.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * Donate Form
4
 *
5
 * @package     Give
6
 * @subpackage  Classes/Give_Donate_Form
7
 * @copyright   Copyright (c) 2015, WordImpress
8
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
9
 * @since       1.0
10
 */
11
12
// Exit if accessed directly.
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
/**
18
 * Give_Donate_Form Class.
19
 *
20
 * This class handles donation forms.
21
 *
22
 * @since 1.0
23
 *
24
 * @property $price
25
 * @property $minimum_price
26
 * @property $prices
27
 * @property $goal
28
 * @property $sales
29
 * @property $earnings
30
 * @property $post_type
31
 */
32
class Give_Donate_Form {
33
34
	/**
35
	 * The donation ID.
36
	 *
37
	 * @since  1.0
38
	 * @access public
39
	 *
40
	 * @var    int
41
	 */
42
	public $ID = 0;
43
44
	/**
45
	 * The donation price.
46
	 *
47
	 * @since  1.0
48
	 * @access private
49
	 *
50
	 * @var    float
51
	 */
52
	private $price;
53
54
	/**
55
	 * The minimum donation price.
56
	 *
57
	 * @since  1.3.6
58
	 * @access private
59
	 *
60
	 * @var    float
61
	 */
62
	private $minimum_price;
63
64
	/**
65
	 * The donation prices, if Price Levels are enabled.
66
	 *
67
	 * @since  1.0
68
	 * @access private
69
	 *
70
	 * @var    array
71
	 */
72
	private $prices;
73
74
	/**
75
	 * The donation goal.
76
	 *
77
	 * @since  1.0
78
	 * @access private
79
	 *
80
	 * @var    float
81
	 */
82
	private $goal;
83
84
	/**
85
	 * The form's sale count.
86
	 *
87
	 * @since  1.0
88
	 * @access private
89
	 *
90
	 * @var    int
91
	 */
92
	private $sales;
93
94
	/**
95
	 * The form's total earnings
96
	 *
97
	 * @since  1.0
98
	 * @access private
99
	 *
100
	 * @var    float
101
	 */
102
	private $earnings;
103
104
	/**
105
	 * Declare the default properties in WP_Post as we can't extend it
106
	 * Anything we've declared above has been removed.
107
	 */
108
109
	/**
110
	 * The post author
111
	 *
112
	 * @since  1.0
113
	 * @access public
114
	 *
115
	 * @var    int
116
	 */
117
	public $post_author = 0;
118
119
	/**
120
	 * The post date
121
	 *
122
	 * @since  1.0
123
	 * @access public
124
	 *
125
	 * @var    string
126
	 */
127
	public $post_date = '0000-00-00 00:00:00';
128
129
	/**
130
	 * The post GTM date
131
	 *
132
	 * @since  1.0
133
	 * @access public
134
	 *
135
	 * @var    string
136
	 */
137
	public $post_date_gmt = '0000-00-00 00:00:00';
138
139
	/**
140
	 * The post content
141
	 *
142
	 * @since  1.0
143
	 * @access public
144
	 *
145
	 * @var    string
146
	 */
147
	public $post_content = '';
148
149
	/**
150
	 * The post title
151
	 *
152
	 * @since  1.0
153
	 * @access public
154
	 *
155
	 * @var    string
156
	 */
157
	public $post_title = '';
158
159
	/**
160
	 * The post excerpt
161
	 *
162
	 * @since  1.0
163
	 * @access public
164
	 *
165
	 * @var    string
166
	 */
167
	public $post_excerpt = '';
168
169
	/**
170
	 * The post status
171
	 *
172
	 * @since  1.0
173
	 * @access public
174
	 *
175
	 * @var    string
176
	 */
177
	public $post_status = 'publish';
178
179
	/**
180
	 * The comment status
181
	 *
182
	 * @since  1.0
183
	 * @access public
184
	 *
185
	 * @var    string
186
	 */
187
	public $comment_status = 'open';
188
189
	/**
190
	 * The ping status
191
	 *
192
	 * @since  1.0
193
	 * @access public
194
	 *
195
	 * @var    string
196
	 */
197
	public $ping_status = 'open';
198
199
	/**
200
	 * The post password
201
	 *
202
	 * @since  1.0
203
	 * @access public
204
	 *
205
	 * @var    string
206
	 */
207
	public $post_password = '';
208
209
	/**
210
	 * The post name
211
	 *
212
	 * @since  1.0
213
	 * @access public
214
	 *
215
	 * @var    string
216
	 */
217
	public $post_name = '';
218
219
	/**
220
	 * Ping
221
	 *
222
	 * @since  1.0
223
	 * @access public
224
	 *
225
	 * @var    string
226
	 */
227
	public $to_ping = '';
228
229
	/**
230
	 * Pinged
231
	 *
232
	 * @since  1.0
233
	 * @access public
234
	 *
235
	 * @var    string
236
	 */
237
	public $pinged = '';
238
239
	/**
240
	 * The post modified date
241
	 *
242
	 * @since  1.0
243
	 * @access public
244
	 *
245
	 * @var    string
246
	 */
247
	public $post_modified = '0000-00-00 00:00:00';
248
249
	/**
250
	 * The post modified GTM date
251
	 *
252
	 * @since  1.0
253
	 * @access public
254
	 *
255
	 * @var    string
256
	 */
257
	public $post_modified_gmt = '0000-00-00 00:00:00';
258
259
	/**
260
	 * The post filtered content
261
	 *
262
	 * @since  1.0
263
	 * @access public
264
	 *
265
	 * @var    string
266
	 */
267
	public $post_content_filtered = '';
268
269
	/**
270
	 * The post parent
271
	 *
272
	 * @since  1.0
273
	 * @access public
274
	 *
275
	 * @var    int
276
	 */
277
	public $post_parent = 0;
278
279
	/**
280
	 * The post GUID
281
	 *
282
	 * @since  1.0
283
	 * @access public
284
	 *
285
	 * @var    string
286
	 */
287
	public $guid = '';
288
289
	/**
290
	 * The menu order
291
	 *
292
	 * @since  1.0
293
	 * @access public
294
	 *
295
	 * @var    int
296
	 */
297
	public $menu_order = 0;
298
299
	/**
300
	 * The mime type0
301
	 *
302
	 * @since  1.0
303
	 * @access public
304
	 *
305
	 * @var    string
306
	 */
307
	public $post_mime_type = '';
308
309
	/**
310
	 * The comment count
311
	 *
312
	 * @since  1.0
313
	 * @access public
314
	 *
315
	 * @var    int
316
	 */
317
	public $comment_count = 0;
318
319
	/**
320
	 * Filtered
321
	 *
322
	 * @since  1.0
323
	 * @access public
324
	 *
325
	 * @var    string
326
	 */
327
	public $filter;
328
329
	/**
330
	 * Class Constructor
331
	 *
332
	 * Set up the Give Donate Form Class.
333
	 *
334
	 * @since  1.0
335
	 * @access public
336
	 *
337
	 * @param  bool  $_id   Post id. Default is false.
338
	 * @param  array $_args Arguments passed.
339
	 */
340
	public function __construct( $_id = false, $_args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $_args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
341
342
		$donation_form = WP_Post::get_instance( $_id );
343
344
		return $this->setup_donation_form( $donation_form );
0 ignored issues
show
Bug introduced by
Constructors do not have meaningful return values, anything that is returned from here is discarded. Are you sure this is correct?
Loading history...
345
	}
346
347
	/**
348
	 * Given the donation form data, let's set the variables
349
	 *
350
	 * @since  1.5
351
	 * @access private
352
	 *
353
	 * @param  WP_Post $donation_form WP_Post Object for the donation form.
354
	 *
355
	 * @return bool                   If the setup was successful or not.
356
	 */
357
	private function setup_donation_form( $donation_form ) {
358
359
		if ( ! is_object( $donation_form ) ) {
360
			return false;
361
		}
362
363
		if ( ! is_a( $donation_form, 'WP_Post' ) ) {
364
			return false;
365
		}
366
367
		if ( 'give_forms' !== $donation_form->post_type ) {
368
			return false;
369
		}
370
371
		foreach ( $donation_form as $key => $value ) {
372
373
			switch ( $key ) {
374
375
				default:
0 ignored issues
show
Unused Code introduced by
default: $this->{$key} = $value; break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
376
					$this->$key = $value;
377
					break;
378
379
			}
380
381
		}
382
383
		return true;
384
385
	}
386
387
	/**
388
	 * Magic __get function to dispatch a call to retrieve a private property
389
	 *
390
	 * @since  1.0
391
	 * @access public
392
	 *
393
	 * @param  string $key
394
	 *
395
	 * @return mixed
396
	 */
397
	public function __get( $key ) {
398
399
		if ( method_exists( $this, 'get_' . $key ) ) {
400
401
			return call_user_func( array( $this, 'get_' . $key ) );
402
403
		} else {
404
405
			/* translators: %s: property key */
406
			return new WP_Error( 'give-form-invalid-property', sprintf( esc_html__( 'Can\'t get property %s.', 'give' ), $key ) );
407
408
		}
409
410
	}
411
412
	/**
413
	 * Creates a donation form
414
	 *
415
	 * @since  1.5
416
	 * @access public
417
	 *
418
	 * @param  array $data Array of attributes for a donation form.
419
	 *
420
	 * @return bool|int    False if data isn't passed and class not instantiated for creation, or New Form ID.
421
	 */
422
	public function create( $data = array() ) {
423
424
		if ( $this->id != 0 ) {
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<Give_Donate_Form>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
425
			return false;
426
		}
427
428
		$defaults = array(
429
			'post_type'   => 'give_forms',
430
			'post_status' => 'draft',
431
			'post_title'  => __( 'New Donation Form', 'give' ),
432
		);
433
434
		$args = wp_parse_args( $data, $defaults );
435
436
		/**
437
		 * Fired before a donation form is created
438
		 *
439
		 * @param array $args The post object arguments used for creation.
440
		 */
441
		do_action( 'give_form_pre_create', $args );
442
443
		$id = wp_insert_post( $args, true );
444
445
		$donation_form = WP_Post::get_instance( $id );
446
447
		/**
448
		 * Fired after a donation form is created
449
		 *
450
		 * @param int   $id   The post ID of the created item.
451
		 * @param array $args The post object arguments used for creation.
452
		 */
453
		do_action( 'give_form_post_create', $id, $args );
454
455
		return $this->setup_donation_form( $donation_form );
456
457
	}
458
459
	/**
460
	 * Retrieve the ID
461
	 *
462
	 * @since  1.0
463
	 * @access public
464
	 *
465
	 * @return int    Donation form ID.
466
	 */
467
	public function get_ID() {
468
		return $this->ID;
469
	}
470
471
	/**
472
	 * Retrieve the donation form name
473
	 *
474
	 * @since  1.5
475
	 * @access public
476
	 *
477
	 * @return string Donation form name.
478
	 */
479
	public function get_name() {
480
		return get_the_title( $this->ID );
481
	}
482
483
	/**
484
	 * Retrieve the price
485
	 *
486
	 * @since  1.0
487
	 * @access public
488
	 *
489
	 * @return float  Price.
490
	 */
491
	public function get_price() {
492
493
		if ( ! isset( $this->price ) ) {
494
495
			$this->price = get_post_meta( $this->ID, '_give_set_price', true );
496
497
			if ( $this->price ) {
498
499
				$this->price = give_sanitize_amount( $this->price );
500
501
			} else {
502
503
				$this->price = 0;
504
505
			}
506
507
		}
508
509
		/**
510
		 * Override the donation form set price.
511
		 *
512
		 * @since 1.0
513
		 *
514
		 * @param string     $price The donation form price.
515
		 * @param string|int $id    The form ID.
516
		 */
517
		return apply_filters( 'give_get_set_price', $this->price, $this->ID );
518
	}
519
520
	/**
521
	 * Retrieve the minimum price.
522
	 *
523
	 * @since  1.3.6
524
	 * @access public
525
	 *
526
	 * @return float  Minimum price.
527
	 */
528
	public function get_minimum_price() {
529
530
		if ( ! isset( $this->minimum_price ) ) {
531
532
			$allow_custom_amount = get_post_meta( $this->ID, '_give_custom_amount', true );
533
			$this->minimum_price = get_post_meta( $this->ID, '_give_custom_amount_minimum', true );
534
535
			if ( give_is_setting_enabled( $allow_custom_amount ) && $this->minimum_price ) {
536
537
				$this->minimum_price = give_sanitize_amount( $this->minimum_price );
538
539
			} else {
540
541
				$this->minimum_price = 0;
542
543
			}
544
545
		}
546
547
		return apply_filters( 'give_get_set_minimum_price', $this->minimum_price, $this->ID );
548
	}
549
550
	/**
551
	 * Retrieve the variable prices
552
	 *
553
	 * @since  1.0
554
	 * @access public
555
	 *
556
	 * @return array  Variable prices.
557
	 */
558
	public function get_prices() {
559
560
		if ( ! isset( $this->prices ) ) {
561
562
			$this->prices = get_post_meta( $this->ID, '_give_donation_levels', true );
563
564
		}
565
566
		/**
567
		 * Override multi-level prices
568
		 *
569
		 * @since 1.0
570
		 *
571
		 * @param array      $prices The array of mulit-level prices.
572
		 * @param int|string $ID     The ID of the form.
573
		 */
574
		return apply_filters( 'give_get_donation_levels', $this->prices, $this->ID );
575
576
	}
577
578
	/**
579
	 * Retrieve the goal
580
	 *
581
	 * @since  1.0
582
	 * @access public
583
	 *
584
	 * @return float  Goal.
585
	 */
586
	public function get_goal() {
587
588
		if ( ! isset( $this->goal ) ) {
589
590
			$this->goal = get_post_meta( $this->ID, '_give_set_goal', true );
591
592
			if ( $this->goal ) {
593
594
				$this->goal = give_sanitize_amount( $this->goal );
595
596
			} else {
597
598
				$this->goal = 0;
599
600
			}
601
602
		}
603
604
		return apply_filters( 'give_get_set_goal', $this->goal, $this->ID );
605
606
	}
607
608
	/**
609
	 * Determine if single price mode is enabled or disabled
610
	 *
611
	 * @since  1.0
612
	 * @access public
613
	 *
614
	 * @return bool
615
	 */
616
	public function is_single_price_mode() {
617
618
		$option = get_post_meta( $this->ID, '_give_price_option', true );
619
		$ret    = 0;
620
621
		if ( empty( $option ) || $option === 'set' ) {
622
			$ret = 1;
623
		}
624
625
		/**
626
		 * Override the price mode for a donation when checking if is in single price mode.
627
		 *
628
		 * @since 1.0
629
		 *
630
		 * @param bool       $ret Is donation form in single price mode?
631
		 * @param int|string $ID The ID of the donation form.
632
		 */
633
		return (bool) apply_filters( 'give_single_price_option_mode', $ret, $this->ID );
634
635
	}
636
637
	/**
638
	 * Determine if custom price mode is enabled or disabled
639
	 *
640
	 * @since  1.6
641
	 * @access public
642
	 *
643
	 * @return bool
644
	 */
645
	public function is_custom_price_mode() {
646
647
		$option = get_post_meta( $this->ID, '_give_custom_amount', true );
648
		$ret    = 0;
649
650
		if ( give_is_setting_enabled( $option ) ) {
651
			$ret = 1;
652
		}
653
654
		/**
655
		 * Override the price mode for a donation when checking if is in custom price mode.
656
		 *
657
		 * @since 1.6
658
		 *
659
		 * @param bool       $ret Is donation form in custom price mode?
660
		 * @param int|string $ID  The ID of the donation form.
661
		 */
662
		return (bool) apply_filters( 'give_custom_price_option_mode', $ret, $this->ID );
663
664
	}
665
666
	/**
667
	 * Has Variable Prices
668
	 *
669
	 * Determine if the donation form has variable prices enabled
670
	 *
671
	 * @since  1.0
672
	 * @access public
673
	 *
674
	 * @return bool
675
	 */
676
	public function has_variable_prices() {
677
678
		$option = get_post_meta( $this->ID, '_give_price_option', true );
679
		$ret    = 0;
680
681
		if ( $option === 'multi' ) {
682
			$ret = 1;
683
		}
684
685
		/**
686
		 * Filter: Override whether the donation form has variables prices.
687
		 *
688
		 * @param bool       $ret Does donation form have variable prices?
689
		 * @param int|string $ID  The ID of the donation form.
690
		 */
691
		return (bool) apply_filters( 'give_has_variable_prices', $ret, $this->ID );
692
693
	}
694
695
	/**
696
	 * Retrieve the donation form type, set or multi-level
697
	 *
698
	 * @since  1.5
699
	 * @access public
700
	 *
701
	 * @return string Type of donation form, either 'set' or 'multi'.
702
	 */
703
	public function get_type() {
704
705
		if ( ! isset( $this->type ) ) {
706
707
			$this->type = get_post_meta( $this->ID, '_give_price_option', true );
0 ignored issues
show
Bug introduced by
The property type does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
708
709
			if ( empty( $this->type ) ) {
710
				$this->type = 'set';
711
			}
712
713
		}
714
715
		return apply_filters( 'give_get_form_type', $this->type, $this->ID );
716
717
	}
718
719
	/**
720
	 * Get form tag classes.
721
	 *
722
	 * Provides the classes for the donation <form> html tag and filters for customization.
723
	 *
724
	 * @since  1.6
725
	 * @access public
726
	 *
727
	 * @param  $args
728
	 *
729
	 * @return string
730
	 */
731
	public function get_form_classes( $args ) {
732
733
		$float_labels_option = give_is_float_labels_enabled( $args )
734
			? 'float-labels-enabled'
735
			: '';
736
737
		$form_classes_array = apply_filters( 'give_form_classes', array(
738
			'give-form',
739
			'give-form-' . $this->ID,
740
			'give-form-type-' . $this->get_type(),
741
			$float_labels_option,
742
		), $this->ID, $args );
743
744
		// Remove empty class names.
745
		$form_classes_array = array_filter( $form_classes_array );
746
747
		return implode( ' ', $form_classes_array );
748
749
	}
750
751
	/**
752
	 * Get form wrap Classes.
753
	 *
754
	 * Provides the classes for the donation form div wrapper and filters for customization.
755
	 *
756
	 * @access public
757
	 *
758
	 * @param  $args
759
	 *
760
	 * @return string
761
	 */
762
	public function get_form_wrap_classes( $args ) {
763
764
		$display_option = ( isset( $args['display_style'] ) && ! empty( $args['display_style'] ) )
765
			? $args['display_style']
766
			: get_post_meta( $this->ID, '_give_payment_display', true );
767
768
		// If admin want to show only button for form then user inbuilt modal functionality.
769
		if( 'button' === $display_option ) {
770
			$display_option = 'modal give-display-button-only';
771
		}
772
773
		$form_wrap_classes_array = apply_filters( 'give_form_wrap_classes', array(
774
			'give-form-wrap',
775
			'give-display-' . $display_option,
776
		), $this->ID, $args );
777
778
779
		return implode( ' ', $form_wrap_classes_array );
780
781
	}
782
783
	/**
784
	 * Get if form type set or not.
785
	 *
786
	 * @since  1.6
787
	 * @access public
788
	 *
789
	 * @return bool
790
	 */
791
	public function is_set_type_donation_form() {
792
		$form_type = $this->get_type();
793
794
		return ( 'set' === $form_type ? true : false );
795
	}
796
797
	/**
798
	 * Get if form type multi or not.
799
	 *
800
	 * @since  1.6
801
	 * @access public
802
	 *
803
	 * @return bool True if form type is 'multi' and false otherwise.
804
	 */
805
	public function is_multi_type_donation_form() {
806
		$form_type = $this->get_type();
807
808
		return ( 'multi' === $form_type ? true : false );
809
810
	}
811
812
	/**
813
	 * Retrieve the sale count for the donation form
814
	 *
815
	 * @since  1.0
816
	 * @access public
817
	 *
818
	 * @return int    Donation form sale count.
819
	 */
820
	public function get_sales() {
821
822
		if ( ! isset( $this->sales ) ) {
823
824
			if ( '' == get_post_meta( $this->ID, '_give_form_sales', true ) ) {
825
				add_post_meta( $this->ID, '_give_form_sales', 0 );
826
			} // End if
827
828
			$this->sales = get_post_meta( $this->ID, '_give_form_sales', true );
829
830
			if ( $this->sales < 0 ) {
831
				// Never let sales be less than zero
832
				$this->sales = 0;
833
			}
834
835
		}
836
837
		return $this->sales;
838
839
	}
840
841
	/**
842
	 * Increment the sale count by one
843
	 *
844
	 * @since  1.0
845
	 * @access public
846
	 *
847
	 * @param  int $quantity The quantity to increase the donations by. Default is 1.
848
	 *
849
	 * @return int|false     New number of total sales.
850
	 */
851
	public function increase_sales( $quantity = 1 ) {
852
853
		$sales       = give_get_form_sales_stats( $this->ID );
854
		$quantity    = absint( $quantity );
855
		$total_sales = $sales + $quantity;
856
857
		if ( $this->update_meta( '_give_form_sales', $total_sales ) ) {
858
859
			$this->sales = $total_sales;
860
861
			return $this->sales;
862
863
		}
864
865
		return false;
866
	}
867
868
	/**
869
	 * Decrement the sale count by one
870
	 *
871
	 * @since  1.0
872
	 * @access public
873
	 *
874
	 * @param  int $quantity The quantity to decrease by. Default is 1.
875
	 *
876
	 * @return int|false     New number of total sales.
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|double|false?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
877
	 */
878
	public function decrease_sales( $quantity = 1 ) {
879
880
		$sales = give_get_form_sales_stats( $this->ID );
881
882
		// Only decrease if not already zero
883
		if ( $sales > 0 ) {
884
885
			$quantity    = absint( $quantity );
886
			$total_sales = $sales - $quantity;
887
888
			if ( $this->update_meta( '_give_form_sales', $total_sales ) ) {
889
890
				$this->sales = $sales;
891
892
				return $sales;
893
894
			}
895
896
		}
897
898
		return false;
899
900
	}
901
902
	/**
903
	 * Retrieve the total earnings for the form
904
	 *
905
	 * @since  1.0
906
	 * @access public
907
	 *
908
	 * @return float  Donation form total earnings.
909
	 */
910
	public function get_earnings() {
911
912
		if ( ! isset( $this->earnings ) ) {
913
914
			if ( '' == get_post_meta( $this->ID, '_give_form_earnings', true ) ) {
915
				add_post_meta( $this->ID, '_give_form_earnings', 0 );
916
			}
917
918
			$this->earnings = get_post_meta( $this->ID, '_give_form_earnings', true );
919
920
			if ( $this->earnings < 0 ) {
921
				// Never let earnings be less than zero
922
				$this->earnings = 0;
923
			}
924
925
		}
926
927
		return $this->earnings;
928
929
	}
930
931
	/**
932
	 * Increase the earnings by the given amount
933
	 *
934
	 * @since  1.0
935
	 * @access public
936
	 *
937
	 * @param  int $amount Amount of donation. Default is 0.
938
	 *
939
	 * @return float|false
940
	 */
941
	public function increase_earnings( $amount = 0 ) {
942
943
		$earnings   = give_get_form_earnings_stats( $this->ID );
944
		$new_amount = $earnings + (float) $amount;
945
946
		if ( $this->update_meta( '_give_form_earnings', $new_amount ) ) {
947
948
			$this->earnings = $new_amount;
949
950
			return $this->earnings;
951
952
		}
953
954
		return false;
955
956
	}
957
958
	/**
959
	 * Decrease the earnings by the given amount
960
	 *
961
	 * @since  1.0
962
	 * @access public
963
	 *
964
	 * @param  int $amount Amount of donation.
965
	 *
966
	 * @return float|false
967
	 */
968
	public function decrease_earnings( $amount ) {
969
970
		$earnings = give_get_form_earnings_stats( $this->ID );
971
972
		if ( $earnings > 0 ) {
973
			// Only decrease if greater than zero
974
			$new_amount = $earnings - (float) $amount;
975
976
977
			if ( $this->update_meta( '_give_form_earnings', $new_amount ) ) {
978
979
				$this->earnings = $new_amount;
980
981
				return $this->earnings;
982
983
			}
984
985
		}
986
987
		return false;
988
989
	}
990
991
	/**
992
	 * Determine if the donation is free or if the given price ID is free
993
	 *
994
	 * @since  1.0
995
	 * @access public
996
	 *
997
	 * @param  int $price_id Price ID. Default is false.
998
	 *
999
	 * @return bool
1000
	 */
1001
	public function is_free( $price_id = false ) {
1002
1003
		$is_free          = false;
1004
		$variable_pricing = give_has_variable_prices( $this->ID );
1005
1006
		if ( $variable_pricing && ! is_null( $price_id ) && $price_id !== false ) {
1007
			$price = give_get_price_option_amount( $this->ID, $price_id );
1008
		} elseif ( ! $variable_pricing ) {
1009
			$price = get_post_meta( $this->ID, '_give_set_price', true );
1010
		}
1011
1012
		if ( isset( $price ) && (float) $price == 0 ) {
1013
			$is_free = true;
1014
		}
1015
1016
		return (bool) apply_filters( 'give_is_free_donation', $is_free, $this->ID, $price_id );
1017
1018
	}
1019
1020
	/**
1021
	 * Determine if donation form closed or not
1022
	 *
1023
	 * Form will be close if:
1024
	 *  a. form has fixed goal
1025
	 *  b. close form when goal achieved cmb2 setting is set to 'Yes'
1026
	 *  c. goal has been achieved
1027
	 *
1028
	 * @since  1.4.5
1029
	 * @access public
1030
	 *
1031
	 * @return bool
1032
	 */
1033
	public function is_close_donation_form() {
1034
1035
		/**
1036
		 * Filter the close form result.
1037
		 *
1038
		 * @since 1.8
1039
		 */
1040
		$is_close_form = apply_filters(
1041
			'give_is_close_donation_form',
1042
			(
1043
			give_is_setting_enabled( get_post_meta( $this->ID, '_give_goal_option', true ) ) )
1044
			&& give_is_setting_enabled( get_post_meta( $this->ID, '_give_close_form_when_goal_achieved', true ) )
1045
			&& ( $this->get_goal() <= $this->get_earnings()
1046
			),
1047
			$this->ID
1048
		);
1049
1050
		return $is_close_form;
1051
	}
1052
1053
	/**
1054
	 * Updates a single meta entry for the donation form
1055
	 *
1056
	 * @since  1.5
1057
	 * @access private
1058
	 *
1059
	 * @param  string              $meta_key   The meta_key to update.
1060
	 * @param  string|array|object $meta_value The value to put into the meta.
1061
	 *
1062
	 * @return bool                            The result of the update query.
1063
	 */
1064
	private function update_meta( $meta_key = '', $meta_value = '' ) {
1065
1066
		/* @var WPDB $wpdb */
1067
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1068
1069
		if ( empty( $meta_key ) ) {
1070
			return false;
1071
		}
1072
1073
		// Make sure if it needs to be serialized, we do
1074
		$meta_value = maybe_serialize( $meta_value );
1075
1076
		if ( is_numeric( $meta_value ) ) {
1077
			$value_type = is_float( $meta_value ) ? '%f' : '%d';
1078
		} else {
1079
			$value_type = "'%s'";
1080
		}
1081
1082
		$sql = $wpdb->prepare( "UPDATE $wpdb->postmeta SET meta_value = $value_type WHERE post_id = $this->ID AND meta_key = '%s'", $meta_value, $meta_key );
1083
1084
		if ( $wpdb->query( $sql ) ) {
1085
1086
			clean_post_cache( $this->ID );
1087
1088
			return true;
1089
1090
		}
1091
1092
		return false;
1093
	}
1094
1095
}
1096