Completed
Push — issue-2719 ( c98c0f )
by Ravinder
383:18 queued 375:02
created

Give_Donate_Form::get_level_info()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 5
nop 1
dl 0
loc 19
rs 9.3222
c 0
b 0
f 0
1
<?php
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 $maximum_price
27
 * @property $prices
28
 * @property $goal
29
 * @property $sales
30
 * @property $earnings
31
 * @property $post_type
32
 */
33
class Give_Donate_Form {
34
35
	/**
36
	 * The donation ID.
37
	 *
38
	 * @since  1.0
39
	 * @access public
40
	 *
41
	 * @var    int
42
	 */
43
	public $ID = 0;
44
45
	/**
46
	 * The donation price.
47
	 *
48
	 * @since  1.0
49
	 * @access private
50
	 *
51
	 * @var    float
52
	 */
53
	private $price;
54
55
	/**
56
	 * The minimum donation price.
57
	 *
58
	 * @since  1.3.6
59
	 * @access private
60
	 *
61
	 * @var    float
62
	 */
63
	private $minimum_price;
64
65
	/**
66
	 * The maximum donation price.
67
	 *
68
	 * @since  2.0
69
	 * @access private
70
	 *
71
	 * @var    float
72
	 */
73
	private $maximum_price;
74
75
	/**
76
	 * The donation prices, if Price Levels are enabled.
77
	 *
78
	 * @since  1.0
79
	 * @access private
80
	 *
81
	 * @var    array
82
	 */
83
	private $prices;
84
85
	/**
86
	 * The donation goal.
87
	 *
88
	 * @since  1.0
89
	 * @access private
90
	 *
91
	 * @var    float
92
	 */
93
	private $goal;
94
95
	/**
96
	 * The form's sale count.
97
	 *
98
	 * @since  1.0
99
	 * @access private
100
	 *
101
	 * @var    int
102
	 */
103
	private $sales;
104
105
	/**
106
	 * The form's total earnings
107
	 *
108
	 * @since  1.0
109
	 * @access private
110
	 *
111
	 * @var    float
112
	 */
113
	private $earnings;
114
115
	/**
116
	 * Declare the default properties in WP_Post as we can't extend it
117
	 * Anything we've declared above has been removed.
118
	 */
119
120
	/**
121
	 * The post author
122
	 *
123
	 * @since  1.0
124
	 * @access public
125
	 *
126
	 * @var    int
127
	 */
128
	public $post_author = 0;
129
130
	/**
131
	 * The post date
132
	 *
133
	 * @since  1.0
134
	 * @access public
135
	 *
136
	 * @var    string
137
	 */
138
	public $post_date = '0000-00-00 00:00:00';
139
140
	/**
141
	 * The post GTM date
142
	 *
143
	 * @since  1.0
144
	 * @access public
145
	 *
146
	 * @var    string
147
	 */
148
	public $post_date_gmt = '0000-00-00 00:00:00';
149
150
	/**
151
	 * The post content
152
	 *
153
	 * @since  1.0
154
	 * @access public
155
	 *
156
	 * @var    string
157
	 */
158
	public $post_content = '';
159
160
	/**
161
	 * The post title
162
	 *
163
	 * @since  1.0
164
	 * @access public
165
	 *
166
	 * @var    string
167
	 */
168
	public $post_title = '';
169
170
	/**
171
	 * The post excerpt
172
	 *
173
	 * @since  1.0
174
	 * @access public
175
	 *
176
	 * @var    string
177
	 */
178
	public $post_excerpt = '';
179
180
	/**
181
	 * The post status
182
	 *
183
	 * @since  1.0
184
	 * @access public
185
	 *
186
	 * @var    string
187
	 */
188
	public $post_status = 'publish';
189
190
	/**
191
	 * The comment status
192
	 *
193
	 * @since  1.0
194
	 * @access public
195
	 *
196
	 * @var    string
197
	 */
198
	public $comment_status = 'open';
199
200
	/**
201
	 * The ping status
202
	 *
203
	 * @since  1.0
204
	 * @access public
205
	 *
206
	 * @var    string
207
	 */
208
	public $ping_status = 'open';
209
210
	/**
211
	 * The post password
212
	 *
213
	 * @since  1.0
214
	 * @access public
215
	 *
216
	 * @var    string
217
	 */
218
	public $post_password = '';
219
220
	/**
221
	 * The post name
222
	 *
223
	 * @since  1.0
224
	 * @access public
225
	 *
226
	 * @var    string
227
	 */
228
	public $post_name = '';
229
230
	/**
231
	 * Ping
232
	 *
233
	 * @since  1.0
234
	 * @access public
235
	 *
236
	 * @var    string
237
	 */
238
	public $to_ping = '';
239
240
	/**
241
	 * Pinged
242
	 *
243
	 * @since  1.0
244
	 * @access public
245
	 *
246
	 * @var    string
247
	 */
248
	public $pinged = '';
249
250
	/**
251
	 * The post modified date
252
	 *
253
	 * @since  1.0
254
	 * @access public
255
	 *
256
	 * @var    string
257
	 */
258
	public $post_modified = '0000-00-00 00:00:00';
259
260
	/**
261
	 * The post modified GTM date
262
	 *
263
	 * @since  1.0
264
	 * @access public
265
	 *
266
	 * @var    string
267
	 */
268
	public $post_modified_gmt = '0000-00-00 00:00:00';
269
270
	/**
271
	 * The post filtered content
272
	 *
273
	 * @since  1.0
274
	 * @access public
275
	 *
276
	 * @var    string
277
	 */
278
	public $post_content_filtered = '';
279
280
	/**
281
	 * The post parent
282
	 *
283
	 * @since  1.0
284
	 * @access public
285
	 *
286
	 * @var    int
287
	 */
288
	public $post_parent = 0;
289
290
	/**
291
	 * The post GUID
292
	 *
293
	 * @since  1.0
294
	 * @access public
295
	 *
296
	 * @var    string
297
	 */
298
	public $guid = '';
299
300
	/**
301
	 * The menu order
302
	 *
303
	 * @since  1.0
304
	 * @access public
305
	 *
306
	 * @var    int
307
	 */
308
	public $menu_order = 0;
309
310
	/**
311
	 * The mime type0
312
	 *
313
	 * @since  1.0
314
	 * @access public
315
	 *
316
	 * @var    string
317
	 */
318
	public $post_mime_type = '';
319
320
	/**
321
	 * The comment count
322
	 *
323
	 * @since  1.0
324
	 * @access public
325
	 *
326
	 * @var    int
327
	 */
328
	public $comment_count = 0;
329
330
	/**
331
	 * Filtered
332
	 *
333
	 * @since  1.0
334
	 * @access public
335
	 *
336
	 * @var    string
337
	 */
338
	public $filter;
339
340
	/**
341
	 * Class Constructor
342
	 *
343
	 * Set up the Give Donate Form Class.
344
	 *
345
	 * @since  1.0
346
	 * @access public
347
	 *
348
	 * @param  int|bool $_id   Post id. Default is false.
349
	 * @param  array    $_args Arguments passed.
350
	 */
351
	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...
352
353
		$donation_form = WP_Post::get_instance( $_id );
354
355
		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...
356
	}
357
358
	/**
359
	 * Given the donation form data, let's set the variables
360
	 *
361
	 * @since  1.5
362
	 * @access private
363
	 *
364
	 * @param  WP_Post $donation_form WP_Post Object for the donation form.
365
	 *
366
	 * @return bool                   If the setup was successful or not.
367
	 */
368
	private function setup_donation_form( $donation_form ) {
369
370
		if ( ! is_object( $donation_form ) ) {
371
			return false;
372
		}
373
374
		if ( ! is_a( $donation_form, 'WP_Post' ) ) {
375
			return false;
376
		}
377
378
		if ( 'give_forms' !== $donation_form->post_type ) {
379
			return false;
380
		}
381
382
		foreach ( $donation_form as $key => $value ) {
383
384
			switch ( $key ) {
385
386
				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...
387
					$this->$key = $value;
388
					break;
389
390
			}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
391
392
		}
393
394
		return true;
395
396
	}
397
398
	/**
399
	 * Magic __get function to dispatch a call to retrieve a private property
400
	 *
401
	 * @since  1.0
402
	 * @access public
403
	 *
404
	 * @param  string $key
405
	 *
406
	 * @return mixed
407
	 */
408 View Code Duplication
	public function __get( $key ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
409
410
		if ( method_exists( $this, 'get_' . $key ) ) {
411
412
			return call_user_func( array( $this, 'get_' . $key ) );
413
414
		} else {
415
416
			/* translators: %s: property key */
417
			return new WP_Error( 'give-form-invalid-property', sprintf( esc_html__( 'Can\'t get property %s.', 'give' ), $key ) );
418
419
		}
420
421
	}
422
423
	/**
424
	 * Creates a donation form
425
	 *
426
	 * @since  1.5
427
	 * @access public
428
	 *
429
	 * @param  array $data Array of attributes for a donation form.
430
	 *
431
	 * @return bool|int    False if data isn't passed and class not instantiated for creation, or New Form ID.
432
	 */
433
	public function create( $data = array() ) {
434
435
		if ( $this->id != 0 ) {
0 ignored issues
show
introduced by
Found "!= 0". Use Yoda Condition checks, you must
Loading history...
436
			return false;
437
		}
438
439
		$defaults = array(
440
			'post_type'   => 'give_forms',
441
			'post_status' => 'draft',
442
			'post_title'  => __( 'New Donation Form', 'give' ),
443
		);
444
445
		$args = wp_parse_args( $data, $defaults );
446
447
		/**
448
		 * Fired before a donation form is created
449
		 *
450
		 * @param array $args The post object arguments used for creation.
451
		 */
452
		do_action( 'give_form_pre_create', $args );
453
454
		$id = wp_insert_post( $args, true );
455
456
		$donation_form = WP_Post::get_instance( $id );
457
458
		/**
459
		 * Fired after a donation form is created
460
		 *
461
		 * @param int   $id   The post ID of the created item.
462
		 * @param array $args The post object arguments used for creation.
463
		 */
464
		do_action( 'give_form_post_create', $id, $args );
465
466
		return $this->setup_donation_form( $donation_form );
467
468
	}
469
470
	/**
471
	 * Retrieve the ID
472
	 *
473
	 * @since  1.0
474
	 * @access public
475
	 *
476
	 * @return int    Donation form ID.
477
	 */
478
	public function get_ID() {
0 ignored issues
show
Coding Style introduced by
The function name get_ID is in camel caps, but expected get_i_d instead as per the coding standard.
Loading history...
479
		return $this->ID;
480
	}
481
482
	/**
483
	 * Retrieve the donation form name
484
	 *
485
	 * @since  1.5
486
	 * @access public
487
	 *
488
	 * @return string Donation form name.
489
	 */
490
	public function get_name() {
491
		return get_the_title( $this->ID );
492
	}
493
494
	/**
495
	 * Retrieve the price
496
	 *
497
	 * @since  1.0
498
	 * @access public
499
	 *
500
	 * @return float  Price.
501
	 */
502 View Code Duplication
	public function get_price() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
503
504
		if ( ! isset( $this->price ) ) {
505
506
			$this->price = give_maybe_sanitize_amount(
0 ignored issues
show
Documentation Bug introduced by
It seems like give_maybe_sanitize_amou...give_set_price', true)) can also be of type integer or string. However, the property $price is declared as type double. 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...
507
				give_get_meta(
508
					$this->ID,
509
					'_give_set_price',
510
					true
511
				)
512
			);
513
514
			if ( ! $this->price ) {
515
				$this->price = 0;
0 ignored issues
show
Documentation Bug introduced by
The property $price was declared of type double, but 0 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
516
			}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
517
518
		}
519
520
		/**
521
		 * Override the donation form set price.
522
		 *
523
		 * @since 1.0
524
		 *
525
		 * @param string     $price The donation form price.
526
		 * @param string|int $id    The form ID.
527
		 */
528
		return apply_filters( 'give_get_set_price', $this->price, $this->ID );
529
	}
530
531
	/**
532
	 * Retrieve the minimum price.
533
	 *
534
	 * @since  1.3.6
535
	 * @access public
536
	 *
537
	 * @return float  Minimum price.
538
	 */
539 View Code Duplication
	public function get_minimum_price() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
540
541
		if ( ! isset( $this->minimum_price ) ) {
542
543
			$this->minimum_price = give_get_meta( $this->ID, '_give_custom_amount_range_minimum', true );
544
545
			// Give backward < 2.1
546
			if ( empty( $this->minimum_price ) ) {
547
				$this->minimum_price = give_get_meta( $this->ID, '_give_custom_amount_minimum', true );
548
			}
549
550
			if ( ! $this->is_custom_price_mode() ) {
551
				$this->minimum_price = 0;
0 ignored issues
show
Documentation Bug introduced by
The property $minimum_price was declared of type double, but 0 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
552
			}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
553
554
		}
555
556
		return apply_filters( 'give_get_set_minimum_price', $this->minimum_price, $this->ID );
557
	}
558
559
	/**
560
	 * Retrieve the maximum price.
561
	 *
562
	 * @since  2.1
563
	 * @access public
564
	 *
565
	 * @return float  Maximum price.
566
	 */
567
	public function get_maximum_price() {
568
569
		if ( ! isset( $this->maximum_price ) ) {
570
			$this->maximum_price = give_get_meta( $this->ID, '_give_custom_amount_range_maximum', true );
571
572
			if ( ! $this->is_custom_price_mode() ) {
573
				$this->maximum_price = 999999.99;
574
			}
575
		}
576
577
		return apply_filters( 'give_get_set_maximum_price', $this->maximum_price, $this->ID );
578
	}
579
580
	/**
581
	 * Retrieve the variable prices
582
	 *
583
	 * @since  1.0
584
	 * @access public
585
	 *
586
	 * @return array  Variable prices.
587
	 */
588
	public function get_prices() {
589
590
		if ( ! isset( $this->prices ) ) {
591
592
			$this->prices = give_get_meta( $this->ID, '_give_donation_levels', true );
0 ignored issues
show
Documentation Bug introduced by
It seems like give_get_meta($this->ID,...donation_levels', true) of type * is incompatible with the declared type array of property $prices.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
593
594
		}
595
596
		/**
597
		 * Override multi-level prices
598
		 *
599
		 * @since 1.0
600
		 *
601
		 * @param array      $prices The array of mulit-level prices.
602
		 * @param int|string $ID     The ID of the form.
603
		 */
604
		return apply_filters( 'give_get_donation_levels', $this->prices, $this->ID );
605
606
	}
607
608
	/**
609
	 * Get donation form level info
610
	 *
611
	 * @since  2.0.6
612
	 * @access public
613
	 *
614
	 * @param $price_id
615
	 *
616
	 * @return array|null
617
	 */
618
	public function get_level_info( $price_id ) {
619
		$level_info = array();
620
621
		// Bailout.
622
		if ( 'multi' !== $this->get_type() ) {
623
			return null;
624
		} elseif ( ! ( $levels = $this->get_prices() ) ) {
625
			return $level_info;
626
		}
627
628
		foreach ( $levels as $level ) {
629
			if( $price_id === $level['_give_id']['level_id'] ) {
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
630
				$level_info = $level;
631
				break;
632
			}
633
		}
634
635
		return $level_info;
636
	}
637
638
639
	/**
640
	 * Retrieve the goal
641
	 *
642
	 * @since  1.0
643
	 * @access public
644
	 *
645
	 * @return float  Goal.
646
	 */
647 View Code Duplication
	public function get_goal() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
648
649
		if ( ! isset( $this->goal ) ) {
650
651
			if ( 'donation' === give_get_form_goal_format( $this->ID ) ) {
652
				$this->goal = give_get_meta( $this->ID, '_give_number_of_donation_goal', true );
653
			} else {
654
				$this->goal = give_get_meta( $this->ID, '_give_set_goal', true );
655
			}
656
657
			if ( ! $this->goal ) {
658
				$this->goal = 0;
0 ignored issues
show
Documentation Bug introduced by
The property $goal was declared of type double, but 0 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
659
			}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
660
661
		}
662
663
		return apply_filters( 'give_get_set_goal', $this->goal, $this->ID );
664
665
	}
666
667
	/**
668
	 * Determine if single price mode is enabled or disabled
669
	 *
670
	 * @since  1.0
671
	 * @access public
672
	 *
673
	 * @return bool
674
	 */
675 View Code Duplication
	public function is_single_price_mode() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
676
677
		$option = give_get_meta( $this->ID, '_give_price_option', true );
678
		$ret    = 0;
679
680
		if ( empty( $option ) || $option === 'set' ) {
0 ignored issues
show
introduced by
Found "=== '". Use Yoda Condition checks, you must
Loading history...
681
			$ret = 1;
682
		}
683
684
		/**
685
		 * Override the price mode for a donation when checking if is in single price mode.
686
		 *
687
		 * @since 1.0
688
		 *
689
		 * @param bool       $ret Is donation form in single price mode?
690
		 * @param int|string $ID The ID of the donation form.
691
		 */
692
		return (bool) apply_filters( 'give_single_price_option_mode', $ret, $this->ID );
693
694
	}
695
696
	/**
697
	 * Determine if custom price mode is enabled or disabled
698
	 *
699
	 * @since  1.6
700
	 * @access public
701
	 *
702
	 * @return bool
703
	 */
704
	public function is_custom_price_mode() {
705
706
		$option = give_get_meta( $this->ID, '_give_custom_amount', true );
707
		$ret    = 0;
708
709
		if ( give_is_setting_enabled( $option ) ) {
710
			$ret = 1;
711
		}
712
713
		/**
714
		 * Override the price mode for a donation when checking if is in custom price mode.
715
		 *
716
		 * @since 1.6
717
		 *
718
		 * @param bool       $ret Is donation form in custom price mode?
719
		 * @param int|string $ID  The ID of the donation form.
720
		 */
721
		return (bool) apply_filters( 'give_custom_price_option_mode', $ret, $this->ID );
722
723
	}
724
725
	/**
726
	 * Determine if custom price mode is enabled or disabled
727
	 *
728
	 * @since  1.8.18
729
	 * @access public
730
	 *
731
	 * @param string|float $amount Donation Amount.
732
	 *
733
	 * @return bool
734
	 */
735
	public function is_custom_price( $amount ) {
736
		$result = false;
737
		$amount = give_maybe_sanitize_amount( $amount );
738
739
		if ( $this->is_custom_price_mode() ) {
740
741
			if ( 'set' === $this->get_type() ) {
742
				if ( $amount !== $this->get_price() ) {
743
					$result = true;
744
				}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
745
746
			} elseif ( 'multi' === $this->get_type() ) {
747
				$level_amounts = array_map( 'give_maybe_sanitize_amount', wp_list_pluck( $this->get_prices(), '_give_amount' ) );
748
				$result        = ! in_array( $amount, $level_amounts );
749
			}
750
		}
751
752
		/**
753
		 * Filter to reset whether it is custom price or not.
754
		 *
755
		 * @param bool         $result True/False.
756
		 * @param string|float $amount Donation Amount.
757
		 * @param int          $this->ID Form ID.
758
		 *
759
		 * @since 1.8.18
760
		 */
761
		return (bool) apply_filters( 'give_is_custom_price', $result, $amount, $this->ID );
762
	}
763
764
	/**
765
	 * Has Variable Prices
766
	 *
767
	 * Determine if the donation form has variable prices enabled
768
	 *
769
	 * @since  1.0
770
	 * @access public
771
	 *
772
	 * @return bool
773
	 */
774 View Code Duplication
	public function has_variable_prices() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
775
776
		$option = give_get_meta( $this->ID, '_give_price_option', true );
777
		$ret    = 0;
778
779
		if ( $option === 'multi' ) {
0 ignored issues
show
introduced by
Found "=== '". Use Yoda Condition checks, you must
Loading history...
780
			$ret = 1;
781
		}
782
783
		/**
784
		 * Filter: Override whether the donation form has variables prices.
785
		 *
786
		 * @param bool       $ret Does donation form have variable prices?
787
		 * @param int|string $ID  The ID of the donation form.
788
		 */
789
		return (bool) apply_filters( 'give_has_variable_prices', $ret, $this->ID );
790
791
	}
792
793
	/**
794
	 * Retrieve the donation form type, set or multi-level
795
	 *
796
	 * @since  1.5
797
	 * @access public
798
	 *
799
	 * @return string Type of donation form, either 'set' or 'multi'.
800
	 */
801 View Code Duplication
	public function get_type() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
802
803
		if ( ! isset( $this->type ) ) {
804
805
			$this->type = give_get_meta( $this->ID, '_give_price_option', true );
806
807
			if ( empty( $this->type ) ) {
808
				$this->type = 'set';
809
			}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
810
811
		}
812
813
		return apply_filters( 'give_get_form_type', $this->type, $this->ID );
814
815
	}
816
817
	/**
818
	 * Get form tag classes.
819
	 *
820
	 * Provides the classes for the donation <form> html tag and filters for customization.
821
	 *
822
	 * @since  1.6
823
	 * @access public
824
	 *
825
	 * @param  $args
826
	 *
827
	 * @return string
828
	 */
829
	public function get_form_classes( $args ) {
830
831
		$float_labels_option = give_is_float_labels_enabled( $args )
832
			? 'float-labels-enabled'
833
			: '';
834
835
		$form_classes_array = apply_filters( 'give_form_classes', array(
836
			'give-form',
837
			'give-form-' . $this->ID,
838
			'give-form-type-' . $this->get_type(),
839
			$float_labels_option,
840
		), $this->ID, $args );
841
842
		// Remove empty class names.
843
		$form_classes_array = array_filter( $form_classes_array );
844
845
		return implode( ' ', $form_classes_array );
846
847
	}
848
849
	/**
850
	 * Get form wrap Classes.
851
	 *
852
	 * Provides the classes for the donation form div wrapper and filters for customization.
853
	 *
854
	 * @access public
855
	 *
856
	 * @param  $args
857
	 *
858
	 * @return string
859
	 */
860
	public function get_form_wrap_classes( $args ) {
861
		$custom_class = array(
862
			'give-form-wrap',
863
		);
864
865
		if ( $this->is_close_donation_form() ) {
866
			$custom_class[] = 'give-form-closed';
867
		} else{
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
868
			$display_option = ( isset( $args['display_style'] ) && ! empty( $args['display_style'] ) )
869
				? $args['display_style']
870
				: give_get_meta( $this->ID, '_give_payment_display', true );
871
872
			$custom_class[] = "give-display-{$display_option}";
873
874
			// If admin want to show only button for form then user inbuilt modal functionality.
875
			if ( 'button' === $display_option ) {
876
				$custom_class[] = 'give-display-button-only';
877
			}
878
		}
879
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
880
881
		/**
882
		 * Filter the donation form classes.
883
		 *
884
		 * @since 1.0
885
		 */
886
		$form_wrap_classes_array = (array) apply_filters( 'give_form_wrap_classes', $custom_class, $this->ID, $args );
887
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
888
889
		return implode( ' ', $form_wrap_classes_array );
890
891
	}
892
893
	/**
894
	 * Get if form type set or not.
895
	 *
896
	 * @since  1.6
897
	 * @access public
898
	 *
899
	 * @return bool
900
	 */
901
	public function is_set_type_donation_form() {
902
		$form_type = $this->get_type();
903
904
		return ( 'set' === $form_type ? true : false );
905
	}
906
907
	/**
908
	 * Get if form type multi or not.
909
	 *
910
	 * @since  1.6
911
	 * @access public
912
	 *
913
	 * @return bool True if form type is 'multi' and false otherwise.
914
	 */
915
	public function is_multi_type_donation_form() {
916
		$form_type = $this->get_type();
917
918
		return ( 'multi' === $form_type ? true : false );
919
920
	}
921
922
	/**
923
	 * Retrieve the sale count for the donation form
924
	 *
925
	 * @since  1.0
926
	 * @access public
927
	 *
928
	 * @return int    Donation form sale count.
929
	 */
930 View Code Duplication
	public function get_sales() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
931
932
		if ( ! isset( $this->sales ) ) {
933
934
			if ( '' == give_get_meta( $this->ID, '_give_form_sales', true ) ) {
935
				add_post_meta( $this->ID, '_give_form_sales', 0 );
936
			} // End if
937
938
			$this->sales = give_get_meta( $this->ID, '_give_form_sales', true );
939
940
			if ( $this->sales < 0 ) {
941
				// Never let sales be less than zero.
942
				$this->sales = 0;
943
			}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
944
945
		}
946
947
		return $this->sales;
948
949
	}
950
951
	/**
952
	 * Increment the sale count by one
953
	 *
954
	 * @since  1.0
955
	 * @access public
956
	 *
957
	 * @param  int $quantity The quantity to increase the donations by. Default is 1.
958
	 *
959
	 * @return int|false     New number of total sales.
960
	 */
961
	public function increase_sales( $quantity = 1 ) {
962
963
		$sales       = give_get_form_sales_stats( $this->ID );
964
		$quantity    = absint( $quantity );
965
		$total_sales = $sales + $quantity;
966
967
		if ( $this->update_meta( '_give_form_sales', $total_sales ) ) {
968
969
			$this->sales = $total_sales;
970
971
			return $this->sales;
972
973
		}
974
975
		return false;
976
	}
977
978
	/**
979
	 * Decrement the sale count by one
980
	 *
981
	 * @since  1.0
982
	 * @access public
983
	 *
984
	 * @param  int $quantity The quantity to decrease by. Default is 1.
985
	 *
986
	 * @return int|false     New number of total sales.
987
	 */
988
	public function decrease_sales( $quantity = 1 ) {
989
990
		$sales = give_get_form_sales_stats( $this->ID );
991
992
		// Only decrease if not already zero
993
		if ( $sales > 0 ) {
994
995
			$quantity    = absint( $quantity );
996
			$total_sales = $sales - $quantity;
997
998
			if ( $this->update_meta( '_give_form_sales', $total_sales ) ) {
999
1000
				$this->sales = $sales;
0 ignored issues
show
Documentation Bug introduced by
It seems like $sales can also be of type double. However, the property $sales is declared as type integer. 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...
1001
1002
				return $sales;
1003
1004
			}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
1005
1006
		}
1007
1008
		return false;
1009
1010
	}
1011
1012
	/**
1013
	 * Retrieve the total earnings for the form
1014
	 *
1015
	 * @since  1.0
1016
	 * @access public
1017
	 *
1018
	 * @return float  Donation form total earnings.
1019
	 */
1020 View Code Duplication
	public function get_earnings() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1021
1022
		if ( ! isset( $this->earnings ) ) {
1023
1024
			if ( '' == give_get_meta( $this->ID, '_give_form_earnings', true ) ) {
1025
				add_post_meta( $this->ID, '_give_form_earnings', 0 );
1026
			}
1027
1028
			$this->earnings = give_get_meta( $this->ID, '_give_form_earnings', true );
1029
1030
			if ( $this->earnings < 0 ) {
1031
				// Never let earnings be less than zero
1032
				$this->earnings = 0;
0 ignored issues
show
Documentation Bug introduced by
The property $earnings was declared of type double, but 0 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
1033
			}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
1034
1035
		}
1036
1037
		return $this->earnings;
1038
1039
	}
1040
1041
	/**
1042
	 * Increase the earnings by the given amount
1043
	 *
1044
	 * @since  1.0
1045
	 * @access public
1046
	 *
1047
	 * @param  int $amount Amount of donation. Default is 0.
1048
	 *
1049
	 * @return float|false
1050
	 */
1051 View Code Duplication
	public function increase_earnings( $amount = 0 ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1052
1053
		$earnings   = give_get_form_earnings_stats( $this->ID );
1054
		$new_amount = $earnings + (float) $amount;
1055
1056
		if ( $this->update_meta( '_give_form_earnings', $new_amount ) ) {
1057
1058
			$this->earnings = $new_amount;
1059
1060
			return $this->earnings;
1061
1062
		}
1063
1064
		return false;
1065
1066
	}
1067
1068
	/**
1069
	 * Decrease the earnings by the given amount
1070
	 *
1071
	 * @since  1.0
1072
	 * @access public
1073
	 *
1074
	 * @param  int $amount Amount of donation.
1075
	 *
1076
	 * @return float|false
1077
	 */
1078 View Code Duplication
	public function decrease_earnings( $amount ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1079
1080
		$earnings = give_get_form_earnings_stats( $this->ID );
1081
1082
		if ( $earnings > 0 ) {
1083
			// Only decrease if greater than zero
1084
			$new_amount = $earnings - (float) $amount;
1085
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
1086
1087
			if ( $this->update_meta( '_give_form_earnings', $new_amount ) ) {
1088
1089
				$this->earnings = $new_amount;
1090
1091
				return $this->earnings;
1092
1093
			}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
1094
1095
		}
1096
1097
		return false;
1098
1099
	}
1100
1101
	/**
1102
	 * Determine if the donation is free or if the given price ID is free
1103
	 *
1104
	 * @since  1.0
1105
	 * @access public
1106
	 *
1107
	 * @param  int $price_id Price ID. Default is false.
1108
	 *
1109
	 * @return bool
1110
	 */
1111
	public function is_free( $price_id = false ) {
1112
1113
		$is_free          = false;
1114
		$variable_pricing = give_has_variable_prices( $this->ID );
1115
1116
		if ( $variable_pricing && ! is_null( $price_id ) && $price_id !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
1117
			$price = give_get_price_option_amount( $this->ID, $price_id );
1118
		} elseif ( ! $variable_pricing ) {
1119
			$price = give_get_meta( $this->ID, '_give_set_price', true );
1120
		}
1121
1122
		if ( isset( $price ) && (float) $price == 0 ) {
0 ignored issues
show
introduced by
Found "== 0". Use Yoda Condition checks, you must
Loading history...
1123
			$is_free = true;
1124
		}
1125
1126
		return (bool) apply_filters( 'give_is_free_donation', $is_free, $this->ID, $price_id );
1127
1128
	}
1129
1130
	/**
1131
	 * Determine if donation form closed or not
1132
	 *
1133
	 * Form will be close if:
1134
	 *  a. form has fixed goal
1135
	 *  b. close form when goal achieved cmb2 setting is set to 'Yes'
1136
	 *  c. goal has been achieved
1137
	 *
1138
	 * @since  1.4.5
1139
	 * @access public
1140
	 *
1141
	 * @return bool
1142
	 */
1143
	public function is_close_donation_form() {
1144
1145
		$goal_format = give_get_form_goal_format( $this->ID );
1146
1147
		/**
1148
		 * Filter the close form result.
1149
		 *
1150
		 * @since 1.8
1151
		 */
1152
		$is_close_form = apply_filters(
1153
			'give_is_close_donation_form',
1154
			(
1155
				give_is_setting_enabled( give_get_meta( $this->ID, '_give_goal_option', true ) ) &&
1156
				give_is_setting_enabled( give_get_meta( $this->ID, '_give_close_form_when_goal_achieved', true ) ) &&
1157
				( 'donation' === $goal_format ? $this->get_goal() <= $this->get_sales() : $this->get_goal() <= $this->get_earnings() )
1158
			),
1159
			$this->ID
1160
		);
1161
1162
		return $is_close_form;
1163
	}
1164
1165
	/**
1166
	 * Updates a single meta entry for the donation form
1167
	 *
1168
	 * @since  1.5
1169
	 * @access private
1170
	 *
1171
	 * @param  string              $meta_key   The meta_key to update.
1172
	 * @param  string|array|object $meta_value The value to put into the meta.
1173
	 *
1174
	 * @return bool                            The result of the update query.
1175
	 */
1176
	private function update_meta( $meta_key = '', $meta_value = '' ) {
1177
1178
		/* @var WPDB $wpdb */
1179
		global $wpdb;
1180
1181
		// Bailout.
1182
		if ( empty( $meta_key ) ) {
1183
			return false;
1184
		}
1185
1186
		if ( give_update_meta( $this->ID, $meta_key, $meta_value  ) ) {
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 2 found
Loading history...
1187
			return true;
1188
		}
1189
1190
		return false;
1191
	}
1192
1193
}
1194