Completed
Branch BUG-9179-default-price-please (cae472)
by
unknown
85:30 queued 68:14
created

EE_Event::set_donations()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 3
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php if ( !defined( 'EVENT_ESPRESSO_VERSION' ) ) {
2
	exit( 'No direct script access allowed' );
3
}
4
5
/**
6
 * EE_Event
7
 *
8
 * @package 			Event Espresso
9
 * @subpackage 	includes/models/
10
 * @author 				Mike Nelson
11
 */
12
class EE_Event extends EE_CPT_Base implements EEI_Line_Item_Object, EEI_Admin_Links, EEI_Has_Icon {
13
14
	/**
15
	 * cached value for the the logical active status for the event
16
	 * @see get_active_status()
17
	 * @var string
18
	 */
19
	protected $_active_status = '';
20
21
	/**
22
	 * This is just used for caching the Primary Datetime for the Event on initial retrieval
23
	 * @var EE_Datetime
24
	 */
25
	protected $_Primary_Datetime;
26
27
28
29
	/**
30
	 *
31
	 * @param array $props_n_values  incoming values
32
	 * @param string $timezone  incoming timezone (if not set the timezone set for the website will be
33
	 *                          		used.)
34
	 * @param array $date_formats  incoming date_formats in an array where the first value is the
35
	 *                             		    date_format and the second value is the time format
36
	 * @return EE_Event
37
	 */
38
	public static function new_instance( $props_n_values = array(), $timezone = null, $date_formats = array() ) {
39
		$has_object = parent::_check_for_object( $props_n_values, __CLASS__ );
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (_check_for_object() instead of new_instance()). Are you sure this is correct? If so, you might want to change this to $this->_check_for_object().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
40
		return $has_object ? $has_object : new self( $props_n_values, false, $timezone, $date_formats );
41
	}
42
43
44
45
	/**
46
	 * @param array $props_n_values  incoming values from the database
47
	 * @param string $timezone  incoming timezone as set by the model.  If not set the timezone for
48
	 *                          		the website will be used.
49
	 * @return EE_Event
50
	 */
51
	public static function new_instance_from_db( $props_n_values = array(), $timezone = null ) {
52
		return new self( $props_n_values, TRUE, $timezone );
53
	}
54
55
56
57
	/**
58
	 * Overrides parent set() method so that all calls to set( 'status', $status ) can be routed to internal methods
59
	 *
60
	 * @param string $field_name
61
	 * @param mixed  $field_value
62
	 * @param bool   $use_default
63
	 */
64
	public function set( $field_name, $field_value, $use_default = false ) {
65
		switch ( $field_name ) {
66
			case 'status' :
67
				$this->set_status( $field_value, $use_default );
68
				break;
69
			default :
70
				parent::set( $field_name, $field_value, $use_default );
71
		}
72
	}
73
74
75
76
	/**
77
	 *    set_status
78
	 *
79
	 * Checks if event status is being changed to SOLD OUT
80
	 * and updates event meta data with previous event status
81
	 * so that we can revert things if/when the event is no longer sold out
82
	 *
83
	 * @access public
84
	 * @param string $new_status
85
	 * @param bool   $use_default
86
	 * @return bool|void
87
	 * @throws \EE_Error
88
	 */
89
	public function set_status( $new_status = null, $use_default = false ) {
90
		// get current Event status
91
		$old_status = $this->status();
92
		// if status has changed
93 View Code Duplication
		if ( $old_status != $new_status ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
94
			// TO sold_out
95
			if ( $new_status == EEM_Event::sold_out ) {
96
				// save the previous event status so that we can revert if the event is no longer sold out
97
				$this->add_post_meta( '_previous_event_status', $old_status );
98
				do_action( 'AHEE__EE_Event__set_status__to_sold_out', $this, $old_status, $new_status );
99
				// OR FROM  sold_out
100
			} else if ( $old_status == EEM_Event::sold_out ) {
101
				$this->delete_post_meta( '_previous_event_status' );
102
				do_action( 'AHEE__EE_Event__set_status__from_sold_out', $this, $old_status, $new_status );
103
			}
104
			// update status
105
			parent::set( 'status', $new_status, $use_default );
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (set() instead of set_status()). Are you sure this is correct? If so, you might want to change this to $this->set().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
106
			do_action( 'AHEE__EE_Event__set_status__after_update', $this );
107
			return true;
108
		} else {
109
			// even though the old value matches the new value, it's still good to
110
			// allow the parent set method to have a say
111
			parent::set( 'status', $new_status, $use_default );
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (set() instead of set_status()). Are you sure this is correct? If so, you might want to change this to $this->set().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
112
			return true;
113
		}
114
	}
115
116
117
118
	/**
119
	 * Gets all the datetimes for this event
120
	 *
121
	 * @param array $query_params like EEM_Base::get_all
122
	 * @return EE_Datetime[]
123
	 */
124
	public function datetimes( $query_params = array() ) {
125
		return $this->get_many_related( 'Datetime', $query_params );
126
	}
127
128
129
130
	/**
131
	 * Gets all the datetimes for this event, ordered by DTT_EVT_start in ascending order
132
	 *
133
	 * @return EE_Datetime[]
134
	 */
135
	public function datetimes_in_chronological_order() {
136
		return $this->get_many_related( 'Datetime', array( 'order_by' => array( 'DTT_EVT_start' => 'ASC' ) ) );
137
	}
138
139
140
141
	/**
142
	 * Gets all the datetimes for this event, ordered by the DTT_order on the datetime.
143
	 * @darren, we should probably UNSET timezone on the EEM_Datetime model
144
	 * after running our query, so that this timezone isn't set for EVERY query
145
	 * on EEM_Datetime for the rest of the request, no?
146
	 *
147
	 * @param boolean $show_expired whether or not to include expired events
148
	 * @param boolean $show_deleted whether or not to include deleted events
149
	 * @param null $limit
150
	 * @return \EE_Datetime[]
151
	 */
152
	public function datetimes_ordered( $show_expired = true, $show_deleted = false, $limit = null ) {
153
		return EEM_Datetime::instance( $this->_timezone )->get_datetimes_for_event_ordered_by_DTT_order( $this->ID(), $show_expired, $show_deleted, $limit );
154
	}
155
156
157
158
	/**
159
	 * Returns one related datetime. Mostly only used by some legacy code.
160
	 * @return EE_Datetime
161
	 */
162
	public function first_datetime() {
163
		return $this->get_first_related( 'Datetime' );
164
	}
165
166
167
168
	/**
169
	 * Returns the 'primary' datetime for the event
170
	 * @param bool $try_to_exclude_expired
171
	 * @param bool $try_to_exclude_deleted
172
	 * @return EE_Datetime
173
	 */
174
	public function primary_datetime( $try_to_exclude_expired = TRUE, $try_to_exclude_deleted = TRUE ) {
175
		if ( !empty ( $this->_Primary_Datetime ) ) {
176
			return $this->_Primary_Datetime;
177
		}
178
		$this->_Primary_Datetime = EEM_Datetime::instance( $this->_timezone )->get_primary_datetime_for_event( $this->ID(), $try_to_exclude_expired, $try_to_exclude_deleted );
179
		return $this->_Primary_Datetime;
180
	}
181
182
183
184
	/**
185
	 * Gets all the tickets available for purchase of this event
186
	 * @param array $query_params like EEM_Base::get_all
187
	 * @return EE_Ticket[]
188
	 */
189
	public function tickets( $query_params = array() ) {
190
		//first get all datetimes
191
		$datetimes = $this->datetimes_ordered();
192
		if ( ! $datetimes ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $datetimes of type EE_Base_Class[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
193
			return array();
194
		}
195
196
		$datetime_ids = array();
197
		foreach ( $datetimes as $datetime ) {
198
			$datetime_ids[] = $datetime->ID();
199
		}
200
201
		$where_params = array( 'Datetime.DTT_ID' => array( 'IN', $datetime_ids ) );
202
203
		//if incoming $query_params has where conditions let's merge but not override existing.
204
		if ( is_array( $query_params ) && isset( $query_params[0]) ) {
205
			$where_params = array_merge( $query_params[0], $where_params );
206
			unset( $query_params[0] );
207
		}
208
209
		//now add $where_params to $query_params
210
		$query_params[0] = $where_params;
211
212
		return EEM_Ticket::instance()->get_all( $query_params );
213
	}
214
215
216
217
	/**
218
	 * @return bool
219
	 */
220
	function additional_limit() {
221
		return $this->get( 'EVT_additional_limit' );
222
	}
223
224
225
226
	/**
227
	 * @return bool
228
	 */
229
	function allow_overflow() {
230
		return $this->get( 'EVT_allow_overflow' );
231
	}
232
233
234
235
	/**
236
	 * @return bool
237
	 */
238
	function created() {
239
		return $this->get( 'EVT_created' );
240
	}
241
242
243
244
	/**
245
	 * @return bool
246
	 */
247
	function description() {
248
		return $this->get( 'EVT_desc' );
249
	}
250
251
252
253
	/**
254
	 * Runs do_shortcode and wpautop on the description
255
	 * @return string of html
256
	 */
257
	function description_filtered() {
258
		return $this->get_pretty( 'EVT_desc' );
259
	}
260
261
262
263
	/**
264
	 * @return bool
265
	 */
266
	function display_description() {
267
		return $this->get( 'EVT_display_desc' );
268
	}
269
270
271
272
	/**
273
	 * @return bool
274
	 */
275
	function display_ticket_selector() {
276
		return (bool)$this->get( 'EVT_display_ticket_selector' );
277
	}
278
279
280
281
	/**
282
	 * @return bool
283
	 */
284
	function external_url() {
285
		return $this->get( 'EVT_external_URL' );
286
	}
287
288
289
290
	/**
291
	 * @return bool
292
	 */
293
	function member_only() {
294
		return $this->get( 'EVT_member_only' );
295
	}
296
297
298
299
	/**
300
	 * @return bool
301
	 */
302
	function phone() {
303
		return $this->get( 'EVT_phone' );
304
	}
305
306
307
308
	/**
309
	 * @return bool
310
	 */
311
	function modified() {
312
		return $this->get( 'EVT_modified' );
313
	}
314
315
316
317
	/**
318
	 * @return bool
319
	 */
320
	function name() {
321
		return $this->get( 'EVT_name' );
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->get('EVT_name'); (boolean) is incompatible with the return type declared by the interface EEI_Line_Item_Object::name of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
322
	}
323
324
325
326
	/**
327
	 * @return bool
328
	 */
329
	function order() {
330
		return $this->get( 'EVT_order' );
331
	}
332
333
334
335
	/**
336
	 * @return bool|string
337
	 */
338
	function default_registration_status() {
339
		$event_default_registration_status = $this->get( 'EVT_default_registration_status' );
340
		return !empty( $event_default_registration_status ) ? $event_default_registration_status : EE_Registry::instance()->CFG->registration->default_STS_ID;
341
	}
342
343
344
345
	/**
346
	 * @param int  $num_words
347
	 * @param null $more
348
	 * @param bool $not_full_desc
349
	 * @return bool|string
350
	 */
351
	function short_description( $num_words = 55, $more = NULL, $not_full_desc = FALSE ) {
352
		$short_desc = $this->get( 'EVT_short_desc' );
353
		if ( !empty( $short_desc ) || $not_full_desc ) {
354
			return $short_desc;
355
		}
356
		else {
357
			$full_desc = $this->get( 'EVT_desc' );
358
			return wp_trim_words( $full_desc, $num_words, $more );
359
		}
360
	}
361
362
363
364
	/**
365
	 * @return bool
366
	 */
367
	function slug() {
368
		return $this->get( 'EVT_slug' );
369
	}
370
371
372
373
	/**
374
	 * @return bool
375
	 */
376
	function timezone_string() {
377
		return $this->get( 'EVT_timezone_string' );
378
	}
379
380
381
382
	/**
383
	 * @return bool
384
	 */
385
	function visible_on() {
386
		return $this->get( 'EVT_visible_on' );
387
	}
388
389
390
391
	/**
392
	 * @return bool
393
	 */
394
	function wp_user() {
395
		return $this->get( 'EVT_wp_user' );
396
	}
397
398
399
400
	/**
401
	 * @return bool
402
	 */
403
	function donations() {
404
		return $this->get( 'EVT_donations' );
405
	}
406
407
408
409
	/**
410
	 * @param $limit
411
	 */
412
	function set_additional_limit( $limit ) {
413
		$this->set( 'EVT_additional_limit', $limit );
414
	}
415
416
417
418
	/**
419
	 * @param $created
420
	 */
421
	function set_created( $created ) {
422
		$this->set( 'EVT_created', $created );
423
	}
424
425
426
427
	/**
428
	 * @param $desc
429
	 */
430
	function set_description( $desc ) {
431
		$this->set( 'EVT_desc', $desc );
432
	}
433
434
435
436
	/**
437
	 * @param $display_desc
438
	 */
439
	function set_display_description( $display_desc ) {
440
		$this->set( 'EVT_display_desc', $display_desc );
441
	}
442
443
444
445
	/**
446
	 * @param $display_ticket_selector
447
	 */
448
	function set_display_ticket_selector( $display_ticket_selector ) {
449
		$this->set( 'EVT_display_ticket_selector', $display_ticket_selector );
450
	}
451
452
453
454
	/**
455
	 * @param $external_url
456
	 */
457
	function set_external_url( $external_url ) {
458
		$this->set( 'EVT_external_URL', $external_url );
459
	}
460
461
462
463
	/**
464
	 * @param $member_only
465
	 */
466
	function set_member_only( $member_only ) {
467
		$this->set( 'EVT_member_only', $member_only );
468
	}
469
470
471
472
	/**
473
	 * @param $event_phone
474
	 */
475
	function set_event_phone( $event_phone ) {
476
		$this->set( 'EVT_phone', $event_phone );
477
	}
478
479
480
481
	/**
482
	 * @param $modified
483
	 */
484
	function set_modified( $modified ) {
485
		$this->set( 'EVT_modified', $modified );
486
	}
487
488
489
490
	/**
491
	 * @param $name
492
	 */
493
	function set_name( $name ) {
494
		$this->set( 'EVT_name', $name );
495
	}
496
497
498
499
	/**
500
	 * @param $order
501
	 */
502
	function set_order( $order ) {
503
		$this->set( 'EVT_order', $order );
504
	}
505
506
507
508
	/**
509
	 * @param $short_desc
510
	 */
511
	function set_short_description( $short_desc ) {
512
		$this->set( 'EVT_short_desc', $short_desc );
513
	}
514
515
516
517
	/**
518
	 * @param $slug
519
	 */
520
	function set_slug( $slug ) {
521
		$this->set( 'EVT_slug', $slug );
522
	}
523
524
525
526
	/**
527
	 * @param $timezone_string
528
	 */
529
	function set_timezone_string( $timezone_string ) {
530
		$this->set( 'EVT_timezone_string', $timezone_string );
531
	}
532
533
534
535
	/**
536
	 * @param $visible_on
537
	 */
538
	function set_visible_on( $visible_on ) {
539
		$this->set( 'EVT_visible_on', $visible_on );
540
	}
541
542
543
544
	/**
545
	 * @param $wp_user
546
	 */
547
	function set_wp_user( $wp_user ) {
548
		$this->set( 'EVT_wp_user', $wp_user );
549
	}
550
551
552
553
	/**
554
	 * @param $default_registration_status
555
	 */
556
	function set_default_registration_status( $default_registration_status ) {
557
		$this->set( 'EVT_default_registration_status', $default_registration_status );
558
	}
559
560
561
562
	/**
563
	 * @param $donations
564
	 */
565
	function set_donations( $donations ) {
566
		$this->set( 'EVT_donations', $donations );
567
	}
568
569
570
571
	/**
572
	 * Adds a venue to this event
573
	 * @param EE_Venue /int $venue_id_or_obj
574
	 * @return EE_Venue
575
	 */
576
	function add_venue( $venue_id_or_obj ) {
577
		return $this->_add_relation_to( $venue_id_or_obj, 'Venue' );
578
	}
579
580
581
582
	/**
583
	 * Removes a venue from the event
584
	 * @param EE_Venue /int $venue_id_or_obj
585
	 * @return EE_Venue
586
	 */
587
	function remove_venue( $venue_id_or_obj ) {
588
		return $this->_remove_relation_to( $venue_id_or_obj, 'Venue' );
589
	}
590
591
592
593
	/**
594
	 * Gets all the venues related ot the event. May provide additional $query_params if desired
595
	 * @param array $query_params like EEM_Base::get_all's $query_params
596
	 * @return EE_Venue[]
597
	 */
598
	function venues( $query_params = array() ) {
599
		return $this->get_many_related( 'Venue', $query_params );
600
	}
601
602
603
604
	/**
605
	 * check if event id is present and if event is published
606
	 * @access public
607
	 * @return boolean true yes, false no
608
	 */
609
	private function _has_ID_and_is_published() {
610
		// first check if event id is present and not NULL, then check if this event is published (or any of the equivalent "published" statuses)
611
		return ( $this->ID() && $this->ID() !== NULL && ( $this->status() == 'publish' || $this->status() == EEM_Event::sold_out || $this->status() == EEM_Event::postponed || $this->status() == EEM_Event::cancelled ) ) ? TRUE : FALSE;
612
	}
613
614
615
616
	/**
617
	 * This simply compares the internal dates with NOW and determines if the event is upcoming or not.
618
	 * @access public
619
	 * @return boolean true yes, false no
620
	 */
621 View Code Duplication
	public function is_upcoming() {
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...
622
		// check if event id is present and if this event is published
623
		if ( $this->is_inactive() ) {
624
			return FALSE;
625
		}
626
		// set initial value
627
		$upcoming = FALSE;
628
		//next let's get all datetimes and loop through them
629
		$datetimes = $this->datetimes_in_chronological_order();
630
		foreach ( $datetimes as $datetime ) {
631
			if ( $datetime instanceof EE_Datetime ) {
632
				//if this dtt is expired then we continue cause one of the other datetimes might be upcoming.
633
				if ( $datetime->is_expired() ) {
634
					continue;
635
				}
636
				//if this dtt is active then we return false.
637
				if ( $datetime->is_active() ) {
638
					return FALSE;
639
				}
640
				//otherwise let's check upcoming status
641
				$upcoming = $datetime->is_upcoming();
642
			}
643
		}
644
		return $upcoming;
645
	}
646
647
648
649
	/**
650
	 * @return bool
651
	 */
652 View Code Duplication
	public function is_active() {
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...
653
		// check if event id is present and if this event is published
654
		if ( $this->is_inactive() ) {
655
			return FALSE;
656
		}
657
		// set initial value
658
		$active = FALSE;
659
		//next let's get all datetimes and loop through them
660
		$datetimes = $this->datetimes_in_chronological_order();
661
		foreach ( $datetimes as $datetime ) {
662
			if ( $datetime instanceof EE_Datetime ) {
663
				//if this dtt is expired then we continue cause one of the other datetimes might be active.
664
				if ( $datetime->is_expired() ) {
665
					continue;
666
				}
667
				//if this dtt is upcoming then we return false.
668
				if ( $datetime->is_upcoming() ) {
669
					return FALSE;
670
				}
671
				//otherwise let's check active status
672
				$active = $datetime->is_active();
673
			}
674
		}
675
		return $active;
676
	}
677
678
679
680
	/**
681
	 * @return bool
682
	 */
683 View Code Duplication
	public function is_expired() {
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...
684
		// check if event id is present and if this event is published
685
		if ( $this->is_inactive() ) {
686
			return FALSE;
687
		}
688
		// set initial value
689
		$expired = FALSE;
690
		//first let's get all datetimes and loop through them
691
		$datetimes = $this->datetimes_in_chronological_order();
692
		foreach ( $datetimes as $datetime ) {
693
			if ( $datetime instanceof EE_Datetime ) {
694
				//if this dtt is upcoming or active then we return false.
695
				if ( $datetime->is_upcoming() || $datetime->is_active() ) {
696
					return FALSE;
697
				}
698
				//otherwise let's check active status
699
				$expired = $datetime->is_expired();
700
			}
701
		}
702
		return $expired;
703
	}
704
705
706
707
	/**
708
	 * @return bool
709
	 */
710
	public function is_inactive() {
711
		// check if event id is present and if this event is published
712
		if ( $this->_has_ID_and_is_published() ) {
713
			return FALSE;
714
		}
715
		return TRUE;
716
	}
717
718
719
720
	/**
721
	 *    perform_sold_out_status_check
722
	 *    checks all of this events's datetime  reg_limit - sold values to determine if ANY datetimes have spaces available...
723
	 *    if NOT, then the event status will get toggled to 'sold_out'
724
	 *
725
	 * @access public
726
	 * @return bool    return the ACTUAL sold out state.
727
	 */
728
	public function perform_sold_out_status_check() {
729
		// get all unexpired untrashed tickets
730
		$tickets = $this->tickets( array(
731
			array(
732
				'TKT_end_date'   => array( '>=', EEM_Ticket::instance()->current_time_for_query( 'TKT_end_date' ) ),
733
				'TKT_deleted'    => false
734
			)
735
		));
736
		// if all the tickets are just expired, then don't update the event status to sold out
737
		if ( empty( $tickets )) {
738
			return true;
739
		}
740
		// set initial value
741
		$spaces_remaining = 0;
742
		foreach( $tickets as $ticket ) {
743
			if ( $ticket instanceof EE_Ticket ) {
744
				$spaces_remaining += $ticket->qty( 'saleable' );
745
			}
746
		}
747
		if ( $spaces_remaining === 0 ) {
748
			$this->set_status( EEM_Event::sold_out );
749
			if ( !is_admin() || ( is_admin() && defined( 'DOING_AJAX' ) ) ) {
750
				$this->save();
751
			}
752
			$sold_out = TRUE;
753
		} else {
754
			$sold_out = FALSE;
755
			// was event previously marked as sold out ?
756
			if ( $this->status() == EEM_Event::sold_out ) {
757
				// revert status to previous value, if it was set
758
				$previous_event_status = $this->get_post_meta( '_previous_event_status', true );
759
				if ( $previous_event_status ) {
760
					$this->set_status( $previous_event_status );
761
				}
762
			}
763
		}
764
		//note: I considered changing the EEM_Event status away from sold_out if this status check reveals that it's no longer sold out (yet the status is still set as sold out) but the problem is... what do we change the status BACK to?  We can't always assume that the previous event status was 'published' because this status check is always done in the admin and its entirely possible the event admin manually changes to sold_out status from some other status.  We also don't want a draft event to become a "publish event" because the sold out check reveals its NOT sold out.
765
		// So I'll forgo the automatic switch away from sold out status for now and instead just return the $sold out status... so this check can be used to validate the TRUE sold out status regardless of what the Event status is set to.
766
		return $sold_out;
767
	}
768
769
770
	/**
771
	 * This returns the total remaining spaces for sale on this event.
772
	 *
773
	 * ############################
774
	 * VERY IMPORTANT FOR DEVELOPERS:
775
	 * While included here, this method is still being tested internally, so its signature and behaviour COULD change. While
776
	 * this comment block is in place, usage is at your own risk and know that it may change in future builds.
777
	 * ############################
778
	 *
779
	 * @uses EE_Event::total_available_spaces()
780
	 * @return float|int  (EE_INF is returned as float)
781
	 */
782
	public function spaces_remaining_for_sale() {
783
		//first get total available spaces including consideration for tickets that have already sold.
784
		$spaces_available = $this->total_available_spaces( true );
785
786
		//if total available = 0, then exit right away because that means everything is expired.
787
		if ( $spaces_available === 0 ) {
788
			return 0;
789
		}
790
791
		//subtract total approved registrations from spaces available to get how many are remaining.
792
		$spots_taken = EEM_Registration::instance()->count( array( array( 'EVT_ID' => $this->ID(), 'STS_ID' => EEM_Registration::status_id_approved ) ), 'REG_ID', true );
793
		$spaces_remaining = $spaces_available - $spots_taken;
794
795
		return $spaces_remaining > 0 ? $spaces_remaining : 0;
796
	}
797
798
799
800
801
802
	/**
803
	 * This returns the total spaces available for an event while considering all the qtys on the tickets and the reg limits
804
	 * on the datetimes attached to this event.
805
	 *
806
	 * ############################
807
	 * VERY IMPORTANT FOR DEVELOPERS:
808
	 * While included here, this method is still being tested internally, so its signature and behaviour COULD change. While
809
	 * this comment block is in place, usage is at your own risk and know that it may change in future builds.
810
	 * ############################
811
	 *
812
	 * Note: by "spaces available" we are not returning how many spaces remain.  That is a calculation involving using the value
813
	 * from this method and subtracting the approved registrations for the event.
814
	 *
815
	 * @param   bool    $current_total_available    Whether to consider any tickets that have already sold in our calculation.
816
	 *                                              If this is false, then we return the most tickets that could ever be sold
817
	 *                                              for this event with the datetime and tickets setup on the event under optimal
818
	 *                                              selling conditions.  Otherwise we return a live calculation of spaces available
819
	 *                                              based on tickets sold.  Depending on setup and stage of sales, this
820
	 *                                              may appear to equal remaining tickets.  However, the more tickets are
821
	 *                                              sold out, the more accurate the "live" total is.
822
	 *
823
	 * @return  int|float  (Note: if EE_INF is returned its considered a float by PHP)
824
	 */
825
	public function total_available_spaces( $current_total_available = false ) {
826
		$spaces_available = 0;
827
828
		//first get all tickets on the event and include expired tickets
829
		$tickets = $this->tickets( array( 'default_where_conditions' => 'none' ) );
830
		$ticket_sums = array();
831
		$datetime_limits = array();
832
833
		//loop through tickets and normalize them
834
		foreach ( $tickets as $ticket ) {
835
			$datetimes = $ticket->datetimes( array( 'order_by' => array( 'DTT_reg_limit' => 'ASC' ) ) );
836
837
			if ( empty( $datetimes ) ) {
838
				continue;
839
			}
840
841
			//first datetime should be the lowest datetime
842
			$least_datetime = reset( $datetimes );
843
844
			//lets reset the ticket quantity to be the lower of either the lowest datetime reg limit or the ticket quantity
845
			//IF datetimes sold (and we're not doing current live total available, then use spaces remaining for datetime, not reg_limit.
846
			if ( $current_total_available ) {
847
				if ( $ticket->is_remaining() ) {
848
					$remaining = $ticket->remaining();
849
				} else {
850
					$spaces_available += $ticket->sold();
851
					//and we don't cache this ticket to our list because its sold out.
852
					continue;
853
				}
854
			} else {
855
				$remaining = min( $ticket->qty(), $least_datetime->reg_limit() );
0 ignored issues
show
Documentation Bug introduced by
The method reg_limit does not exist on object<EE_Base_Class>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
856
			}
857
858
			//if $ticket_limit == infinity then let's drop out right away and just return that because any infinity amount trumps all other "available" amounts.
859
			if ( $remaining == EE_INF ) {
860
				return EE_INF;
861
			}
862
863
			//multiply normalized $tkt quantity by the number of datetimes on the ticket as the "sum"
864
			//also include the sum of all the datetime reg limits on the ticket for breaking ties.
865
			$ticket_sums[$ticket->ID()]['sum'] = $remaining * count( $datetimes );
866
			$ticket_sums[$ticket->ID()]['datetime_sums'] = 0;
867
			foreach ( $datetimes as $datetime ) {
868
				if ( $datetime->reg_limit() === EE_INF ) {
869
					$ticket_sums[$ticket->ID()]['datetime_sums'] = EE_INF;
870
				} else {
871
					$ticket_sums[ $ticket->ID() ]['datetime_sums'] += $current_total_available ? $datetime->spaces_remaining() : $datetime->reg_limit();
872
				}
873
				$datetime_limits[$datetime->ID()] = $current_total_available ? $datetime->spaces_remaining() : $datetime->reg_limit();
874
			}
875
			$ticket_sums[$ticket->ID()]['ticket'] = $ticket;
876
		}
877
878
		//The order is sorted by lowest available first (which is calculated for each ticket by multiplying the normalized
879
		//ticket quantity by the number of datetimes on the ticket).  For tie-breakers, then the next sort is based on the
880
		//ticket with the greatest sum of all remaining datetime->spaces_remaining() ( or $datetime->reg_limit() if not
881
		//$current_total_available ) for the datetimes on the ticket.
882
		usort( $ticket_sums, function( $a, $b ) {
883
			if ( $a['sum'] == $b['sum'] ) {
884
				if ( $a['datetime_sums'] == $b['datetime_sums'] ) {
885
					return 0;
886
				}
887
888
				return $a['datetime_sums'] < $b['datetime_sums'] ? 1 : -1;
889
			}
890
			return ( $a['sum'] < $b['sum'] ) ? -1 : 1;
891
		});
892
893
		//now let's loop through the sorted tickets and simulate sellouts
894
		foreach ( $ticket_sums as $ticket_info ) {
895
			if ( $ticket_info['ticket'] instanceof EE_Ticket ) {
896
897
				$datetimes = $ticket_info['ticket']->datetimes( array( 'order_by' => array( 'DTT_reg_limit' => 'ASC' ) ) );
898
				//need to sort these $datetimes by remaining (only if $current_total_available)
899
				//setup datetimes for simulation
900
				$ticket_datetimes_remaining = array();
901
				foreach( $datetimes as $datetime ) {
902
					$ticket_datetimes_remaining[$datetime->ID()]['rem'] = $datetime_limits[$datetime->ID()];
903
					$ticket_datetimes_remaining[$datetime->ID()]['datetime'] = $datetime;
904
				}
905
				usort( $ticket_datetimes_remaining, function( $a, $b ) {
906
					if ( $a['rem'] == $b['rem'] ) {
907
						return 0;
908
					}
909
					return ( $a['rem'] < $b['rem'] ) ? -1 : 1;
910
				});
911
912
913
				//get the remaining on the first datetime (which should be the one with the least remaining) and that is
914
				//what we add to the spaces_available running total.  Then we need to decrease the remaining on our datetime tracker.
915
				$lowest_datetime = reset( $ticket_datetimes_remaining );
916
917
				//need to get the lower of; what the remaining is on the lowest datetime, and the remaining on the ticket.
918
				// If this ends up being 0 (because of previous tickets in our simulation selling out), then it has already
919
				// been tracked on $spaces available and this ticket is now sold out for the simulation, so we can continue
920
				// to the next ticket.
921
				if ( $current_total_available ) {
922
					$remaining = min( $lowest_datetime['rem'], $ticket_info['ticket']->remaining() );
923
				} else {
924
					$remaining = min( $lowest_datetime['rem'], $ticket_info['ticket']->qty() );
925
				}
926
927
				//if $remaining is infinite that means that all datetimes on this ticket are infinite but we've made it here because all
928
				//tickets have a quantity.  So we don't have to track datetimes, we can just use ticket quantities for total
929
				//available.
930
				if ( $remaining === EE_INF ) {
931
					$spaces_available += $ticket_info['ticket']->qty();
932
					continue;
933
				}
934
935
				//if ticket has sold amounts then we also need to add that (but only if doing live counts)
936
				if ( $current_total_available ) {
937
					$spaces_available += $ticket_info['ticket']->sold();
938
				}
939
940
				if ( $remaining <= 0 ) {
941
					continue;
942
				} else {
943
					$spaces_available += $remaining;
944
				}
945
946
				//loop through the datetimes and sell them out!
947
				foreach ( $ticket_datetimes_remaining as $datetime_info ) {
948
					if ( $datetime_info['datetime'] instanceof EE_Datetime ) {
949
						$datetime_limits[ $datetime_info['datetime']->ID() ] += - $remaining;
950
					}
951
				}
952
			}
953
		}
954
955
		return $spaces_available;
956
	}
957
958
959
960
	/**
961
	 * Checks if the event is set to sold out
962
	 * @param  bool $actual whether or not to perform calculations to not only figure the actual status but also to flip the status if necessary to sold out If false, we just check the existing status of the event
963
	 * @return boolean
964
	 */
965
	public function is_sold_out( $actual = FALSE ) {
966
		if ( ! $actual ) {
967
			return $this->status() == EEM_Event::sold_out;
968
		}
969
		else {
970
			return $this->perform_sold_out_status_check();
971
		}
972
	}
973
974
975
976
	/**
977
	 * Checks if the event is marked as postponed
978
	 * @return boolean
979
	 */
980
	public function is_postponed() {
981
		return $this->status() == EEM_Event::postponed;
982
	}
983
984
985
986
	/**
987
	 * Checks if the event is marked as cancelled
988
	 * @return boolean
989
	 */
990
	public function is_cancelled() {
991
		return $this->status() == EEM_Event::cancelled;
992
	}
993
994
995
996
	/**
997
	 * Get the logical active status in a hierarchical order for all the datetimes.  Note
998
	 *
999
	 * Basically, we order the datetimes by EVT_start_date.  Then first test on whether the event is published.  If its
1000
	 * NOT published then we test for whether its expired or not.  IF it IS published then we test first on whether an
1001
	 * event has any active dates.  If no active dates then we check for any upcoming dates.  If no upcoming dates then
1002
	 * the event is considered expired.
1003
	 *
1004
	 * NOTE: this method does NOT calculate whether the datetimes are sold out when event is published.  Sold Out is a status
1005
	 * set on the EVENT when it is not published and thus is done
1006
	 *
1007
	 * @param bool $reset
1008
	 *
1009
	 * @return bool | string - based on EE_Datetime active constants or FALSE if error.
1010
	 */
1011
	public function get_active_status( $reset = false ) {
1012
		// if the active status has already been set, then just use that value (unless we are resetting it)
1013
		if ( ! empty( $this->_active_status ) && ! $reset ) {
1014
			return $this->_active_status;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->_active_status; (string) is incompatible with the return type documented by EE_Event::get_active_status of type boolean.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
1015
		}
1016
		//first check if event id is present on this object
1017
		if ( ! $this->ID() ) {
1018
			return false;
1019
		}
1020
1021
		$where_params_for_event  = array( array( 'EVT_ID' => $this->ID() ) );
1022
1023
		//if event is published:
1024
		if ( $this->status() === 'publish' ) {
1025
			//active?
1026
			if ( EEM_Datetime::instance()->get_datetime_count_for_status( EE_Datetime::active, $where_params_for_event ) > 0 ) {
1027
				$this->_active_status = EE_Datetime::active;
1028
			} else {
1029
				//upcoming?
1030
				if ( EEM_Datetime::instance()->get_datetime_count_for_status( EE_Datetime::upcoming, $where_params_for_event  ) > 0 ) {
1031
					$this->_active_status = EE_Datetime::upcoming;
1032
				} else {
1033
					//expired?
1034
					if ( EEM_Datetime::instance()->get_datetime_count_for_status( EE_Datetime::expired, $where_params_for_event  ) > 0 ) {
1035
						$this->_active_status = EE_Datetime::expired;
1036
					} else {
1037
						//it would be odd if things make it this far because it basically means there are no datetime's
1038
						//attached to the event.  So in this case it will just be considered inactive.
1039
						$this->_active_status = EE_Datetime::inactive;
1040
					}
1041
				}
1042
			}
1043
		} else {
1044
			//the event is not published, so let's just set it's active status according to its' post status
1045
			switch ( $this->status() ) {
1046
				case EEM_Event::sold_out :
1047
					$this->_active_status = EE_Datetime::sold_out;
1048
					break;
1049
				case EEM_Event::cancelled :
1050
					$this->_active_status = EE_Datetime::cancelled;
1051
					break;
1052
				case EEM_Event::postponed :
1053
					$this->_active_status = EE_Datetime::postponed;
1054
					break;
1055
				default :
1056
					$this->_active_status = EE_Datetime::inactive;
1057
			}
1058
		}
1059
		return $this->_active_status;
1060
	}
1061
1062
1063
1064
	/**
1065
	 *    pretty_active_status
1066
	 *
1067
	 * @access public
1068
	 * @param boolean $echo     whether to return (FALSE), or echo out the result (TRUE)
1069
	 * @return mixed void|string
1070
	 */
1071
	public function pretty_active_status( $echo = TRUE ) {
1072
		$active_status = $this->get_active_status();
1073
		$status = '<span class="ee-status event-active-status-' . $active_status . '">' . EEH_Template::pretty_status( $active_status, FALSE, 'sentence' ) . '</span>';
0 ignored issues
show
Documentation introduced by
$active_status is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1074
		if ( $echo ) {
1075
			echo $status;
1076
			return '';
1077
		}
1078
		return $status;
1079
	}
1080
1081
1082
1083
	/**
1084
	 * @return bool|int
1085
	 */
1086
	public function get_number_of_tickets_sold() {
1087
		$tkt_sold = 0;
1088
		if ( !$this->ID() ) {
1089
			return 0;
1090
		}
1091
		$datetimes = $this->datetimes();
1092
		foreach ( $datetimes as $datetime ) {
1093
			if ( $datetime instanceof EE_Datetime ) {
1094
				$tkt_sold += $datetime->sold();
1095
			}
1096
		}
1097
		return $tkt_sold;
1098
	}
1099
1100
1101
1102
	/**
1103
	 * This just returns a count of all the registrations for this event
1104
	 * @access  public
1105
	 * @return int
1106
	 */
1107
	public function get_count_of_all_registrations() {
1108
		return EEM_Event::instance()->count_related( $this, 'Registration' );
1109
	}
1110
1111
1112
1113
	/**
1114
	 * This returns the ticket with the earliest start time that is available for this event (across all datetimes attached to the event)
1115
	 * @return EE_Ticket
1116
	 */
1117
	public function get_ticket_with_earliest_start_time() {
1118
		$where[ 'Datetime.EVT_ID' ] = $this->ID();
0 ignored issues
show
Coding Style Comprehensibility introduced by
$where was never initialized. Although not strictly required by PHP, it is generally a good practice to add $where = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1119
		$query_params = array( $where, 'order_by' => array( 'TKT_start_date' => 'ASC' ) );
1120
		return EE_Registry::instance()->load_model( 'Ticket' )->get_one( $query_params );
0 ignored issues
show
Bug introduced by
The method get_one cannot be called on \EE_Registry::instance()->load_model('Ticket') (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1121
	}
1122
1123
1124
1125
	/**
1126
	 * This returns the ticket with the latest end time that is available for this event (across all datetimes attached to the event)
1127
	 * @return EE_Ticket
1128
	 */
1129
	public function get_ticket_with_latest_end_time() {
1130
		$where[ 'Datetime.EVT_ID' ] = $this->ID();
0 ignored issues
show
Coding Style Comprehensibility introduced by
$where was never initialized. Although not strictly required by PHP, it is generally a good practice to add $where = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1131
		$query_params = array( $where, 'order_by' => array( 'TKT_end_date' => 'DESC' ) );
1132
		return EE_Registry::instance()->load_model( 'Ticket' )->get_one( $query_params );
0 ignored issues
show
Bug introduced by
The method get_one cannot be called on \EE_Registry::instance()->load_model('Ticket') (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1133
	}
1134
1135
1136
1137
	/**
1138
	 * This returns whether there are any tickets on sale for this event.
1139
	 * @return bool true = YES tickets on sale.
1140
	 */
1141
	public function tickets_on_sale() {
1142
		$earliest_ticket = $this->get_ticket_with_earliest_start_time();
1143
		$latest_ticket = $this->get_ticket_with_latest_end_time();
1144
		if ( !$latest_ticket instanceof EE_Ticket && !$earliest_ticket instanceof EE_Ticket ) {
1145
			return FALSE;
1146
		}
1147
		//check on sale for these two tickets.
1148
		if ( $latest_ticket->is_on_sale() || $earliest_ticket->is_on_sale() ) {
1149
			return TRUE;
1150
		}
1151
		return FALSE;
1152
	}
1153
1154
1155
1156
	/**
1157
	 * Gets the URL for viewing this event on the front-end. Overrides parent
1158
	 * to check for an external URL first
1159
	 * @return string
1160
	 */
1161
	public function get_permalink() {
1162
		if ( $this->external_url() ) {
1163
			return $this->external_url();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->external_url(); (boolean) is incompatible with the return type of the parent method EE_CPT_Base::get_permalink of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
1164
		}
1165
		else {
1166
			return parent::get_permalink();
1167
		}
1168
	}
1169
1170
1171
1172
	/**
1173
	 * Gets the first term for 'espresso_event_categories' we can find
1174
	 * @param array $query_params like EEM_Base::get_all
1175
	 * @return EE_Term
1176
	 */
1177
	public function first_event_category( $query_params = array() ) {
1178
		$query_params[ 0 ][ 'Term_Taxonomy.taxonomy' ] = 'espresso_event_categories';
1179
		$query_params[ 0 ][ 'Term_Taxonomy.Event.EVT_ID' ] = $this->ID();
1180
		return EEM_Term::instance()->get_one( $query_params );
1181
	}
1182
1183
1184
1185
	/**
1186
	 * Gets all terms for 'espresso_event_categories' we can find
1187
	 * @param array $query_params
1188
	 * @return EE_Term[]
1189
	 */
1190
	public function get_all_event_categories( $query_params = array() ) {
1191
		$query_params[ 0 ][ 'Term_Taxonomy.taxonomy' ] = 'espresso_event_categories';
1192
		$query_params[ 0 ][ 'Term_Taxonomy.Event.EVT_ID' ] = $this->ID();
1193
		return EEM_Term::instance()->get_all( $query_params );
1194
	}
1195
1196
	/**
1197
	 * Gets all the question groups, ordering them by QSG_order ascending
1198
	 * @param array $query_params @see EEM_Base::get_all
1199
	 * @return EE_Question_Group[]
1200
	 */
1201
	public function question_groups($query_params = array()){
1202
		$query_params = ! empty( $query_params ) ? $query_params : array( 'order_by' => array( 'QSG_order' => 'ASC' ));
1203
		return $this->get_many_related('Question_Group', $query_params);
1204
	}
1205
1206
1207
1208
1209
	/**
1210
	 * Implementation for EEI_Has_Icon interface method.
1211
	 * @see EEI_Visual_Representation for comments
1212
	 * @return string
1213
	 */
1214
	public function get_icon() {
1215
		return '<span class="dashicons dashicons-flag"></span>';
1216
	}
1217
1218
1219
1220
1221
	/**
1222
	 * Implementation for EEI_Admin_Links interface method.
1223
	 * @see EEI_Admin_Links for comments
1224
	 * @return string
1225
	 */
1226
	public function get_admin_details_link() {
1227
		return $this->get_admin_edit_link();
1228
	}
1229
1230
1231
1232
1233
1234
1235
	/**
1236
	 * Implementation for EEI_Admin_Links interface method.
1237
	 * @see EEI_Admin_Links for comments
1238
	 * @return string
1239
	 */
1240 View Code Duplication
	public function get_admin_edit_link() {
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...
1241
		EE_Registry::instance()->load_helper('URL');
1242
		return EEH_URL::add_query_args_and_nonce( array(
1243
			'page' => 'espresso_events',
1244
			'action' => 'edit',
1245
			'post' => $this->ID()
1246
			),
1247
			admin_url( 'admin.php' )
1248
		);
1249
	}
1250
1251
1252
1253
	/**
1254
	 * Implementation for EEI_Admin_Links interface method.
1255
	 * @see EEI_Admin_Links for comments
1256
	 * @return string
1257
	 */
1258 View Code Duplication
	public function get_admin_settings_link() {
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...
1259
		EE_Registry::instance()->load_helper('URL');
1260
		return EEH_URL::add_query_args_and_nonce( array(
1261
			'page' => 'espresso_events',
1262
			'action' => 'default_event_settings'
1263
			),
1264
			admin_url( 'admin.php' )
1265
		);
1266
	}
1267
1268
1269
1270
1271
1272
	/**
1273
	 * Implementation for EEI_Admin_Links interface method.
1274
	 * @see EEI_Admin_Links for comments
1275
	 * @return string
1276
	 */
1277 View Code Duplication
	public function get_admin_overview_link() {
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...
1278
1279
		EE_Registry::instance()->load_helper('URL');
1280
		return EEH_URL::add_query_args_and_nonce( array(
1281
			'page' => 'espresso_events',
1282
			'action' => 'default'
1283
		),
1284
			admin_url( 'admin.php' )
1285
		);
1286
	}
1287
1288
}
1289