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_Messages_Processor 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_Processor, and based on these observations, apply Extract Interface, too.
1 | <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) { exit('No direct script access allowed'); } |
||
12 | class EE_Messages_Processor { |
||
13 | |||
14 | |||
15 | /** |
||
16 | * @type EE_Message_Resource_Manager $_message_resource_manager |
||
17 | */ |
||
18 | protected $_message_resource_manager; |
||
19 | |||
20 | /** |
||
21 | * @type EE_Messages_Queue |
||
22 | */ |
||
23 | protected $_queue; |
||
24 | |||
25 | /** |
||
26 | * @type EE_Messages_Generator |
||
27 | */ |
||
28 | protected $_generator; |
||
29 | |||
30 | |||
31 | |||
32 | |||
33 | /** |
||
34 | * constructor |
||
35 | * |
||
36 | * @param EE_Message_Resource_Manager $message_resource_manager |
||
37 | */ |
||
38 | public function __construct( EE_Message_Resource_Manager $message_resource_manager ) { |
||
42 | |||
43 | |||
44 | |||
45 | |||
46 | /** |
||
47 | * This method sets (or resets) the various properties for use. |
||
48 | * |
||
49 | * - $_queue = holds the messages queue |
||
50 | * - $_generator = holds the messages generator |
||
51 | */ |
||
52 | protected function _init_queue_and_generator() { |
||
56 | |||
57 | |||
58 | |||
59 | |||
60 | /** |
||
61 | * This returns the current set queue. |
||
62 | * @return EE_Messages_Queue |
||
63 | */ |
||
64 | public function get_queue() { |
||
67 | |||
68 | |||
69 | |||
70 | /** |
||
71 | * This method can be utilized to process messages from a queue and they will be processed immediately on the same request. |
||
72 | * Please note that this method alone does not bypass the usual "locks" for generation/sending (it assumes client code |
||
73 | * has already filtered those if necessary). |
||
74 | * |
||
75 | * @param EE_Messages_Queue $queue_to_process |
||
76 | * @return bool true for success false for error. |
||
77 | */ |
||
78 | public function process_immediately_from_queue( EE_Messages_Queue $queue_to_process ) { |
||
79 | $success = false; |
||
80 | $messages_to_send = array(); |
||
81 | $messages_to_generate = array(); |
||
82 | //loop through and setup the various messages from the queue so we know what is being processed |
||
83 | $queue_to_process->get_message_repository()->rewind(); |
||
84 | foreach ( $queue_to_process->get_message_repository() as $message ) { |
||
85 | if ( $message->STS_ID() === EEM_Message::status_incomplete ) { |
||
86 | $messages_to_generate[] = $message; |
||
87 | continue; |
||
88 | } |
||
89 | |||
90 | if ( in_array( $message->STS_ID(), EEM_Message::instance()->stati_indicating_to_send() ) ) { |
||
91 | $messages_to_send[] = $message; |
||
92 | continue; |
||
93 | } |
||
94 | } |
||
95 | |||
96 | //do generation/sends |
||
97 | if ( $messages_to_generate ) { |
||
|
|||
98 | $success = $this->batch_generate_from_queue( $messages_to_generate, true ); |
||
99 | } |
||
100 | |||
101 | if ( $messages_to_send ) { |
||
102 | $sent = $this->batch_send_from_queue( $messages_to_send, true ); |
||
103 | //if there was messages to generate and it failed, then we override any success value for the sending process |
||
104 | //otherwise we just use the return from batch send. The intent is that there is a simple response for success/fail. |
||
105 | //Either everything was successful or we consider it a fail. To be clear, this is a limitation of doing |
||
106 | //all messages processing on the same request. |
||
107 | $success = $messages_to_generate && ! $success ? false : $sent; |
||
108 | } |
||
109 | return $success; |
||
110 | } |
||
111 | |||
112 | |||
113 | /** |
||
114 | * Calls the EE_Messages_Queue::get_batch_to_generate() method and sends to EE_Messages_Generator. |
||
115 | * |
||
116 | * @param EE_Message[] $messages Array of EE_Message objects (optional) to build the queue with. |
||
117 | * @param bool $clear_queue Whether to ensure a fresh queue or not. |
||
118 | * |
||
119 | * @return bool|EE_Messages_Queue return false if nothing generated. This returns a new EE_Message_Queue with |
||
120 | * generated messages. |
||
121 | */ |
||
122 | public function batch_generate_from_queue( $messages = array(), $clear_queue = false ) { |
||
135 | |||
136 | |||
137 | |||
138 | /** |
||
139 | * This method preps a queue for generation. |
||
140 | * |
||
141 | * @since 4.9.0 |
||
142 | * |
||
143 | * @param EE_Message[] $messages Array of EE_Message objects to build the queue with |
||
144 | * |
||
145 | * @param bool $clear_queue This indicates whether the existing queue should be dumped or not. |
||
146 | * |
||
147 | * @return bool true means queue prepped, false means there was a lock so no generation please. |
||
148 | */ |
||
149 | protected function _build_queue_for_generation( $messages = array(), $clear_queue = false ) { |
||
174 | |||
175 | |||
176 | /** |
||
177 | * This method preps a queue for sending. |
||
178 | * |
||
179 | * @param EE_Message[] $messages |
||
180 | * @param bool $clear_queue Used to indicate whether to start with a fresh queue or not. |
||
181 | * |
||
182 | * @return bool true means queue prepped, false means there was a lock so no queue prepped. |
||
183 | */ |
||
184 | protected function _build_queue_for_sending( $messages, $clear_queue = false ) { |
||
203 | |||
204 | |||
205 | /** |
||
206 | * Calls the EE_Message_Queue::get_to_send_batch_and_send() method and then immediately just calls EE_Message_Queue::execute() |
||
207 | * to iterate and send unsent messages. |
||
208 | * |
||
209 | * @param EE_Message[] $messages If an array of messages is sent in then use it. |
||
210 | * |
||
211 | * @param bool $clear_queue Whether to initialize a new queue or keep the existing one. |
||
212 | * |
||
213 | * @return EE_Messages_Queue |
||
214 | */ |
||
215 | public function batch_send_from_queue( $messages = array(), $clear_queue = false ) { |
||
228 | |||
229 | |||
230 | |||
231 | |||
232 | |||
233 | |||
234 | /** |
||
235 | * This immediately generates messages using the given array of EE_Message_To_Generate objects and returns the |
||
236 | * EE_Message_Queue with the generated messages for the caller to work with. Note, this does NOT save the generated |
||
237 | * messages in the queue, leaving it up to the caller to do so. |
||
238 | * |
||
239 | * @param EE_Message_To_Generate[] $messages_to_generate |
||
240 | * @return EE_Messages_Queue |
||
241 | */ |
||
242 | public function generate_and_return( $messages_to_generate ) { |
||
247 | |||
248 | |||
249 | |||
250 | |||
251 | /** |
||
252 | * Executes the generator generate method on the current internal queue, and returns the generated queue. |
||
253 | * @param bool $persist Indicate whether to instruct the generator to persist the generated queue (true) or not (false). |
||
254 | * @return EE_Messages_Queue |
||
255 | */ |
||
256 | public function generate_queue( $persist = true ) { |
||
259 | |||
260 | |||
261 | |||
262 | |||
263 | /** |
||
264 | * Queue for generation. Note this does NOT persist to the db. Client code should call get_message_repository()->save() if desire |
||
265 | * to persist. This method is provided to client code to decide what it wants to do with queued messages for generation. |
||
266 | * @param EE_Message_To_Generate $message_to_generate |
||
267 | * @param bool $test_send Whether this item is for a test send or not. |
||
268 | * @return EE_Messages_Queue |
||
269 | */ |
||
270 | public function queue_for_generation( EE_Message_To_Generate $message_to_generate, $test_send = false ) { |
||
271 | if ( $message_to_generate->valid() ) { |
||
272 | $this->_generator->create_and_add_message_to_queue( $message_to_generate, $test_send ); |
||
273 | } |
||
274 | } |
||
275 | |||
276 | |||
277 | |||
278 | |||
279 | |||
280 | |||
281 | |||
282 | /** |
||
283 | * This receives an array of EE_Message_To_Generate objects, converts them to EE_Message adds them to the generation queue |
||
284 | * and then persists to storage. |
||
285 | * |
||
286 | * @param EE_Message_To_Generate[] $messages_to_generate |
||
287 | */ |
||
288 | public function batch_queue_for_generation_and_persist( $messages_to_generate ) { |
||
293 | |||
294 | |||
295 | |||
296 | |||
297 | |||
298 | |||
299 | /** |
||
300 | * This receives an array of EE_Message_To_Generate objects, converts them to EE_Message and adds them to the generation |
||
301 | * queue. Does NOT persist to storage (unless there is an error. |
||
302 | * Client code can retrieve the generated queue by calling EEM_Messages_Processor::get_queue() |
||
303 | * |
||
304 | * @param EE_Message_To_Generate[] $messages_to_generate |
||
305 | */ |
||
306 | public function batch_queue_for_generation_no_persist( $messages_to_generate ) { |
||
310 | |||
311 | |||
312 | |||
313 | |||
314 | /** |
||
315 | * Simply loops through the given array of EE_Message_To_Generate objects and adds them to the _queue as EE_Message |
||
316 | * objects. |
||
317 | * |
||
318 | * @param EE_Message_To_Generate[] $messages_to_generate |
||
319 | */ |
||
320 | protected function _queue_for_generation_loop( $messages_to_generate ) { |
||
332 | |||
333 | |||
334 | |||
335 | |||
336 | |||
337 | /** |
||
338 | * Receives an array of EE_Message_To_Generate objects and generates the EE_Message objects, then persists (so its |
||
339 | * queued for sending). |
||
340 | * @param EE_Message_To_Generate[] |
||
341 | * @return EE_Messages_Queue |
||
342 | */ |
||
343 | public function generate_and_queue_for_sending( $messages_to_generate ) { |
||
348 | |||
349 | |||
350 | |||
351 | |||
352 | |||
353 | /** |
||
354 | * Generate for preview and execute right away. |
||
355 | * |
||
356 | * @param EE_Message_To_Generate $message_to_generate |
||
357 | * @param bool $test_send Whether this is a test send or not. |
||
358 | * @return EE_Messages_Queue | bool false if unable to generate otherwise the generated queue. |
||
359 | */ |
||
360 | public function generate_for_preview( EE_Message_To_Generate $message_to_generate, $test_send = false ) { |
||
361 | if ( ! $message_to_generate->valid() ) { |
||
362 | EE_Error::add_error( |
||
363 | __( 'Unable to generate preview because of invalid data', 'event_espresso' ), |
||
364 | __FILE__, |
||
365 | __FUNCTION__, |
||
366 | __LINE__ |
||
367 | ); |
||
368 | return false; |
||
369 | } |
||
370 | //just make sure preview is set on the $message_to_generate (in case client forgot) |
||
371 | $message_to_generate->set_preview( true ); |
||
372 | $this->_init_queue_and_generator(); |
||
373 | $this->queue_for_generation( $message_to_generate, $test_send ); |
||
374 | $generated_queue = $this->_generator->generate( false ); |
||
375 | if ( $generated_queue->execute( false ) ) { |
||
376 | //the first queue item should be the preview |
||
377 | $generated_queue->get_message_repository()->rewind(); |
||
378 | if ( ! $generated_queue->get_message_repository()->valid() ) { |
||
379 | return $generated_queue; |
||
380 | } |
||
381 | return $generated_queue; |
||
382 | } else { |
||
383 | return false; |
||
384 | } |
||
385 | } |
||
386 | |||
387 | |||
388 | /** |
||
389 | * This queues for sending. |
||
390 | * The messenger send now method is also verified to see if sending immediately is requested. |
||
391 | * otherwise its just saved to the queue. |
||
392 | * @param EE_Message_To_Generate $message_to_generate |
||
393 | * @return bool true or false for success. |
||
394 | */ |
||
395 | public function queue_for_sending( EE_Message_To_Generate $message_to_generate ) { |
||
409 | |||
410 | |||
411 | /** |
||
412 | * This generates and sends from the given EE_Message_To_Generate class immediately. |
||
413 | * @param EE_Message_To_Generate $message_to_generate |
||
414 | * @return EE_Messages_Queue | null |
||
415 | */ |
||
416 | public function generate_and_send_now( EE_Message_To_Generate $message_to_generate ) { |
||
449 | |||
450 | |||
451 | |||
452 | |||
453 | /** |
||
454 | * Creates mtg objects for all active messengers and queues for generation. |
||
455 | * This method also calls the execute by priority method on the queue which will optionally kick off a new non-blocking |
||
456 | * request to complete the action if the priority for the message requires immediate action. |
||
457 | * @param string $message_type |
||
458 | * @param mixed $data The data being used for generation. |
||
459 | * @param bool $persist Whether to persist the queued messages to the db or not. |
||
460 | */ |
||
461 | public function generate_for_all_active_messengers( $message_type, $data, $persist = true ) { |
||
470 | |||
471 | |||
472 | |||
473 | |||
474 | /** |
||
475 | * This simply loops through all active messengers and takes care of setting up the |
||
476 | * EE_Message_To_Generate objects. |
||
477 | * @param $message_type |
||
478 | * @param $data |
||
479 | * |
||
480 | * @return EE_Message_To_Generate[] |
||
481 | */ |
||
482 | public function setup_mtgs_for_all_active_messengers( $message_type, $data ) { |
||
492 | |||
493 | |||
494 | |||
495 | |||
496 | /** |
||
497 | * This accepts an array of EE_Message::MSG_ID values and will use that to retrieve the objects from the database |
||
498 | * and send. |
||
499 | * @param array $message_ids |
||
500 | */ |
||
501 | public function setup_messages_from_ids_and_send( $message_ids ) { |
||
525 | |||
526 | |||
527 | |||
528 | /** |
||
529 | * This method checks for registration IDs in the request via the given key and creates the messages to generate |
||
530 | * objects from them, then returns the array of messages to generate objects. |
||
531 | * Note, this sets up registrations for the registration family of message types. |
||
532 | * |
||
533 | * @param string $registration_ids_key This is used to indicate what represents the registration ids in the request. |
||
534 | * |
||
535 | * @return EE_Message_To_Generate[] |
||
536 | */ |
||
537 | public function setup_messages_to_generate_from_registration_ids_in_request( $registration_ids_key = '_REG_ID' ) { |
||
579 | |||
580 | |||
581 | |||
582 | } //end class EE_Messages_Processor |
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.