Complex classes like EE_Messages_Generator 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_Messages_Generator, and based on these observations, apply Extract Interface, too.
1 | <?php if ( ! defined( 'EVENT_ESPRESSO_VERSION' )) { exit( 'No direct script access allowed' ); } |
||
11 | class EE_Messages_Generator { |
||
12 | |||
13 | |||
14 | /** |
||
15 | * @type EE_Messages_Data_Handler_Collection |
||
16 | */ |
||
17 | protected $_data_handler_collection; |
||
18 | |||
19 | /** |
||
20 | * @type EE_Message_Template_Group_Collection |
||
21 | */ |
||
22 | protected $_template_collection; |
||
23 | |||
24 | /** |
||
25 | * This will hold the data handler for the current EE_Message being generated. |
||
26 | * @type EE_Messages_incoming_data |
||
27 | */ |
||
28 | protected $_current_data_handler; |
||
29 | |||
30 | /** |
||
31 | * This holds the EE_Messages_Queue that contains the messages to generate. |
||
32 | * @type EE_Messages_Queue |
||
33 | */ |
||
34 | protected $_generation_queue; |
||
35 | |||
36 | /** |
||
37 | * This holds the EE_Messages_Queue that will store the generated EE_Message objects. |
||
38 | * @type EE_Messages_Queue |
||
39 | */ |
||
40 | protected $_ready_queue; |
||
41 | |||
42 | /** |
||
43 | * This is a container for any error messages that get created through the generation |
||
44 | * process. |
||
45 | * @type array |
||
46 | */ |
||
47 | protected $_error_msg = array(); |
||
48 | |||
49 | /** |
||
50 | * Flag used to set when the current EE_Message in the generation queue has been verified. |
||
51 | * @type bool |
||
52 | */ |
||
53 | protected $_verified = false; |
||
54 | |||
55 | /** |
||
56 | * This will hold the current messenger object corresponding with the current EE_Message in the generation queue. |
||
57 | * |
||
58 | * @type EE_messenger |
||
59 | */ |
||
60 | protected $_current_messenger; |
||
61 | |||
62 | /** |
||
63 | * This will hold the current message type object corresponding with the current EE_Message in the generation queue. |
||
64 | * @type EE_message_type |
||
65 | */ |
||
66 | protected $_current_message_type; |
||
67 | |||
68 | /** |
||
69 | * @type EEH_Parse_Shortcodes |
||
70 | */ |
||
71 | protected $_shortcode_parser; |
||
72 | |||
73 | |||
74 | |||
75 | /** |
||
76 | * @param EE_Messages_Queue $generation_queue |
||
77 | * @param \EE_Messages_Queue $ready_queue |
||
78 | * @param \EE_Messages_Data_Handler_Collection $data_handler_collection |
||
79 | * @param \EE_Message_Template_Group_Collection $template_collection |
||
80 | * @param \EEH_Parse_Shortcodes $shortcode_parser |
||
81 | */ |
||
82 | public function __construct( |
||
95 | |||
96 | |||
97 | |||
98 | /** |
||
99 | * @return EE_Messages_Queue |
||
100 | */ |
||
101 | public function generation_queue() { |
||
104 | |||
105 | |||
106 | |||
107 | |||
108 | |||
109 | /** |
||
110 | * This iterates through the provided queue and generates the EE_Message objects. |
||
111 | * When iterating through the queue, the queued item that served as the base for generating other EE_Message objects |
||
112 | * gets removed and the new EE_Message objects get added to a NEW queue. The NEW queue is then returned for the |
||
113 | * caller to decide what to do with it. |
||
114 | * |
||
115 | * @param bool $save Whether to save the EE_Message objects in the new queue or just return. |
||
116 | * |
||
117 | * @return EE_Messages_Queue The new queue for holding generated EE_Message objects. |
||
118 | */ |
||
119 | public function generate( $save = true ) { |
||
120 | //iterate through the messages in the queue, generate, and add to new queue. |
||
121 | $this->_generation_queue->get_queue()->rewind(); |
||
122 | while ( $this->_generation_queue->get_queue()->valid() ) { |
||
123 | //reset "current" properties |
||
124 | $this->_reset_current_properties(); |
||
125 | |||
126 | /** @type EE_Message $msg */ |
||
127 | $msg = $this->_generation_queue->get_queue()->current(); |
||
128 | |||
129 | if ( $this->_verify() ) { |
||
130 | //let's get generating! |
||
131 | $this->_generate(); |
||
132 | } |
||
133 | |||
134 | /** |
||
135 | * need to get the next object and capture it for setting manually after deletes. The reason is that when |
||
136 | * an object is removed from the repo then valid for the next object will fail. |
||
137 | */ |
||
138 | $this->_generation_queue->get_queue()->next(); |
||
139 | $next_msg = $this->_generation_queue->get_queue()->current(); |
||
140 | //restore pointer to current item |
||
141 | $this->_generation_queue->get_queue()->set_current( $msg ); |
||
142 | |||
143 | //if there are error messages then let's set the status and the error message. |
||
144 | if ( $this->_error_msg ) { |
||
|
|||
145 | //if the status is already debug only, then let's leave it at that. |
||
146 | if ( $msg->STS_ID() !== EEM_Message::status_debug_only ) { |
||
147 | $msg->set_STS_ID( EEM_Message::status_failed ); |
||
148 | } |
||
149 | $msg->set_error_message( |
||
150 | __( 'Message failed to generate for the following reasons: ' ) |
||
151 | . "\n" |
||
152 | . implode( "\n", $this->_error_msg ) |
||
153 | ); |
||
154 | $msg->set_modified( time() ); |
||
155 | } else { |
||
156 | //remove from db |
||
157 | $this->_generation_queue->get_queue()->delete(); |
||
158 | } |
||
159 | //next item |
||
160 | $this->_generation_queue->get_queue()->set_current( $next_msg ); |
||
161 | } |
||
162 | |||
163 | //generation queue is ALWAYS saved to record any errors in the generation process. |
||
164 | $this->_generation_queue->save(); |
||
165 | |||
166 | /** |
||
167 | * save _ready_queue if flag set. |
||
168 | * Note: The EE_Message objects have values set via the EE_Base_Class::set_field_or_extra_meta() method. This |
||
169 | * means if a field was added that is not a valid database column. The EE_Message was already saved to the db |
||
170 | * so a EE_Extra_Meta entry could be created and attached to the EE_Message. In those cases the save flag is |
||
171 | * irrelevant. |
||
172 | */ |
||
173 | if ( $save ) { |
||
174 | $this->_ready_queue->save(); |
||
175 | } |
||
176 | |||
177 | //final reset of properties |
||
178 | $this->_reset_current_properties(); |
||
179 | |||
180 | return $this->_ready_queue; |
||
181 | } |
||
182 | |||
183 | |||
184 | /** |
||
185 | * This resets all the properties used for holding "current" values corresponding to the current EE_Message object |
||
186 | * in the generation queue. |
||
187 | */ |
||
188 | protected function _reset_current_properties() { |
||
196 | |||
197 | |||
198 | |||
199 | |||
200 | |||
201 | /** |
||
202 | * This proceeds with the actual generation of a message. By the time this is called, there should already be a |
||
203 | * $_current_data_handler set and all incoming information should be validated for the current EE_Message in the |
||
204 | * _generating_queue. |
||
205 | * |
||
206 | * @return bool Whether the message was successfully generated or not. |
||
207 | */ |
||
208 | protected function _generate() { |
||
209 | //double check verification has run and that everything is ready to work with (saves us having to validate everything again). |
||
210 | if ( ! $this->_verified ) { |
||
211 | return false; //get out because we don't have a valid setup to work with. |
||
212 | } |
||
213 | |||
214 | |||
215 | try { |
||
216 | $addressees = $this->_current_message_type->get_addressees( |
||
217 | $this->_current_data_handler, |
||
218 | $this->_generation_queue->get_queue()->current()->context() |
||
219 | ); |
||
220 | } catch ( EE_Error $e ) { |
||
221 | $this->_error_msg[] = $e->getMessage(); |
||
222 | return false; |
||
223 | } |
||
224 | |||
225 | |||
226 | //if no addressees then get out because there is nothing to generation (possible bad data). |
||
227 | if ( ! $this->_valid_addressees( $addressees ) ) { |
||
228 | $this->_generation_queue->get_queue()->current()->set_STS_ID( EEM_Message::status_debug_only ); |
||
229 | $this->_error_msg[] = __( 'This is not a critical error but an informational notice. Unable to generate messages EE_Messages_Addressee objects. There were no attendees prepared by the data handler. |
||
230 | Sometimes this is because messages only get generated for certain registration statuses. For example, the ticket notice message type only goes to approved registrations.', 'event_espresso' ); |
||
231 | return false; |
||
232 | } |
||
233 | |||
234 | $message_template_group = $this->_get_message_template_group(); |
||
235 | |||
236 | //in the unlikely event there is no EE_Message_Template_Group available, get out! |
||
237 | if ( ! $message_template_group instanceof EE_Message_Template_Group ) { |
||
238 | $this->_error_msg[] = __( 'Unable to get the Message Templates for the Message being generated. No message template group accessible.', 'event_espresso' ); |
||
239 | return false; |
||
240 | } |
||
241 | |||
242 | //get formatted templates for using to parse and setup EE_Message objects. |
||
243 | $templates = $this->_get_templates( $message_template_group ); |
||
244 | |||
245 | |||
246 | //setup new EE_Message objects (and add to _ready_queue) |
||
247 | return $this->_assemble_messages( $addressees, $templates, $message_template_group ); |
||
248 | } |
||
249 | |||
250 | |||
251 | |||
252 | |||
253 | |||
254 | /** |
||
255 | * Retrieves the message template group being used for generating messages. |
||
256 | * Note: this also utilizes the EE_Message_Template_Group_Collection to avoid having to hit the db multiple times. |
||
257 | * |
||
258 | * @return EE_Message_Template_Group | null |
||
259 | */ |
||
260 | protected function _get_message_template_group() { |
||
335 | |||
336 | |||
337 | |||
338 | |||
339 | |||
340 | /** |
||
341 | * Retrieves formatted array of template information for each context specific to the given EE_Message_Template_Group |
||
342 | * |
||
343 | * @param EE_Message_Template_Group |
||
344 | * |
||
345 | * @return array The returned array is in this structure: |
||
346 | * array( |
||
347 | * 'field_name' => array( |
||
348 | * 'context' => 'content' |
||
349 | * ) |
||
350 | * ) |
||
351 | */ |
||
352 | protected function _get_templates( EE_Message_Template_Group $message_template_group ) { |
||
365 | |||
366 | |||
367 | |||
368 | |||
369 | |||
370 | |||
371 | /** |
||
372 | * Assembles new fully generated EE_Message objects and adds to _ready_queue |
||
373 | * |
||
374 | * @param array $addressees Array of EE_Messages_Addressee objects indexed by message type context. |
||
375 | * @param array $templates formatted array of templates used for parsing data. |
||
376 | * @param EE_Message_Template_Group $message_template_group |
||
377 | * @return bool true if message generation went a-ok. false if some sort of exception occurred. Note: The method will |
||
378 | * attempt to generate ALL EE_Message objects and add to the _ready_queue. Successfully generated messages |
||
379 | * get added to the queue with EEM_Message::status_idle, unsuccessfully generated messages will get added |
||
380 | * to the queue as EEM_Message::status_failed. Very rarely should "false" be returned from this method. |
||
381 | */ |
||
382 | protected function _assemble_messages( $addressees, $templates, EE_Message_Template_Group $message_template_group ) { |
||
410 | |||
411 | |||
412 | |||
413 | |||
414 | |||
415 | /** |
||
416 | * @param string $context The context for the generated message. |
||
417 | * @param EE_Messages_Addressee $recipient |
||
418 | * @param array $templates formatted array of templates used for parsing data. |
||
419 | * @param EE_Message_Template_Group $message_template_group |
||
420 | * @return EE_Message | bool (false is used when no EE_Message is generated) |
||
421 | */ |
||
422 | protected function _setup_message_object( |
||
500 | |||
501 | |||
502 | |||
503 | /** |
||
504 | * This verifies that the incoming array has a EE_messenger object and a EE_message_type object and sets appropriate |
||
505 | * error message if either is missing. |
||
506 | * |
||
507 | * @return bool true means there were no errors, false means there were errors. |
||
508 | */ |
||
509 | protected function _verify() { |
||
521 | |||
522 | |||
523 | /** |
||
524 | * This accepts an array and validates that it is an array indexed by context with each value being an array of |
||
525 | * EE_Messages_Addressee objects. |
||
526 | * |
||
527 | * @param array $addressees Keys correspond to contexts for the message type and values are EE_Messages_Addressee[] |
||
528 | * @return bool |
||
529 | */ |
||
530 | protected function _valid_addressees( $addressees ) { |
||
544 | |||
545 | |||
546 | |||
547 | |||
548 | |||
549 | /** |
||
550 | * This validates the messenger, message type, and presences of generation data for the current EE_Message in the queue. |
||
551 | * This process sets error messages if something is wrong. |
||
552 | * |
||
553 | * @return bool true is if there are no errors. false is if there is. |
||
554 | */ |
||
555 | protected function _validate_messenger_and_message_type() { |
||
587 | |||
588 | |||
589 | |||
590 | |||
591 | |||
592 | /** |
||
593 | * This method retrieves the expected data handler for the message type and validates the generation data for that |
||
594 | * data handler. |
||
595 | * |
||
596 | * @return bool true means there are no errors. false means there were errors (and handler did not get setup). |
||
597 | */ |
||
598 | protected function _validate_and_setup_data() { |
||
635 | |||
636 | |||
637 | |||
638 | |||
639 | |||
640 | /** |
||
641 | * Sets the $_current_data_handler property that is used for generating the current EE_Message in the queue, and |
||
642 | * adds it to the _data repository. |
||
643 | * |
||
644 | * @param mixed $generating_data This is data expected by the instantiated data handler. |
||
645 | * @param string $data_handler_class_name This is the reference string indicating what data handler is being |
||
646 | * instantiated. |
||
647 | * |
||
648 | * @return void. |
||
649 | */ |
||
650 | protected function _set_data_handler( $generating_data, $data_handler_class_name ) { |
||
664 | |||
665 | |||
666 | |||
667 | |||
668 | |||
669 | /** |
||
670 | * The queued EE_Message for generation does not save the data used for generation as objects |
||
671 | * because serialization of those objects could be problematic if the data is saved to the db. |
||
672 | * So this method calls the static method on the associated data_handler for the given message_type |
||
673 | * and that preps the data for later instantiation when generating. |
||
674 | * |
||
675 | * @param EE_Message_To_Generate $message_to_generate |
||
676 | * @param bool $preview Indicate whether this is being used for a preview or not. |
||
677 | * @return mixed Prepped data for persisting to the queue. false is returned if unable to prep data. |
||
678 | */ |
||
679 | protected function _prepare_data_for_queue( EE_Message_To_Generate $message_to_generate, $preview ) { |
||
687 | |||
688 | |||
689 | |||
690 | |||
691 | |||
692 | /** |
||
693 | * This sets up a EEM_Message::status_incomplete EE_Message object and adds it to the generation queue. |
||
694 | * |
||
695 | * @param EE_Message_To_Generate $message_to_generate |
||
696 | * @param bool $test_send Whether this is just a test send or not. Typically used for previews. |
||
697 | */ |
||
698 | public function create_and_add_message_to_queue( EE_Message_To_Generate $message_to_generate, $test_send = false ) { |
||
719 | |||
720 | |||
721 | |||
722 | } //end EE_Messages_Generator |
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.