Completed
Pull Request — master (#627)
by Devin
04:26
created

Give_Donate_Form::get_goal()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 8
c 1
b 0
f 0
nc 3
nop 0
dl 0
loc 21
rs 9.3142
ccs 9
cts 9
cp 1
crap 3
1
<?php
2
/**
3
 * Donate Form Object
4
 *
5
 * @package     Give
6
 * @subpackage  Classes/Forms
7
 * @copyright   Copyright (c) 2015, WordImpress
8
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
 * @since       1.0
10
 */
11
12
/**
13
 * Give_Donate_Form Class
14
 *
15
 * @since 1.0
16
 */
17
class Give_Donate_Form {
18
19
	/**
20
	 * The donation ID
21
	 *
22
	 * @since 1.0
23
	 */
24
	public $ID = 0;
25
26
	/**
27
	 * The donation price
28
	 *
29
	 * @since 1.0
30
	 */
31
	private $price;
32
33
	/**
34
	 * The minimum donation price
35
	 *
36
	 * @since 1.3.6
37
	 */
38
	private $minimum_price;
39
40
	/**
41
	 * The donation goal
42
	 *
43
	 * @since 1.0
44
	 */
45
	private $goal;
46
47
	/**
48
	 * The donation prices, if Price Levels are enabled
49
	 *
50
	 * @since 1.0
51
	 */
52
	private $prices;
53
54
	/**
55
	 * The form's sale count
56
	 *
57
	 * @since 1.0
58
	 */
59
	private $sales;
60
61
	/**
62
	 * The form's total earnings
63
	 *
64
	 * @since 1.0
65
	 */
66
	private $earnings;
67
68
	/**
69
	 * Declare the default properties in WP_Post as we can't extend it
70
	 * Anything we've declared above has been removed.
71
	 */
72
	public $post_author = 0;
73
	public $post_date = '0000-00-00 00:00:00';
74
	public $post_date_gmt = '0000-00-00 00:00:00';
75
	public $post_content = '';
76
	public $post_title = '';
77
	public $post_excerpt = '';
78
	public $post_status = 'publish';
79
	public $comment_status = 'open';
80
	public $ping_status = 'open';
81
	public $post_password = '';
82
	public $post_name = '';
83
	public $to_ping = '';
84
	public $pinged = '';
85
	public $post_modified = '0000-00-00 00:00:00';
86
	public $post_modified_gmt = '0000-00-00 00:00:00';
87
	public $post_content_filtered = '';
88
	public $post_parent = 0;
89
	public $guid = '';
90
	public $menu_order = 0;
91
	public $post_mime_type = '';
92
	public $comment_count = 0;
93
	public $filter;
94
95
	/**
96
	 * Give_Donate_Form constructor.
97
	 *
98
	 * @since 1.0
99
	 *
100
	 * @param bool $_id
101
	 * @param array $_args
102
	 */
103 57
	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...
104
105
106 57
		$donation_form = WP_Post::get_instance( $_id );
107
108 57
		return $this->setup_donation_form( $donation_form );
109
	}
110
111
	/**
112
	 * Given the donation form data, let's set the variables
113
	 *
114
	 * @since  1.5
115
	 *
116
	 * @param  object $donation_form The Donation Form Object
117
	 *
118
	 * @return bool             If the setup was successful or not
119
	 */
120 57
	private function setup_donation_form( $donation_form ) {
121
122 57
		if ( ! is_object( $donation_form ) ) {
123 5
			return false;
124
		}
125
126 57
		if ( ! is_a( $donation_form, 'WP_Post' ) ) {
127
			return false;
128
		}
129
130 57
		if ( 'give_forms' !== $donation_form->post_type ) {
131
			return false;
132
		}
133
134 57
		foreach ( $donation_form as $key => $value ) {
135
136
			switch ( $key ) {
137
138 57
				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...
139 57
					$this->$key = $value;
140 57
					break;
141
142 57
			}
143
144 57
		}
145
146 57
		return true;
147
148
	}
149
150
	/**
151
	 * Magic __get function to dispatch a call to retrieve a private property
152
	 *
153
	 * @since 1.0
154
	 *
155
	 * @param $key
156
	 *
157
	 * @return mixed
158
	 * @throws Exception
159
	 */
160 53
	public function __get( $key ) {
161
162 53
		if ( method_exists( $this, 'get_' . $key ) ) {
163
164 53
			return call_user_func( array( $this, 'get_' . $key ) );
165
166
		} else {
167
168
			return new WP_Error( 'give-form-invalid-property', sprintf( __( 'Can\'t get property %s', 'give' ), $key ) );
169
170
		}
171
172
	}
173
174
175
	/**
176
	 * Creates a donation form
177
	 *
178
	 * @since  1.5
179
	 *
180
	 * @param  array $data Array of attributes for a donation form
181
	 *
182
	 * @return mixed  false if data isn't passed and class not instantiated for creation, or New Form ID
183
	 */
184
	public function create( $data = array() ) {
185
186
		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...
187
			return false;
188
		}
189
190
		$defaults = array(
191
			'post_type'   => 'give_forms',
192
			'post_status' => 'draft',
193
			'post_title'  => __( 'New Donation Form', 'give' )
194
		);
195
196
		$args = wp_parse_args( $data, $defaults );
197
198
		/**
199
		 * Fired before a donation form is created
200
		 *
201
		 * @param array $args The post object arguments used for creation.
202
		 */
203
		do_action( 'give_form_pre_create', $args );
204
205
		$id = wp_insert_post( $args, true );
206
207
		$donation_form = WP_Post::get_instance( $id );
208
209
		/**
210
		 * Fired after a donation form is created
211
		 *
212
		 * @param int $id The post ID of the created item.
213
		 * @param array $args The post object arguments used for creation.
214
		 */
215
		do_action( 'give_form_post_create', $id, $args );
216
217
		return $this->setup_donation_form( $donation_form );
218
219
	}
220
221
	/**
222
	 * Retrieve the ID
223
	 *
224
	 * @since 1.0
225
	 * @return int
226
	 */
227 1
	public function get_ID() {
228
229 1
		return $this->ID;
230
231
	}
232
233
	/**
234
	 * Retrieve the donation form name
235
	 *
236
	 * @since 1.5
237
	 * @return string Name of the donation form
238
	 */
239
	public function get_name() {
240
		return get_the_title( $this->ID );
241
	}
242
243
	/**
244
	 * Retrieve the price
245
	 *
246
	 * @since 1.0
247
	 * @return float
248
	 */
249 15
	public function get_price() {
250
251 15
		if ( ! isset( $this->price ) ) {
252
253 15
			$this->price = get_post_meta( $this->ID, '_give_set_price', true );
254
255 15
			if ( $this->price ) {
256
257 4
				$this->price = give_sanitize_amount( $this->price );
258
259 4
			} else {
260
261 11
				$this->price = 0;
262
263
			}
264
265 15
		}
266
267
		/**
268
		 * Override the donation form set price.
269
		 *
270
		 * @since 1.0
271
		 *
272
		 * @param string $price The donation form price.
273
		 * @param string|int $id The form ID.
274
		 */
275 15
		return apply_filters( 'give_get_set_price', $this->price, $this->ID );
276
	}
277
278
	/**
279
	 * Retrieve the minimum price
280
	 *
281
	 * @since 1.3.6
282
	 * @return float
283
	 */
284 2
	public function get_minimum_price() {
285
286 2
		if ( ! isset( $this->minimum_price ) ) {
287
288 2
			$allow_custom_amount = get_post_meta( $this->ID, '_give_custom_amount', true );
289 2
			$this->minimum_price = get_post_meta( $this->ID, '_give_custom_amount_minimum', true );
290
291 2
			if ( $allow_custom_amount != 'no' && $this->minimum_price ) {
292
293 1
				$this->minimum_price = give_sanitize_amount( $this->minimum_price );
294
295 1
			} else {
296
297 1
				$this->minimum_price = 0;
298
299
			}
300
301 2
		}
302
303 2
		return apply_filters( 'give_get_set_minimum_price', $this->minimum_price, $this->ID );
304
	}
305
306
	/**
307
	 * Retrieve the variable prices
308
	 *
309
	 * @since 1.0
310
	 * @return array
311
	 */
312 13
	public function get_prices() {
313
314 13
		if ( ! isset( $this->prices ) ) {
315
316 13
			$this->prices = get_post_meta( $this->ID, '_give_donation_levels', true );
317
318 13
		}
319
320
		/**
321
		 * Override multi-level prices
322
		 *
323
		 * @since 1.0
324
		 *
325
		 * @param array $prices The array of mulit-level prices.
326
		 * @param int|string The ID of the form.
327
		 */
328 13
		return apply_filters( 'give_get_donation_levels', $this->prices, $this->ID );
329
330
	}
331
332
	/**
333
	 * Retrieve the goal
334
	 *
335
	 * @since 1.0
336
	 * @return float
337
	 */
338 2
	public function get_goal() {
339
340 2
		if ( ! isset( $this->goal ) ) {
341
342 2
			$this->goal = get_post_meta( $this->ID, '_give_set_goal', true );
343
344 2
			if ( $this->goal ) {
345
346 1
				$this->goal = give_sanitize_amount( $this->goal );
347
348 1
			} else {
349
350 2
				$this->goal = 0;
351
352
			}
353
354 2
		}
355
356 2
		return apply_filters( 'give_get_set_goal', $this->goal, $this->ID );
357
358
	}
359
360
	/**
361
	 * Determine if single price mode is enabled or disabled
362
	 *
363
	 * @since 1.0
364
	 * @return bool
365
	 */
366
	public function is_single_price_mode() {
367
368
		$option = get_post_meta( $this->ID, '_give_price_options_mode', true );
369
		$ret    = 0;
370
371
		if ( empty( $option ) || $option === 'set' ) {
372
			$ret = 1;
373
		}
374
		
375
		/**
376
		 * Override the price mode for a donation when checking if is in single price mode.
377
		 *
378
		 * @since 1.0
379
		 *
380
		 * @param bool $ret Is donation form in single price mode?
381
		 * @param int|string The ID of the donation form.
382
		 */
383
		return (bool) apply_filters( 'give_single_price_option_mode', $ret, $this->ID );
384
385
	}
386
387
	/**
388
	 * Has Variable Prices
389
	 *
390
	 * @description Determine if the donation form has variable prices enabled
391
	 *
392
	 * @since       1.0
393
	 * @return bool
394
	 */
395 53
	public function has_variable_prices() {
396
397 53
		$option = get_post_meta( $this->ID, '_give_price_option', true );
398 53
		$ret    = 0;
399
400 53
		if ( $option === 'multi' ) {
401 34
			$ret = 1;
402 34
		}
403
404
		/**
405
		 * Filter: Override whether the donation form has variables prices.
406
		 *
407
		 * @param bool $ret Does donation form have variable prices?
408
		 * @param int|string The ID of the donation form.
409
		 */
410 53
		return (bool) apply_filters( 'give_has_variable_prices', $ret, $this->ID );
411
412
	}
413
414
	/**
415
	 * Retrieve the donation form type, set or multi-level
416
	 *
417
	 * @since 1.5
418
	 * @return string Type of donation form, either 'set' or 'multi'
419
	 */
420
	public function get_type() {
421
422
		if ( ! isset( $this->type ) ) {
423
424
			$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...
425
426
			if ( empty( $this->type ) ) {
427
				$this->type = 'set';
428
			}
429
430
		}
431
432
		return apply_filters( 'give_get_form_type', $this->type, $this->ID );
433
434
	}
435
436
	/**
437
	 * Retrieve the sale count for the donation form
438
	 *
439
	 * @since 1.0
440
	 * @return int
441
	 */
442 52
	public function get_sales() {
443
444 52
		if ( ! isset( $this->sales ) ) {
445
446 52
			if ( '' == get_post_meta( $this->ID, '_give_form_sales', true ) ) {
447 29
				add_post_meta( $this->ID, '_give_form_sales', 0 );
448 29
			} // End if
449
450 52
			$this->sales = get_post_meta( $this->ID, '_give_form_sales', true );
451
452 52
			if ( $this->sales < 0 ) {
453
				// Never let sales be less than zero
454
				$this->sales = 0;
455
			}
456
457 52
		}
458
459 52
		return $this->sales;
460
461
	}
462
463
	/**
464
	 * Increment the sale count by one
465
	 *
466
	 * @since 1.0
467
	 *
468
	 * @param int $quantity The quantity to increase the donations by
469
	 *
470
	 * @return int|false  New number of total sales
471
	 */
472 42
	public function increase_sales( $quantity = 1 ) {
473
474 42
		$sales       = give_get_form_sales_stats( $this->ID );
475 42
		$quantity    = absint( $quantity );
476 42
		$total_sales = $sales + $quantity;
477
478 42
		if ( $this->update_meta( '_give_form_sales', $total_sales ) ) {
479
480 42
			$this->sales = $total_sales;
481
482 42
			return $this->sales;
483
484
		}
485
486 1
		return false;
487
	}
488
489
	/**
490
	 * Decrement the sale count by one
491
	 *
492
	 * @since 1.0
493
	 *
494
	 * @param int $quantity The quantity to decrease by
495
	 *
496
	 * @return int|false  New number of total sales
497
	 */
498 31
	public function decrease_sales( $quantity = 1 ) {
499
500 31
		$sales = give_get_form_sales_stats( $this->ID );
501
502
		// Only decrease if not already zero
503 31
		if ( $sales > 0 ) {
504
505 26
			$quantity    = absint( $quantity );
506 26
			$total_sales = $sales - $quantity;
507
508 26
			if ( $this->update_meta( '_give_form_sales', $total_sales ) ) {
509
510 5
				$this->sales = $sales;
511
512 5
				return $sales;
513
514
			}
515
516 23
		}
517
518 31
		return false;
519
520
	}
521
522
	/**
523
	 * Retrieve the total earnings for the form
524
	 *
525
	 * @since 1.0
526
	 * @return float
527
	 */
528 53
	public function get_earnings() {
529
530 53
		if ( ! isset( $this->earnings ) ) {
531
532 53
			if ( '' == get_post_meta( $this->ID, '_give_form_earnings', true ) ) {
533 29
				add_post_meta( $this->ID, '_give_form_earnings', 0 );
534 29
			}
535
536 53
			$this->earnings = get_post_meta( $this->ID, '_give_form_earnings', true );
537
538 53
			if ( $this->earnings < 0 ) {
539
				// Never let earnings be less than zero
540
				$this->earnings = 0;
541
			}
542
543 53
		}
544
545 53
		return $this->earnings;
546
547
	}
548
549
	/**
550
	 * Increase the earnings by the given amount
551
	 *
552
	 * @since 1.0
553
	 * @return float|false
554
	 */
555 42
	public function increase_earnings( $amount = 0 ) {
556
557 42
		$earnings   = give_get_form_earnings_stats( $this->ID );
558 42
		$new_amount = $earnings + (float) $amount;
559
560 42
		if ( $this->update_meta( '_give_form_earnings', $new_amount ) ) {
561
562 42
			$this->earnings = $new_amount;
563
564 42
			return $this->earnings;
565
566
		}
567
568 1
		return false;
569
570
	}
571
572
	/**
573
	 * Decrease the earnings by the given amount
574
	 *
575
	 * @since 1.0
576
	 * @return float|false
577
	 */
578 31
	public function decrease_earnings( $amount ) {
579
580 31
		$earnings = give_get_form_earnings_stats( $this->ID );
581
582 31
		if ( $earnings > 0 ) {
583
			// Only decrease if greater than zero
584 26
			$new_amount = $earnings - (float) $amount;
585
586
587 26
			if ( $this->update_meta( '_give_form_earnings', $new_amount ) ) {
588
589 5
				$this->earnings = $new_amount;
590
591 5
				return $this->earnings;
592
593
			}
594
595 23
		}
596
597 31
		return false;
598
599
	}
600
601
	/**
602
	 * Determine if the donation is free or if the given price ID is free
603
	 *
604
	 * @since 1.0
605
	 * @return bool
606
	 */
607
	public function is_free( $price_id = false ) {
608
609
		$is_free          = false;
610
		$variable_pricing = give_has_variable_prices( $this->ID );
611
612
		if ( $variable_pricing && ! is_null( $price_id ) && $price_id !== false ) {
613
			$price = give_get_price_option_amount( $this->ID, $price_id );
614
		} elseif ( ! $variable_pricing ) {
615
			$price = get_post_meta( $this->ID, '_give_set_price', true );
616
		}
617
618
		if ( isset( $price ) && (float) $price == 0 ) {
619
			$is_free = true;
620
		}
621
622
		return (bool) apply_filters( 'give_is_free_donation', $is_free, $this->ID, $price_id );
623
624
	}
625
626
627
	/**
628
	 * Updates a single meta entry for the donation form
629
	 *
630
	 * @since  1.5
631
	 * @access private
632
	 *
633
	 * @param  string $meta_key The meta_key to update
634
	 * @param  string|array|object $meta_value The value to put into the meta
635
	 *
636
	 * @return bool             The result of the update query
637
	 */
638 51
	private function update_meta( $meta_key = '', $meta_value = '' ) {
639
640 51
		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...
641
642 51
		if ( empty( $meta_key ) || empty( $meta_value ) ) {
643 2
			return false;
644
		}
645
646
		// Make sure if it needs to be serialized, we do
647 51
		$meta_value = maybe_serialize( $meta_value );
648
649 51
		if ( is_numeric( $meta_value ) ) {
650 51
			$value_type = is_float( $meta_value ) ? '%f' : '%d';
651 51
		} else {
652
			$value_type = "'%s'";
653
		}
654
655 51
		$sql = $wpdb->prepare( "UPDATE $wpdb->postmeta SET meta_value = $value_type WHERE post_id = $this->ID AND meta_key = '%s'", $meta_value, $meta_key );
656
657 51
		if ( $wpdb->query( $sql ) ) {
658
659 42
			clean_post_cache( $this->ID );
660
661 42
			return true;
662
663
		}
664
665 24
		return false;
666
	}
667
668
669
}
670