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_Checkout 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_Checkout, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
15 | class EE_Checkout |
||
16 | { |
||
17 | |||
18 | /** |
||
19 | * whether current request originated from the EE admin |
||
20 | * |
||
21 | * @type bool |
||
22 | */ |
||
23 | public $admin_request = false; |
||
24 | |||
25 | /** |
||
26 | * whether returning to edit attendee information or to retry a payment |
||
27 | * |
||
28 | * @type bool |
||
29 | */ |
||
30 | public $revisit = false; |
||
31 | |||
32 | /** |
||
33 | * whether the primary registrant is returning to edit attendee information or to retry a payment |
||
34 | * |
||
35 | * @type bool |
||
36 | */ |
||
37 | public $primary_revisit = false; |
||
38 | |||
39 | /** |
||
40 | * is registration allowed to progress or halted for some reason such as failing to pass recaptcha? |
||
41 | * |
||
42 | * @type bool |
||
43 | */ |
||
44 | public $continue_reg = true; |
||
45 | |||
46 | /** |
||
47 | * redirect to thank you page ? |
||
48 | * |
||
49 | * @type bool |
||
50 | */ |
||
51 | public $redirect = false; |
||
52 | |||
53 | /** |
||
54 | * generate the reg form or not ? |
||
55 | * |
||
56 | * @type bool |
||
57 | */ |
||
58 | public $generate_reg_form = true; |
||
59 | |||
60 | /** |
||
61 | * process a reg form submission or not ? |
||
62 | * |
||
63 | * @type bool |
||
64 | */ |
||
65 | public $process_form_submission = false; |
||
66 | |||
67 | /** |
||
68 | * tracks whether the TXN status modified during this checkout |
||
69 | * |
||
70 | * @type bool |
||
71 | */ |
||
72 | public $txn_status_updated = false; |
||
73 | |||
74 | /** |
||
75 | * only triggered to true after absolutely everything has finished. |
||
76 | * |
||
77 | * @type bool |
||
78 | */ |
||
79 | protected $exit_spco = false; |
||
80 | |||
81 | /** |
||
82 | * tracks whether any of the TXN's Registrations statuses modified during this checkout |
||
83 | * indexed by registration ID |
||
84 | * |
||
85 | * @type array |
||
86 | */ |
||
87 | protected $reg_status_updated = array(); |
||
88 | |||
89 | /** |
||
90 | * timestamp when redirected from Ticket Selector to the checkout |
||
91 | * |
||
92 | * @type int |
||
93 | */ |
||
94 | public $uts = 0; |
||
95 | |||
96 | /** |
||
97 | * total number of tickets that were in the cart |
||
98 | * |
||
99 | * @type int |
||
100 | */ |
||
101 | public $total_ticket_count = 0; |
||
102 | |||
103 | /** |
||
104 | * corresponds loosely to EE_Transaction::remaining() |
||
105 | * but can be modified by SPCO |
||
106 | * |
||
107 | * @type float |
||
108 | */ |
||
109 | public $amount_owing = 0; |
||
110 | |||
111 | /** |
||
112 | * the reg step slug from the incoming request |
||
113 | * |
||
114 | * @type string |
||
115 | */ |
||
116 | public $step = ''; |
||
117 | |||
118 | /** |
||
119 | * the reg step slug for a step being edited |
||
120 | * |
||
121 | * @type string |
||
122 | */ |
||
123 | public $edit_step = ''; |
||
124 | |||
125 | /** |
||
126 | * the action being performed on the current step |
||
127 | * |
||
128 | * @type string |
||
129 | */ |
||
130 | public $action = ''; |
||
131 | |||
132 | /** |
||
133 | * reg_url_link for a previously saved registration |
||
134 | * |
||
135 | * @type string |
||
136 | */ |
||
137 | public $reg_url_link = ''; |
||
138 | |||
139 | /** |
||
140 | * string slug for the payment method that was selected during the payment options step |
||
141 | * |
||
142 | * @type string |
||
143 | */ |
||
144 | public $selected_method_of_payment = ''; |
||
145 | |||
146 | /** |
||
147 | * base url for the site's registration checkout page - additional url params will be added to this |
||
148 | * |
||
149 | * @type string |
||
150 | */ |
||
151 | public $reg_page_base_url = ''; |
||
152 | |||
153 | /** |
||
154 | * base url for the site's registration cancelled page - additional url params will be added to this |
||
155 | * |
||
156 | * @type string |
||
157 | */ |
||
158 | public $cancel_page_url = ''; |
||
159 | |||
160 | /** |
||
161 | * base url for the site's thank you page - additional url params will be added to this |
||
162 | * |
||
163 | * @type string |
||
164 | */ |
||
165 | public $thank_you_page_url = ''; |
||
166 | |||
167 | /** |
||
168 | * base url for any redirects - additional url params will be added to this |
||
169 | * |
||
170 | * @type string |
||
171 | */ |
||
172 | public $redirect_url = ''; |
||
173 | |||
174 | /** |
||
175 | * form of POST data for use with off-site gateways |
||
176 | * |
||
177 | * @type string |
||
178 | */ |
||
179 | public $redirect_form = ''; |
||
180 | |||
181 | /** |
||
182 | * array of query where params to use when retrieving cached registrations from $this->checkout->transaction |
||
183 | * |
||
184 | * @type array |
||
185 | */ |
||
186 | public $reg_cache_where_params = array(); |
||
187 | |||
188 | /** |
||
189 | * a class for managing and creating the JSON encoded array of data that gets passed back to the client during AJAX |
||
190 | * requests |
||
191 | * |
||
192 | * @type EE_SPCO_JSON_Response |
||
193 | */ |
||
194 | public $json_response; |
||
195 | |||
196 | /** |
||
197 | * where we are going next in the reg process |
||
198 | * |
||
199 | * @type EE_SPCO_Reg_Step |
||
200 | */ |
||
201 | public $next_step; |
||
202 | |||
203 | /** |
||
204 | * where we are in the reg process |
||
205 | * |
||
206 | * @type EE_SPCO_Reg_Step |
||
207 | */ |
||
208 | public $current_step; |
||
209 | |||
210 | /** |
||
211 | * $_cart - the current cart object |
||
212 | * |
||
213 | * @var EE_CART |
||
214 | */ |
||
215 | public $cart; |
||
216 | |||
217 | /** |
||
218 | * $_transaction - the current transaction object |
||
219 | * |
||
220 | * @var EE_Transaction |
||
221 | */ |
||
222 | public $transaction; |
||
223 | |||
224 | /** |
||
225 | * the related attendee object for the primary registrant |
||
226 | * |
||
227 | * @type EE_Attendee |
||
228 | */ |
||
229 | public $primary_attendee_obj; |
||
230 | |||
231 | /** |
||
232 | * $payment_method - the payment method object for the selected method of payment |
||
233 | * |
||
234 | * @type EE_Payment_Method |
||
235 | */ |
||
236 | public $payment_method; |
||
237 | |||
238 | /** |
||
239 | * $payment - if a payment was successfully made during the reg process, |
||
240 | * then here it is !!! |
||
241 | * |
||
242 | * @type EE_Payment |
||
243 | */ |
||
244 | public $payment; |
||
245 | |||
246 | /** |
||
247 | * if a payment method was selected that uses an on-site gateway, then this is the billing form |
||
248 | * |
||
249 | * @type EE_Billing_Info_Form | EE_Billing_Attendee_Info_Form |
||
250 | */ |
||
251 | public $billing_form; |
||
252 | |||
253 | /** |
||
254 | * the entire registration form composed of ALL of the subsections generated by the various reg steps |
||
255 | * |
||
256 | * @type EE_Form_Section_Proper |
||
257 | */ |
||
258 | public $registration_form; |
||
259 | |||
260 | /** |
||
261 | * array of EE_SPCO_Reg_Step objects |
||
262 | * |
||
263 | * @type EE_SPCO_Reg_Step[] |
||
264 | */ |
||
265 | public $reg_steps = array(); |
||
266 | |||
267 | /** |
||
268 | * array of EE_Payment_Method objects |
||
269 | * |
||
270 | * @type EE_Payment_Method[] |
||
271 | */ |
||
272 | public $available_payment_methods = array(); |
||
273 | |||
274 | |||
275 | /** |
||
276 | * class constructor |
||
277 | * |
||
278 | * @access public |
||
279 | */ |
||
280 | public function __construct() |
||
292 | |||
293 | |||
294 | /** |
||
295 | * returns true if ANY reg status was updated during checkout |
||
296 | * |
||
297 | * @return boolean |
||
298 | */ |
||
299 | public function any_reg_status_updated() |
||
308 | |||
309 | |||
310 | /** |
||
311 | * @param $REG_ID |
||
312 | * @return boolean |
||
313 | */ |
||
314 | public function reg_status_updated($REG_ID) |
||
318 | |||
319 | |||
320 | /** |
||
321 | * @param $REG_ID |
||
322 | * @param $reg_status |
||
323 | */ |
||
324 | public function set_reg_status_updated($REG_ID, $reg_status) |
||
328 | |||
329 | |||
330 | /** |
||
331 | * exit_spco |
||
332 | * |
||
333 | * @return bool |
||
334 | */ |
||
335 | public function exit_spco() |
||
339 | |||
340 | |||
341 | /** |
||
342 | * set_exit_spco |
||
343 | * can ONLY be set by the Finalize_Registration reg step |
||
344 | */ |
||
345 | public function set_exit_spco() |
||
351 | |||
352 | |||
353 | /** |
||
354 | * reset_for_current_request |
||
355 | * |
||
356 | * @access public |
||
357 | * @return void |
||
358 | */ |
||
359 | public function reset_for_current_request() |
||
374 | |||
375 | |||
376 | /** |
||
377 | * add_reg_step |
||
378 | * |
||
379 | * @access public |
||
380 | * @param EE_SPCO_Reg_Step $reg_step_obj |
||
381 | * @return void |
||
382 | */ |
||
383 | public function add_reg_step(EE_SPCO_Reg_Step $reg_step_obj) |
||
387 | |||
388 | |||
389 | /** |
||
390 | * skip_reg_step |
||
391 | * if the current reg step does not need to run for some reason, |
||
392 | * then this will advance SPCO to the next reg step, |
||
393 | * and mark the skipped step as completed |
||
394 | * |
||
395 | * @access public |
||
396 | * @param string $reg_step_slug |
||
397 | * @return void |
||
398 | * @throws \EE_Error |
||
399 | */ |
||
400 | public function skip_reg_step($reg_step_slug = '') |
||
419 | |||
420 | |||
421 | /** |
||
422 | * remove_reg_step |
||
423 | * |
||
424 | * @access public |
||
425 | * @param string $reg_step_slug |
||
426 | * @param bool $reset whether to reset reg steps after removal |
||
427 | * @throws EE_Error |
||
428 | */ |
||
429 | public function remove_reg_step($reg_step_slug = '', $reset = true) |
||
441 | |||
442 | |||
443 | /** |
||
444 | * set_reg_step_order |
||
445 | * |
||
446 | * @access public |
||
447 | * @param string $reg_step_slug |
||
448 | * @param int $order |
||
449 | * @return void |
||
450 | */ |
||
451 | public function set_reg_step_order($reg_step_slug = '', $order = 100) |
||
457 | |||
458 | |||
459 | /** |
||
460 | * set_current_step |
||
461 | * |
||
462 | * @access public |
||
463 | * @param string $current_step |
||
464 | * @return void |
||
465 | */ |
||
466 | public function set_current_step($current_step) |
||
496 | |||
497 | |||
498 | /** |
||
499 | * set_next_step |
||
500 | * advances the reg_steps array pointer and sets the next step, then reverses pointer back to the current step |
||
501 | * |
||
502 | * @access public |
||
503 | * @return void |
||
504 | */ |
||
505 | public function set_next_step() |
||
523 | |||
524 | |||
525 | /** |
||
526 | * get_next_reg_step |
||
527 | * this simply returns the next step from reg_steps array |
||
528 | * |
||
529 | * @access public |
||
530 | * @return EE_SPCO_Reg_Step | null |
||
531 | */ |
||
532 | public function get_next_reg_step() |
||
538 | |||
539 | |||
540 | /** |
||
541 | * get_prev_reg_step |
||
542 | * this simply returns the previous step from reg_steps array |
||
543 | * |
||
544 | * @access public |
||
545 | * @return EE_SPCO_Reg_Step | null |
||
546 | */ |
||
547 | public function get_prev_reg_step() |
||
553 | |||
554 | |||
555 | /** |
||
556 | * sort_reg_steps |
||
557 | * |
||
558 | * @access public |
||
559 | * @return void |
||
560 | */ |
||
561 | public function sort_reg_steps() |
||
569 | |||
570 | |||
571 | /** |
||
572 | * find_reg_step |
||
573 | * finds a reg step by the given slug |
||
574 | * |
||
575 | * @access public |
||
576 | * @param string $reg_step_slug |
||
577 | * @return EE_SPCO_Reg_Step|null |
||
578 | */ |
||
579 | public function find_reg_step($reg_step_slug = '') |
||
597 | |||
598 | |||
599 | /** |
||
600 | * reg_step_sorting_callback |
||
601 | * |
||
602 | * @access public |
||
603 | * @param EE_SPCO_Reg_Step $reg_step_A |
||
604 | * @param EE_SPCO_Reg_Step $reg_step_B |
||
605 | * @return int |
||
606 | */ |
||
607 | public function reg_step_sorting_callback(EE_SPCO_Reg_Step $reg_step_A, EE_SPCO_Reg_Step $reg_step_B) |
||
620 | |||
621 | |||
622 | /** |
||
623 | * set_reg_step_initiated |
||
624 | * |
||
625 | * @access public |
||
626 | * @param EE_SPCO_Reg_Step $reg_step |
||
627 | * @throws \EE_Error |
||
628 | */ |
||
629 | public function set_reg_step_initiated(EE_SPCO_Reg_Step $reg_step) |
||
657 | |||
658 | |||
659 | /** |
||
660 | * set_reg_step_JSON_info |
||
661 | * |
||
662 | * @access public |
||
663 | * @return void |
||
664 | */ |
||
665 | public function set_reg_step_JSON_info() |
||
675 | |||
676 | |||
677 | /** |
||
678 | * reset_reg_steps |
||
679 | * |
||
680 | * @access public |
||
681 | * @return void |
||
682 | */ |
||
683 | public function reset_reg_steps() |
||
692 | |||
693 | |||
694 | /** |
||
695 | * get_registration_time_limit |
||
696 | * |
||
697 | * @access public |
||
698 | * @return string |
||
699 | */ |
||
700 | public function get_registration_time_limit() |
||
711 | |||
712 | |||
713 | /** |
||
714 | * payment_required |
||
715 | * |
||
716 | * @return boolean |
||
717 | */ |
||
718 | public function payment_required() |
||
731 | |||
732 | |||
733 | /** |
||
734 | * get_cart_for_transaction |
||
735 | * |
||
736 | * @access public |
||
737 | * @param EE_Transaction $transaction |
||
738 | * @return EE_Cart |
||
739 | */ |
||
740 | public function get_cart_for_transaction($transaction) |
||
751 | |||
752 | |||
753 | /** |
||
754 | * initialize_txn_reg_steps_array |
||
755 | * |
||
756 | * @access public |
||
757 | * @return array |
||
758 | */ |
||
759 | public function initialize_txn_reg_steps_array() |
||
767 | |||
768 | |||
769 | /** |
||
770 | * update_txn_reg_steps_array |
||
771 | * |
||
772 | * @access public |
||
773 | * @return bool |
||
774 | * @throws \EE_Error |
||
775 | */ |
||
776 | public function update_txn_reg_steps_array() |
||
791 | |||
792 | |||
793 | /** |
||
794 | * stash_transaction_and_checkout |
||
795 | * |
||
796 | * @access public |
||
797 | * @return void |
||
798 | * @throws \EE_Error |
||
799 | */ |
||
800 | public function stash_transaction_and_checkout() |
||
811 | |||
812 | |||
813 | /** |
||
814 | * track_transaction_and_registration_status_updates |
||
815 | * stores whether any updates were made to the TXN or it's related registrations |
||
816 | * |
||
817 | * @access public |
||
818 | * @return void |
||
819 | * @throws \EE_Error |
||
820 | */ |
||
821 | public function track_transaction_and_registration_status_updates() |
||
837 | |||
838 | |||
839 | /** |
||
840 | * visit_allows_processing_of_this_registration |
||
841 | * determines if the current SPCO visit should allow the passed EE_Registration to be used in processing. |
||
842 | * one of the following conditions must be met: |
||
843 | * EITHER: A) first time thru SPCO -> process ALL registrations ( NOT a revisit ) |
||
844 | * OR : B) primary registrant is editing info -> process ALL registrations ( primary_revisit ) |
||
845 | * OR : C) another registrant is editing info -> ONLY process their registration ( revisit AND their |
||
846 | * reg_url_link matches ) |
||
847 | * |
||
848 | * @access public |
||
849 | * @param EE_Registration $registration |
||
850 | * @return bool |
||
851 | * @throws \EE_Error |
||
852 | */ |
||
853 | public function visit_allows_processing_of_this_registration(EE_Registration $registration) |
||
863 | |||
864 | |||
865 | /** |
||
866 | * _transaction_has_primary_registration |
||
867 | * |
||
868 | * @access private |
||
869 | * @return bool |
||
870 | */ |
||
871 | public function transaction_has_primary_registrant() |
||
875 | |||
876 | |||
877 | /** |
||
878 | * save_all_data |
||
879 | * simply loops through the current transaction and saves all data for each registration |
||
880 | * |
||
881 | * @access public |
||
882 | * @param bool $show_errors |
||
883 | * @return bool |
||
884 | * @throws \EE_Error |
||
885 | */ |
||
886 | public function save_all_data($show_errors = true) |
||
912 | |||
913 | |||
914 | /** |
||
915 | * _save_registration_attendee |
||
916 | * |
||
917 | * @param EE_Registration $registration |
||
918 | * @param bool $show_errors |
||
919 | * @return void |
||
920 | * @throws \EE_Error |
||
921 | */ |
||
922 | private function _save_registration($registration, $show_errors = true) |
||
967 | |||
968 | |||
969 | /** |
||
970 | * _save_registration_attendee |
||
971 | * |
||
972 | * @param EE_Registration $registration |
||
973 | * @param bool $show_errors |
||
974 | * @return void |
||
975 | * @throws \EE_Error |
||
976 | */ |
||
977 | private function _save_registration_attendee($registration, $show_errors = true) |
||
1013 | |||
1014 | |||
1015 | /** |
||
1016 | * _save_question_answers |
||
1017 | * |
||
1018 | * @param EE_Registration $registration |
||
1019 | * @param bool $show_errors |
||
1020 | * @return void |
||
1021 | * @throws \EE_Error |
||
1022 | */ |
||
1023 | private function _save_registration_answers($registration, $show_errors = true) |
||
1059 | |||
1060 | |||
1061 | /** |
||
1062 | * refresh_all_entities |
||
1063 | * will either refresh the entity map with objects form the db or from the checkout cache |
||
1064 | * |
||
1065 | * @access public |
||
1066 | * @param bool $from_db |
||
1067 | * @return bool |
||
1068 | * @throws \EE_Error |
||
1069 | */ |
||
1070 | public function refresh_all_entities($from_db = false) |
||
1083 | |||
1084 | |||
1085 | /** |
||
1086 | * refresh_entity_map |
||
1087 | * simply loops through the current transaction and updates each |
||
1088 | * model's entity map using EEM_Base::refresh_entity_map_from_db() |
||
1089 | * |
||
1090 | * @access public |
||
1091 | * @return bool |
||
1092 | * @throws \EE_Error |
||
1093 | */ |
||
1094 | protected function refresh_from_db() |
||
1125 | |||
1126 | |||
1127 | /** |
||
1128 | * _refresh_primary_attendee_obj_from_db |
||
1129 | * |
||
1130 | * @param EE_Transaction $transaction |
||
1131 | * @return EE_Attendee | null |
||
1132 | * @throws \EE_Error |
||
1133 | */ |
||
1134 | protected function _refresh_primary_attendee_obj_from_db(EE_Transaction $transaction) |
||
1161 | |||
1162 | |||
1163 | /** |
||
1164 | * refresh_entity_map |
||
1165 | * simply loops through the current transaction and updates |
||
1166 | * each model's entity map using EEM_Base::refresh_entity_map_with() |
||
1167 | * |
||
1168 | * @access public |
||
1169 | * @return bool |
||
1170 | * @throws \EE_Error |
||
1171 | */ |
||
1172 | protected function refresh_entity_map() |
||
1233 | |||
1234 | |||
1235 | /** |
||
1236 | * _refresh_registration |
||
1237 | * |
||
1238 | * @param string | int $reg_cache_ID |
||
1239 | * @param EE_Registration $registration |
||
1240 | * @return void |
||
1241 | * @throws \EE_Error |
||
1242 | */ |
||
1243 | protected function _refresh_registration($reg_cache_ID, $registration) |
||
1266 | |||
1267 | |||
1268 | /** |
||
1269 | * _save_registration_attendee |
||
1270 | * |
||
1271 | * @param EE_Registration $registration |
||
1272 | * @return void |
||
1273 | * @throws \EE_Error |
||
1274 | */ |
||
1275 | protected function _refresh_registration_attendee($registration) |
||
1289 | |||
1290 | |||
1291 | /** |
||
1292 | * _refresh_registration_answers |
||
1293 | * |
||
1294 | * @param EE_Registration $registration |
||
1295 | * @return void |
||
1296 | * @throws \EE_Error |
||
1297 | */ |
||
1298 | protected function _refresh_registration_answers($registration) |
||
1322 | |||
1323 | |||
1324 | /** |
||
1325 | * __sleep |
||
1326 | * to conserve db space, let's remove the reg_form and the EE_Checkout object from EE_SPCO_Reg_Step objects upon |
||
1327 | * serialization EE_Checkout will handle the reimplementation of itself upon waking, but we won't bother with the |
||
1328 | * reg form, because if needed, it will be regenerated anyways |
||
1329 | * |
||
1330 | * @return array |
||
1331 | * @throws \EE_Error |
||
1332 | */ |
||
1333 | public function __sleep() |
||
1343 | |||
1344 | |||
1345 | /** |
||
1346 | * __wakeup |
||
1347 | * to conserve db space, we are removing the EE_Checkout object from EE_SPCO_Reg_Step objects upon serialization |
||
1348 | * this will reinstate the EE_Checkout object on each EE_SPCO_Reg_Step object |
||
1349 | */ |
||
1350 | public function __wakeup() |
||
1364 | |||
1365 | |||
1366 | /** |
||
1367 | * debug |
||
1368 | * |
||
1369 | * @param string $class |
||
1370 | * @param string $func |
||
1371 | * @param string $line |
||
1372 | * @param array $info |
||
1373 | * @param bool $display_request |
||
1374 | * @throws \EE_Error |
||
1375 | */ |
||
1376 | public function log($class = '', $func = '', $line = '', $info = array(), $display_request = false) |
||
1416 | |||
1417 | |||
1418 | /** |
||
1419 | * _strip_objects |
||
1420 | * |
||
1421 | * @param array $info |
||
1422 | * @return array |
||
1423 | */ |
||
1424 | public function _strip_objects($info = array()) |
||
1443 | } |
||
1444 |