Completed
Branch BUG-9623-config-log (c144cd)
by
unknown
110:09 queued 92:18
created

EE_Messages_Queue::execute()   C

Complexity

Conditions 11
Paths 38

Size

Total Lines 51
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 11
eloc 31
c 2
b 0
f 0
nc 38
nop 3
dl 0
loc 51
rs 5.7333

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) { exit('No direct script access allowed'); }
2
3
/**
4
 * This class is used for managing and interacting with the EE_messages Queue.  An instance
5
 * of this object is used for interacting with a specific batch of EE_Message objects.
6
 *
7
 * @package    Event Espresso
8
 * @subpackage messages
9
 * @author     Darren Ethier
10
 * @since      4.9.0
11
 */
12
class EE_Messages_Queue {
13
14
15
	/**
16
	 * @type    string  reference for sending action
17
	 */
18
	const action_sending = 'sending';
19
20
	/**
21
	 * @type    string  reference for generation action
22
	 */
23
	const action_generating = 'generation';
24
25
26
27
	/**
28
	 * @type EE_Message_Repository $_message_repository
29
	 */
30
	protected $_message_repository;
31
32
	/**
33
	 * Sets the limit of how many messages are generated per process.
34
	 * @type int
35
	 */
36
	protected $_batch_count;
37
38
	/**
39
	 * Sets the limit of how many messages can be sent per hour.
40
	 * @type int
41
	 */
42
	protected $_rate_limit;
43
44
	/**
45
	 * This is an array of cached queue items being stored in this object.
46
	 * The array keys will be the ID of the EE_Message in the db if saved.  If the EE_Message
47
	 * is not saved to the db then its key will be an increment of "UNS" (i.e. UNS1, UNS2 etc.)
48
	 * @type EE_Message[]
49
	 */
50
	protected $_cached_queue_items;
51
52
	/**
53
	 * Tracks the number of unsaved queue items.
54
	 * @type int
55
	 */
56
	protected $_unsaved_count = 0;
57
58
	/**
59
	 * used to record if a do_messenger_hooks has already been called for a message type.  This prevents multiple
60
	 * hooks getting fired if users have setup their action/filter hooks to prevent duplicate calls.
61
	 *
62
	 * @type array
63
	 */
64
	protected $_did_hook = array();
65
66
67
68
	/**
69
	 * Constructor.
70
	 * Setup all the initial properties and load a EE_Message_Repository.
71
	 *
72
	 * @param \EE_Message_Repository       $message_repository
73
	 */
74
	public function __construct( EE_Message_Repository $message_repository ) {
75
		$this->_batch_count        = apply_filters( 'FHEE__EE_Messages_Queue___batch_count', 50 );
76
		$this->_rate_limit         = $this->get_rate_limit();
77
		$this->_message_repository = $message_repository;
78
	}
79
80
81
82
	/**
83
	 * Add a EE_Message object to the queue
84
	 *
85
	 * @param EE_Message    $message
86
	 * @param array         $data     This will be an array of data to attach to the object in the repository.  If the
87
	 *                                object is persisted, this data will be saved on an extra_meta object related to
88
	 *                                EE_Message.
89
	 * @param  bool         $preview  Whether this EE_Message represents a preview or not.
90
	 * @param  bool         $test_send This indicates whether to do a test send instead of actual send. A test send will
91
	 *                                 use the messenger send method but typically is based on preview data.
92
	 * @return bool          Whether the message was successfully added to the repository or not.
93
	 */
94
	public function add( EE_Message $message, $data = array(), $preview = false, $test_send = false ) {
95
		$data['preview'] = $preview;
96
		$data['test_send'] = $test_send;
97
		return $this->_message_repository->add( $message, $data );
98
	}
99
100
101
102
103
	/**
104
	 * Removes EE_Message from _queue that matches the given EE_Message if the pointer is on a matching EE_Message
105
	 * @param EE_Message    $message    The message to detach from the queue
106
	 * @param bool          $persist    This flag indicates whether to attempt to delete the object from the db as well.
107
	 * @return bool
108
	 */
109
	public function remove( EE_Message $message, $persist = false ) {
110
		if ( $persist && $this->_message_repository->current() !== $message ) {
111
			//get pointer on right message
112
			if ( $this->_message_repository->has( $message ) ) {
113
				$this->_message_repository->rewind();
114
				while( $this->_message_repository->valid() ) {
115
					if ( $this->_message_repository->current() === $message ) {
116
						break;
117
					}
118
					$this->_message_repository->next();
119
				}
120
			} else {
121
				return false;
122
			}
123
		}
124
		return $persist ? $this->_message_repository->delete() : $this->_message_repository->remove( $message );
125
	}
126
127
128
129
130
	/**
131
	 * Persists all queued EE_Message objects to the db.
132
	 * @return array()  @see EE_Messages_Repository::saveAll() for return values.
0 ignored issues
show
Documentation introduced by
The doc-type array() could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
133
	 */
134
	public function save() {
135
		return $this->_message_repository->saveAll();
136
	}
137
138
139
140
141
142
	/**
143
	 * @return EE_Message_Repository
144
	 */
145
	public function get_message_repository() {
146
		return $this->_message_repository;
147
	}
148
149
150
151
152
	/**
153
	 * This does the following things:
154
	 * 1. Checks if there is a lock on generation (prevents race conditions).  If there is a lock then exits (return false).
155
	 * 2. If no lock, sets lock, then retrieves a batch of non-generated EE_Message objects and adds to queue
156
	 * 3. Returns bool.  True = batch ready.  False = no batch ready (or nothing available for generation).
157
	 *
158
	 * Note: Callers should make sure they release the lock otherwise batch generation will be prevented from continuing.
159
	 *       The lock is on a transient that is set to expire after one hour as a fallback in case locks are not removed.
160
	 *
161
	 * @return bool  true if successfully retrieved batch, false no batch ready.
162
	 */
163
	public function get_batch_to_generate() {
164
		if ( $this->is_locked( EE_Messages_Queue::action_generating ) ) {
165
			return false;
166
		}
167
168
		//lock batch generation to prevent race conditions.
169
		$this->lock_queue( EE_Messages_Queue::action_generating );
170
171
		$query_args = array(
172
			// key 0 = where conditions
173
			0 => array( 'STS_ID' => EEM_Message::status_incomplete ),
174
			'order_by' => $this->_get_priority_orderby(),
175
			'limit' => $this->_batch_count
176
		);
177
		$messages = EEM_Message::instance()->get_all( $query_args );
178
179
		if ( ! $messages ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $messages 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...
180
			return false; //nothing to generate
181
		}
182
183
		foreach ( $messages as $message ) {
184
			if ( $message instanceof EE_Message ) {
185
				$data = $message->all_extra_meta_array();
186
				$this->add( $message, $data );
187
			}
188
		}
189
		return true;
190
	}
191
192
193
	/**
194
	 * This does the following things:
195
	 * 1. Checks if there is a lock on sending (prevents race conditions).  If there is a lock then exits (return false).
196
	 * 2. Grabs the allowed number of messages to send for the rate_limit.  If cannot send any more messages, then return false.
197
	 * 2. If no lock, sets lock, then retrieves a batch of EE_Message objects, adds to queue and triggers execution.
198
	 * 3. On success or unsuccessful send, sets status appropriately.
199
	 * 4. Saves messages via the queue
200
	 * 5. Releases lock.
201
	 *
202
	 * @return bool  true on success, false if something preventing sending (i.e. lock set).  Note: true does not necessarily
203
	 *               mean that all messages were successfully sent.  It just means that this method successfully completed.
204
	 *               On true, client may want to call $this->count_STS_in_queue( EEM_Message::status_failed ) to see if
205
	 *               any failed EE_Message objects.  Each failed message object will also have a saved error message on it
206
	 *               to assist with notifying user.
207
	 */
208
	public function get_to_send_batch_and_send() {
209
		if ( $this->is_locked( EE_Messages_Queue::action_sending ) || $this->_rate_limit < 1 ) {
210
			return false;
211
		}
212
213
		$this->lock_queue( EE_Messages_Queue::action_sending );
214
215
		$batch = $this->_batch_count < $this->_rate_limit ? $this->_batch_count : $this->_rate_limit;
216
217
		$query_args = array(
218
			// key 0 = where conditions
219
			0 => array( 'STS_ID' => array( 'IN', EEM_Message::instance()->stati_indicating_to_send() ) ),
220
			'order_by' => $this->_get_priority_orderby(),
221
			'limit' => $batch
222
		);
223
224
		$messages_to_send = EEM_Message::instance()->get_all( $query_args );
225
226
227
		//any to send?
228
		if ( ! $messages_to_send ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $messages_to_send 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...
229
			$this->unlock_queue( EE_Messages_Queue::action_sending );
230
			return false;
231
		}
232
233
		//add to queue.
234
		foreach ( $messages_to_send as $message ) {
235
			if ( $message instanceof EE_Message ) {
236
				$this->add( $message );
237
			}
238
		}
239
240
		//send messages  (this also updates the rate limit)
241
		$this->execute();
242
243
		//release lock
244
		$this->unlock_queue( EE_Messages_Queue::action_sending );
245
		return true;
246
	}
247
248
249
250
251
	/**
252
	 * Locks the queue so that no other queues can call the "batch" methods.
253
	 *
254
	 * @param   string  $type   The type of queue being locked.
255
	 */
256
	public function lock_queue( $type = EE_Messages_Queue::action_generating ) {
257
		set_transient( $this->_get_lock_key( $type ), 1, $this->_get_lock_expiry( $type ) );
258
	}
259
260
261
262
263
	/**
264
	 * Unlocks the queue so that batch methods can be used.
265
	 *
266
	 * @param   string  $type   The type of queue being unlocked.
267
	 */
268
	public function unlock_queue( $type = EE_Messages_Queue::action_generating ) {
269
		delete_transient( $this->_get_lock_key( $type ) );
270
	}
271
272
273
274
275
	/**
276
	 * Retrieve the key used for the lock transient.
277
	 * @param string $type  The type of lock.
278
	 * @return string
279
	 */
280
	protected function _get_lock_key( $type = EE_Messages_Queue::action_generating ) {
281
		return '_ee_lock_' . $type;
282
	}
283
284
285
286
287
	/**
288
	 * Retrieve the expiry time for the lock transient.
289
	 * @param string $type  The type of lock
290
	 * @return int   time to expiry in seconds.
291
	 */
292
	protected function _get_lock_expiry( $type = EE_Messages_Queue::action_generating ) {
293
		return (int) apply_filters( 'FHEE__EE_Messages_Queue__lock_expiry', HOUR_IN_SECONDS, $type );
294
	}
295
296
297
	/**
298
	 * Returns the key used for rate limit transient.
299
	 * @return string
300
	 */
301
	protected function _get_rate_limit_key() {
302
		return '_ee_rate_limit';
303
	}
304
305
306
	/**
307
	 * Returns the rate limit expiry time.
308
	 * @return int
309
	 */
310
	protected function _get_rate_limit_expiry() {
311
		return (int) apply_filters( 'FHEE__EE_Messages_Queue__rate_limit_expiry', HOUR_IN_SECONDS );
312
	}
313
314
315
316
317
	/**
318
	 * Returns the default rate limit for sending messages.
319
	 * @return int
320
	 */
321
	protected function _default_rate_limit() {
322
		return (int) apply_filters( 'FHEE__EE_Messages_Queue___rate_limit', 200 );
323
	}
324
325
326
327
328
	/**
329
	 * Return the orderby array for priority.
330
	 * @return array
331
	 */
332
	protected function _get_priority_orderby() {
333
		return array(
334
			'MSG_priority' => 'ASC',
335
			'MSG_modified' => 'DESC'
336
		);
337
	}
338
339
340
341
342
	/**
343
	 * Returns whether batch methods are "locked" or not.
344
	 *
345
	 * @param  string $type The type of lock being checked for.
346
	 * @return bool
347
	 */
348
	public function is_locked( $type = EE_Messages_Queue::action_generating ) {
349
		return filter_var(
350
			apply_filters(
351
				'FHEE__EE_Messages_Queue__is_locked',
352
				get_transient( $this->_get_lock_key( $type ) ),
353
				$this
354
			),
355
			FILTER_VALIDATE_BOOLEAN
356
		);
357
	}
358
359
360
361
362
363
364
365
	/**
366
	 * Retrieves the rate limit that may be cached as a transient.
367
	 * If the rate limit is not set, then this sets the default rate limit and expiry and returns it.
368
	 * @return int
369
	 */
370
	public function get_rate_limit() {
371
		if ( ! $rate_limit = get_transient( $this->_get_rate_limit_key() ) ) {
372
			$rate_limit = $this->_default_rate_limit();
373
			set_transient( $this->_get_rate_limit_key(), $rate_limit, $this->_get_rate_limit_key() );
374
		}
375
		return $rate_limit;
376
	}
377
378
379
380
381
	/**
382
	 * This updates existing rate limit with the new limit which is the old minus the batch.
383
	 * @param int $batch_completed  This sets the new rate limit based on the given batch that was completed.
384
	 */
385
	public function set_rate_limit( $batch_completed ) {
386
		//first get the most up to date rate limit (in case its expired and reset)
387
		$rate_limit = $this->get_rate_limit();
388
		$new_limit = $rate_limit - $batch_completed;
389
		//updating the transient option directly to avoid resetting the expiry.
390
		update_option( '_transient_' . $this->_get_rate_limit_key(), $new_limit );
391
	}
392
393
394
	/**
395
	 * This method checks the queue for ANY EE_Message objects with a priority matching the given priority passed in.
396
	 * If that exists, then we immediately initiate a non-blocking request to do the requested action type.
397
	 *
398
	 * Note: Keep in mind that there is the possibility that the request will not execute if there is already another request
399
	 * running on a queue for the given task.
400
	 * @param string $task This indicates what type of request is going to be initiated.
401
	 * @param int    $priority  This indicates the priority that triggers initiating the request.
402
	 */
403
	public function initiate_request_by_priority( $task = 'generate', $priority = EEM_Message::priority_high ) {
404
		//determine what status is matched with the priority as part of the trigger conditions.
405
		$status = $task == 'generate'
406
			? EEM_Message::status_incomplete
407
			: EEM_Message::instance()->stati_indicating_to_send();
408
		// always make sure we save because either this will get executed immediately on a separate request
409
		// or remains in the queue for the regularly scheduled queue batch.
410
		$this->save();
411
		if ( $this->_message_repository->count_by_priority_and_status( $priority, $status ) ) {
412
			EE_Messages_Scheduler::initiate_scheduled_non_blocking_request( $task );
413
		}
414
	}
415
416
417
418
	/**
419
	 *  Loops through the EE_Message objects in the _queue and calls the messenger send methods for each message.
420
	 *
421
	 * @param   bool $save                      Used to indicate whether to save the message queue after sending
422
	 *                                          (default will save).
423
	 * @param   mixed $sending_messenger 		(optional) When the sending messenger is different than
424
	 *                                          what is on the EE_Message object in the queue.
425
	 *                                          For instance, showing the browser view of an email message,
426
	 *                                          or giving a pdf generated view of an html document.
427
	 *                                     		This should be an instance of EE_messenger but if you call this method
428
	 *                                          intending it to be a sending messenger but a valid one could not be retrieved
429
	 *                                          then send in an instance of EE_Error that contains the related error message.
430
	 * @param   bool|int $by_priority           When set, this indicates that only messages
431
	 *                                          matching the given priority should be executed.
432
	 *
433
	 * @return int        Number of messages sent.  Note, 0 does not mean that no messages were processed.
434
	 *                    Also, if the messenger is an request type messenger (or a preview),
435
	 * 					  its entirely possible that the messenger will exit before
436
	 */
437
	public function execute( $save = true, $sending_messenger = null, $by_priority = false ) {
438
		$messages_sent = 0;
439
		$this->_did_hook = array();
440
		$this->_message_repository->rewind();
441
442
		while ( $this->_message_repository->valid() ) {
443
			$error_messages = array();
444
			/** @type EE_Message $message */
445
			$message = $this->_message_repository->current();
446
			//if the message in the queue has a sent status, then skip
447
			if ( in_array( $message->STS_ID(), EEM_Message::instance()->stati_indicating_sent() ) ) {
448
				$this->_message_repository->next();
449
				continue;
450
			}
451
			//if $by_priority is set and does not match then continue;
452
			if ( $by_priority && $by_priority != $message->priority() ) {
453
				$this->_message_repository->next();
454
				continue;
455
			}
456
			//error checking
457
			if ( ! $message->valid_messenger() ) {
458
				$error_messages[] = sprintf(
459
					__( 'The %s messenger is not active at time of sending.', 'event_espresso' ),
460
					$message->messenger()
461
				);
462
			}
463
			if ( ! $message->valid_message_type() ) {
464
				$error_messages[] = sprintf(
465
					__( 'The %s message type is not active at the time of sending.', 'event_espresso' ),
466
					$message->message_type()
467
				);
468
			}
469
			// if there was supposed to be a sending messenger for this message, but it was invalid/inactive,
470
			// then it will instead be an EE_Error object, so let's check for that
471
			if ( $sending_messenger instanceof EE_Error ) {
472
				$error_messages[] = $sending_messenger->getMessage();
473
			}
474
			// if there are no errors, then let's process the message
475
			if ( empty( $error_messages ) && $this->_process_message( $message, $sending_messenger ) ) {
476
				$messages_sent++;
477
			}
478
			$this->_set_error_message( $message, $error_messages );
479
			//add modified time
480
			$message->set_modified( time() );
481
			$this->_message_repository->next();
482
		}
483
		if ( $save ) {
484
			$this->save();
485
		}
486
		return $messages_sent;
487
	}
488
489
490
491
	/**
492
	 * _process_message
493
	 *
494
	 * @param EE_Message $message
495
	 * @param mixed 	 $sending_messenger (optional)
496
	 * @return bool
497
	 */
498
	protected function _process_message( EE_Message $message, $sending_messenger = null ) {
499
		// these *should* have been validated in the execute() method above
500
		$messenger = $message->messenger_object();
501
		$message_type = $message->message_type_object();
502
		//do actions for sending messenger if it differs from generating messenger and swap values.
503
		if (
504
			$sending_messenger instanceof EE_messenger
505
			&& $messenger instanceof EE_messenger
506
			&& $sending_messenger->name != $messenger->name
507
		) {
508
			$messenger->do_secondary_messenger_hooks( $sending_messenger->name );
509
			$messenger = $sending_messenger;
510
		}
511
		// send using messenger, but double check objects
512
		if ( $messenger instanceof EE_messenger && $message_type instanceof EE_message_type ) {
513
			//set hook for message type (but only if not using another messenger to send).
514
			if ( ! isset( $this->_did_hook[ $message_type->name ] ) ) {
515
				$message_type->do_messenger_hooks( $messenger );
516
				$this->_did_hook[ $message_type->name ] = 1;
517
			}
518
			//if preview then use preview method
519
			return $this->_message_repository->is_preview()
520
				? $this->_do_preview( $message, $messenger, $message_type, $this->_message_repository->is_test_send() )
521
				: $this->_do_send( $message, $messenger, $message_type );
522
		}
523
		return false;
524
	}
525
526
527
528
	/**
529
	 * The intention of this method is to count how many EE_Message objects
530
	 * are in the queue with a given status.
531
	 *
532
	 * Example usage:
533
	 * After a caller calls the "EE_Message_Queue::execute()" method, the caller can check if there were any failed sends
534
	 * by calling $queue->count_STS_in_queue( EEM_Message_Queue::status_failed ).
535
	 *
536
	 * @param array $status  Stati to check for in queue
537
	 * @return int  Count of EE_Message's matching the given status.
538
	 */
539
	public function count_STS_in_queue( $status ) {
540
		$count = 0;
541
		$status = is_array( $status ) ? $status : array( $status );
542
		$this->_message_repository->rewind();
543
		foreach( $this->_message_repository as $message ) {
544
			if ( in_array( $message->STS_ID(), $status ) ) {
545
				$count++;
546
			}
547
		}
548
		return $count;
549
	}
550
551
552
	/**
553
	 * Executes the get_preview method on the provided messenger.
554
	 *
555
*@param EE_Message            $message
556
	 * @param EE_messenger    $messenger
557
	 * @param EE_message_type $message_type
558
	 * @param $test_send
559
	 * @return bool   true means all went well, false means, not so much.
560
	 */
561
	protected function _do_preview( EE_Message $message, EE_messenger $messenger, EE_message_type $message_type, $test_send ) {
562
		if ( $preview = $messenger->get_preview( $message, $message_type, $test_send ) ) {
563
			if ( ! $test_send ) {
564
				$message->set_content( $preview );
0 ignored issues
show
Bug introduced by
It seems like $preview defined by $messenger->get_preview(...ssage_type, $test_send) on line 562 can also be of type boolean; however, EE_Message::set_content() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
565
			}
566
			$message->set_STS_ID( EEM_Message::status_sent );
567
			return true;
568
		} else {
569
			$message->set_STS_ID( EEM_Message::status_failed );
570
			return false;
571
		}
572
	}
573
574
575
576
577
	/**
578
	 * Executes the send method on the provided messenger
579
	 *
580
*@param EE_Message            $message
581
	 * @param EE_messenger    $messenger
582
	 * @param EE_message_type $message_type
583
	 * @return bool true means all went well, false means, not so much.
584
	 */
585
	protected function _do_send( EE_Message $message, EE_messenger $messenger, EE_message_type $message_type ) {
586
		if ( $messenger->send_message( $message, $message_type ) ) {
587
			$message->set_STS_ID( EEM_Message::status_sent );
588
			return true;
589
		} else {
590
			$message->set_STS_ID( EEM_Message::status_retry );
591
			return false;
592
		}
593
	}
594
595
596
597
598
599
	/**
600
	 * This sets any necessary error messages on the message object and its status to failed.
601
	 * @param EE_Message $message
602
	 * @param array      $error_messages the response from the messenger.
603
	 */
604
	protected function _set_error_message( EE_Message $message, $error_messages ) {
605
		$error_messages = (array) $error_messages;
606
		if ( in_array( $message->STS_ID(), EEM_Message::instance()->stati_indicating_failed_sending() ) ) {
607
			$notices = EE_Error::has_notices();
608
			$error_messages[] = __( 'Messenger and Message Type were valid and active, but the messenger send method failed.', 'event_espresso' );
609
			if ( $notices === 1 ) {
610
				$notices = EE_Error::get_vanilla_notices();
611
				$notices['errors'] = isset( $notices['errors'] ) ? $notices['errors'] : array();
612
				$error_messages[] = implode( "\n", $notices['errors'] );
613
			}
614
		}
615
		if ( count( $error_messages ) > 0 ) {
616
			$msg = __( 'Message was not executed successfully.', 'event_espresso' );
617
			$msg = $msg . "\n" . implode( "\n", $error_messages );
618
			$message->set_error_message( $msg );
619
		}
620
	}
621
622
} //end EE_Messages_Queue class