Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like EE_Event often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use EE_Event, and based on these observations, apply Extract Interface, too.
1 | <?php if ( !defined( 'EVENT_ESPRESSO_VERSION' ) ) { |
||
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() ) { |
||
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 ) { |
||
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 ) { |
||
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 ) { |
||
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() ) { |
||
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() { |
||
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 ) { |
||
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() { |
||
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 ) { |
||
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() ) { |
||
214 | |||
215 | |||
216 | |||
217 | /** |
||
218 | * @return bool |
||
219 | */ |
||
220 | function additional_limit() { |
||
223 | |||
224 | |||
225 | |||
226 | /** |
||
227 | * @return bool |
||
228 | */ |
||
229 | function allow_overflow() { |
||
232 | |||
233 | |||
234 | |||
235 | /** |
||
236 | * @return bool |
||
237 | */ |
||
238 | function created() { |
||
241 | |||
242 | |||
243 | |||
244 | /** |
||
245 | * @return bool |
||
246 | */ |
||
247 | function description() { |
||
250 | |||
251 | |||
252 | |||
253 | /** |
||
254 | * Runs do_shortcode and wpautop on the description |
||
255 | * @return string of html |
||
256 | */ |
||
257 | function description_filtered() { |
||
260 | |||
261 | |||
262 | |||
263 | /** |
||
264 | * @return bool |
||
265 | */ |
||
266 | function display_description() { |
||
269 | |||
270 | |||
271 | |||
272 | /** |
||
273 | * @return bool |
||
274 | */ |
||
275 | function display_ticket_selector() { |
||
278 | |||
279 | |||
280 | |||
281 | /** |
||
282 | * @return bool |
||
283 | */ |
||
284 | function external_url() { |
||
287 | |||
288 | |||
289 | |||
290 | /** |
||
291 | * @return bool |
||
292 | */ |
||
293 | function member_only() { |
||
296 | |||
297 | |||
298 | |||
299 | /** |
||
300 | * @return bool |
||
301 | */ |
||
302 | function phone() { |
||
305 | |||
306 | |||
307 | |||
308 | /** |
||
309 | * @return bool |
||
310 | */ |
||
311 | function modified() { |
||
314 | |||
315 | |||
316 | |||
317 | /** |
||
318 | * @return bool |
||
319 | */ |
||
320 | function name() { |
||
323 | |||
324 | |||
325 | |||
326 | /** |
||
327 | * @return bool |
||
328 | */ |
||
329 | function order() { |
||
332 | |||
333 | |||
334 | |||
335 | /** |
||
336 | * @return bool|string |
||
337 | */ |
||
338 | function default_registration_status() { |
||
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 ) { |
||
361 | |||
362 | |||
363 | |||
364 | /** |
||
365 | * @return bool |
||
366 | */ |
||
367 | function slug() { |
||
370 | |||
371 | |||
372 | |||
373 | /** |
||
374 | * @return bool |
||
375 | */ |
||
376 | function timezone_string() { |
||
379 | |||
380 | |||
381 | |||
382 | /** |
||
383 | * @return bool |
||
384 | */ |
||
385 | function visible_on() { |
||
388 | |||
389 | |||
390 | |||
391 | /** |
||
392 | * @return bool |
||
393 | */ |
||
394 | function wp_user() { |
||
397 | |||
398 | |||
399 | |||
400 | /** |
||
401 | * @return bool |
||
402 | */ |
||
403 | function donations() { |
||
406 | |||
407 | |||
408 | |||
409 | /** |
||
410 | * @param $limit |
||
411 | */ |
||
412 | function set_additional_limit( $limit ) { |
||
415 | |||
416 | |||
417 | |||
418 | /** |
||
419 | * @param $created |
||
420 | */ |
||
421 | function set_created( $created ) { |
||
424 | |||
425 | |||
426 | |||
427 | /** |
||
428 | * @param $desc |
||
429 | */ |
||
430 | function set_description( $desc ) { |
||
433 | |||
434 | |||
435 | |||
436 | /** |
||
437 | * @param $display_desc |
||
438 | */ |
||
439 | function set_display_description( $display_desc ) { |
||
442 | |||
443 | |||
444 | |||
445 | /** |
||
446 | * @param $display_ticket_selector |
||
447 | */ |
||
448 | function set_display_ticket_selector( $display_ticket_selector ) { |
||
451 | |||
452 | |||
453 | |||
454 | /** |
||
455 | * @param $external_url |
||
456 | */ |
||
457 | function set_external_url( $external_url ) { |
||
460 | |||
461 | |||
462 | |||
463 | /** |
||
464 | * @param $member_only |
||
465 | */ |
||
466 | function set_member_only( $member_only ) { |
||
469 | |||
470 | |||
471 | |||
472 | /** |
||
473 | * @param $event_phone |
||
474 | */ |
||
475 | function set_event_phone( $event_phone ) { |
||
478 | |||
479 | |||
480 | |||
481 | /** |
||
482 | * @param $modified |
||
483 | */ |
||
484 | function set_modified( $modified ) { |
||
487 | |||
488 | |||
489 | |||
490 | /** |
||
491 | * @param $name |
||
492 | */ |
||
493 | function set_name( $name ) { |
||
496 | |||
497 | |||
498 | |||
499 | /** |
||
500 | * @param $order |
||
501 | */ |
||
502 | function set_order( $order ) { |
||
505 | |||
506 | |||
507 | |||
508 | /** |
||
509 | * @param $short_desc |
||
510 | */ |
||
511 | function set_short_description( $short_desc ) { |
||
514 | |||
515 | |||
516 | |||
517 | /** |
||
518 | * @param $slug |
||
519 | */ |
||
520 | function set_slug( $slug ) { |
||
523 | |||
524 | |||
525 | |||
526 | /** |
||
527 | * @param $timezone_string |
||
528 | */ |
||
529 | function set_timezone_string( $timezone_string ) { |
||
532 | |||
533 | |||
534 | |||
535 | /** |
||
536 | * @param $visible_on |
||
537 | */ |
||
538 | function set_visible_on( $visible_on ) { |
||
541 | |||
542 | |||
543 | |||
544 | /** |
||
545 | * @param $wp_user |
||
546 | */ |
||
547 | function set_wp_user( $wp_user ) { |
||
550 | |||
551 | |||
552 | |||
553 | /** |
||
554 | * @param $default_registration_status |
||
555 | */ |
||
556 | function set_default_registration_status( $default_registration_status ) { |
||
559 | |||
560 | |||
561 | |||
562 | /** |
||
563 | * @param $donations |
||
564 | */ |
||
565 | function set_donations( $donations ) { |
||
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 ) { |
||
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 ) { |
||
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() ) { |
||
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() { |
||
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() { |
|
646 | |||
647 | |||
648 | |||
649 | /** |
||
650 | * @return bool |
||
651 | */ |
||
652 | View Code Duplication | public function is_active() { |
|
677 | |||
678 | |||
679 | |||
680 | /** |
||
681 | * @return bool |
||
682 | */ |
||
683 | View Code Duplication | public function is_expired() { |
|
704 | |||
705 | |||
706 | |||
707 | /** |
||
708 | * @return bool |
||
709 | */ |
||
710 | public function is_inactive() { |
||
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() { |
||
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() { |
||
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 ) { |
||
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 ) { |
||
973 | |||
974 | |||
975 | |||
976 | /** |
||
977 | * Checks if the event is marked as postponed |
||
978 | * @return boolean |
||
979 | */ |
||
980 | public function is_postponed() { |
||
983 | |||
984 | |||
985 | |||
986 | /** |
||
987 | * Checks if the event is marked as cancelled |
||
988 | * @return boolean |
||
989 | */ |
||
990 | public function is_cancelled() { |
||
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 ) { |
||
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 ) { |
||
1080 | |||
1081 | |||
1082 | |||
1083 | /** |
||
1084 | * @return bool|int |
||
1085 | */ |
||
1086 | public function get_number_of_tickets_sold() { |
||
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() { |
||
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() { |
||
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() { |
||
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() { |
||
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() { |
||
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() ) { |
||
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() ) { |
||
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()){ |
||
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() { |
||
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() { |
||
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() { |
|
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() { |
|
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() { |
|
1287 | |||
1288 | } |
||
1289 |
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:
The
getFirstName()
method in theSon
calls the wrong method in the parent class.