Completed
Branch fix-dummy-related-question-qst... (e5efcf)
by
unknown
07:49 queued 03:45
created
core/libraries/messages/EE_Messages_Queue.lib.php 2 patches
Indentation   +705 added lines, -705 removed lines patch added patch discarded remove patch
@@ -13,709 +13,709 @@
 block discarded – undo
13 13
  */
14 14
 class EE_Messages_Queue
15 15
 {
16
-    /**
17
-     * @type    string  reference for sending action
18
-     */
19
-    const action_sending = 'sending';
20
-
21
-    /**
22
-     * @type    string  reference for generation action
23
-     */
24
-    const action_generating = 'generation';
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
-     *
35
-     * @type int
36
-     */
37
-    protected $_batch_count;
38
-
39
-
40
-    /**
41
-     * This is an array of cached queue items being stored in this object.
42
-     * The array keys will be the ID of the EE_Message in the db if saved.  If the EE_Message
43
-     * is not saved to the db then its key will be an increment of "UNS" (i.e. UNS1, UNS2 etc.)
44
-     *
45
-     * @type EE_Message[]
46
-     */
47
-    protected $_cached_queue_items;
48
-
49
-    /**
50
-     * Tracks the number of unsaved queue items.
51
-     *
52
-     * @type int
53
-     */
54
-    protected $_unsaved_count = 0;
55
-
56
-    /**
57
-     * used to record if a do_messenger_hooks has already been called for a message type.  This prevents multiple
58
-     * hooks getting fired if users have setup their action/filter hooks to prevent duplicate calls.
59
-     *
60
-     * @type array
61
-     */
62
-    protected $_did_hook = [];
63
-
64
-
65
-    /**
66
-     * Constructor.
67
-     * Setup all the initial properties and load a EE_Message_Repository.
68
-     *
69
-     * @param EE_Message_Repository $message_repository
70
-     */
71
-    public function __construct(EE_Message_Repository $message_repository)
72
-    {
73
-        $this->_batch_count        = apply_filters('FHEE__EE_Messages_Queue___batch_count', 50);
74
-        $this->_message_repository = $message_repository;
75
-    }
76
-
77
-
78
-    /**
79
-     * Add a EE_Message object to the queue
80
-     *
81
-     * @param EE_Message $message
82
-     * @param array      $data         This will be an array of data to attach to the object in the repository.  If the
83
-     *                                 object is persisted, this data will be saved on an extra_meta object related to
84
-     *                                 EE_Message.
85
-     * @param bool       $preview      Whether this EE_Message represents a preview or not.
86
-     * @param bool       $test_send    This indicates whether to do a test send instead of actual send. A test send will
87
-     *                                 use the messenger send method but typically is based on preview data.
88
-     * @return bool          Whether the message was successfully added to the repository or not.
89
-     */
90
-    public function add(EE_Message $message, $data = [], $preview = false, $test_send = false)
91
-    {
92
-        $data['preview']   = $preview;
93
-        $data['test_send'] = $test_send;
94
-        return $this->_message_repository->add($message, $data);
95
-    }
96
-
97
-
98
-    /**
99
-     * Removes EE_Message from _queue that matches the given EE_Message if the pointer is on a matching EE_Message
100
-     *
101
-     * @param EE_Message $message The message to detach from the queue
102
-     * @param bool       $persist This flag indicates whether to attempt to delete the object from the db as well.
103
-     * @return bool
104
-     */
105
-    public function remove(EE_Message $message, $persist = false)
106
-    {
107
-        if ($persist && $this->_message_repository->current() !== $message) {
108
-            // get pointer on right message
109
-            if ($this->_message_repository->has($message)) {
110
-                $this->_message_repository->rewind();
111
-                while ($this->_message_repository->valid()) {
112
-                    if ($this->_message_repository->current() === $message) {
113
-                        break;
114
-                    }
115
-                    $this->_message_repository->next();
116
-                }
117
-            } else {
118
-                return false;
119
-            }
120
-        }
121
-        return $persist ? $this->_message_repository->delete() : $this->_message_repository->remove($message);
122
-    }
123
-
124
-
125
-    /**
126
-     * Persists all queued EE_Message objects to the db.
127
-     *
128
-     * @param bool $do_hooks_only @see EE_Message_Repository::saveAll
129
-     * @return array @see EE_Messages_Repository::saveAll() for return values.
130
-     */
131
-    public function save($do_hooks_only = false)
132
-    {
133
-        return $this->_message_repository->saveAll($do_hooks_only);
134
-    }
135
-
136
-
137
-    /**
138
-     * @return EE_Message_Repository
139
-     */
140
-    public function get_message_repository()
141
-    {
142
-        return $this->_message_repository;
143
-    }
144
-
145
-
146
-    /**
147
-     * This does the following things:
148
-     * 1. Checks if there is a lock on generation (prevents race conditions).  If there is a lock then exits (return
149
-     * false).
150
-     * 2. If no lock, sets lock, then retrieves a batch of non-generated EE_Message objects and adds to queue
151
-     * 3. Returns bool.  True = batch ready.  False = no batch ready (or nothing available for generation).
152
-     * Note: Callers should make sure they release the lock otherwise batch generation will be prevented from
153
-     * continuing. The lock is on a transient that is set to expire after one hour as a fallback in case locks are not
154
-     * removed.
155
-     *
156
-     * @return bool  true if successfully retrieved batch, false no batch ready.
157
-     * @throws EE_Error
158
-     * @throws ReflectionException
159
-     */
160
-    public function get_batch_to_generate()
161
-    {
162
-        if ($this->is_locked()) {
163
-            return false;
164
-        }
165
-
166
-        // lock batch generation to prevent race conditions.
167
-        $this->lock_queue();
168
-
169
-        $query_args = [
170
-            // key 0 = where conditions
171
-            0          => ['STS_ID' => EEM_Message::status_incomplete],
172
-            'order_by' => $this->_get_priority_orderby(),
173
-            'limit'    => $this->_batch_count,
174
-        ];
175
-        $messages   = EEM_Message::instance()->get_all($query_args);
176
-
177
-        if (! $messages) {
178
-            return false; // nothing to generate
179
-        }
180
-
181
-        foreach ($messages as $message) {
182
-            if ($message instanceof EE_Message) {
183
-                $data = $message->all_extra_meta_array();
184
-                $this->add($message, $data);
185
-            }
186
-        }
187
-        return true;
188
-    }
189
-
190
-
191
-    /**
192
-     * This does the following things:
193
-     * 1. Checks if there is a lock on sending (prevents race conditions).  If there is a lock then exits (return
194
-     * false).
195
-     * 2. Grabs the allowed number of messages to send for the rate_limit.  If cannot send any more messages, then
196
-     * 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
203
-     *               necessarily mean that all messages were successfully sent.  It just means that this method
204
-     *               successfully completed. On true, client may want to call $this->count_STS_in_queue(
205
-     *               EEM_Message::status_failed ) to see if any failed EE_Message objects.  Each failed message object
206
-     *               will also have a saved error message on it to assist with notifying user.
207
-     * @throws EE_Error
208
-     * @throws ReflectionException
209
-     */
210
-    public function get_to_send_batch_and_send()
211
-    {
212
-        $rate_limit = $this->get_rate_limit();
213
-        if (
214
-            $rate_limit < 1
215
-            || $this->is_locked(EE_Messages_Queue::action_sending)
216
-        ) {
217
-            return false;
218
-        }
219
-
220
-        $this->lock_queue(EE_Messages_Queue::action_sending);
221
-
222
-        $batch = $this->_batch_count < $rate_limit ? $this->_batch_count : $rate_limit;
223
-
224
-        $query_args = [
225
-            // key 0 = where conditions
226
-            0          => ['STS_ID' => ['IN', EEM_Message::instance()->stati_indicating_to_send()]],
227
-            'order_by' => $this->_get_priority_orderby(),
228
-            'limit'    => $batch,
229
-        ];
230
-
231
-        $messages_to_send = EEM_Message::instance()->get_all($query_args);
232
-
233
-
234
-        // any to send?
235
-        if (! $messages_to_send) {
236
-            $this->unlock_queue(EE_Messages_Queue::action_sending);
237
-            return false;
238
-        }
239
-
240
-        $queue_count = 0;
241
-
242
-        // add to queue.
243
-        foreach ($messages_to_send as $message) {
244
-            if ($message instanceof EE_Message) {
245
-                $queue_count++;
246
-                $this->add($message);
247
-            }
248
-        }
249
-
250
-        // send messages  (this also updates the rate limit)
251
-        $this->execute();
252
-
253
-        // release lock
254
-        $this->unlock_queue(EE_Messages_Queue::action_sending);
255
-        // update rate limit
256
-        $this->set_rate_limit($queue_count);
257
-        return true;
258
-    }
259
-
260
-
261
-    /**
262
-     * Locks the queue so that no other queues can call the "batch" methods.
263
-     *
264
-     * @param string $type The type of queue being locked.
265
-     */
266
-    public function lock_queue($type = EE_Messages_Queue::action_generating)
267
-    {
268
-        update_option($this->_get_lock_key($type), $this->_get_lock_expiry($type));
269
-    }
270
-
271
-
272
-    /**
273
-     * Unlocks the queue so that batch methods can be used.
274
-     *
275
-     * @param string $type The type of queue being unlocked.
276
-     */
277
-    public function unlock_queue($type = EE_Messages_Queue::action_generating)
278
-    {
279
-        delete_option($this->_get_lock_key($type));
280
-    }
281
-
282
-
283
-    /**
284
-     * Retrieve the key used for the lock transient.
285
-     *
286
-     * @param string $type The type of lock.
287
-     * @return string
288
-     */
289
-    protected function _get_lock_key($type = EE_Messages_Queue::action_generating)
290
-    {
291
-        return '_ee_lock_' . $type;
292
-    }
293
-
294
-
295
-    /**
296
-     * Retrieve the expiry time for the lock transient.
297
-     *
298
-     * @param string $type The type of lock
299
-     * @return int   time to expiry in seconds.
300
-     */
301
-    protected function _get_lock_expiry($type = EE_Messages_Queue::action_generating)
302
-    {
303
-        return time() + (int) apply_filters('FHEE__EE_Messages_Queue__lock_expiry', HOUR_IN_SECONDS, $type);
304
-    }
305
-
306
-
307
-    /**
308
-     * Returns the key used for rate limit transient.
309
-     *
310
-     * @return string
311
-     */
312
-    protected function _get_rate_limit_key()
313
-    {
314
-        return '_ee_rate_limit';
315
-    }
316
-
317
-
318
-    /**
319
-     * Returns the rate limit expiry time.
320
-     *
321
-     * @return int
322
-     */
323
-    protected function _get_rate_limit_expiry()
324
-    {
325
-        return time() + (int) apply_filters('FHEE__EE_Messages_Queue__rate_limit_expiry', HOUR_IN_SECONDS);
326
-    }
327
-
328
-
329
-    /**
330
-     * Returns the default rate limit for sending messages.
331
-     *
332
-     * @return int
333
-     */
334
-    protected function _default_rate_limit()
335
-    {
336
-        return (int) apply_filters('FHEE__EE_Messages_Queue___rate_limit', 200);
337
-    }
338
-
339
-
340
-    /**
341
-     * Return the orderby array for priority.
342
-     *
343
-     * @return array
344
-     */
345
-    protected function _get_priority_orderby()
346
-    {
347
-        return [
348
-            'MSG_priority' => 'ASC',
349
-            'MSG_modified' => 'DESC',
350
-        ];
351
-    }
352
-
353
-
354
-    /**
355
-     * Returns whether batch methods are "locked" or not, and if models an currently be used to query the database.
356
-     * Return true when batch methods should not be used; returns false when they can be.
357
-     *
358
-     * @param string $type The type of lock being checked for.
359
-     * @return bool
360
-     */
361
-    public function is_locked($type = EE_Messages_Queue::action_generating)
362
-    {
363
-        if (! EE_Maintenance_Mode::instance()->models_can_query()) {
364
-            return true;
365
-        }
366
-        $lock = (int) get_option($this->_get_lock_key($type), 0);
367
-        /**
368
-         * This filters the default is_locked behaviour.
369
-         */
370
-        $is_locked = filter_var(
371
-            apply_filters(
372
-                'FHEE__EE_Messages_Queue__is_locked',
373
-                $lock > time(),
374
-                $this
375
-            ),
376
-            FILTER_VALIDATE_BOOLEAN
377
-        );
378
-
379
-        /**
380
-         * @see usage of this filter in EE_Messages_Queue::initiate_request_by_priority() method.
381
-         *            Also implemented here because messages processed on the same request should not have any locks applied.
382
-         */
383
-        if (
384
-            apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
385
-            || EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
386
-        ) {
387
-            $is_locked = false;
388
-        }
389
-
390
-
391
-        return $is_locked;
392
-    }
393
-
394
-
395
-    /**
396
-     * Retrieves the rate limit that may be cached as a transient.
397
-     * If the rate limit is not set, then this sets the default rate limit and expiry and returns it.
398
-     *
399
-     * @param bool $return_expiry If true then return the expiry time not the rate_limit.
400
-     * @return int
401
-     */
402
-    protected function get_rate_limit($return_expiry = false)
403
-    {
404
-        $stored_rate_info = get_option($this->_get_rate_limit_key(), []);
405
-        $rate_limit       = isset($stored_rate_info[0])
406
-            ? (int) $stored_rate_info[0]
407
-            : 0;
408
-        $expiry           = isset($stored_rate_info[1])
409
-            ? (int) $stored_rate_info[1]
410
-            : 0;
411
-        // set the default for tracking?
412
-        if (empty($stored_rate_info) || time() > $expiry) {
413
-            $expiry     = $this->_get_rate_limit_expiry();
414
-            $rate_limit = $this->_default_rate_limit();
415
-            update_option($this->_get_rate_limit_key(), [$rate_limit, $expiry]);
416
-        }
417
-        return $return_expiry ? $expiry : $rate_limit;
418
-    }
419
-
420
-
421
-    /**
422
-     * This updates existing rate limit with the new limit which is the old minus the batch.
423
-     *
424
-     * @param int $batch_completed This sets the new rate limit based on the given batch that was completed.
425
-     */
426
-    protected function set_rate_limit($batch_completed)
427
-    {
428
-        // first get the most up to date rate limit (in case its expired and reset)
429
-        $rate_limit = $this->get_rate_limit();
430
-        $expiry     = $this->get_rate_limit(true);
431
-        $new_limit  = $rate_limit - $batch_completed;
432
-        // updating the transient option directly to avoid resetting the expiry.
433
-
434
-        update_option($this->_get_rate_limit_key(), [$new_limit, $expiry]);
435
-    }
436
-
437
-
438
-    /**
439
-     * This method checks the queue for ANY EE_Message objects with a priority matching the given priority passed in.
440
-     * If that exists, then we immediately initiate a non-blocking request to do the requested action type.
441
-     * Note: Keep in mind that there is the possibility that the request will not execute if there is already another
442
-     * request running on a queue for the given task.
443
-     *
444
-     * @param string $task     This indicates what type of request is going to be initiated.
445
-     * @param int    $priority This indicates the priority that triggers initiating the request.
446
-     * @return bool|EE_Messages_Queue|void
447
-     * @throws EE_Error
448
-     * @throws ReflectionException
449
-     */
450
-    public function initiate_request_by_priority($task = 'generate', $priority = EEM_Message::priority_high)
451
-    {
452
-        // determine what status is matched with the priority as part of the trigger conditions.
453
-        $status = $task == 'generate'
454
-            ? EEM_Message::status_incomplete
455
-            : EEM_Message::instance()->stati_indicating_to_send();
456
-        // always make sure we save because either this will get executed immediately on a separate request
457
-        // or remains in the queue for the regularly scheduled queue batch.
458
-        $this->save();
459
-        /**
460
-         * This filter/option allows users to override processing of messages on separate requests and instead have everything
461
-         * happen on the same request.  If this is utilized remember:
462
-         * - message priorities don't matter
463
-         * - existing unprocessed messages in the queue will not get processed unless manually triggered.
464
-         * - things will be perceived to take longer to happen for end users (i.e. registrations) because of the additional
465
-         *   processing happening on the same request.
466
-         * - any race condition protection (locks) are removed because they don't apply when things are processed on
467
-         *   the same request.
468
-         */
469
-        if (
470
-            apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
471
-            || EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
472
-        ) {
473
-            $messages_processor = EE_Registry::instance()->load_lib('Messages_Processor');
474
-            if ($messages_processor instanceof EE_Messages_Processor) {
475
-                return $messages_processor->process_immediately_from_queue($this);
476
-            }
477
-            // if we get here then that means the messages processor couldn't be loaded so messages will just remain
478
-            // queued for manual triggering by end user.
479
-        }
480
-
481
-        if ($this->_message_repository->count_by_priority_and_status($priority, $status)) {
482
-            EE_Messages_Scheduler::initiate_scheduled_non_blocking_request($task);
483
-        }
484
-    }
485
-
486
-
487
-    /**
488
-     *  Loops through the EE_Message objects in the _queue and calls the messenger send methods for each message.
489
-     *
490
-     * @param bool     $save                      Used to indicate whether to save the message queue after sending
491
-     *                                            (default will save).
492
-     * @param mixed    $sending_messenger         (optional) When the sending messenger is different than
493
-     *                                            what is on the EE_Message object in the queue.
494
-     *                                            For instance, showing the browser view of an email message,
495
-     *                                            or giving a pdf generated view of an html document.
496
-     *                                            This should be an instance of EE_messenger but if you call this
497
-     *                                            method
498
-     *                                            intending it to be a sending messenger but a valid one could not be
499
-     *                                            retrieved then send in an instance of EE_Error that contains the
500
-     *                                            related error message.
501
-     * @param bool|int $by_priority               When set, this indicates that only messages
502
-     *                                            matching the given priority should be executed.
503
-     * @return int        Number of messages sent.  Note, 0 does not mean that no messages were processed.
504
-     *                                            Also, if the messenger is an request type messenger (or a preview),
505
-     *                                            its entirely possible that the messenger will exit before
506
-     * @throws EE_Error
507
-     * @throws ReflectionException
508
-     */
509
-    public function execute($save = true, $sending_messenger = null, $by_priority = false)
510
-    {
511
-        $messages_sent   = 0;
512
-        $this->_did_hook = [];
513
-        $this->_message_repository->rewind();
514
-
515
-        while ($this->_message_repository->valid()) {
516
-            $error_messages = [];
517
-            $message        = $this->_message_repository->current();
518
-
519
-            // only process things that are queued for sending
520
-            if (! in_array($message->STS_ID(), EEM_Message::instance()->stati_indicating_to_send())) {
521
-                $this->_message_repository->next();
522
-                continue;
523
-            }
524
-            // if $by_priority is set and does not match then continue;
525
-            if ($by_priority && $by_priority != $message->priority()) {
526
-                $this->_message_repository->next();
527
-                continue;
528
-            }
529
-            // error checking
530
-            if (! $message->valid_messenger()) {
531
-                $error_messages[] = sprintf(
532
-                    esc_html__('The %s messenger is not active at time of sending.', 'event_espresso'),
533
-                    $message->messenger()
534
-                );
535
-            }
536
-            if (! $message->valid_message_type()) {
537
-                $error_messages[] = sprintf(
538
-                    esc_html__('The %s message type is not active at the time of sending.', 'event_espresso'),
539
-                    $message->message_type()
540
-                );
541
-            }
542
-            // if there was supposed to be a sending messenger for this message, but it was invalid/inactive,
543
-            // then it will instead be an EE_Error object, so let's check for that
544
-            if ($sending_messenger instanceof EE_Error) {
545
-                $error_messages[] = $sending_messenger->getMessage();
546
-            }
547
-            // if there are no errors, then let's process the message
548
-            if (empty($error_messages)) {
549
-                if ($save) {
550
-                    $message->set_messenger_is_executing();
551
-                }
552
-                if ($this->_process_message($message, $sending_messenger)) {
553
-                    $messages_sent++;
554
-                }
555
-            }
556
-            $this->_set_error_message($message, $error_messages);
557
-            // add modified time
558
-            $message->set_modified(time());
559
-            // we save each message after its processed to make sure its status persists in case PHP times-out or runs
560
-            // out of memory. @see https://events.codebasehq.com/projects/event-espresso/tickets/10281
561
-            if ($save) {
562
-                $message->save();
563
-            }
564
-
565
-            $this->_message_repository->next();
566
-        }
567
-        if ($save) {
568
-            $this->save(true);
569
-        }
570
-        return $messages_sent;
571
-    }
572
-
573
-
574
-    /**
575
-     * _process_message
576
-     *
577
-     * @param EE_Message $message
578
-     * @param mixed      $sending_messenger (optional)
579
-     * @return bool
580
-     */
581
-    protected function _process_message(EE_Message $message, $sending_messenger = null)
582
-    {
583
-        // these *should* have been validated in the execute() method above
584
-        $messenger    = $message->messenger_object();
585
-        $message_type = $message->message_type_object();
586
-        // do actions for sending messenger if it differs from generating messenger and swap values.
587
-        if (
588
-            $sending_messenger instanceof EE_messenger
589
-            && $messenger instanceof EE_messenger
590
-            && $sending_messenger->name != $messenger->name
591
-        ) {
592
-            $messenger->do_secondary_messenger_hooks($sending_messenger->name);
593
-            $messenger = $sending_messenger;
594
-        }
595
-        // send using messenger, but double check objects
596
-        if ($messenger instanceof EE_messenger && $message_type instanceof EE_message_type) {
597
-            // set hook for message type (but only if not using another messenger to send).
598
-            if (! isset($this->_did_hook[ $message_type->name ])) {
599
-                $message_type->do_messenger_hooks($messenger);
600
-                $this->_did_hook[ $message_type->name ] = 1;
601
-            }
602
-            // if preview then use preview method
603
-            return $this->_message_repository->is_preview()
604
-                ? $this->_do_preview($message, $messenger, $message_type, $this->_message_repository->is_test_send())
605
-                : $this->_do_send($message, $messenger, $message_type);
606
-        }
607
-        return false;
608
-    }
609
-
610
-
611
-    /**
612
-     * The intention of this method is to count how many EE_Message objects
613
-     * are in the queue with a given status.
614
-     * Example usage:
615
-     * After a caller calls the "EE_Message_Queue::execute()" method, the caller can check if there were any failed
616
-     * sends by calling $queue->count_STS_in_queue( EEM_Message_Queue::status_failed ).
617
-     *
618
-     * @param array|string $status Stati to check for in queue
619
-     * @return int  Count of EE_Message's matching the given status.
620
-     */
621
-    public function count_STS_in_queue($status)
622
-    {
623
-        $count  = 0;
624
-        $status = is_array($status) ? $status : [$status];
625
-        $this->_message_repository->rewind();
626
-        foreach ($this->_message_repository as $message) {
627
-            if (in_array($message->STS_ID(), $status)) {
628
-                $count++;
629
-            }
630
-        }
631
-        return $count;
632
-    }
633
-
634
-
635
-    /**
636
-     * Executes the get_preview method on the provided messenger.
637
-     *
638
-     * @param EE_Message      $message
639
-     * @param EE_messenger    $messenger
640
-     * @param EE_message_type $message_type
641
-     * @param                 $test_send
642
-     * @return bool   true means all went well, false means, not so much.
643
-     */
644
-    protected function _do_preview(
645
-        EE_Message $message,
646
-        EE_messenger $messenger,
647
-        EE_message_type $message_type,
648
-        $test_send
649
-    ) {
650
-        if ($preview = $messenger->get_preview($message, $message_type, $test_send)) {
651
-            if (! $test_send) {
652
-                $message->set_content($preview);
653
-            }
654
-            $message->set_STS_ID(EEM_Message::status_sent);
655
-            return true;
656
-        } else {
657
-            $message->set_STS_ID(EEM_Message::status_failed);
658
-            return false;
659
-        }
660
-    }
661
-
662
-
663
-    /**
664
-     * Executes the send method on the provided messenger
665
-     * EE_Messengers are expected to:
666
-     * - return true if the send was successful.
667
-     * - return false if the send was unsuccessful but can be tried again.
668
-     * - throw an Exception if the send was unsuccessful and cannot be tried again.
669
-     *
670
-     * @param EE_Message      $message
671
-     * @param EE_messenger    $messenger
672
-     * @param EE_message_type $message_type
673
-     * @return bool true means all went well, false means, not so much.
674
-     */
675
-    protected function _do_send(EE_Message $message, EE_messenger $messenger, EE_message_type $message_type)
676
-    {
677
-        try {
678
-            if ($messenger->send_message($message, $message_type)) {
679
-                $message->set_STS_ID(EEM_Message::status_sent);
680
-                return true;
681
-            } else {
682
-                $message->set_STS_ID(EEM_Message::status_retry);
683
-                return false;
684
-            }
685
-        } catch (SendMessageException $e) {
686
-            $message->set_STS_ID(EEM_Message::status_failed);
687
-            $message->set_error_message($e->getMessage());
688
-            return false;
689
-        }
690
-    }
691
-
692
-
693
-    /**
694
-     * This sets any necessary error messages on the message object and its status to failed.
695
-     *
696
-     * @param EE_Message $message
697
-     * @param array      $error_messages the response from the messenger.
698
-     * @throws EE_Error
699
-     */
700
-    protected function _set_error_message(EE_Message $message, $error_messages)
701
-    {
702
-        $error_messages = (array) $error_messages;
703
-        if (in_array($message->STS_ID(), EEM_Message::instance()->stati_indicating_failed_sending())) {
704
-            $notices          = EE_Error::has_notices();
705
-            $error_messages[] = esc_html__(
706
-                'Messenger and Message Type were valid and active, but the messenger send method failed.',
707
-                'event_espresso'
708
-            );
709
-            if ($notices === 1) {
710
-                $notices           = EE_Error::get_vanilla_notices();
711
-                $notices['errors'] = isset($notices['errors']) ? $notices['errors'] : [];
712
-                $error_messages[]  = implode("\n", $notices['errors']);
713
-            }
714
-        }
715
-        if (count($error_messages) > 0) {
716
-            $msg = esc_html__('Message was not executed successfully.', 'event_espresso');
717
-            $msg = $msg . "\n" . implode("\n", $error_messages);
718
-            $message->set_error_message($msg);
719
-        }
720
-    }
16
+	/**
17
+	 * @type    string  reference for sending action
18
+	 */
19
+	const action_sending = 'sending';
20
+
21
+	/**
22
+	 * @type    string  reference for generation action
23
+	 */
24
+	const action_generating = 'generation';
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
+	 *
35
+	 * @type int
36
+	 */
37
+	protected $_batch_count;
38
+
39
+
40
+	/**
41
+	 * This is an array of cached queue items being stored in this object.
42
+	 * The array keys will be the ID of the EE_Message in the db if saved.  If the EE_Message
43
+	 * is not saved to the db then its key will be an increment of "UNS" (i.e. UNS1, UNS2 etc.)
44
+	 *
45
+	 * @type EE_Message[]
46
+	 */
47
+	protected $_cached_queue_items;
48
+
49
+	/**
50
+	 * Tracks the number of unsaved queue items.
51
+	 *
52
+	 * @type int
53
+	 */
54
+	protected $_unsaved_count = 0;
55
+
56
+	/**
57
+	 * used to record if a do_messenger_hooks has already been called for a message type.  This prevents multiple
58
+	 * hooks getting fired if users have setup their action/filter hooks to prevent duplicate calls.
59
+	 *
60
+	 * @type array
61
+	 */
62
+	protected $_did_hook = [];
63
+
64
+
65
+	/**
66
+	 * Constructor.
67
+	 * Setup all the initial properties and load a EE_Message_Repository.
68
+	 *
69
+	 * @param EE_Message_Repository $message_repository
70
+	 */
71
+	public function __construct(EE_Message_Repository $message_repository)
72
+	{
73
+		$this->_batch_count        = apply_filters('FHEE__EE_Messages_Queue___batch_count', 50);
74
+		$this->_message_repository = $message_repository;
75
+	}
76
+
77
+
78
+	/**
79
+	 * Add a EE_Message object to the queue
80
+	 *
81
+	 * @param EE_Message $message
82
+	 * @param array      $data         This will be an array of data to attach to the object in the repository.  If the
83
+	 *                                 object is persisted, this data will be saved on an extra_meta object related to
84
+	 *                                 EE_Message.
85
+	 * @param bool       $preview      Whether this EE_Message represents a preview or not.
86
+	 * @param bool       $test_send    This indicates whether to do a test send instead of actual send. A test send will
87
+	 *                                 use the messenger send method but typically is based on preview data.
88
+	 * @return bool          Whether the message was successfully added to the repository or not.
89
+	 */
90
+	public function add(EE_Message $message, $data = [], $preview = false, $test_send = false)
91
+	{
92
+		$data['preview']   = $preview;
93
+		$data['test_send'] = $test_send;
94
+		return $this->_message_repository->add($message, $data);
95
+	}
96
+
97
+
98
+	/**
99
+	 * Removes EE_Message from _queue that matches the given EE_Message if the pointer is on a matching EE_Message
100
+	 *
101
+	 * @param EE_Message $message The message to detach from the queue
102
+	 * @param bool       $persist This flag indicates whether to attempt to delete the object from the db as well.
103
+	 * @return bool
104
+	 */
105
+	public function remove(EE_Message $message, $persist = false)
106
+	{
107
+		if ($persist && $this->_message_repository->current() !== $message) {
108
+			// get pointer on right message
109
+			if ($this->_message_repository->has($message)) {
110
+				$this->_message_repository->rewind();
111
+				while ($this->_message_repository->valid()) {
112
+					if ($this->_message_repository->current() === $message) {
113
+						break;
114
+					}
115
+					$this->_message_repository->next();
116
+				}
117
+			} else {
118
+				return false;
119
+			}
120
+		}
121
+		return $persist ? $this->_message_repository->delete() : $this->_message_repository->remove($message);
122
+	}
123
+
124
+
125
+	/**
126
+	 * Persists all queued EE_Message objects to the db.
127
+	 *
128
+	 * @param bool $do_hooks_only @see EE_Message_Repository::saveAll
129
+	 * @return array @see EE_Messages_Repository::saveAll() for return values.
130
+	 */
131
+	public function save($do_hooks_only = false)
132
+	{
133
+		return $this->_message_repository->saveAll($do_hooks_only);
134
+	}
135
+
136
+
137
+	/**
138
+	 * @return EE_Message_Repository
139
+	 */
140
+	public function get_message_repository()
141
+	{
142
+		return $this->_message_repository;
143
+	}
144
+
145
+
146
+	/**
147
+	 * This does the following things:
148
+	 * 1. Checks if there is a lock on generation (prevents race conditions).  If there is a lock then exits (return
149
+	 * false).
150
+	 * 2. If no lock, sets lock, then retrieves a batch of non-generated EE_Message objects and adds to queue
151
+	 * 3. Returns bool.  True = batch ready.  False = no batch ready (or nothing available for generation).
152
+	 * Note: Callers should make sure they release the lock otherwise batch generation will be prevented from
153
+	 * continuing. The lock is on a transient that is set to expire after one hour as a fallback in case locks are not
154
+	 * removed.
155
+	 *
156
+	 * @return bool  true if successfully retrieved batch, false no batch ready.
157
+	 * @throws EE_Error
158
+	 * @throws ReflectionException
159
+	 */
160
+	public function get_batch_to_generate()
161
+	{
162
+		if ($this->is_locked()) {
163
+			return false;
164
+		}
165
+
166
+		// lock batch generation to prevent race conditions.
167
+		$this->lock_queue();
168
+
169
+		$query_args = [
170
+			// key 0 = where conditions
171
+			0          => ['STS_ID' => EEM_Message::status_incomplete],
172
+			'order_by' => $this->_get_priority_orderby(),
173
+			'limit'    => $this->_batch_count,
174
+		];
175
+		$messages   = EEM_Message::instance()->get_all($query_args);
176
+
177
+		if (! $messages) {
178
+			return false; // nothing to generate
179
+		}
180
+
181
+		foreach ($messages as $message) {
182
+			if ($message instanceof EE_Message) {
183
+				$data = $message->all_extra_meta_array();
184
+				$this->add($message, $data);
185
+			}
186
+		}
187
+		return true;
188
+	}
189
+
190
+
191
+	/**
192
+	 * This does the following things:
193
+	 * 1. Checks if there is a lock on sending (prevents race conditions).  If there is a lock then exits (return
194
+	 * false).
195
+	 * 2. Grabs the allowed number of messages to send for the rate_limit.  If cannot send any more messages, then
196
+	 * 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
203
+	 *               necessarily mean that all messages were successfully sent.  It just means that this method
204
+	 *               successfully completed. On true, client may want to call $this->count_STS_in_queue(
205
+	 *               EEM_Message::status_failed ) to see if any failed EE_Message objects.  Each failed message object
206
+	 *               will also have a saved error message on it to assist with notifying user.
207
+	 * @throws EE_Error
208
+	 * @throws ReflectionException
209
+	 */
210
+	public function get_to_send_batch_and_send()
211
+	{
212
+		$rate_limit = $this->get_rate_limit();
213
+		if (
214
+			$rate_limit < 1
215
+			|| $this->is_locked(EE_Messages_Queue::action_sending)
216
+		) {
217
+			return false;
218
+		}
219
+
220
+		$this->lock_queue(EE_Messages_Queue::action_sending);
221
+
222
+		$batch = $this->_batch_count < $rate_limit ? $this->_batch_count : $rate_limit;
223
+
224
+		$query_args = [
225
+			// key 0 = where conditions
226
+			0          => ['STS_ID' => ['IN', EEM_Message::instance()->stati_indicating_to_send()]],
227
+			'order_by' => $this->_get_priority_orderby(),
228
+			'limit'    => $batch,
229
+		];
230
+
231
+		$messages_to_send = EEM_Message::instance()->get_all($query_args);
232
+
233
+
234
+		// any to send?
235
+		if (! $messages_to_send) {
236
+			$this->unlock_queue(EE_Messages_Queue::action_sending);
237
+			return false;
238
+		}
239
+
240
+		$queue_count = 0;
241
+
242
+		// add to queue.
243
+		foreach ($messages_to_send as $message) {
244
+			if ($message instanceof EE_Message) {
245
+				$queue_count++;
246
+				$this->add($message);
247
+			}
248
+		}
249
+
250
+		// send messages  (this also updates the rate limit)
251
+		$this->execute();
252
+
253
+		// release lock
254
+		$this->unlock_queue(EE_Messages_Queue::action_sending);
255
+		// update rate limit
256
+		$this->set_rate_limit($queue_count);
257
+		return true;
258
+	}
259
+
260
+
261
+	/**
262
+	 * Locks the queue so that no other queues can call the "batch" methods.
263
+	 *
264
+	 * @param string $type The type of queue being locked.
265
+	 */
266
+	public function lock_queue($type = EE_Messages_Queue::action_generating)
267
+	{
268
+		update_option($this->_get_lock_key($type), $this->_get_lock_expiry($type));
269
+	}
270
+
271
+
272
+	/**
273
+	 * Unlocks the queue so that batch methods can be used.
274
+	 *
275
+	 * @param string $type The type of queue being unlocked.
276
+	 */
277
+	public function unlock_queue($type = EE_Messages_Queue::action_generating)
278
+	{
279
+		delete_option($this->_get_lock_key($type));
280
+	}
281
+
282
+
283
+	/**
284
+	 * Retrieve the key used for the lock transient.
285
+	 *
286
+	 * @param string $type The type of lock.
287
+	 * @return string
288
+	 */
289
+	protected function _get_lock_key($type = EE_Messages_Queue::action_generating)
290
+	{
291
+		return '_ee_lock_' . $type;
292
+	}
293
+
294
+
295
+	/**
296
+	 * Retrieve the expiry time for the lock transient.
297
+	 *
298
+	 * @param string $type The type of lock
299
+	 * @return int   time to expiry in seconds.
300
+	 */
301
+	protected function _get_lock_expiry($type = EE_Messages_Queue::action_generating)
302
+	{
303
+		return time() + (int) apply_filters('FHEE__EE_Messages_Queue__lock_expiry', HOUR_IN_SECONDS, $type);
304
+	}
305
+
306
+
307
+	/**
308
+	 * Returns the key used for rate limit transient.
309
+	 *
310
+	 * @return string
311
+	 */
312
+	protected function _get_rate_limit_key()
313
+	{
314
+		return '_ee_rate_limit';
315
+	}
316
+
317
+
318
+	/**
319
+	 * Returns the rate limit expiry time.
320
+	 *
321
+	 * @return int
322
+	 */
323
+	protected function _get_rate_limit_expiry()
324
+	{
325
+		return time() + (int) apply_filters('FHEE__EE_Messages_Queue__rate_limit_expiry', HOUR_IN_SECONDS);
326
+	}
327
+
328
+
329
+	/**
330
+	 * Returns the default rate limit for sending messages.
331
+	 *
332
+	 * @return int
333
+	 */
334
+	protected function _default_rate_limit()
335
+	{
336
+		return (int) apply_filters('FHEE__EE_Messages_Queue___rate_limit', 200);
337
+	}
338
+
339
+
340
+	/**
341
+	 * Return the orderby array for priority.
342
+	 *
343
+	 * @return array
344
+	 */
345
+	protected function _get_priority_orderby()
346
+	{
347
+		return [
348
+			'MSG_priority' => 'ASC',
349
+			'MSG_modified' => 'DESC',
350
+		];
351
+	}
352
+
353
+
354
+	/**
355
+	 * Returns whether batch methods are "locked" or not, and if models an currently be used to query the database.
356
+	 * Return true when batch methods should not be used; returns false when they can be.
357
+	 *
358
+	 * @param string $type The type of lock being checked for.
359
+	 * @return bool
360
+	 */
361
+	public function is_locked($type = EE_Messages_Queue::action_generating)
362
+	{
363
+		if (! EE_Maintenance_Mode::instance()->models_can_query()) {
364
+			return true;
365
+		}
366
+		$lock = (int) get_option($this->_get_lock_key($type), 0);
367
+		/**
368
+		 * This filters the default is_locked behaviour.
369
+		 */
370
+		$is_locked = filter_var(
371
+			apply_filters(
372
+				'FHEE__EE_Messages_Queue__is_locked',
373
+				$lock > time(),
374
+				$this
375
+			),
376
+			FILTER_VALIDATE_BOOLEAN
377
+		);
378
+
379
+		/**
380
+		 * @see usage of this filter in EE_Messages_Queue::initiate_request_by_priority() method.
381
+		 *            Also implemented here because messages processed on the same request should not have any locks applied.
382
+		 */
383
+		if (
384
+			apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
385
+			|| EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
386
+		) {
387
+			$is_locked = false;
388
+		}
389
+
390
+
391
+		return $is_locked;
392
+	}
393
+
394
+
395
+	/**
396
+	 * Retrieves the rate limit that may be cached as a transient.
397
+	 * If the rate limit is not set, then this sets the default rate limit and expiry and returns it.
398
+	 *
399
+	 * @param bool $return_expiry If true then return the expiry time not the rate_limit.
400
+	 * @return int
401
+	 */
402
+	protected function get_rate_limit($return_expiry = false)
403
+	{
404
+		$stored_rate_info = get_option($this->_get_rate_limit_key(), []);
405
+		$rate_limit       = isset($stored_rate_info[0])
406
+			? (int) $stored_rate_info[0]
407
+			: 0;
408
+		$expiry           = isset($stored_rate_info[1])
409
+			? (int) $stored_rate_info[1]
410
+			: 0;
411
+		// set the default for tracking?
412
+		if (empty($stored_rate_info) || time() > $expiry) {
413
+			$expiry     = $this->_get_rate_limit_expiry();
414
+			$rate_limit = $this->_default_rate_limit();
415
+			update_option($this->_get_rate_limit_key(), [$rate_limit, $expiry]);
416
+		}
417
+		return $return_expiry ? $expiry : $rate_limit;
418
+	}
419
+
420
+
421
+	/**
422
+	 * This updates existing rate limit with the new limit which is the old minus the batch.
423
+	 *
424
+	 * @param int $batch_completed This sets the new rate limit based on the given batch that was completed.
425
+	 */
426
+	protected function set_rate_limit($batch_completed)
427
+	{
428
+		// first get the most up to date rate limit (in case its expired and reset)
429
+		$rate_limit = $this->get_rate_limit();
430
+		$expiry     = $this->get_rate_limit(true);
431
+		$new_limit  = $rate_limit - $batch_completed;
432
+		// updating the transient option directly to avoid resetting the expiry.
433
+
434
+		update_option($this->_get_rate_limit_key(), [$new_limit, $expiry]);
435
+	}
436
+
437
+
438
+	/**
439
+	 * This method checks the queue for ANY EE_Message objects with a priority matching the given priority passed in.
440
+	 * If that exists, then we immediately initiate a non-blocking request to do the requested action type.
441
+	 * Note: Keep in mind that there is the possibility that the request will not execute if there is already another
442
+	 * request running on a queue for the given task.
443
+	 *
444
+	 * @param string $task     This indicates what type of request is going to be initiated.
445
+	 * @param int    $priority This indicates the priority that triggers initiating the request.
446
+	 * @return bool|EE_Messages_Queue|void
447
+	 * @throws EE_Error
448
+	 * @throws ReflectionException
449
+	 */
450
+	public function initiate_request_by_priority($task = 'generate', $priority = EEM_Message::priority_high)
451
+	{
452
+		// determine what status is matched with the priority as part of the trigger conditions.
453
+		$status = $task == 'generate'
454
+			? EEM_Message::status_incomplete
455
+			: EEM_Message::instance()->stati_indicating_to_send();
456
+		// always make sure we save because either this will get executed immediately on a separate request
457
+		// or remains in the queue for the regularly scheduled queue batch.
458
+		$this->save();
459
+		/**
460
+		 * This filter/option allows users to override processing of messages on separate requests and instead have everything
461
+		 * happen on the same request.  If this is utilized remember:
462
+		 * - message priorities don't matter
463
+		 * - existing unprocessed messages in the queue will not get processed unless manually triggered.
464
+		 * - things will be perceived to take longer to happen for end users (i.e. registrations) because of the additional
465
+		 *   processing happening on the same request.
466
+		 * - any race condition protection (locks) are removed because they don't apply when things are processed on
467
+		 *   the same request.
468
+		 */
469
+		if (
470
+			apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
471
+			|| EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
472
+		) {
473
+			$messages_processor = EE_Registry::instance()->load_lib('Messages_Processor');
474
+			if ($messages_processor instanceof EE_Messages_Processor) {
475
+				return $messages_processor->process_immediately_from_queue($this);
476
+			}
477
+			// if we get here then that means the messages processor couldn't be loaded so messages will just remain
478
+			// queued for manual triggering by end user.
479
+		}
480
+
481
+		if ($this->_message_repository->count_by_priority_and_status($priority, $status)) {
482
+			EE_Messages_Scheduler::initiate_scheduled_non_blocking_request($task);
483
+		}
484
+	}
485
+
486
+
487
+	/**
488
+	 *  Loops through the EE_Message objects in the _queue and calls the messenger send methods for each message.
489
+	 *
490
+	 * @param bool     $save                      Used to indicate whether to save the message queue after sending
491
+	 *                                            (default will save).
492
+	 * @param mixed    $sending_messenger         (optional) When the sending messenger is different than
493
+	 *                                            what is on the EE_Message object in the queue.
494
+	 *                                            For instance, showing the browser view of an email message,
495
+	 *                                            or giving a pdf generated view of an html document.
496
+	 *                                            This should be an instance of EE_messenger but if you call this
497
+	 *                                            method
498
+	 *                                            intending it to be a sending messenger but a valid one could not be
499
+	 *                                            retrieved then send in an instance of EE_Error that contains the
500
+	 *                                            related error message.
501
+	 * @param bool|int $by_priority               When set, this indicates that only messages
502
+	 *                                            matching the given priority should be executed.
503
+	 * @return int        Number of messages sent.  Note, 0 does not mean that no messages were processed.
504
+	 *                                            Also, if the messenger is an request type messenger (or a preview),
505
+	 *                                            its entirely possible that the messenger will exit before
506
+	 * @throws EE_Error
507
+	 * @throws ReflectionException
508
+	 */
509
+	public function execute($save = true, $sending_messenger = null, $by_priority = false)
510
+	{
511
+		$messages_sent   = 0;
512
+		$this->_did_hook = [];
513
+		$this->_message_repository->rewind();
514
+
515
+		while ($this->_message_repository->valid()) {
516
+			$error_messages = [];
517
+			$message        = $this->_message_repository->current();
518
+
519
+			// only process things that are queued for sending
520
+			if (! in_array($message->STS_ID(), EEM_Message::instance()->stati_indicating_to_send())) {
521
+				$this->_message_repository->next();
522
+				continue;
523
+			}
524
+			// if $by_priority is set and does not match then continue;
525
+			if ($by_priority && $by_priority != $message->priority()) {
526
+				$this->_message_repository->next();
527
+				continue;
528
+			}
529
+			// error checking
530
+			if (! $message->valid_messenger()) {
531
+				$error_messages[] = sprintf(
532
+					esc_html__('The %s messenger is not active at time of sending.', 'event_espresso'),
533
+					$message->messenger()
534
+				);
535
+			}
536
+			if (! $message->valid_message_type()) {
537
+				$error_messages[] = sprintf(
538
+					esc_html__('The %s message type is not active at the time of sending.', 'event_espresso'),
539
+					$message->message_type()
540
+				);
541
+			}
542
+			// if there was supposed to be a sending messenger for this message, but it was invalid/inactive,
543
+			// then it will instead be an EE_Error object, so let's check for that
544
+			if ($sending_messenger instanceof EE_Error) {
545
+				$error_messages[] = $sending_messenger->getMessage();
546
+			}
547
+			// if there are no errors, then let's process the message
548
+			if (empty($error_messages)) {
549
+				if ($save) {
550
+					$message->set_messenger_is_executing();
551
+				}
552
+				if ($this->_process_message($message, $sending_messenger)) {
553
+					$messages_sent++;
554
+				}
555
+			}
556
+			$this->_set_error_message($message, $error_messages);
557
+			// add modified time
558
+			$message->set_modified(time());
559
+			// we save each message after its processed to make sure its status persists in case PHP times-out or runs
560
+			// out of memory. @see https://events.codebasehq.com/projects/event-espresso/tickets/10281
561
+			if ($save) {
562
+				$message->save();
563
+			}
564
+
565
+			$this->_message_repository->next();
566
+		}
567
+		if ($save) {
568
+			$this->save(true);
569
+		}
570
+		return $messages_sent;
571
+	}
572
+
573
+
574
+	/**
575
+	 * _process_message
576
+	 *
577
+	 * @param EE_Message $message
578
+	 * @param mixed      $sending_messenger (optional)
579
+	 * @return bool
580
+	 */
581
+	protected function _process_message(EE_Message $message, $sending_messenger = null)
582
+	{
583
+		// these *should* have been validated in the execute() method above
584
+		$messenger    = $message->messenger_object();
585
+		$message_type = $message->message_type_object();
586
+		// do actions for sending messenger if it differs from generating messenger and swap values.
587
+		if (
588
+			$sending_messenger instanceof EE_messenger
589
+			&& $messenger instanceof EE_messenger
590
+			&& $sending_messenger->name != $messenger->name
591
+		) {
592
+			$messenger->do_secondary_messenger_hooks($sending_messenger->name);
593
+			$messenger = $sending_messenger;
594
+		}
595
+		// send using messenger, but double check objects
596
+		if ($messenger instanceof EE_messenger && $message_type instanceof EE_message_type) {
597
+			// set hook for message type (but only if not using another messenger to send).
598
+			if (! isset($this->_did_hook[ $message_type->name ])) {
599
+				$message_type->do_messenger_hooks($messenger);
600
+				$this->_did_hook[ $message_type->name ] = 1;
601
+			}
602
+			// if preview then use preview method
603
+			return $this->_message_repository->is_preview()
604
+				? $this->_do_preview($message, $messenger, $message_type, $this->_message_repository->is_test_send())
605
+				: $this->_do_send($message, $messenger, $message_type);
606
+		}
607
+		return false;
608
+	}
609
+
610
+
611
+	/**
612
+	 * The intention of this method is to count how many EE_Message objects
613
+	 * are in the queue with a given status.
614
+	 * Example usage:
615
+	 * After a caller calls the "EE_Message_Queue::execute()" method, the caller can check if there were any failed
616
+	 * sends by calling $queue->count_STS_in_queue( EEM_Message_Queue::status_failed ).
617
+	 *
618
+	 * @param array|string $status Stati to check for in queue
619
+	 * @return int  Count of EE_Message's matching the given status.
620
+	 */
621
+	public function count_STS_in_queue($status)
622
+	{
623
+		$count  = 0;
624
+		$status = is_array($status) ? $status : [$status];
625
+		$this->_message_repository->rewind();
626
+		foreach ($this->_message_repository as $message) {
627
+			if (in_array($message->STS_ID(), $status)) {
628
+				$count++;
629
+			}
630
+		}
631
+		return $count;
632
+	}
633
+
634
+
635
+	/**
636
+	 * Executes the get_preview method on the provided messenger.
637
+	 *
638
+	 * @param EE_Message      $message
639
+	 * @param EE_messenger    $messenger
640
+	 * @param EE_message_type $message_type
641
+	 * @param                 $test_send
642
+	 * @return bool   true means all went well, false means, not so much.
643
+	 */
644
+	protected function _do_preview(
645
+		EE_Message $message,
646
+		EE_messenger $messenger,
647
+		EE_message_type $message_type,
648
+		$test_send
649
+	) {
650
+		if ($preview = $messenger->get_preview($message, $message_type, $test_send)) {
651
+			if (! $test_send) {
652
+				$message->set_content($preview);
653
+			}
654
+			$message->set_STS_ID(EEM_Message::status_sent);
655
+			return true;
656
+		} else {
657
+			$message->set_STS_ID(EEM_Message::status_failed);
658
+			return false;
659
+		}
660
+	}
661
+
662
+
663
+	/**
664
+	 * Executes the send method on the provided messenger
665
+	 * EE_Messengers are expected to:
666
+	 * - return true if the send was successful.
667
+	 * - return false if the send was unsuccessful but can be tried again.
668
+	 * - throw an Exception if the send was unsuccessful and cannot be tried again.
669
+	 *
670
+	 * @param EE_Message      $message
671
+	 * @param EE_messenger    $messenger
672
+	 * @param EE_message_type $message_type
673
+	 * @return bool true means all went well, false means, not so much.
674
+	 */
675
+	protected function _do_send(EE_Message $message, EE_messenger $messenger, EE_message_type $message_type)
676
+	{
677
+		try {
678
+			if ($messenger->send_message($message, $message_type)) {
679
+				$message->set_STS_ID(EEM_Message::status_sent);
680
+				return true;
681
+			} else {
682
+				$message->set_STS_ID(EEM_Message::status_retry);
683
+				return false;
684
+			}
685
+		} catch (SendMessageException $e) {
686
+			$message->set_STS_ID(EEM_Message::status_failed);
687
+			$message->set_error_message($e->getMessage());
688
+			return false;
689
+		}
690
+	}
691
+
692
+
693
+	/**
694
+	 * This sets any necessary error messages on the message object and its status to failed.
695
+	 *
696
+	 * @param EE_Message $message
697
+	 * @param array      $error_messages the response from the messenger.
698
+	 * @throws EE_Error
699
+	 */
700
+	protected function _set_error_message(EE_Message $message, $error_messages)
701
+	{
702
+		$error_messages = (array) $error_messages;
703
+		if (in_array($message->STS_ID(), EEM_Message::instance()->stati_indicating_failed_sending())) {
704
+			$notices          = EE_Error::has_notices();
705
+			$error_messages[] = esc_html__(
706
+				'Messenger and Message Type were valid and active, but the messenger send method failed.',
707
+				'event_espresso'
708
+			);
709
+			if ($notices === 1) {
710
+				$notices           = EE_Error::get_vanilla_notices();
711
+				$notices['errors'] = isset($notices['errors']) ? $notices['errors'] : [];
712
+				$error_messages[]  = implode("\n", $notices['errors']);
713
+			}
714
+		}
715
+		if (count($error_messages) > 0) {
716
+			$msg = esc_html__('Message was not executed successfully.', 'event_espresso');
717
+			$msg = $msg . "\n" . implode("\n", $error_messages);
718
+			$message->set_error_message($msg);
719
+		}
720
+	}
721 721
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -172,9 +172,9 @@  discard block
 block discarded – undo
172 172
             'order_by' => $this->_get_priority_orderby(),
173 173
             'limit'    => $this->_batch_count,
174 174
         ];
175
-        $messages   = EEM_Message::instance()->get_all($query_args);
175
+        $messages = EEM_Message::instance()->get_all($query_args);
176 176
 
177
-        if (! $messages) {
177
+        if ( ! $messages) {
178 178
             return false; // nothing to generate
179 179
         }
180 180
 
@@ -232,7 +232,7 @@  discard block
 block discarded – undo
232 232
 
233 233
 
234 234
         // any to send?
235
-        if (! $messages_to_send) {
235
+        if ( ! $messages_to_send) {
236 236
             $this->unlock_queue(EE_Messages_Queue::action_sending);
237 237
             return false;
238 238
         }
@@ -288,7 +288,7 @@  discard block
 block discarded – undo
288 288
      */
289 289
     protected function _get_lock_key($type = EE_Messages_Queue::action_generating)
290 290
     {
291
-        return '_ee_lock_' . $type;
291
+        return '_ee_lock_'.$type;
292 292
     }
293 293
 
294 294
 
@@ -360,7 +360,7 @@  discard block
 block discarded – undo
360 360
      */
361 361
     public function is_locked($type = EE_Messages_Queue::action_generating)
362 362
     {
363
-        if (! EE_Maintenance_Mode::instance()->models_can_query()) {
363
+        if ( ! EE_Maintenance_Mode::instance()->models_can_query()) {
364 364
             return true;
365 365
         }
366 366
         $lock = (int) get_option($this->_get_lock_key($type), 0);
@@ -517,7 +517,7 @@  discard block
 block discarded – undo
517 517
             $message        = $this->_message_repository->current();
518 518
 
519 519
             // only process things that are queued for sending
520
-            if (! in_array($message->STS_ID(), EEM_Message::instance()->stati_indicating_to_send())) {
520
+            if ( ! in_array($message->STS_ID(), EEM_Message::instance()->stati_indicating_to_send())) {
521 521
                 $this->_message_repository->next();
522 522
                 continue;
523 523
             }
@@ -527,13 +527,13 @@  discard block
 block discarded – undo
527 527
                 continue;
528 528
             }
529 529
             // error checking
530
-            if (! $message->valid_messenger()) {
530
+            if ( ! $message->valid_messenger()) {
531 531
                 $error_messages[] = sprintf(
532 532
                     esc_html__('The %s messenger is not active at time of sending.', 'event_espresso'),
533 533
                     $message->messenger()
534 534
                 );
535 535
             }
536
-            if (! $message->valid_message_type()) {
536
+            if ( ! $message->valid_message_type()) {
537 537
                 $error_messages[] = sprintf(
538 538
                     esc_html__('The %s message type is not active at the time of sending.', 'event_espresso'),
539 539
                     $message->message_type()
@@ -595,9 +595,9 @@  discard block
 block discarded – undo
595 595
         // send using messenger, but double check objects
596 596
         if ($messenger instanceof EE_messenger && $message_type instanceof EE_message_type) {
597 597
             // set hook for message type (but only if not using another messenger to send).
598
-            if (! isset($this->_did_hook[ $message_type->name ])) {
598
+            if ( ! isset($this->_did_hook[$message_type->name])) {
599 599
                 $message_type->do_messenger_hooks($messenger);
600
-                $this->_did_hook[ $message_type->name ] = 1;
600
+                $this->_did_hook[$message_type->name] = 1;
601 601
             }
602 602
             // if preview then use preview method
603 603
             return $this->_message_repository->is_preview()
@@ -648,7 +648,7 @@  discard block
 block discarded – undo
648 648
         $test_send
649 649
     ) {
650 650
         if ($preview = $messenger->get_preview($message, $message_type, $test_send)) {
651
-            if (! $test_send) {
651
+            if ( ! $test_send) {
652 652
                 $message->set_content($preview);
653 653
             }
654 654
             $message->set_STS_ID(EEM_Message::status_sent);
@@ -714,7 +714,7 @@  discard block
 block discarded – undo
714 714
         }
715 715
         if (count($error_messages) > 0) {
716 716
             $msg = esc_html__('Message was not executed successfully.', 'event_espresso');
717
-            $msg = $msg . "\n" . implode("\n", $error_messages);
717
+            $msg = $msg."\n".implode("\n", $error_messages);
718 718
             $message->set_error_message($msg);
719 719
         }
720 720
     }
Please login to merge, or discard this patch.
core/libraries/messages/EE_Messages_Processor.lib.php 2 patches
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -284,7 +284,7 @@  discard block
 block discarded – undo
284 284
     public function queue_for_generation(EE_Message_To_Generate $message_to_generate, $test_send = false)
285 285
     {
286 286
         if ($message_to_generate->valid()) {
287
-            if (! $this->_generator->create_and_add_message_to_queue($message_to_generate, $test_send)) {
287
+            if ( ! $this->_generator->create_and_add_message_to_queue($message_to_generate, $test_send)) {
288 288
                 throw new RuntimeException(
289 289
                     esc_html__('Message failed to generate', 'event_espresso')
290 290
                 );
@@ -330,7 +330,7 @@  discard block
 block discarded – undo
330 330
     protected function _queue_for_generation_loop($messages_to_generate)
331 331
     {
332 332
         // make sure is in an array.
333
-        if (! is_array($messages_to_generate)) {
333
+        if ( ! is_array($messages_to_generate)) {
334 334
             $messages_to_generate = [$messages_to_generate];
335 335
         }
336 336
 
@@ -370,7 +370,7 @@  discard block
 block discarded – undo
370 370
      */
371 371
     public function generate_for_preview(EE_Message_To_Generate $message_to_generate, $test_send = false)
372 372
     {
373
-        if (! $message_to_generate->valid()) {
373
+        if ( ! $message_to_generate->valid()) {
374 374
             EE_Error::add_error(
375 375
                 esc_html__('Unable to generate preview because of invalid data', 'event_espresso'),
376 376
                 __FILE__,
@@ -407,7 +407,7 @@  discard block
 block discarded – undo
407 407
      */
408 408
     public function queue_for_sending(EE_Message_To_Generate $message_to_generate)
409 409
     {
410
-        if (! $message_to_generate->valid()) {
410
+        if ( ! $message_to_generate->valid()) {
411 411
             return false;
412 412
         }
413 413
         $this->_init_queue_and_generator();
@@ -432,7 +432,7 @@  discard block
 block discarded – undo
432 432
      */
433 433
     public function generate_and_send_now(EE_Message_To_Generate $message_to_generate)
434 434
     {
435
-        if (! $message_to_generate->valid()) {
435
+        if ( ! $message_to_generate->valid()) {
436 436
             return null;
437 437
         }
438 438
         // is there supposed to be a sending messenger for this message?
@@ -579,7 +579,7 @@  discard block
 block discarded – undo
579 579
 
580 580
         foreach ($regIDs as $regID) {
581 581
             $reg = EEM_Registration::instance()->get_one_by_ID($regID);
582
-            if (! $reg instanceof EE_Registration) {
582
+            if ( ! $reg instanceof EE_Registration) {
583 583
                 EE_Error::add_error(
584 584
                     sprintf(
585 585
                         esc_html__(
@@ -591,7 +591,7 @@  discard block
 block discarded – undo
591 591
                 );
592 592
                 return false;
593 593
             }
594
-            $regs_to_send[ $reg->transaction_ID() ][ $reg->status_ID() ][] = $reg;
594
+            $regs_to_send[$reg->transaction_ID()][$reg->status_ID()][] = $reg;
595 595
         }
596 596
 
597 597
         $messages_to_generate = [];
@@ -599,7 +599,7 @@  discard block
 block discarded – undo
599 599
         foreach ($regs_to_send as $status_group) {
600 600
             foreach ($status_group as $status_id => $registrations) {
601 601
                 $message_type = EEH_MSG_Template::convert_reg_status_to_message_type($status_id);
602
-                if (! $message_type) {
602
+                if ( ! $message_type) {
603 603
                     continue;
604 604
                 }
605 605
                 $messages_to_generate = array_merge(
Please login to merge, or discard this patch.
Indentation   +598 added lines, -598 removed lines patch added patch discarded remove patch
@@ -14,602 +14,602 @@
 block discarded – undo
14 14
  */
15 15
 class EE_Messages_Processor
16 16
 {
17
-    /**
18
-     * @type EE_Message_Resource_Manager $_message_resource_manager
19
-     */
20
-    protected $_message_resource_manager;
21
-
22
-    /**
23
-     * @type EE_Messages_Queue
24
-     */
25
-    protected $_queue;
26
-
27
-    /**
28
-     * @type  EE_Messages_Generator
29
-     */
30
-    protected $_generator;
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)
39
-    {
40
-        $this->_message_resource_manager = $message_resource_manager;
41
-        $this->_init_queue_and_generator();
42
-    }
43
-
44
-
45
-    /**
46
-     * This method sets (or resets) the various properties for use.
47
-     *
48
-     * - $_queue = holds the messages queue
49
-     * - $_generator = holds the messages generator
50
-     */
51
-    protected function _init_queue_and_generator()
52
-    {
53
-        $this->_generator = EE_Registry::factory('EE_Messages_Generator');
54
-        $this->_queue     = $this->_generator->generation_queue();
55
-    }
56
-
57
-
58
-    /**
59
-     * This returns the current set queue.
60
-     *
61
-     * @return EE_Messages_Queue
62
-     */
63
-    public function get_queue()
64
-    {
65
-        return $this->_queue;
66
-    }
67
-
68
-
69
-    /**
70
-     * This method can be utilized to process messages from a queue and they will be processed immediately on the same
71
-     * request. Please note that this method alone does not bypass the usual "locks" for generation/sending (it assumes
72
-     * client code has already filtered those if necessary).
73
-     *
74
-     * @param EE_Messages_Queue $queue_to_process
75
-     * @return bool  true for success false for error.
76
-     * @throws EE_Error
77
-     * @throws ReflectionException
78
-     */
79
-    public function process_immediately_from_queue(EE_Messages_Queue $queue_to_process)
80
-    {
81
-        $success              = false;
82
-        $messages_to_send     = [];
83
-        $messages_to_generate = [];
84
-        // loop through and setup the various messages from the queue so we know what is being processed
85
-        $queue_to_process->get_message_repository()->rewind();
86
-        foreach ($queue_to_process->get_message_repository() as $message) {
87
-            if ($message->STS_ID() === EEM_Message::status_incomplete) {
88
-                $messages_to_generate[] = $message;
89
-                continue;
90
-            }
91
-
92
-            if (in_array($message->STS_ID(), EEM_Message::instance()->stati_indicating_to_send())) {
93
-                $messages_to_send[] = $message;
94
-            }
95
-        }
96
-
97
-        // do generation/sends
98
-        if ($messages_to_generate) {
99
-            $success = $this->batch_generate_from_queue($messages_to_generate, true);
100
-        }
101
-
102
-        if ($messages_to_send) {
103
-            $sent = $this->batch_send_from_queue($messages_to_send, true);
104
-            // if there was messages to generate and it failed, then we override any success value for the sending process
105
-            // otherwise we just use the return from batch send.  The intent is that there is a simple response for success/fail.
106
-            // Either everything was successful or we consider it a fail.  To be clear, this is a limitation of doing
107
-            // all messages processing on the same request.
108
-            $success = $messages_to_generate && ! $success ? false : $sent;
109
-        }
110
-        return $success;
111
-    }
112
-
113
-
114
-    /**
115
-     * Calls the EE_Messages_Queue::get_batch_to_generate() method and sends to EE_Messages_Generator.
116
-     *
117
-     * @param EE_Message[] $messages    Array of EE_Message objects (optional) to build the queue with.
118
-     * @param bool         $clear_queue Whether to ensure a fresh queue or not.
119
-     *
120
-     * @return bool|EE_Messages_Queue return false if nothing generated.  This returns a new EE_Message_Queue with
121
-     *                                   generated messages.
122
-     * @throws EE_Error
123
-     * @throws ReflectionException
124
-     */
125
-    public function batch_generate_from_queue($messages = [], $clear_queue = false)
126
-    {
127
-        if ($this->_build_queue_for_generation($messages, $clear_queue)) {
128
-            $new_queue = $this->_generator->generate();
129
-            if ($new_queue instanceof EE_Messages_Queue) {
130
-                // unlock queue
131
-                $this->_queue->unlock_queue();
132
-                $new_queue->initiate_request_by_priority('send');
133
-                return $new_queue;
134
-            }
135
-        }
136
-        $this->_queue->unlock_queue();
137
-        return false;
138
-    }
139
-
140
-
141
-    /**
142
-     * This method preps a queue for generation.
143
-     *
144
-     * @param EE_Message[] $messages    Array of EE_Message objects to build the queue with
145
-     *
146
-     * @param bool         $clear_queue This indicates whether the existing queue should be dumped or not.
147
-     *
148
-     * @return bool true means queue prepped, false means there was a lock so no generation please.
149
-     * @throws EE_Error
150
-     * @throws ReflectionException
151
-     * @since    4.9.0
152
-     *
153
-     */
154
-    protected function _build_queue_for_generation($messages = [], $clear_queue = false)
155
-    {
156
-
157
-        if ($clear_queue) {
158
-            $this->_init_queue_and_generator();
159
-        }
160
-
161
-        if ($messages) {
162
-            // if generation is locked then get out now because that means processing is already happening.
163
-            if ($this->_queue->is_locked()) {
164
-                return false;
165
-            }
166
-
167
-            $this->_queue->lock_queue();
168
-            $messages = is_array($messages) ? $messages : [$messages];
169
-            foreach ($messages as $message) {
170
-                if ($message instanceof EE_Message) {
171
-                    $data = $message->all_extra_meta_array();
172
-                    $this->_queue->add($message, $data);
173
-                }
174
-            }
175
-            return true;
176
-        } else {
177
-            return $this->_queue->get_batch_to_generate();
178
-        }
179
-    }
180
-
181
-
182
-    /**
183
-     * This method preps a queue for sending.
184
-     *
185
-     * @param EE_Message[] $messages
186
-     * @param bool         $clear_queue Used to indicate whether to start with a fresh queue or not.
187
-     *
188
-     * @return bool true means queue prepped, false means there was a lock so no queue prepped.
189
-     */
190
-    protected function _build_queue_for_sending($messages, $clear_queue = false)
191
-    {
192
-        // if sending is locked then get out now because that means processing is already happening.
193
-        if ($this->_queue->is_locked(EE_Messages_Queue::action_sending)) {
194
-            return false;
195
-        }
196
-
197
-        $this->_queue->lock_queue(EE_Messages_Queue::action_sending);
198
-
199
-        if ($clear_queue) {
200
-            $this->_init_queue_and_generator();
201
-        }
202
-
203
-        $messages = is_array($messages) ? $messages : [$messages];
204
-
205
-        foreach ($messages as $message) {
206
-            $this->_queue->add($message);
207
-        }
208
-        return true;
209
-    }
210
-
211
-
212
-    /**
213
-     * Calls the EE_Message_Queue::get_to_send_batch_and_send() method and then immediately just calls
214
-     * EE_Message_Queue::execute() to iterate and send unsent messages.
215
-     *
216
-     * @param EE_Message[] $messages    If an array of messages is sent in then use it.
217
-     *
218
-     * @param bool         $clear_queue Whether to initialize a new queue or keep the existing one.
219
-     *
220
-     * @return EE_Messages_Queue
221
-     * @throws EE_Error
222
-     * @throws ReflectionException
223
-     */
224
-    public function batch_send_from_queue($messages = [], $clear_queue = false)
225
-    {
226
-
227
-        if ($messages && $this->_build_queue_for_sending($messages, $clear_queue)) {
228
-            $this->_queue->execute();
229
-            $this->_queue->unlock_queue(EE_Messages_Queue::action_sending);
230
-        } else {
231
-            // get messages to send and execute.
232
-            $this->_queue->get_to_send_batch_and_send();
233
-        }
234
-        // note: callers can use the EE_Messages_Queue::count_STS_in_queue() method to find out if there were any failed
235
-        // messages in the queue and decide how to handle at that point.
236
-        return $this->_queue;
237
-    }
238
-
239
-
240
-    /**
241
-     * This immediately generates messages using the given array of EE_Message_To_Generate objects and returns the
242
-     * EE_Message_Queue with the generated messages for the caller to work with.  Note, this does NOT save the generated
243
-     * messages in the queue, leaving it up to the caller to do so.
244
-     *
245
-     * @param EE_Message_To_Generate[] $messages_to_generate
246
-     * @return EE_Messages_Queue
247
-     * @throws EE_Error
248
-     * @throws ReflectionException
249
-     */
250
-    public function generate_and_return($messages_to_generate)
251
-    {
252
-        $this->_init_queue_and_generator();
253
-        $this->_queue_for_generation_loop($messages_to_generate);
254
-        return $this->_generator->generate(false);
255
-    }
256
-
257
-
258
-    /**
259
-     * Executes the generator generate method on the current internal queue, and returns the generated queue.
260
-     *
261
-     * @param bool $persist Indicate whether to instruct the generator to persist the generated queue (true) or not
262
-     *                      (false).
263
-     * @return EE_Messages_Queue
264
-     * @throws EE_Error
265
-     * @throws ReflectionException
266
-     */
267
-    public function generate_queue($persist = true)
268
-    {
269
-        return $this->_generator->generate($persist);
270
-    }
271
-
272
-
273
-    /**
274
-     * Queue for generation.  Note this does NOT persist to the db.  Client code should call
275
-     * get_message_repository()->save() if desire to persist.  This method is provided to client code to decide what it
276
-     * wants to do with queued messages for generation.
277
-     *
278
-     * @param EE_Message_To_Generate $message_to_generate
279
-     * @param bool                   $test_send Whether this item is for a test send or not.
280
-     * @return void
281
-     */
282
-    public function queue_for_generation(EE_Message_To_Generate $message_to_generate, $test_send = false)
283
-    {
284
-        if ($message_to_generate->valid()) {
285
-            if (! $this->_generator->create_and_add_message_to_queue($message_to_generate, $test_send)) {
286
-                throw new RuntimeException(
287
-                    esc_html__('Message failed to generate', 'event_espresso')
288
-                );
289
-            }
290
-        }
291
-    }
292
-
293
-
294
-    /**
295
-     * This receives an array of EE_Message_To_Generate objects, converts them to EE_Message adds them to the
296
-     * generation queue and then persists to storage.
297
-     *
298
-     * @param EE_Message_To_Generate[] $messages_to_generate
299
-     */
300
-    public function batch_queue_for_generation_and_persist($messages_to_generate)
301
-    {
302
-        $this->_init_queue_and_generator();
303
-        $this->_queue_for_generation_loop($messages_to_generate);
304
-        $this->_queue->save();
305
-    }
306
-
307
-
308
-    /**
309
-     * This receives an array of EE_Message_To_Generate objects, converts them to EE_Message and adds them to the
310
-     * generation queue.  Does NOT persist to storage (unless there is an error. Client code can retrieve the generated
311
-     * queue by calling EEM_Messages_Processor::get_queue()
312
-     *
313
-     * @param EE_Message_To_Generate[] $messages_to_generate
314
-     */
315
-    public function batch_queue_for_generation_no_persist($messages_to_generate)
316
-    {
317
-        $this->_init_queue_and_generator();
318
-        $this->_queue_for_generation_loop($messages_to_generate);
319
-    }
320
-
321
-
322
-    /**
323
-     * Simply loops through the given array of EE_Message_To_Generate objects and adds them to the _queue as EE_Message
324
-     * objects.
325
-     *
326
-     * @param EE_Message_To_Generate[] $messages_to_generate
327
-     */
328
-    protected function _queue_for_generation_loop($messages_to_generate)
329
-    {
330
-        // make sure is in an array.
331
-        if (! is_array($messages_to_generate)) {
332
-            $messages_to_generate = [$messages_to_generate];
333
-        }
334
-
335
-        foreach ($messages_to_generate as $message_to_generate) {
336
-            if ($message_to_generate instanceof EE_Message_To_Generate && $message_to_generate->valid()) {
337
-                $this->queue_for_generation($message_to_generate);
338
-            }
339
-        }
340
-    }
341
-
342
-
343
-    /**
344
-     * Receives an array of EE_Message_To_Generate objects and generates the EE_Message objects, then persists (so its
345
-     * queued for sending).
346
-     *
347
-     * @param EE_Message_To_Generate[]
348
-     * @return EE_Messages_Queue
349
-     * @throws EE_Error
350
-     * @throws ReflectionException
351
-     */
352
-    public function generate_and_queue_for_sending($messages_to_generate)
353
-    {
354
-        $this->_init_queue_and_generator();
355
-        $this->_queue_for_generation_loop($messages_to_generate);
356
-        return $this->_generator->generate();
357
-    }
358
-
359
-
360
-    /**
361
-     * Generate for preview and execute right away.
362
-     *
363
-     * @param EE_Message_To_Generate $message_to_generate
364
-     * @param bool                   $test_send Whether this is a test send or not.
365
-     * @return  EE_Messages_Queue | bool   false if unable to generate otherwise the generated queue.
366
-     * @throws EE_Error
367
-     * @throws ReflectionException
368
-     */
369
-    public function generate_for_preview(EE_Message_To_Generate $message_to_generate, $test_send = false)
370
-    {
371
-        if (! $message_to_generate->valid()) {
372
-            EE_Error::add_error(
373
-                esc_html__('Unable to generate preview because of invalid data', 'event_espresso'),
374
-                __FILE__,
375
-                __FUNCTION__,
376
-                __LINE__
377
-            );
378
-            return false;
379
-        }
380
-        // just make sure preview is set on the $message_to_generate (in case client forgot)
381
-        $message_to_generate->set_preview(true);
382
-        $this->_init_queue_and_generator();
383
-        $this->queue_for_generation($message_to_generate, $test_send);
384
-        $generated_queue = $this->_generator->generate(false);
385
-        if ($generated_queue->execute(false)) {
386
-            // the first queue item should be the preview
387
-            $generated_queue->get_message_repository()->rewind();
388
-            if ($generated_queue->get_message_repository()->valid()) {
389
-                return $generated_queue;
390
-            }
391
-        }
392
-        return false;
393
-    }
394
-
395
-
396
-    /**
397
-     * This queues for sending.
398
-     * The messenger send now method is also verified to see if sending immediately is requested.
399
-     * otherwise its just saved to the queue.
400
-     *
401
-     * @param EE_Message_To_Generate $message_to_generate
402
-     * @return bool true or false for success.
403
-     * @throws EE_Error
404
-     * @throws ReflectionException
405
-     */
406
-    public function queue_for_sending(EE_Message_To_Generate $message_to_generate)
407
-    {
408
-        if (! $message_to_generate->valid()) {
409
-            return false;
410
-        }
411
-        $this->_init_queue_and_generator();
412
-        $message = $message_to_generate->get_EE_Message();
413
-        $this->_queue->add($message);
414
-        if ($message->send_now()) {
415
-            $this->_queue->execute(false);
416
-        } else {
417
-            $this->_queue->save();
418
-        }
419
-        return true;
420
-    }
421
-
422
-
423
-    /**
424
-     * This generates and sends from the given EE_Message_To_Generate class immediately.
425
-     *
426
-     * @param EE_Message_To_Generate $message_to_generate
427
-     * @return EE_Messages_Queue | null
428
-     * @throws EE_Error
429
-     * @throws ReflectionException
430
-     */
431
-    public function generate_and_send_now(EE_Message_To_Generate $message_to_generate)
432
-    {
433
-        if (! $message_to_generate->valid()) {
434
-            return null;
435
-        }
436
-        // is there supposed to be a sending messenger for this message?
437
-        if ($message_to_generate instanceof EEI_Has_Sending_Messenger) {
438
-            // make sure it's valid, but if it's not,
439
-            // then set the value of $sending_messenger to an EE_Error object
440
-            // so that downstream code can easily see that things went wrong.
441
-            $sending_messenger = $message_to_generate->sending_messenger() instanceof EE_messenger
442
-                ? $message_to_generate->sending_messenger()
443
-                : new EE_Error(
444
-                    esc_html__(
445
-                        'There was a specific sending messenger requested for the send action, but it was either invalid or not active at time of sending.',
446
-                        'event_espresso'
447
-                    )
448
-                );
449
-        } else {
450
-            $sending_messenger = null;
451
-        }
452
-
453
-        if ($message_to_generate->get_EE_Message()->STS_ID() === EEM_Message::status_idle) {
454
-            $this->_init_queue_and_generator();
455
-            $this->_queue->add($message_to_generate->get_EE_Message());
456
-            $this->_queue->execute(false, $sending_messenger);
457
-            return $this->_queue;
458
-        } elseif ($message_to_generate->get_EE_Message()->STS_ID() === EEM_Message::status_incomplete) {
459
-            $generated_queue = $this->generate_and_return([$message_to_generate]);
460
-            $generated_queue->execute(false, $sending_messenger);
461
-            return $generated_queue;
462
-        }
463
-        return null;
464
-    }
465
-
466
-
467
-    /**
468
-     * Creates mtg objects for all active messengers and queues for generation.
469
-     * This method also calls the execute by priority method on the queue which will optionally kick off a new
470
-     * non-blocking request to complete the action if the priority for the message requires immediate action.
471
-     *
472
-     * @param string $message_type
473
-     * @param mixed  $data    The data being used for generation.
474
-     * @param bool   $persist Whether to persist the queued messages to the db or not.
475
-     * @throws EE_Error
476
-     * @throws ReflectionException
477
-     */
478
-    public function generate_for_all_active_messengers($message_type, $data, $persist = true)
479
-    {
480
-        $messages_to_generate = $this->setup_mtgs_for_all_active_messengers($message_type, $data);
481
-        if ($persist) {
482
-            $this->batch_queue_for_generation_and_persist($messages_to_generate);
483
-            $this->_queue->initiate_request_by_priority();
484
-        } else {
485
-            $this->batch_queue_for_generation_no_persist($messages_to_generate);
486
-        }
487
-    }
488
-
489
-
490
-    /**
491
-     * This simply loops through all active messengers and takes care of setting up the
492
-     * EE_Message_To_Generate objects.
493
-     *
494
-     * @param $message_type
495
-     * @param $data
496
-     *
497
-     * @return EE_Message_To_Generate[]
498
-     */
499
-    public function setup_mtgs_for_all_active_messengers($message_type, $data)
500
-    {
501
-        $messages_to_generate = [];
502
-        foreach ($this->_message_resource_manager->active_messengers() as $messenger_slug => $messenger_object) {
503
-            $message_to_generate = new EE_Message_To_Generate($messenger_slug, $message_type, $data);
504
-            if ($message_to_generate->valid()) {
505
-                $messages_to_generate[] = $message_to_generate;
506
-            }
507
-        }
508
-        return $messages_to_generate;
509
-    }
510
-
511
-
512
-    /**
513
-     * This accepts an array of EE_Message::MSG_ID values
514
-     * and will use that to retrieve the objects from the database and send.
515
-     *
516
-     * @param array $message_ids
517
-     * @throws EE_Error
518
-     * @throws ReflectionException
519
-     */
520
-    public function setup_messages_from_ids_and_send($message_ids)
521
-    {
522
-        $this->_init_queue_and_generator();
523
-        $messages = EEM_Message::instance()->get_all(
524
-            [
525
-                 [
526
-                     'MSG_ID' => ['IN', $message_ids],
527
-                     'STS_ID' => [
528
-                         'IN',
529
-                         array_merge(
530
-                             EEM_Message::instance()->stati_indicating_sent(),
531
-                             [EEM_Message::status_retry]
532
-                         ),
533
-                     ],
534
-                 ],
535
-             ]
536
-        );
537
-        // set the Messages to resend.
538
-        foreach ($messages as $message) {
539
-            if ($message instanceof EE_Message) {
540
-                $message->set_STS_ID(EEM_Message::status_resend);
541
-                $this->_queue->add($message);
542
-            }
543
-        }
544
-
545
-        $this->_queue->initiate_request_by_priority('send');
546
-    }
547
-
548
-
549
-    /**
550
-     * This method checks for registration IDs in the request via the given key and creates the messages to generate
551
-     * objects from them, then returns the array of messages to generate objects.
552
-     * Note, this sets up registrations for the registration family of message types.
553
-     *
554
-     * @param string $registration_ids_key This is used to indicate what represents the registration ids in the request.
555
-     *
556
-     * @return EE_Message_To_Generate[]|bool
557
-     * @throws EE_Error
558
-     */
559
-    public function setup_messages_to_generate_from_registration_ids_in_request($registration_ids_key = '_REG_ID')
560
-    {
561
-        /** @var RequestInterface $request */
562
-        $request      = LoaderFactory::getLoader()->getShared(RequestInterface::class);
563
-        $regs_to_send = [];
564
-        $regIDs       = $request->getRequestParam($registration_ids_key, [], 'int', true);
565
-        if (empty($regIDs)) {
566
-            EE_Error::add_error(
567
-                esc_html__('Something went wrong because we\'re missing the registration ID', 'event_espresso'),
568
-                __FILE__,
569
-                __FUNCTION__,
570
-                __LINE__
571
-            );
572
-            return false;
573
-        }
574
-
575
-        // make sure is an array
576
-        $regIDs = is_array($regIDs) ? $regIDs : [$regIDs];
577
-
578
-        foreach ($regIDs as $regID) {
579
-            $reg = EEM_Registration::instance()->get_one_by_ID($regID);
580
-            if (! $reg instanceof EE_Registration) {
581
-                EE_Error::add_error(
582
-                    sprintf(
583
-                        esc_html__(
584
-                            'Unable to retrieve a registration object for the given reg id (%s)',
585
-                            'event_espresso'
586
-                        ),
587
-                        $regID
588
-                    )
589
-                );
590
-                return false;
591
-            }
592
-            $regs_to_send[ $reg->transaction_ID() ][ $reg->status_ID() ][] = $reg;
593
-        }
594
-
595
-        $messages_to_generate = [];
596
-
597
-        foreach ($regs_to_send as $status_group) {
598
-            foreach ($status_group as $status_id => $registrations) {
599
-                $message_type = EEH_MSG_Template::convert_reg_status_to_message_type($status_id);
600
-                if (! $message_type) {
601
-                    continue;
602
-                }
603
-                $messages_to_generate = array_merge(
604
-                    $messages_to_generate,
605
-                    $this->setup_mtgs_for_all_active_messengers(
606
-                        $message_type,
607
-                        [$registrations, $status_id]
608
-                    )
609
-                );
610
-            }
611
-        }
612
-
613
-        return $messages_to_generate;
614
-    }
17
+	/**
18
+	 * @type EE_Message_Resource_Manager $_message_resource_manager
19
+	 */
20
+	protected $_message_resource_manager;
21
+
22
+	/**
23
+	 * @type EE_Messages_Queue
24
+	 */
25
+	protected $_queue;
26
+
27
+	/**
28
+	 * @type  EE_Messages_Generator
29
+	 */
30
+	protected $_generator;
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)
39
+	{
40
+		$this->_message_resource_manager = $message_resource_manager;
41
+		$this->_init_queue_and_generator();
42
+	}
43
+
44
+
45
+	/**
46
+	 * This method sets (or resets) the various properties for use.
47
+	 *
48
+	 * - $_queue = holds the messages queue
49
+	 * - $_generator = holds the messages generator
50
+	 */
51
+	protected function _init_queue_and_generator()
52
+	{
53
+		$this->_generator = EE_Registry::factory('EE_Messages_Generator');
54
+		$this->_queue     = $this->_generator->generation_queue();
55
+	}
56
+
57
+
58
+	/**
59
+	 * This returns the current set queue.
60
+	 *
61
+	 * @return EE_Messages_Queue
62
+	 */
63
+	public function get_queue()
64
+	{
65
+		return $this->_queue;
66
+	}
67
+
68
+
69
+	/**
70
+	 * This method can be utilized to process messages from a queue and they will be processed immediately on the same
71
+	 * request. Please note that this method alone does not bypass the usual "locks" for generation/sending (it assumes
72
+	 * client code has already filtered those if necessary).
73
+	 *
74
+	 * @param EE_Messages_Queue $queue_to_process
75
+	 * @return bool  true for success false for error.
76
+	 * @throws EE_Error
77
+	 * @throws ReflectionException
78
+	 */
79
+	public function process_immediately_from_queue(EE_Messages_Queue $queue_to_process)
80
+	{
81
+		$success              = false;
82
+		$messages_to_send     = [];
83
+		$messages_to_generate = [];
84
+		// loop through and setup the various messages from the queue so we know what is being processed
85
+		$queue_to_process->get_message_repository()->rewind();
86
+		foreach ($queue_to_process->get_message_repository() as $message) {
87
+			if ($message->STS_ID() === EEM_Message::status_incomplete) {
88
+				$messages_to_generate[] = $message;
89
+				continue;
90
+			}
91
+
92
+			if (in_array($message->STS_ID(), EEM_Message::instance()->stati_indicating_to_send())) {
93
+				$messages_to_send[] = $message;
94
+			}
95
+		}
96
+
97
+		// do generation/sends
98
+		if ($messages_to_generate) {
99
+			$success = $this->batch_generate_from_queue($messages_to_generate, true);
100
+		}
101
+
102
+		if ($messages_to_send) {
103
+			$sent = $this->batch_send_from_queue($messages_to_send, true);
104
+			// if there was messages to generate and it failed, then we override any success value for the sending process
105
+			// otherwise we just use the return from batch send.  The intent is that there is a simple response for success/fail.
106
+			// Either everything was successful or we consider it a fail.  To be clear, this is a limitation of doing
107
+			// all messages processing on the same request.
108
+			$success = $messages_to_generate && ! $success ? false : $sent;
109
+		}
110
+		return $success;
111
+	}
112
+
113
+
114
+	/**
115
+	 * Calls the EE_Messages_Queue::get_batch_to_generate() method and sends to EE_Messages_Generator.
116
+	 *
117
+	 * @param EE_Message[] $messages    Array of EE_Message objects (optional) to build the queue with.
118
+	 * @param bool         $clear_queue Whether to ensure a fresh queue or not.
119
+	 *
120
+	 * @return bool|EE_Messages_Queue return false if nothing generated.  This returns a new EE_Message_Queue with
121
+	 *                                   generated messages.
122
+	 * @throws EE_Error
123
+	 * @throws ReflectionException
124
+	 */
125
+	public function batch_generate_from_queue($messages = [], $clear_queue = false)
126
+	{
127
+		if ($this->_build_queue_for_generation($messages, $clear_queue)) {
128
+			$new_queue = $this->_generator->generate();
129
+			if ($new_queue instanceof EE_Messages_Queue) {
130
+				// unlock queue
131
+				$this->_queue->unlock_queue();
132
+				$new_queue->initiate_request_by_priority('send');
133
+				return $new_queue;
134
+			}
135
+		}
136
+		$this->_queue->unlock_queue();
137
+		return false;
138
+	}
139
+
140
+
141
+	/**
142
+	 * This method preps a queue for generation.
143
+	 *
144
+	 * @param EE_Message[] $messages    Array of EE_Message objects to build the queue with
145
+	 *
146
+	 * @param bool         $clear_queue This indicates whether the existing queue should be dumped or not.
147
+	 *
148
+	 * @return bool true means queue prepped, false means there was a lock so no generation please.
149
+	 * @throws EE_Error
150
+	 * @throws ReflectionException
151
+	 * @since    4.9.0
152
+	 *
153
+	 */
154
+	protected function _build_queue_for_generation($messages = [], $clear_queue = false)
155
+	{
156
+
157
+		if ($clear_queue) {
158
+			$this->_init_queue_and_generator();
159
+		}
160
+
161
+		if ($messages) {
162
+			// if generation is locked then get out now because that means processing is already happening.
163
+			if ($this->_queue->is_locked()) {
164
+				return false;
165
+			}
166
+
167
+			$this->_queue->lock_queue();
168
+			$messages = is_array($messages) ? $messages : [$messages];
169
+			foreach ($messages as $message) {
170
+				if ($message instanceof EE_Message) {
171
+					$data = $message->all_extra_meta_array();
172
+					$this->_queue->add($message, $data);
173
+				}
174
+			}
175
+			return true;
176
+		} else {
177
+			return $this->_queue->get_batch_to_generate();
178
+		}
179
+	}
180
+
181
+
182
+	/**
183
+	 * This method preps a queue for sending.
184
+	 *
185
+	 * @param EE_Message[] $messages
186
+	 * @param bool         $clear_queue Used to indicate whether to start with a fresh queue or not.
187
+	 *
188
+	 * @return bool true means queue prepped, false means there was a lock so no queue prepped.
189
+	 */
190
+	protected function _build_queue_for_sending($messages, $clear_queue = false)
191
+	{
192
+		// if sending is locked then get out now because that means processing is already happening.
193
+		if ($this->_queue->is_locked(EE_Messages_Queue::action_sending)) {
194
+			return false;
195
+		}
196
+
197
+		$this->_queue->lock_queue(EE_Messages_Queue::action_sending);
198
+
199
+		if ($clear_queue) {
200
+			$this->_init_queue_and_generator();
201
+		}
202
+
203
+		$messages = is_array($messages) ? $messages : [$messages];
204
+
205
+		foreach ($messages as $message) {
206
+			$this->_queue->add($message);
207
+		}
208
+		return true;
209
+	}
210
+
211
+
212
+	/**
213
+	 * Calls the EE_Message_Queue::get_to_send_batch_and_send() method and then immediately just calls
214
+	 * EE_Message_Queue::execute() to iterate and send unsent messages.
215
+	 *
216
+	 * @param EE_Message[] $messages    If an array of messages is sent in then use it.
217
+	 *
218
+	 * @param bool         $clear_queue Whether to initialize a new queue or keep the existing one.
219
+	 *
220
+	 * @return EE_Messages_Queue
221
+	 * @throws EE_Error
222
+	 * @throws ReflectionException
223
+	 */
224
+	public function batch_send_from_queue($messages = [], $clear_queue = false)
225
+	{
226
+
227
+		if ($messages && $this->_build_queue_for_sending($messages, $clear_queue)) {
228
+			$this->_queue->execute();
229
+			$this->_queue->unlock_queue(EE_Messages_Queue::action_sending);
230
+		} else {
231
+			// get messages to send and execute.
232
+			$this->_queue->get_to_send_batch_and_send();
233
+		}
234
+		// note: callers can use the EE_Messages_Queue::count_STS_in_queue() method to find out if there were any failed
235
+		// messages in the queue and decide how to handle at that point.
236
+		return $this->_queue;
237
+	}
238
+
239
+
240
+	/**
241
+	 * This immediately generates messages using the given array of EE_Message_To_Generate objects and returns the
242
+	 * EE_Message_Queue with the generated messages for the caller to work with.  Note, this does NOT save the generated
243
+	 * messages in the queue, leaving it up to the caller to do so.
244
+	 *
245
+	 * @param EE_Message_To_Generate[] $messages_to_generate
246
+	 * @return EE_Messages_Queue
247
+	 * @throws EE_Error
248
+	 * @throws ReflectionException
249
+	 */
250
+	public function generate_and_return($messages_to_generate)
251
+	{
252
+		$this->_init_queue_and_generator();
253
+		$this->_queue_for_generation_loop($messages_to_generate);
254
+		return $this->_generator->generate(false);
255
+	}
256
+
257
+
258
+	/**
259
+	 * Executes the generator generate method on the current internal queue, and returns the generated queue.
260
+	 *
261
+	 * @param bool $persist Indicate whether to instruct the generator to persist the generated queue (true) or not
262
+	 *                      (false).
263
+	 * @return EE_Messages_Queue
264
+	 * @throws EE_Error
265
+	 * @throws ReflectionException
266
+	 */
267
+	public function generate_queue($persist = true)
268
+	{
269
+		return $this->_generator->generate($persist);
270
+	}
271
+
272
+
273
+	/**
274
+	 * Queue for generation.  Note this does NOT persist to the db.  Client code should call
275
+	 * get_message_repository()->save() if desire to persist.  This method is provided to client code to decide what it
276
+	 * wants to do with queued messages for generation.
277
+	 *
278
+	 * @param EE_Message_To_Generate $message_to_generate
279
+	 * @param bool                   $test_send Whether this item is for a test send or not.
280
+	 * @return void
281
+	 */
282
+	public function queue_for_generation(EE_Message_To_Generate $message_to_generate, $test_send = false)
283
+	{
284
+		if ($message_to_generate->valid()) {
285
+			if (! $this->_generator->create_and_add_message_to_queue($message_to_generate, $test_send)) {
286
+				throw new RuntimeException(
287
+					esc_html__('Message failed to generate', 'event_espresso')
288
+				);
289
+			}
290
+		}
291
+	}
292
+
293
+
294
+	/**
295
+	 * This receives an array of EE_Message_To_Generate objects, converts them to EE_Message adds them to the
296
+	 * generation queue and then persists to storage.
297
+	 *
298
+	 * @param EE_Message_To_Generate[] $messages_to_generate
299
+	 */
300
+	public function batch_queue_for_generation_and_persist($messages_to_generate)
301
+	{
302
+		$this->_init_queue_and_generator();
303
+		$this->_queue_for_generation_loop($messages_to_generate);
304
+		$this->_queue->save();
305
+	}
306
+
307
+
308
+	/**
309
+	 * This receives an array of EE_Message_To_Generate objects, converts them to EE_Message and adds them to the
310
+	 * generation queue.  Does NOT persist to storage (unless there is an error. Client code can retrieve the generated
311
+	 * queue by calling EEM_Messages_Processor::get_queue()
312
+	 *
313
+	 * @param EE_Message_To_Generate[] $messages_to_generate
314
+	 */
315
+	public function batch_queue_for_generation_no_persist($messages_to_generate)
316
+	{
317
+		$this->_init_queue_and_generator();
318
+		$this->_queue_for_generation_loop($messages_to_generate);
319
+	}
320
+
321
+
322
+	/**
323
+	 * Simply loops through the given array of EE_Message_To_Generate objects and adds them to the _queue as EE_Message
324
+	 * objects.
325
+	 *
326
+	 * @param EE_Message_To_Generate[] $messages_to_generate
327
+	 */
328
+	protected function _queue_for_generation_loop($messages_to_generate)
329
+	{
330
+		// make sure is in an array.
331
+		if (! is_array($messages_to_generate)) {
332
+			$messages_to_generate = [$messages_to_generate];
333
+		}
334
+
335
+		foreach ($messages_to_generate as $message_to_generate) {
336
+			if ($message_to_generate instanceof EE_Message_To_Generate && $message_to_generate->valid()) {
337
+				$this->queue_for_generation($message_to_generate);
338
+			}
339
+		}
340
+	}
341
+
342
+
343
+	/**
344
+	 * Receives an array of EE_Message_To_Generate objects and generates the EE_Message objects, then persists (so its
345
+	 * queued for sending).
346
+	 *
347
+	 * @param EE_Message_To_Generate[]
348
+	 * @return EE_Messages_Queue
349
+	 * @throws EE_Error
350
+	 * @throws ReflectionException
351
+	 */
352
+	public function generate_and_queue_for_sending($messages_to_generate)
353
+	{
354
+		$this->_init_queue_and_generator();
355
+		$this->_queue_for_generation_loop($messages_to_generate);
356
+		return $this->_generator->generate();
357
+	}
358
+
359
+
360
+	/**
361
+	 * Generate for preview and execute right away.
362
+	 *
363
+	 * @param EE_Message_To_Generate $message_to_generate
364
+	 * @param bool                   $test_send Whether this is a test send or not.
365
+	 * @return  EE_Messages_Queue | bool   false if unable to generate otherwise the generated queue.
366
+	 * @throws EE_Error
367
+	 * @throws ReflectionException
368
+	 */
369
+	public function generate_for_preview(EE_Message_To_Generate $message_to_generate, $test_send = false)
370
+	{
371
+		if (! $message_to_generate->valid()) {
372
+			EE_Error::add_error(
373
+				esc_html__('Unable to generate preview because of invalid data', 'event_espresso'),
374
+				__FILE__,
375
+				__FUNCTION__,
376
+				__LINE__
377
+			);
378
+			return false;
379
+		}
380
+		// just make sure preview is set on the $message_to_generate (in case client forgot)
381
+		$message_to_generate->set_preview(true);
382
+		$this->_init_queue_and_generator();
383
+		$this->queue_for_generation($message_to_generate, $test_send);
384
+		$generated_queue = $this->_generator->generate(false);
385
+		if ($generated_queue->execute(false)) {
386
+			// the first queue item should be the preview
387
+			$generated_queue->get_message_repository()->rewind();
388
+			if ($generated_queue->get_message_repository()->valid()) {
389
+				return $generated_queue;
390
+			}
391
+		}
392
+		return false;
393
+	}
394
+
395
+
396
+	/**
397
+	 * This queues for sending.
398
+	 * The messenger send now method is also verified to see if sending immediately is requested.
399
+	 * otherwise its just saved to the queue.
400
+	 *
401
+	 * @param EE_Message_To_Generate $message_to_generate
402
+	 * @return bool true or false for success.
403
+	 * @throws EE_Error
404
+	 * @throws ReflectionException
405
+	 */
406
+	public function queue_for_sending(EE_Message_To_Generate $message_to_generate)
407
+	{
408
+		if (! $message_to_generate->valid()) {
409
+			return false;
410
+		}
411
+		$this->_init_queue_and_generator();
412
+		$message = $message_to_generate->get_EE_Message();
413
+		$this->_queue->add($message);
414
+		if ($message->send_now()) {
415
+			$this->_queue->execute(false);
416
+		} else {
417
+			$this->_queue->save();
418
+		}
419
+		return true;
420
+	}
421
+
422
+
423
+	/**
424
+	 * This generates and sends from the given EE_Message_To_Generate class immediately.
425
+	 *
426
+	 * @param EE_Message_To_Generate $message_to_generate
427
+	 * @return EE_Messages_Queue | null
428
+	 * @throws EE_Error
429
+	 * @throws ReflectionException
430
+	 */
431
+	public function generate_and_send_now(EE_Message_To_Generate $message_to_generate)
432
+	{
433
+		if (! $message_to_generate->valid()) {
434
+			return null;
435
+		}
436
+		// is there supposed to be a sending messenger for this message?
437
+		if ($message_to_generate instanceof EEI_Has_Sending_Messenger) {
438
+			// make sure it's valid, but if it's not,
439
+			// then set the value of $sending_messenger to an EE_Error object
440
+			// so that downstream code can easily see that things went wrong.
441
+			$sending_messenger = $message_to_generate->sending_messenger() instanceof EE_messenger
442
+				? $message_to_generate->sending_messenger()
443
+				: new EE_Error(
444
+					esc_html__(
445
+						'There was a specific sending messenger requested for the send action, but it was either invalid or not active at time of sending.',
446
+						'event_espresso'
447
+					)
448
+				);
449
+		} else {
450
+			$sending_messenger = null;
451
+		}
452
+
453
+		if ($message_to_generate->get_EE_Message()->STS_ID() === EEM_Message::status_idle) {
454
+			$this->_init_queue_and_generator();
455
+			$this->_queue->add($message_to_generate->get_EE_Message());
456
+			$this->_queue->execute(false, $sending_messenger);
457
+			return $this->_queue;
458
+		} elseif ($message_to_generate->get_EE_Message()->STS_ID() === EEM_Message::status_incomplete) {
459
+			$generated_queue = $this->generate_and_return([$message_to_generate]);
460
+			$generated_queue->execute(false, $sending_messenger);
461
+			return $generated_queue;
462
+		}
463
+		return null;
464
+	}
465
+
466
+
467
+	/**
468
+	 * Creates mtg objects for all active messengers and queues for generation.
469
+	 * This method also calls the execute by priority method on the queue which will optionally kick off a new
470
+	 * non-blocking request to complete the action if the priority for the message requires immediate action.
471
+	 *
472
+	 * @param string $message_type
473
+	 * @param mixed  $data    The data being used for generation.
474
+	 * @param bool   $persist Whether to persist the queued messages to the db or not.
475
+	 * @throws EE_Error
476
+	 * @throws ReflectionException
477
+	 */
478
+	public function generate_for_all_active_messengers($message_type, $data, $persist = true)
479
+	{
480
+		$messages_to_generate = $this->setup_mtgs_for_all_active_messengers($message_type, $data);
481
+		if ($persist) {
482
+			$this->batch_queue_for_generation_and_persist($messages_to_generate);
483
+			$this->_queue->initiate_request_by_priority();
484
+		} else {
485
+			$this->batch_queue_for_generation_no_persist($messages_to_generate);
486
+		}
487
+	}
488
+
489
+
490
+	/**
491
+	 * This simply loops through all active messengers and takes care of setting up the
492
+	 * EE_Message_To_Generate objects.
493
+	 *
494
+	 * @param $message_type
495
+	 * @param $data
496
+	 *
497
+	 * @return EE_Message_To_Generate[]
498
+	 */
499
+	public function setup_mtgs_for_all_active_messengers($message_type, $data)
500
+	{
501
+		$messages_to_generate = [];
502
+		foreach ($this->_message_resource_manager->active_messengers() as $messenger_slug => $messenger_object) {
503
+			$message_to_generate = new EE_Message_To_Generate($messenger_slug, $message_type, $data);
504
+			if ($message_to_generate->valid()) {
505
+				$messages_to_generate[] = $message_to_generate;
506
+			}
507
+		}
508
+		return $messages_to_generate;
509
+	}
510
+
511
+
512
+	/**
513
+	 * This accepts an array of EE_Message::MSG_ID values
514
+	 * and will use that to retrieve the objects from the database and send.
515
+	 *
516
+	 * @param array $message_ids
517
+	 * @throws EE_Error
518
+	 * @throws ReflectionException
519
+	 */
520
+	public function setup_messages_from_ids_and_send($message_ids)
521
+	{
522
+		$this->_init_queue_and_generator();
523
+		$messages = EEM_Message::instance()->get_all(
524
+			[
525
+				 [
526
+					 'MSG_ID' => ['IN', $message_ids],
527
+					 'STS_ID' => [
528
+						 'IN',
529
+						 array_merge(
530
+							 EEM_Message::instance()->stati_indicating_sent(),
531
+							 [EEM_Message::status_retry]
532
+						 ),
533
+					 ],
534
+				 ],
535
+			 ]
536
+		);
537
+		// set the Messages to resend.
538
+		foreach ($messages as $message) {
539
+			if ($message instanceof EE_Message) {
540
+				$message->set_STS_ID(EEM_Message::status_resend);
541
+				$this->_queue->add($message);
542
+			}
543
+		}
544
+
545
+		$this->_queue->initiate_request_by_priority('send');
546
+	}
547
+
548
+
549
+	/**
550
+	 * This method checks for registration IDs in the request via the given key and creates the messages to generate
551
+	 * objects from them, then returns the array of messages to generate objects.
552
+	 * Note, this sets up registrations for the registration family of message types.
553
+	 *
554
+	 * @param string $registration_ids_key This is used to indicate what represents the registration ids in the request.
555
+	 *
556
+	 * @return EE_Message_To_Generate[]|bool
557
+	 * @throws EE_Error
558
+	 */
559
+	public function setup_messages_to_generate_from_registration_ids_in_request($registration_ids_key = '_REG_ID')
560
+	{
561
+		/** @var RequestInterface $request */
562
+		$request      = LoaderFactory::getLoader()->getShared(RequestInterface::class);
563
+		$regs_to_send = [];
564
+		$regIDs       = $request->getRequestParam($registration_ids_key, [], 'int', true);
565
+		if (empty($regIDs)) {
566
+			EE_Error::add_error(
567
+				esc_html__('Something went wrong because we\'re missing the registration ID', 'event_espresso'),
568
+				__FILE__,
569
+				__FUNCTION__,
570
+				__LINE__
571
+			);
572
+			return false;
573
+		}
574
+
575
+		// make sure is an array
576
+		$regIDs = is_array($regIDs) ? $regIDs : [$regIDs];
577
+
578
+		foreach ($regIDs as $regID) {
579
+			$reg = EEM_Registration::instance()->get_one_by_ID($regID);
580
+			if (! $reg instanceof EE_Registration) {
581
+				EE_Error::add_error(
582
+					sprintf(
583
+						esc_html__(
584
+							'Unable to retrieve a registration object for the given reg id (%s)',
585
+							'event_espresso'
586
+						),
587
+						$regID
588
+					)
589
+				);
590
+				return false;
591
+			}
592
+			$regs_to_send[ $reg->transaction_ID() ][ $reg->status_ID() ][] = $reg;
593
+		}
594
+
595
+		$messages_to_generate = [];
596
+
597
+		foreach ($regs_to_send as $status_group) {
598
+			foreach ($status_group as $status_id => $registrations) {
599
+				$message_type = EEH_MSG_Template::convert_reg_status_to_message_type($status_id);
600
+				if (! $message_type) {
601
+					continue;
602
+				}
603
+				$messages_to_generate = array_merge(
604
+					$messages_to_generate,
605
+					$this->setup_mtgs_for_all_active_messengers(
606
+						$message_type,
607
+						[$registrations, $status_id]
608
+					)
609
+				);
610
+			}
611
+		}
612
+
613
+		return $messages_to_generate;
614
+	}
615 615
 }
Please login to merge, or discard this patch.
core/libraries/messages/EE_Messages_Generator.lib.php 2 patches
Spacing   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -266,7 +266,7 @@  discard block
 block discarded – undo
266 266
     {
267 267
         // double check verification has run and that everything is ready to work with (saves us having to validate
268 268
         // everything again).
269
-        if (! $this->_verified) {
269
+        if ( ! $this->_verified) {
270 270
             return false; // get out because we don't have a valid setup to work with.
271 271
         }
272 272
 
@@ -283,7 +283,7 @@  discard block
 block discarded – undo
283 283
 
284 284
 
285 285
         // if no addressees then get out because there is nothing to generation (possible bad data).
286
-        if (! $this->_valid_addressees($addressees)) {
286
+        if ( ! $this->_valid_addressees($addressees)) {
287 287
             do_action(
288 288
                 'AHEE__EE_Messages_Generator___generate__invalid_addressees',
289 289
                 $this->_generation_queue->get_message_repository()->current(),
@@ -305,7 +305,7 @@  discard block
 block discarded – undo
305 305
         $message_template_group = $this->_get_message_template_group();
306 306
 
307 307
         // in the unlikely event there is no EE_Message_Template_Group available, get out!
308
-        if (! $message_template_group instanceof EE_Message_Template_Group) {
308
+        if ( ! $message_template_group instanceof EE_Message_Template_Group) {
309 309
             $this->_error_msg[] = esc_html__(
310 310
                 'Unable to get the Message Templates for the Message being generated.  No message template group accessible.',
311 311
                 'event_espresso'
@@ -417,7 +417,7 @@  discard block
 block discarded – undo
417 417
             // attempt to retrieve from repo first
418 418
             $message_template_group = $this->_template_collection->get_by_ID($GRP_ID);
419 419
             if ($message_template_group instanceof EE_Message_Template_Group) {
420
-                return $message_template_group;  // got it!
420
+                return $message_template_group; // got it!
421 421
             }
422 422
 
423 423
             // nope don't have it yet.  Get from DB then add to repo if its not here, then that means the current GRP_ID
@@ -446,7 +446,7 @@  discard block
 block discarded – undo
446 446
     protected function _queue_shares_same_message_template_group_for_events(array $event_ids)
447 447
     {
448 448
         foreach ($this->_current_data_handler->events as $event) {
449
-            $event_ids[ $event['ID'] ] = $event['ID'];
449
+            $event_ids[$event['ID']] = $event['ID'];
450 450
         }
451 451
         $count_of_message_template_groups = EEM_Message_Template_Group::instance()->count(
452 452
             [
@@ -522,7 +522,7 @@  discard block
 block discarded – undo
522 522
         );
523 523
 
524 524
         // if we don't have a group lets hit the db.
525
-        if (! $global_message_template_group instanceof EE_Message_Template_Group) {
525
+        if ( ! $global_message_template_group instanceof EE_Message_Template_Group) {
526 526
             $global_message_template_group = EEM_Message_Template_Group::instance()->get_one(
527 527
                 [
528 528
                     [
@@ -554,7 +554,7 @@  discard block
 block discarded – undo
554 554
     {
555 555
         $event_ids = [];
556 556
         foreach ($this->_current_data_handler->events as $event) {
557
-            $event_ids[ $event['ID'] ] = $event['ID'];
557
+            $event_ids[$event['ID']] = $event['ID'];
558 558
         }
559 559
         return $event_ids;
560 560
     }
@@ -583,10 +583,10 @@  discard block
 block discarded – undo
583 583
         $context_templates = $message_template_group->context_templates();
584 584
         foreach ($context_templates as $context => $template_fields) {
585 585
             foreach ($template_fields as $template_field => $template_obj) {
586
-                if (! $template_obj instanceof EE_Message_Template) {
586
+                if ( ! $template_obj instanceof EE_Message_Template) {
587 587
                     continue;
588 588
                 }
589
-                $templates[ $template_field ][ $context ] = $template_obj->get('MTP_content');
589
+                $templates[$template_field][$context] = $template_obj->get('MTP_content');
590 590
             }
591 591
         }
592 592
         return $templates;
@@ -617,7 +617,7 @@  discard block
 block discarded – undo
617 617
     {
618 618
 
619 619
         // if templates are empty then get out because we can't generate anything.
620
-        if (! $templates) {
620
+        if ( ! $templates) {
621 621
             $this->_error_msg[] = esc_html__(
622 622
                 'Unable to assemble messages because there are no templates retrieved for generating the messages with',
623 623
                 'event_espresso'
@@ -707,7 +707,7 @@  discard block
 block discarded – undo
707 707
         if (
708 708
             ! $this->_generation_queue->get_message_repository()->is_preview()
709 709
             && (
710
-                (empty($templates['to'][ $context ]) && ! $this->_current_messenger->allow_empty_to_field())
710
+                (empty($templates['to'][$context]) && ! $this->_current_messenger->allow_empty_to_field())
711 711
                 || ! $message_template_group->is_context_active($context)
712 712
             )
713 713
         ) {
@@ -719,15 +719,15 @@  discard block
 block discarded – undo
719 719
         foreach ($templates as $field => $field_context) {
720 720
             $error_msg = [];
721 721
             // let's setup the valid shortcodes for the incoming context.
722
-            $valid_shortcodes = $mt_shortcodes[ $context ];
722
+            $valid_shortcodes = $mt_shortcodes[$context];
723 723
             // merge in valid shortcodes for the field.
724
-            $shortcodes = isset($m_shortcodes[ $field ]) ? $m_shortcodes[ $field ] : $valid_shortcodes;
725
-            if (isset($field_context[ $context ])) {
724
+            $shortcodes = isset($m_shortcodes[$field]) ? $m_shortcodes[$field] : $valid_shortcodes;
725
+            if (isset($field_context[$context])) {
726 726
                 // prefix field.
727
-                $column_name = 'MSG_' . $field;
727
+                $column_name = 'MSG_'.$field;
728 728
                 try {
729 729
                     $content = $this->_shortcode_parser->parse_message_template(
730
-                        $field_context[ $context ],
730
+                        $field_context[$context],
731 731
                         $recipient,
732 732
                         $shortcodes,
733 733
                         $this->_current_message_type,
@@ -791,13 +791,13 @@  discard block
 block discarded – undo
791 791
      */
792 792
     protected function _valid_addressees($addressees)
793 793
     {
794
-        if (! $addressees || ! is_array($addressees)) {
794
+        if ( ! $addressees || ! is_array($addressees)) {
795 795
             return false;
796 796
         }
797 797
 
798 798
         foreach ($addressees as $addressee_array) {
799 799
             foreach ($addressee_array as $addressee) {
800
-                if (! $addressee instanceof EE_Messages_Addressee) {
800
+                if ( ! $addressee instanceof EE_Messages_Addressee) {
801 801
                     return false;
802 802
                 }
803 803
             }
@@ -875,7 +875,7 @@  discard block
 block discarded – undo
875 875
         /** @type EE_Messages_incoming_data $data_handler_class_name - well not really... just the class name actually */
876 876
         $data_handler_class_name = $this->_generation_queue->get_message_repository()->get_data_handler()
877 877
             ? $this->_generation_queue->get_message_repository()->get_data_handler()
878
-            : 'EE_Messages_' . $this->_current_message_type->get_data_handler($generation_data) . '_incoming_data';
878
+            : 'EE_Messages_'.$this->_current_message_type->get_data_handler($generation_data).'_incoming_data';
879 879
 
880 880
         // If this EE_Message is for a preview, then let's switch out to the preview data handler.
881 881
         if ($this->_generation_queue->get_message_repository()->is_preview()) {
@@ -883,7 +883,7 @@  discard block
 block discarded – undo
883 883
         }
884 884
 
885 885
         // First get the class name for the data handler (and also verifies it exists.
886
-        if (! class_exists($data_handler_class_name)) {
886
+        if ( ! class_exists($data_handler_class_name)) {
887 887
             $this->_error_msg[] = sprintf(
888 888
             /* Translators: Both placeholders are the names of php classes. */
889 889
                 esc_html__(
@@ -924,7 +924,7 @@  discard block
 block discarded – undo
924 924
                 $generating_data
925 925
             )
926 926
         );
927
-        if (! $this->_current_data_handler instanceof EE_Messages_incoming_data) {
927
+        if ( ! $this->_current_data_handler instanceof EE_Messages_incoming_data) {
928 928
             // no saved data_handler in the repo so let's set one up and add it to the repo.
929 929
             try {
930 930
                 $this->_current_data_handler = new $data_handler_class_name($generating_data);
@@ -948,7 +948,7 @@  discard block
 block discarded – undo
948 948
      */
949 949
     protected function _prepare_data_for_queue(EE_Message_To_Generate $message_to_generate, $preview)
950 950
     {
951
-        if (! $message_to_generate->valid()) {
951
+        if ( ! $message_to_generate->valid()) {
952 952
             return false; // unable to get the data because the info in the EE_Message_To_Generate class is invalid.
953 953
         }
954 954
         /** @type EE_Messages_incoming_data $data_handler - well not really... just the class name actually */
Please login to merge, or discard this patch.
Indentation   +989 added lines, -989 removed lines patch added patch discarded remove patch
@@ -15,994 +15,994 @@
 block discarded – undo
15 15
  */
16 16
 class EE_Messages_Generator
17 17
 {
18
-    /**
19
-     * @type EE_Messages_Data_Handler_Collection
20
-     */
21
-    protected $_data_handler_collection;
22
-
23
-    /**
24
-     * @type  EE_Message_Template_Group_Collection
25
-     */
26
-    protected $_template_collection;
27
-
28
-    /**
29
-     * This will hold the data handler for the current EE_Message being generated.
30
-     *
31
-     * @type EE_Messages_incoming_data
32
-     */
33
-    protected $_current_data_handler;
34
-
35
-    /**
36
-     * This holds the EE_Messages_Queue that contains the messages to generate.
37
-     *
38
-     * @type EE_Messages_Queue
39
-     */
40
-    protected $_generation_queue;
41
-
42
-    /**
43
-     * This holds the EE_Messages_Queue that will store the generated EE_Message objects.
44
-     *
45
-     * @type EE_Messages_Queue
46
-     */
47
-    protected $_ready_queue;
48
-
49
-    /**
50
-     * This is a container for any error messages that get created through the generation
51
-     * process.
52
-     *
53
-     * @type array
54
-     */
55
-    protected $_error_msg = [];
56
-
57
-    /**
58
-     * Flag used to set when the current EE_Message in the generation queue has been verified.
59
-     *
60
-     * @type bool
61
-     */
62
-    protected $_verified = false;
63
-
64
-    /**
65
-     * This will hold the current messenger object corresponding with the current EE_Message in the generation queue.
66
-     *
67
-     * @type EE_messenger
68
-     */
69
-    protected $_current_messenger;
70
-
71
-    /**
72
-     * This will hold the current message type object corresponding with the current EE_Message in the generation queue.
73
-     *
74
-     * @type EE_message_type
75
-     */
76
-    protected $_current_message_type;
77
-
78
-    /**
79
-     * @type EEH_Parse_Shortcodes
80
-     */
81
-    protected $_shortcode_parser;
82
-
83
-
84
-    /**
85
-     * @param EE_Messages_Queue                    $generation_queue
86
-     * @param EE_Messages_Queue                    $ready_queue
87
-     * @param EE_Messages_Data_Handler_Collection  $data_handler_collection
88
-     * @param EE_Message_Template_Group_Collection $template_collection
89
-     * @param EEH_Parse_Shortcodes                 $shortcode_parser
90
-     */
91
-    public function __construct(
92
-        EE_Messages_Queue $generation_queue,
93
-        EE_Messages_Queue $ready_queue,
94
-        EE_Messages_Data_Handler_Collection $data_handler_collection,
95
-        EE_Message_Template_Group_Collection $template_collection,
96
-        EEH_Parse_Shortcodes $shortcode_parser
97
-    ) {
98
-        $this->_generation_queue        = $generation_queue;
99
-        $this->_ready_queue             = $ready_queue;
100
-        $this->_data_handler_collection = $data_handler_collection;
101
-        $this->_template_collection     = $template_collection;
102
-        $this->_shortcode_parser        = $shortcode_parser;
103
-    }
104
-
105
-
106
-    /**
107
-     * @return EE_Messages_Queue
108
-     */
109
-    public function generation_queue()
110
-    {
111
-        return $this->_generation_queue;
112
-    }
113
-
114
-
115
-    /**
116
-     *  This iterates through the provided queue and generates the EE_Message objects.
117
-     *  When iterating through the queue, the queued item that served as the base for generating other EE_Message
118
-     *  objects gets removed and the new EE_Message objects get added to a NEW queue.  The NEW queue is then returned
119
-     *  for the caller to decide what to do with it.
120
-     *
121
-     * @param bool $save Whether to save the EE_Message objects in the new queue or just return.
122
-     * @return EE_Messages_Queue The new queue for holding generated EE_Message objects.
123
-     * @throws EE_Error
124
-     * @throws InvalidArgumentException
125
-     * @throws InvalidDataTypeException
126
-     * @throws InvalidInterfaceException
127
-     * @throws ReflectionException
128
-     */
129
-    public function generate($save = true)
130
-    {
131
-        // iterate through the messages in the queue, generate, and add to new queue.
132
-        $this->_generation_queue->get_message_repository()->rewind();
133
-
134
-        while ($this->_generation_queue->get_message_repository()->valid()) {
135
-            // reset "current" properties
136
-            $this->_reset_current_properties();
137
-
138
-            $msg = $this->_generation_queue->get_message_repository()->current();
139
-
140
-            /**
141
-             * need to get the next object and capture it for setting manually after deletes.  The reason is that when
142
-             * an object is removed from the repo then valid for the next object will fail.
143
-             */
144
-            $this->_generation_queue->get_message_repository()->next();
145
-            $next_msg = $this->_generation_queue->get_message_repository()->valid()
146
-                ? $this->_generation_queue->get_message_repository()->current()
147
-                :  null;
148
-            // restore pointer to current item
149
-            $this->_generation_queue->get_message_repository()->set_current($msg);
150
-
151
-            // skip and delete if the current $msg is NOT incomplete (queued for generation)
152
-            if ($msg->STS_ID() !== EEM_Message::status_incomplete) {
153
-                // we keep this item in the db just remove from the repo.
154
-                $this->_generation_queue->get_message_repository()->remove($msg);
155
-                // next item
156
-                $this->_generation_queue->get_message_repository()->set_current($next_msg);
157
-                continue;
158
-            }
159
-
160
-            if ($this->_verify()) {
161
-                // let's get generating!
162
-                $this->_generate();
163
-            }
164
-
165
-            // don't persist debug_only messages if the messages system is not in debug mode.
166
-            if (
167
-                $msg->STS_ID() === EEM_Message::status_debug_only
168
-                && ! EEM_Message::debug()
169
-            ) {
170
-                do_action(
171
-                    'AHEE__EE_Messages_Generator__generate__before_debug_delete',
172
-                    $msg,
173
-                    $this->_error_msg,
174
-                    $this->_current_messenger,
175
-                    $this->_current_message_type,
176
-                    $this->_current_data_handler
177
-                );
178
-                $this->_generation_queue->get_message_repository()->delete();
179
-                $this->_generation_queue->get_message_repository()->set_current($next_msg);
180
-                continue;
181
-            }
182
-
183
-            // if there are error messages then let's set the status and the error message.
184
-            if ($this->_error_msg) {
185
-                // if the status is already debug only, then let's leave it at that.
186
-                if ($msg->STS_ID() !== EEM_Message::status_debug_only) {
187
-                    $msg->set_STS_ID(EEM_Message::status_failed);
188
-                }
189
-                do_action(
190
-                    'AHEE__EE_Messages_Generator__generate__processing_failed_message',
191
-                    $msg,
192
-                    $this->_error_msg,
193
-                    $this->_current_messenger,
194
-                    $this->_current_message_type,
195
-                    $this->_current_data_handler
196
-                );
197
-                $msg->set_error_message(
198
-                    esc_html__('Message failed to generate for the following reasons: ', 'event_espresso')
199
-                    . "\n"
200
-                    . implode("\n", $this->_error_msg)
201
-                );
202
-                $msg->set_modified(time());
203
-            } else {
204
-                do_action(
205
-                    'AHEE__EE_Messages_Generator__generate__before_successful_generated_message_delete',
206
-                    $msg,
207
-                    $this->_error_msg,
208
-                    $this->_current_messenger,
209
-                    $this->_current_message_type,
210
-                    $this->_current_data_handler
211
-                );
212
-                // remove from db
213
-                $this->_generation_queue->get_message_repository()->delete();
214
-            }
215
-            // next item
216
-            $this->_generation_queue->get_message_repository()->set_current($next_msg);
217
-        }
218
-
219
-        // generation queue is ALWAYS saved to record any errors in the generation process.
220
-        $this->_generation_queue->save();
221
-
222
-        /**
223
-         * save _ready_queue if flag set.
224
-         * Note: The EE_Message objects have values set via the EE_Base_Class::set_field_or_extra_meta() method.  This
225
-         * means if a field was added that is not a valid database column.  The EE_Message was already saved to the db
226
-         * so a EE_Extra_Meta entry could be created and attached to the EE_Message.  In those cases the save flag is
227
-         * irrelevant.
228
-         */
229
-        if ($save) {
230
-            $this->_ready_queue->save();
231
-        }
232
-
233
-        // final reset of properties
234
-        $this->_reset_current_properties();
235
-
236
-        return $this->_ready_queue;
237
-    }
238
-
239
-
240
-    /**
241
-     * This resets all the properties used for holding "current" values corresponding to the current EE_Message object
242
-     * in the generation queue.
243
-     */
244
-    protected function _reset_current_properties()
245
-    {
246
-        $this->_verified = false;
247
-        // make sure any _data value in the current message type is reset
248
-        if ($this->_current_message_type instanceof EE_message_type) {
249
-            $this->_current_message_type->reset_data();
250
-        }
251
-        $this->_current_messenger = $this->_current_message_type = $this->_current_data_handler = null;
252
-    }
253
-
254
-
255
-    /**
256
-     * This proceeds with the actual generation of a message.  By the time this is called, there should already be a
257
-     * $_current_data_handler set and all incoming information should be validated for the current EE_Message in the
258
-     * _generating_queue.
259
-     *
260
-     * @return bool Whether the message was successfully generated or not.
261
-     * @throws EE_Error
262
-     * @throws InvalidArgumentException
263
-     * @throws InvalidDataTypeException
264
-     * @throws InvalidInterfaceException
265
-     * @throws ReflectionException
266
-     */
267
-    protected function _generate()
268
-    {
269
-        // double check verification has run and that everything is ready to work with (saves us having to validate
270
-        // everything again).
271
-        if (! $this->_verified) {
272
-            return false; // get out because we don't have a valid setup to work with.
273
-        }
274
-
275
-
276
-        try {
277
-            $addressees = $this->_current_message_type->get_addressees(
278
-                $this->_current_data_handler,
279
-                $this->_generation_queue->get_message_repository()->current()->context()
280
-            );
281
-        } catch (EE_Error $e) {
282
-            $this->_error_msg[] = $e->getMessage();
283
-            return false;
284
-        }
285
-
286
-
287
-        // if no addressees then get out because there is nothing to generation (possible bad data).
288
-        if (! $this->_valid_addressees($addressees)) {
289
-            do_action(
290
-                'AHEE__EE_Messages_Generator___generate__invalid_addressees',
291
-                $this->_generation_queue->get_message_repository()->current(),
292
-                $addressees,
293
-                $this->_current_messenger,
294
-                $this->_current_message_type,
295
-                $this->_current_data_handler
296
-            );
297
-            $this->_generation_queue->get_message_repository()->current()->set_STS_ID(
298
-                EEM_Message::status_debug_only
299
-            );
300
-            $this->_error_msg[] = esc_html__(
301
-                '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. Sometimes this is because messages only get generated for certain registration statuses. For example, the ticket notice message type only goes to approved registrations.',
302
-                'event_espresso'
303
-            );
304
-            return false;
305
-        }
306
-
307
-        $message_template_group = $this->_get_message_template_group();
308
-
309
-        // in the unlikely event there is no EE_Message_Template_Group available, get out!
310
-        if (! $message_template_group instanceof EE_Message_Template_Group) {
311
-            $this->_error_msg[] = esc_html__(
312
-                'Unable to get the Message Templates for the Message being generated.  No message template group accessible.',
313
-                'event_espresso'
314
-            );
315
-            return false;
316
-        }
317
-
318
-        // get formatted templates for using to parse and setup EE_Message objects.
319
-        $templates = $this->_get_templates($message_template_group);
320
-
321
-
322
-        // setup new EE_Message objects (and add to _ready_queue)
323
-        return $this->_assemble_messages($addressees, $templates, $message_template_group);
324
-    }
325
-
326
-
327
-    /**
328
-     * Retrieves the message template group being used for generating messages.
329
-     * Note: this also utilizes the EE_Message_Template_Group_Collection to avoid having to hit the db multiple times.
330
-     *
331
-     * @return EE_Message_Template_Group|null
332
-     * @throws EE_Error
333
-     * @throws InvalidArgumentException
334
-     * @throws InvalidDataTypeException
335
-     * @throws InvalidInterfaceException
336
-     * @throws ReflectionException
337
-     */
338
-    protected function _get_message_template_group()
339
-    {
340
-        // first see if there is a specific message template group requested
341
-        // (current message in the queue has a specific GRP_ID)
342
-        $message_template_group = $this->_specific_message_template_group_from_queue();
343
-        if ($message_template_group instanceof EE_Message_Template_Group) {
344
-            return $message_template_group;
345
-        }
346
-
347
-        // get event_ids from the data handler so we can check to see
348
-        // if there's already a message template group for them in the collection.
349
-        $event_ids              = $this->_get_event_ids_from_current_data_handler();
350
-        $message_template_group = $this->_template_collection->get_by_key(
351
-            $this->_template_collection->getKey(
352
-                $this->_current_messenger->name,
353
-                $this->_current_message_type->name,
354
-                $event_ids
355
-            )
356
-        );
357
-
358
-        // if we have a message template group then no need to hit the database, just return it.
359
-        if ($message_template_group instanceof EE_Message_Template_Group) {
360
-            return $message_template_group;
361
-        }
362
-
363
-        // get the global group first for this messenger and message type
364
-        // to ensure there is no override set.
365
-        $global_message_template_group =
366
-            $this->_get_global_message_template_group_for_current_messenger_and_message_type();
367
-
368
-        if (
369
-            $global_message_template_group instanceof EE_Message_Template_Group
370
-            && $global_message_template_group->get('MTP_is_override')
371
-        ) {
372
-            return $global_message_template_group;
373
-        }
374
-
375
-        // if we're still here, that means there was no message template group for the events in the collection and
376
-        // the global message template group for the messenger and message type is not set for override.  So next step
377
-        // is to see if there is a common shared custom message template group for this set of events.
378
-        $message_template_group = $this->_get_shared_message_template_for_events($event_ids);
379
-        if ($message_template_group instanceof EE_Message_Template_Group) {
380
-            return $message_template_group;
381
-        }
382
-
383
-        // STILL here?  Okay that means the fallback is to just use the global message template group for this event
384
-        // set. So we'll cache the global group for this event set (so this logic doesn't have to be repeated in this
385
-        // request) and return it.
386
-        if ($global_message_template_group instanceof EE_Message_Template_Group) {
387
-            $this->_template_collection->add(
388
-                $global_message_template_group,
389
-                $event_ids
390
-            );
391
-            return $global_message_template_group;
392
-        }
393
-
394
-        // if we land here that means there's NO active message template group for this set.
395
-        // TODO this will be a good target for some optimization down the road.  Whenever there is no active message
396
-        // template group for a given event set then cache that result so we don't repeat the logic.  However, for now,
397
-        // this should likely bit hit rarely enough that it's not a significant issue.
398
-        return null;
399
-    }
400
-
401
-
402
-    /**
403
-     * This checks the current message in the queue and determines if there is a specific Message Template Group
404
-     * requested for that message.
405
-     *
406
-     * @return EE_Message_Template_Group|null
407
-     * @throws EE_Error
408
-     * @throws InvalidArgumentException
409
-     * @throws InvalidDataTypeException
410
-     * @throws InvalidInterfaceException
411
-     */
412
-    protected function _specific_message_template_group_from_queue()
413
-    {
414
-        // is there a GRP_ID already on the EE_Message object?  If there is, then a specific template has been requested
415
-        // so let's use that.
416
-        $GRP_ID = $this->_generation_queue->get_message_repository()->current()->GRP_ID();
417
-
418
-        if ($GRP_ID) {
419
-            // attempt to retrieve from repo first
420
-            $message_template_group = $this->_template_collection->get_by_ID($GRP_ID);
421
-            if ($message_template_group instanceof EE_Message_Template_Group) {
422
-                return $message_template_group;  // got it!
423
-            }
424
-
425
-            // nope don't have it yet.  Get from DB then add to repo if its not here, then that means the current GRP_ID
426
-            // is not valid, so we'll continue on in the code assuming there's NO GRP_ID.
427
-            $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
428
-            if ($message_template_group instanceof EE_Message_Template_Group) {
429
-                $this->_template_collection->add($message_template_group);
430
-                return $message_template_group;
431
-            }
432
-        }
433
-        return null;
434
-    }
435
-
436
-
437
-    /**
438
-     * Returns whether the event ids passed in all share the same message template group for the current message type
439
-     * and messenger.
440
-     *
441
-     * @param array $event_ids
442
-     * @return bool true means they DO share the same message template group, false means they don't.
443
-     * @throws EE_Error
444
-     * @throws InvalidArgumentException
445
-     * @throws InvalidDataTypeException
446
-     * @throws InvalidInterfaceException
447
-     */
448
-    protected function _queue_shares_same_message_template_group_for_events(array $event_ids)
449
-    {
450
-        foreach ($this->_current_data_handler->events as $event) {
451
-            $event_ids[ $event['ID'] ] = $event['ID'];
452
-        }
453
-        $count_of_message_template_groups = EEM_Message_Template_Group::instance()->count(
454
-            [
455
-                [
456
-                    'Event.EVT_ID'     => ['IN', $event_ids],
457
-                    'MTP_messenger'    => $this->_current_messenger->name,
458
-                    'MTP_message_type' => $this->_current_message_type->name,
459
-                ],
460
-            ],
461
-            'GRP_ID',
462
-            true
463
-        );
464
-        return $count_of_message_template_groups === 1;
465
-    }
466
-
467
-
468
-    /**
469
-     * This will get the shared message template group for events that are in the current data handler but ONLY if
470
-     * there's a single shared message template group among all the events.  Otherwise it returns null.
471
-     *
472
-     * @param array $event_ids
473
-     * @return EE_Message_Template_Group|null
474
-     * @throws EE_Error
475
-     * @throws InvalidArgumentException
476
-     * @throws InvalidDataTypeException
477
-     * @throws InvalidInterfaceException
478
-     */
479
-    protected function _get_shared_message_template_for_events(array $event_ids)
480
-    {
481
-        $message_template_group = null;
482
-        if ($this->_queue_shares_same_message_template_group_for_events($event_ids)) {
483
-            $message_template_group = EEM_Message_Template_Group::instance()->get_one(
484
-                [
485
-                    [
486
-                        'Event.EVT_ID'     => ['IN', $event_ids],
487
-                        'MTP_messenger'    => $this->_current_messenger->name,
488
-                        'MTP_message_type' => $this->_current_message_type->name,
489
-                        'MTP_is_active'    => true,
490
-                    ],
491
-                    'group_by' => 'GRP_ID',
492
-                ]
493
-            );
494
-            // store this in the collection if its valid
495
-            if ($message_template_group instanceof EE_Message_Template_Group) {
496
-                $this->_template_collection->add(
497
-                    $message_template_group,
498
-                    $event_ids
499
-                );
500
-            }
501
-        }
502
-        return $message_template_group;
503
-    }
504
-
505
-
506
-    /**
507
-     * Retrieves the global message template group for the current messenger and message type.
508
-     *
509
-     * @return EE_Message_Template_Group|null
510
-     * @throws EE_Error
511
-     * @throws InvalidArgumentException
512
-     * @throws InvalidDataTypeException
513
-     * @throws InvalidInterfaceException
514
-     */
515
-    protected function _get_global_message_template_group_for_current_messenger_and_message_type()
516
-    {
517
-        // first check the collection (we use an array with 0 in it to represent global groups).
518
-        $global_message_template_group = $this->_template_collection->get_by_key(
519
-            $this->_template_collection->getKey(
520
-                $this->_current_messenger->name,
521
-                $this->_current_message_type->name,
522
-                [0]
523
-            )
524
-        );
525
-
526
-        // if we don't have a group lets hit the db.
527
-        if (! $global_message_template_group instanceof EE_Message_Template_Group) {
528
-            $global_message_template_group = EEM_Message_Template_Group::instance()->get_one(
529
-                [
530
-                    [
531
-                        'MTP_messenger'    => $this->_current_messenger->name,
532
-                        'MTP_message_type' => $this->_current_message_type->name,
533
-                        'MTP_is_active'    => true,
534
-                        'MTP_is_global'    => true,
535
-                    ],
536
-                ]
537
-            );
538
-            // if we have a group, add it to the collection.
539
-            if ($global_message_template_group instanceof EE_Message_Template_Group) {
540
-                $this->_template_collection->add(
541
-                    $global_message_template_group,
542
-                    [0]
543
-                );
544
-            }
545
-        }
546
-        return $global_message_template_group;
547
-    }
548
-
549
-
550
-    /**
551
-     * Returns an array of event ids for all the events within the current data handler.
552
-     *
553
-     * @return array
554
-     */
555
-    protected function _get_event_ids_from_current_data_handler()
556
-    {
557
-        $event_ids = [];
558
-        foreach ($this->_current_data_handler->events as $event) {
559
-            $event_ids[ $event['ID'] ] = $event['ID'];
560
-        }
561
-        return $event_ids;
562
-    }
563
-
564
-
565
-    /**
566
-     *  Retrieves formatted array of template information for each context specific to the given
567
-     *  EE_Message_Template_Group
568
-     *
569
-     * @param EE_Message_Template_Group $message_template_group
570
-     * @return array The returned array is in this structure:
571
-     *                          array(
572
-     *                          'field_name' => array(
573
-     *                          'context' => 'content'
574
-     *                          )
575
-     *                          )
576
-     * @throws EE_Error
577
-     * @throws InvalidArgumentException
578
-     * @throws InvalidDataTypeException
579
-     * @throws InvalidInterfaceException
580
-     * @throws ReflectionException
581
-     */
582
-    protected function _get_templates(EE_Message_Template_Group $message_template_group)
583
-    {
584
-        $templates         = [];
585
-        $context_templates = $message_template_group->context_templates();
586
-        foreach ($context_templates as $context => $template_fields) {
587
-            foreach ($template_fields as $template_field => $template_obj) {
588
-                if (! $template_obj instanceof EE_Message_Template) {
589
-                    continue;
590
-                }
591
-                $templates[ $template_field ][ $context ] = $template_obj->get('MTP_content');
592
-            }
593
-        }
594
-        return $templates;
595
-    }
596
-
597
-
598
-    /**
599
-     * Assembles new fully generated EE_Message objects and adds to _ready_queue
600
-     *
601
-     * @param array                     $addressees  Array of EE_Messages_Addressee objects indexed by message type
602
-     *                                               context.
603
-     * @param array                     $templates   formatted array of templates used for parsing data.
604
-     * @param EE_Message_Template_Group $message_template_group
605
-     * @return bool true if message generation went a-ok.  false if some sort of exception occurred.  Note: The
606
-     *                                               method will attempt to generate ALL EE_Message objects and add to
607
-     *                                               the _ready_queue.  Successfully generated messages get added to the
608
-     *                                               queue with EEM_Message::status_idle, unsuccessfully generated
609
-     *                                               messages will get added to the queue as EEM_Message::status_failed.
610
-     *                                               Very rarely should "false" be returned from this method.
611
-     * @throws EE_Error
612
-     * @throws InvalidArgumentException
613
-     * @throws InvalidDataTypeException
614
-     * @throws InvalidIdentifierException
615
-     * @throws InvalidInterfaceException
616
-     * @throws ReflectionException
617
-     */
618
-    protected function _assemble_messages($addressees, $templates, EE_Message_Template_Group $message_template_group)
619
-    {
620
-
621
-        // if templates are empty then get out because we can't generate anything.
622
-        if (! $templates) {
623
-            $this->_error_msg[] = esc_html__(
624
-                'Unable to assemble messages because there are no templates retrieved for generating the messages with',
625
-                'event_espresso'
626
-            );
627
-            return false;
628
-        }
629
-
630
-        // We use this as the counter for generated messages because don't forget we may be executing this inside of a
631
-        // generation_queue.  So _ready_queue may have generated EE_Message objects already.
632
-        $generated_count = 0;
633
-        foreach ($addressees as $context => $recipients) {
634
-            foreach ($recipients as $recipient) {
635
-                $message = $this->_setup_message_object($context, $recipient, $templates, $message_template_group);
636
-                if ($message instanceof EE_Message) {
637
-                    $this->_ready_queue->add(
638
-                        $message,
639
-                        [],
640
-                        $this->_generation_queue->get_message_repository()->is_preview(),
641
-                        $this->_generation_queue->get_message_repository()->is_test_send()
642
-                    );
643
-                    $generated_count++;
644
-                }
645
-
646
-                // if the current MSG being generated is for a test send then we'll only use ONE message in the
647
-                // generation.
648
-                if ($this->_generation_queue->get_message_repository()->is_test_send()) {
649
-                    break 2;
650
-                }
651
-            }
652
-        }
653
-
654
-        // if there are no generated messages then something else fatal went wrong.
655
-        return $generated_count > 0;
656
-    }
657
-
658
-
659
-    /**
660
-     * @param string                    $context   The context for the generated message.
661
-     * @param EE_Messages_Addressee     $recipient
662
-     * @param array                     $templates formatted array of templates used for parsing data.
663
-     * @param EE_Message_Template_Group $message_template_group
664
-     * @return bool|EE_Message
665
-     * @throws EE_Error
666
-     * @throws InvalidArgumentException
667
-     * @throws InvalidDataTypeException
668
-     * @throws InvalidInterfaceException
669
-     * @throws ReflectionException
670
-     * @throws InvalidIdentifierException
671
-     */
672
-    protected function _setup_message_object(
673
-        $context,
674
-        EE_Messages_Addressee $recipient,
675
-        $templates,
676
-        EE_Message_Template_Group $message_template_group
677
-    ) {
678
-        // stuff we already know
679
-        $transaction_id = $recipient->txn instanceof EE_Transaction ? $recipient->txn->ID() : 0;
680
-        $transaction_id = empty($transaction_id) && $this->_current_data_handler->txn instanceof EE_Transaction
681
-            ? $this->_current_data_handler->txn->ID()
682
-            : $transaction_id;
683
-        $message_fields = [
684
-            'GRP_ID'           => $message_template_group->ID(),
685
-            'TXN_ID'           => $transaction_id,
686
-            'MSG_messenger'    => $this->_current_messenger->name,
687
-            'MSG_message_type' => $this->_current_message_type->name,
688
-            'MSG_context'      => $context,
689
-        ];
690
-
691
-        // recipient id and type should be on the EE_Messages_Addressee object but if this is empty, let's try to grab
692
-        // the info from the att_obj found in the EE_Messages_Addressee object.
693
-        if (empty($recipient->recipient_id) || empty($recipient->recipient_type)) {
694
-            $message_fields['MSG_recipient_ID']   = $recipient->att_obj instanceof EE_Attendee
695
-                ? $recipient->att_obj->ID()
696
-                : 0;
697
-            $message_fields['MSG_recipient_type'] = 'Attendee';
698
-        } else {
699
-            $message_fields['MSG_recipient_ID']   = $recipient->recipient_id;
700
-            $message_fields['MSG_recipient_type'] = $recipient->recipient_type;
701
-        }
702
-        $message = EE_Message_Factory::create($message_fields);
703
-
704
-        // grab valid shortcodes for shortcode parser
705
-        $mt_shortcodes = $this->_current_message_type->get_valid_shortcodes();
706
-        $m_shortcodes  = $this->_current_messenger->get_valid_shortcodes();
707
-
708
-        // if the 'to' field is empty or the context is inactive we skip EXCEPT if we're previewing
709
-        if (
710
-            ! $this->_generation_queue->get_message_repository()->is_preview()
711
-            && (
712
-                (empty($templates['to'][ $context ]) && ! $this->_current_messenger->allow_empty_to_field())
713
-                || ! $message_template_group->is_context_active($context)
714
-            )
715
-        ) {
716
-            // we silently exit here and do NOT record a fail because the message is "turned off" by having no "to"
717
-            // field.
718
-            return false;
719
-        }
720
-        $error_msg = [];
721
-        foreach ($templates as $field => $field_context) {
722
-            $error_msg = [];
723
-            // let's setup the valid shortcodes for the incoming context.
724
-            $valid_shortcodes = $mt_shortcodes[ $context ];
725
-            // merge in valid shortcodes for the field.
726
-            $shortcodes = isset($m_shortcodes[ $field ]) ? $m_shortcodes[ $field ] : $valid_shortcodes;
727
-            if (isset($field_context[ $context ])) {
728
-                // prefix field.
729
-                $column_name = 'MSG_' . $field;
730
-                try {
731
-                    $content = $this->_shortcode_parser->parse_message_template(
732
-                        $field_context[ $context ],
733
-                        $recipient,
734
-                        $shortcodes,
735
-                        $this->_current_message_type,
736
-                        $this->_current_messenger,
737
-                        $message
738
-                    );
739
-                    // the model field removes slashes when setting (usually necessary when the input is from the
740
-                    // request) but this value is from another model and has no slashes. So add them so it matches
741
-                    // what the field expected (otherwise slashes will have been stripped from this an extra time)
742
-                    $message->set_field_or_extra_meta($column_name, addslashes($content));
743
-                } catch (EE_Error $e) {
744
-                    $error_msg[] = sprintf(
745
-                    /* Translators: First place holder is message model field name.
18
+	/**
19
+	 * @type EE_Messages_Data_Handler_Collection
20
+	 */
21
+	protected $_data_handler_collection;
22
+
23
+	/**
24
+	 * @type  EE_Message_Template_Group_Collection
25
+	 */
26
+	protected $_template_collection;
27
+
28
+	/**
29
+	 * This will hold the data handler for the current EE_Message being generated.
30
+	 *
31
+	 * @type EE_Messages_incoming_data
32
+	 */
33
+	protected $_current_data_handler;
34
+
35
+	/**
36
+	 * This holds the EE_Messages_Queue that contains the messages to generate.
37
+	 *
38
+	 * @type EE_Messages_Queue
39
+	 */
40
+	protected $_generation_queue;
41
+
42
+	/**
43
+	 * This holds the EE_Messages_Queue that will store the generated EE_Message objects.
44
+	 *
45
+	 * @type EE_Messages_Queue
46
+	 */
47
+	protected $_ready_queue;
48
+
49
+	/**
50
+	 * This is a container for any error messages that get created through the generation
51
+	 * process.
52
+	 *
53
+	 * @type array
54
+	 */
55
+	protected $_error_msg = [];
56
+
57
+	/**
58
+	 * Flag used to set when the current EE_Message in the generation queue has been verified.
59
+	 *
60
+	 * @type bool
61
+	 */
62
+	protected $_verified = false;
63
+
64
+	/**
65
+	 * This will hold the current messenger object corresponding with the current EE_Message in the generation queue.
66
+	 *
67
+	 * @type EE_messenger
68
+	 */
69
+	protected $_current_messenger;
70
+
71
+	/**
72
+	 * This will hold the current message type object corresponding with the current EE_Message in the generation queue.
73
+	 *
74
+	 * @type EE_message_type
75
+	 */
76
+	protected $_current_message_type;
77
+
78
+	/**
79
+	 * @type EEH_Parse_Shortcodes
80
+	 */
81
+	protected $_shortcode_parser;
82
+
83
+
84
+	/**
85
+	 * @param EE_Messages_Queue                    $generation_queue
86
+	 * @param EE_Messages_Queue                    $ready_queue
87
+	 * @param EE_Messages_Data_Handler_Collection  $data_handler_collection
88
+	 * @param EE_Message_Template_Group_Collection $template_collection
89
+	 * @param EEH_Parse_Shortcodes                 $shortcode_parser
90
+	 */
91
+	public function __construct(
92
+		EE_Messages_Queue $generation_queue,
93
+		EE_Messages_Queue $ready_queue,
94
+		EE_Messages_Data_Handler_Collection $data_handler_collection,
95
+		EE_Message_Template_Group_Collection $template_collection,
96
+		EEH_Parse_Shortcodes $shortcode_parser
97
+	) {
98
+		$this->_generation_queue        = $generation_queue;
99
+		$this->_ready_queue             = $ready_queue;
100
+		$this->_data_handler_collection = $data_handler_collection;
101
+		$this->_template_collection     = $template_collection;
102
+		$this->_shortcode_parser        = $shortcode_parser;
103
+	}
104
+
105
+
106
+	/**
107
+	 * @return EE_Messages_Queue
108
+	 */
109
+	public function generation_queue()
110
+	{
111
+		return $this->_generation_queue;
112
+	}
113
+
114
+
115
+	/**
116
+	 *  This iterates through the provided queue and generates the EE_Message objects.
117
+	 *  When iterating through the queue, the queued item that served as the base for generating other EE_Message
118
+	 *  objects gets removed and the new EE_Message objects get added to a NEW queue.  The NEW queue is then returned
119
+	 *  for the caller to decide what to do with it.
120
+	 *
121
+	 * @param bool $save Whether to save the EE_Message objects in the new queue or just return.
122
+	 * @return EE_Messages_Queue The new queue for holding generated EE_Message objects.
123
+	 * @throws EE_Error
124
+	 * @throws InvalidArgumentException
125
+	 * @throws InvalidDataTypeException
126
+	 * @throws InvalidInterfaceException
127
+	 * @throws ReflectionException
128
+	 */
129
+	public function generate($save = true)
130
+	{
131
+		// iterate through the messages in the queue, generate, and add to new queue.
132
+		$this->_generation_queue->get_message_repository()->rewind();
133
+
134
+		while ($this->_generation_queue->get_message_repository()->valid()) {
135
+			// reset "current" properties
136
+			$this->_reset_current_properties();
137
+
138
+			$msg = $this->_generation_queue->get_message_repository()->current();
139
+
140
+			/**
141
+			 * need to get the next object and capture it for setting manually after deletes.  The reason is that when
142
+			 * an object is removed from the repo then valid for the next object will fail.
143
+			 */
144
+			$this->_generation_queue->get_message_repository()->next();
145
+			$next_msg = $this->_generation_queue->get_message_repository()->valid()
146
+				? $this->_generation_queue->get_message_repository()->current()
147
+				:  null;
148
+			// restore pointer to current item
149
+			$this->_generation_queue->get_message_repository()->set_current($msg);
150
+
151
+			// skip and delete if the current $msg is NOT incomplete (queued for generation)
152
+			if ($msg->STS_ID() !== EEM_Message::status_incomplete) {
153
+				// we keep this item in the db just remove from the repo.
154
+				$this->_generation_queue->get_message_repository()->remove($msg);
155
+				// next item
156
+				$this->_generation_queue->get_message_repository()->set_current($next_msg);
157
+				continue;
158
+			}
159
+
160
+			if ($this->_verify()) {
161
+				// let's get generating!
162
+				$this->_generate();
163
+			}
164
+
165
+			// don't persist debug_only messages if the messages system is not in debug mode.
166
+			if (
167
+				$msg->STS_ID() === EEM_Message::status_debug_only
168
+				&& ! EEM_Message::debug()
169
+			) {
170
+				do_action(
171
+					'AHEE__EE_Messages_Generator__generate__before_debug_delete',
172
+					$msg,
173
+					$this->_error_msg,
174
+					$this->_current_messenger,
175
+					$this->_current_message_type,
176
+					$this->_current_data_handler
177
+				);
178
+				$this->_generation_queue->get_message_repository()->delete();
179
+				$this->_generation_queue->get_message_repository()->set_current($next_msg);
180
+				continue;
181
+			}
182
+
183
+			// if there are error messages then let's set the status and the error message.
184
+			if ($this->_error_msg) {
185
+				// if the status is already debug only, then let's leave it at that.
186
+				if ($msg->STS_ID() !== EEM_Message::status_debug_only) {
187
+					$msg->set_STS_ID(EEM_Message::status_failed);
188
+				}
189
+				do_action(
190
+					'AHEE__EE_Messages_Generator__generate__processing_failed_message',
191
+					$msg,
192
+					$this->_error_msg,
193
+					$this->_current_messenger,
194
+					$this->_current_message_type,
195
+					$this->_current_data_handler
196
+				);
197
+				$msg->set_error_message(
198
+					esc_html__('Message failed to generate for the following reasons: ', 'event_espresso')
199
+					. "\n"
200
+					. implode("\n", $this->_error_msg)
201
+				);
202
+				$msg->set_modified(time());
203
+			} else {
204
+				do_action(
205
+					'AHEE__EE_Messages_Generator__generate__before_successful_generated_message_delete',
206
+					$msg,
207
+					$this->_error_msg,
208
+					$this->_current_messenger,
209
+					$this->_current_message_type,
210
+					$this->_current_data_handler
211
+				);
212
+				// remove from db
213
+				$this->_generation_queue->get_message_repository()->delete();
214
+			}
215
+			// next item
216
+			$this->_generation_queue->get_message_repository()->set_current($next_msg);
217
+		}
218
+
219
+		// generation queue is ALWAYS saved to record any errors in the generation process.
220
+		$this->_generation_queue->save();
221
+
222
+		/**
223
+		 * save _ready_queue if flag set.
224
+		 * Note: The EE_Message objects have values set via the EE_Base_Class::set_field_or_extra_meta() method.  This
225
+		 * means if a field was added that is not a valid database column.  The EE_Message was already saved to the db
226
+		 * so a EE_Extra_Meta entry could be created and attached to the EE_Message.  In those cases the save flag is
227
+		 * irrelevant.
228
+		 */
229
+		if ($save) {
230
+			$this->_ready_queue->save();
231
+		}
232
+
233
+		// final reset of properties
234
+		$this->_reset_current_properties();
235
+
236
+		return $this->_ready_queue;
237
+	}
238
+
239
+
240
+	/**
241
+	 * This resets all the properties used for holding "current" values corresponding to the current EE_Message object
242
+	 * in the generation queue.
243
+	 */
244
+	protected function _reset_current_properties()
245
+	{
246
+		$this->_verified = false;
247
+		// make sure any _data value in the current message type is reset
248
+		if ($this->_current_message_type instanceof EE_message_type) {
249
+			$this->_current_message_type->reset_data();
250
+		}
251
+		$this->_current_messenger = $this->_current_message_type = $this->_current_data_handler = null;
252
+	}
253
+
254
+
255
+	/**
256
+	 * This proceeds with the actual generation of a message.  By the time this is called, there should already be a
257
+	 * $_current_data_handler set and all incoming information should be validated for the current EE_Message in the
258
+	 * _generating_queue.
259
+	 *
260
+	 * @return bool Whether the message was successfully generated or not.
261
+	 * @throws EE_Error
262
+	 * @throws InvalidArgumentException
263
+	 * @throws InvalidDataTypeException
264
+	 * @throws InvalidInterfaceException
265
+	 * @throws ReflectionException
266
+	 */
267
+	protected function _generate()
268
+	{
269
+		// double check verification has run and that everything is ready to work with (saves us having to validate
270
+		// everything again).
271
+		if (! $this->_verified) {
272
+			return false; // get out because we don't have a valid setup to work with.
273
+		}
274
+
275
+
276
+		try {
277
+			$addressees = $this->_current_message_type->get_addressees(
278
+				$this->_current_data_handler,
279
+				$this->_generation_queue->get_message_repository()->current()->context()
280
+			);
281
+		} catch (EE_Error $e) {
282
+			$this->_error_msg[] = $e->getMessage();
283
+			return false;
284
+		}
285
+
286
+
287
+		// if no addressees then get out because there is nothing to generation (possible bad data).
288
+		if (! $this->_valid_addressees($addressees)) {
289
+			do_action(
290
+				'AHEE__EE_Messages_Generator___generate__invalid_addressees',
291
+				$this->_generation_queue->get_message_repository()->current(),
292
+				$addressees,
293
+				$this->_current_messenger,
294
+				$this->_current_message_type,
295
+				$this->_current_data_handler
296
+			);
297
+			$this->_generation_queue->get_message_repository()->current()->set_STS_ID(
298
+				EEM_Message::status_debug_only
299
+			);
300
+			$this->_error_msg[] = esc_html__(
301
+				'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. Sometimes this is because messages only get generated for certain registration statuses. For example, the ticket notice message type only goes to approved registrations.',
302
+				'event_espresso'
303
+			);
304
+			return false;
305
+		}
306
+
307
+		$message_template_group = $this->_get_message_template_group();
308
+
309
+		// in the unlikely event there is no EE_Message_Template_Group available, get out!
310
+		if (! $message_template_group instanceof EE_Message_Template_Group) {
311
+			$this->_error_msg[] = esc_html__(
312
+				'Unable to get the Message Templates for the Message being generated.  No message template group accessible.',
313
+				'event_espresso'
314
+			);
315
+			return false;
316
+		}
317
+
318
+		// get formatted templates for using to parse and setup EE_Message objects.
319
+		$templates = $this->_get_templates($message_template_group);
320
+
321
+
322
+		// setup new EE_Message objects (and add to _ready_queue)
323
+		return $this->_assemble_messages($addressees, $templates, $message_template_group);
324
+	}
325
+
326
+
327
+	/**
328
+	 * Retrieves the message template group being used for generating messages.
329
+	 * Note: this also utilizes the EE_Message_Template_Group_Collection to avoid having to hit the db multiple times.
330
+	 *
331
+	 * @return EE_Message_Template_Group|null
332
+	 * @throws EE_Error
333
+	 * @throws InvalidArgumentException
334
+	 * @throws InvalidDataTypeException
335
+	 * @throws InvalidInterfaceException
336
+	 * @throws ReflectionException
337
+	 */
338
+	protected function _get_message_template_group()
339
+	{
340
+		// first see if there is a specific message template group requested
341
+		// (current message in the queue has a specific GRP_ID)
342
+		$message_template_group = $this->_specific_message_template_group_from_queue();
343
+		if ($message_template_group instanceof EE_Message_Template_Group) {
344
+			return $message_template_group;
345
+		}
346
+
347
+		// get event_ids from the data handler so we can check to see
348
+		// if there's already a message template group for them in the collection.
349
+		$event_ids              = $this->_get_event_ids_from_current_data_handler();
350
+		$message_template_group = $this->_template_collection->get_by_key(
351
+			$this->_template_collection->getKey(
352
+				$this->_current_messenger->name,
353
+				$this->_current_message_type->name,
354
+				$event_ids
355
+			)
356
+		);
357
+
358
+		// if we have a message template group then no need to hit the database, just return it.
359
+		if ($message_template_group instanceof EE_Message_Template_Group) {
360
+			return $message_template_group;
361
+		}
362
+
363
+		// get the global group first for this messenger and message type
364
+		// to ensure there is no override set.
365
+		$global_message_template_group =
366
+			$this->_get_global_message_template_group_for_current_messenger_and_message_type();
367
+
368
+		if (
369
+			$global_message_template_group instanceof EE_Message_Template_Group
370
+			&& $global_message_template_group->get('MTP_is_override')
371
+		) {
372
+			return $global_message_template_group;
373
+		}
374
+
375
+		// if we're still here, that means there was no message template group for the events in the collection and
376
+		// the global message template group for the messenger and message type is not set for override.  So next step
377
+		// is to see if there is a common shared custom message template group for this set of events.
378
+		$message_template_group = $this->_get_shared_message_template_for_events($event_ids);
379
+		if ($message_template_group instanceof EE_Message_Template_Group) {
380
+			return $message_template_group;
381
+		}
382
+
383
+		// STILL here?  Okay that means the fallback is to just use the global message template group for this event
384
+		// set. So we'll cache the global group for this event set (so this logic doesn't have to be repeated in this
385
+		// request) and return it.
386
+		if ($global_message_template_group instanceof EE_Message_Template_Group) {
387
+			$this->_template_collection->add(
388
+				$global_message_template_group,
389
+				$event_ids
390
+			);
391
+			return $global_message_template_group;
392
+		}
393
+
394
+		// if we land here that means there's NO active message template group for this set.
395
+		// TODO this will be a good target for some optimization down the road.  Whenever there is no active message
396
+		// template group for a given event set then cache that result so we don't repeat the logic.  However, for now,
397
+		// this should likely bit hit rarely enough that it's not a significant issue.
398
+		return null;
399
+	}
400
+
401
+
402
+	/**
403
+	 * This checks the current message in the queue and determines if there is a specific Message Template Group
404
+	 * requested for that message.
405
+	 *
406
+	 * @return EE_Message_Template_Group|null
407
+	 * @throws EE_Error
408
+	 * @throws InvalidArgumentException
409
+	 * @throws InvalidDataTypeException
410
+	 * @throws InvalidInterfaceException
411
+	 */
412
+	protected function _specific_message_template_group_from_queue()
413
+	{
414
+		// is there a GRP_ID already on the EE_Message object?  If there is, then a specific template has been requested
415
+		// so let's use that.
416
+		$GRP_ID = $this->_generation_queue->get_message_repository()->current()->GRP_ID();
417
+
418
+		if ($GRP_ID) {
419
+			// attempt to retrieve from repo first
420
+			$message_template_group = $this->_template_collection->get_by_ID($GRP_ID);
421
+			if ($message_template_group instanceof EE_Message_Template_Group) {
422
+				return $message_template_group;  // got it!
423
+			}
424
+
425
+			// nope don't have it yet.  Get from DB then add to repo if its not here, then that means the current GRP_ID
426
+			// is not valid, so we'll continue on in the code assuming there's NO GRP_ID.
427
+			$message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
428
+			if ($message_template_group instanceof EE_Message_Template_Group) {
429
+				$this->_template_collection->add($message_template_group);
430
+				return $message_template_group;
431
+			}
432
+		}
433
+		return null;
434
+	}
435
+
436
+
437
+	/**
438
+	 * Returns whether the event ids passed in all share the same message template group for the current message type
439
+	 * and messenger.
440
+	 *
441
+	 * @param array $event_ids
442
+	 * @return bool true means they DO share the same message template group, false means they don't.
443
+	 * @throws EE_Error
444
+	 * @throws InvalidArgumentException
445
+	 * @throws InvalidDataTypeException
446
+	 * @throws InvalidInterfaceException
447
+	 */
448
+	protected function _queue_shares_same_message_template_group_for_events(array $event_ids)
449
+	{
450
+		foreach ($this->_current_data_handler->events as $event) {
451
+			$event_ids[ $event['ID'] ] = $event['ID'];
452
+		}
453
+		$count_of_message_template_groups = EEM_Message_Template_Group::instance()->count(
454
+			[
455
+				[
456
+					'Event.EVT_ID'     => ['IN', $event_ids],
457
+					'MTP_messenger'    => $this->_current_messenger->name,
458
+					'MTP_message_type' => $this->_current_message_type->name,
459
+				],
460
+			],
461
+			'GRP_ID',
462
+			true
463
+		);
464
+		return $count_of_message_template_groups === 1;
465
+	}
466
+
467
+
468
+	/**
469
+	 * This will get the shared message template group for events that are in the current data handler but ONLY if
470
+	 * there's a single shared message template group among all the events.  Otherwise it returns null.
471
+	 *
472
+	 * @param array $event_ids
473
+	 * @return EE_Message_Template_Group|null
474
+	 * @throws EE_Error
475
+	 * @throws InvalidArgumentException
476
+	 * @throws InvalidDataTypeException
477
+	 * @throws InvalidInterfaceException
478
+	 */
479
+	protected function _get_shared_message_template_for_events(array $event_ids)
480
+	{
481
+		$message_template_group = null;
482
+		if ($this->_queue_shares_same_message_template_group_for_events($event_ids)) {
483
+			$message_template_group = EEM_Message_Template_Group::instance()->get_one(
484
+				[
485
+					[
486
+						'Event.EVT_ID'     => ['IN', $event_ids],
487
+						'MTP_messenger'    => $this->_current_messenger->name,
488
+						'MTP_message_type' => $this->_current_message_type->name,
489
+						'MTP_is_active'    => true,
490
+					],
491
+					'group_by' => 'GRP_ID',
492
+				]
493
+			);
494
+			// store this in the collection if its valid
495
+			if ($message_template_group instanceof EE_Message_Template_Group) {
496
+				$this->_template_collection->add(
497
+					$message_template_group,
498
+					$event_ids
499
+				);
500
+			}
501
+		}
502
+		return $message_template_group;
503
+	}
504
+
505
+
506
+	/**
507
+	 * Retrieves the global message template group for the current messenger and message type.
508
+	 *
509
+	 * @return EE_Message_Template_Group|null
510
+	 * @throws EE_Error
511
+	 * @throws InvalidArgumentException
512
+	 * @throws InvalidDataTypeException
513
+	 * @throws InvalidInterfaceException
514
+	 */
515
+	protected function _get_global_message_template_group_for_current_messenger_and_message_type()
516
+	{
517
+		// first check the collection (we use an array with 0 in it to represent global groups).
518
+		$global_message_template_group = $this->_template_collection->get_by_key(
519
+			$this->_template_collection->getKey(
520
+				$this->_current_messenger->name,
521
+				$this->_current_message_type->name,
522
+				[0]
523
+			)
524
+		);
525
+
526
+		// if we don't have a group lets hit the db.
527
+		if (! $global_message_template_group instanceof EE_Message_Template_Group) {
528
+			$global_message_template_group = EEM_Message_Template_Group::instance()->get_one(
529
+				[
530
+					[
531
+						'MTP_messenger'    => $this->_current_messenger->name,
532
+						'MTP_message_type' => $this->_current_message_type->name,
533
+						'MTP_is_active'    => true,
534
+						'MTP_is_global'    => true,
535
+					],
536
+				]
537
+			);
538
+			// if we have a group, add it to the collection.
539
+			if ($global_message_template_group instanceof EE_Message_Template_Group) {
540
+				$this->_template_collection->add(
541
+					$global_message_template_group,
542
+					[0]
543
+				);
544
+			}
545
+		}
546
+		return $global_message_template_group;
547
+	}
548
+
549
+
550
+	/**
551
+	 * Returns an array of event ids for all the events within the current data handler.
552
+	 *
553
+	 * @return array
554
+	 */
555
+	protected function _get_event_ids_from_current_data_handler()
556
+	{
557
+		$event_ids = [];
558
+		foreach ($this->_current_data_handler->events as $event) {
559
+			$event_ids[ $event['ID'] ] = $event['ID'];
560
+		}
561
+		return $event_ids;
562
+	}
563
+
564
+
565
+	/**
566
+	 *  Retrieves formatted array of template information for each context specific to the given
567
+	 *  EE_Message_Template_Group
568
+	 *
569
+	 * @param EE_Message_Template_Group $message_template_group
570
+	 * @return array The returned array is in this structure:
571
+	 *                          array(
572
+	 *                          'field_name' => array(
573
+	 *                          'context' => 'content'
574
+	 *                          )
575
+	 *                          )
576
+	 * @throws EE_Error
577
+	 * @throws InvalidArgumentException
578
+	 * @throws InvalidDataTypeException
579
+	 * @throws InvalidInterfaceException
580
+	 * @throws ReflectionException
581
+	 */
582
+	protected function _get_templates(EE_Message_Template_Group $message_template_group)
583
+	{
584
+		$templates         = [];
585
+		$context_templates = $message_template_group->context_templates();
586
+		foreach ($context_templates as $context => $template_fields) {
587
+			foreach ($template_fields as $template_field => $template_obj) {
588
+				if (! $template_obj instanceof EE_Message_Template) {
589
+					continue;
590
+				}
591
+				$templates[ $template_field ][ $context ] = $template_obj->get('MTP_content');
592
+			}
593
+		}
594
+		return $templates;
595
+	}
596
+
597
+
598
+	/**
599
+	 * Assembles new fully generated EE_Message objects and adds to _ready_queue
600
+	 *
601
+	 * @param array                     $addressees  Array of EE_Messages_Addressee objects indexed by message type
602
+	 *                                               context.
603
+	 * @param array                     $templates   formatted array of templates used for parsing data.
604
+	 * @param EE_Message_Template_Group $message_template_group
605
+	 * @return bool true if message generation went a-ok.  false if some sort of exception occurred.  Note: The
606
+	 *                                               method will attempt to generate ALL EE_Message objects and add to
607
+	 *                                               the _ready_queue.  Successfully generated messages get added to the
608
+	 *                                               queue with EEM_Message::status_idle, unsuccessfully generated
609
+	 *                                               messages will get added to the queue as EEM_Message::status_failed.
610
+	 *                                               Very rarely should "false" be returned from this method.
611
+	 * @throws EE_Error
612
+	 * @throws InvalidArgumentException
613
+	 * @throws InvalidDataTypeException
614
+	 * @throws InvalidIdentifierException
615
+	 * @throws InvalidInterfaceException
616
+	 * @throws ReflectionException
617
+	 */
618
+	protected function _assemble_messages($addressees, $templates, EE_Message_Template_Group $message_template_group)
619
+	{
620
+
621
+		// if templates are empty then get out because we can't generate anything.
622
+		if (! $templates) {
623
+			$this->_error_msg[] = esc_html__(
624
+				'Unable to assemble messages because there are no templates retrieved for generating the messages with',
625
+				'event_espresso'
626
+			);
627
+			return false;
628
+		}
629
+
630
+		// We use this as the counter for generated messages because don't forget we may be executing this inside of a
631
+		// generation_queue.  So _ready_queue may have generated EE_Message objects already.
632
+		$generated_count = 0;
633
+		foreach ($addressees as $context => $recipients) {
634
+			foreach ($recipients as $recipient) {
635
+				$message = $this->_setup_message_object($context, $recipient, $templates, $message_template_group);
636
+				if ($message instanceof EE_Message) {
637
+					$this->_ready_queue->add(
638
+						$message,
639
+						[],
640
+						$this->_generation_queue->get_message_repository()->is_preview(),
641
+						$this->_generation_queue->get_message_repository()->is_test_send()
642
+					);
643
+					$generated_count++;
644
+				}
645
+
646
+				// if the current MSG being generated is for a test send then we'll only use ONE message in the
647
+				// generation.
648
+				if ($this->_generation_queue->get_message_repository()->is_test_send()) {
649
+					break 2;
650
+				}
651
+			}
652
+		}
653
+
654
+		// if there are no generated messages then something else fatal went wrong.
655
+		return $generated_count > 0;
656
+	}
657
+
658
+
659
+	/**
660
+	 * @param string                    $context   The context for the generated message.
661
+	 * @param EE_Messages_Addressee     $recipient
662
+	 * @param array                     $templates formatted array of templates used for parsing data.
663
+	 * @param EE_Message_Template_Group $message_template_group
664
+	 * @return bool|EE_Message
665
+	 * @throws EE_Error
666
+	 * @throws InvalidArgumentException
667
+	 * @throws InvalidDataTypeException
668
+	 * @throws InvalidInterfaceException
669
+	 * @throws ReflectionException
670
+	 * @throws InvalidIdentifierException
671
+	 */
672
+	protected function _setup_message_object(
673
+		$context,
674
+		EE_Messages_Addressee $recipient,
675
+		$templates,
676
+		EE_Message_Template_Group $message_template_group
677
+	) {
678
+		// stuff we already know
679
+		$transaction_id = $recipient->txn instanceof EE_Transaction ? $recipient->txn->ID() : 0;
680
+		$transaction_id = empty($transaction_id) && $this->_current_data_handler->txn instanceof EE_Transaction
681
+			? $this->_current_data_handler->txn->ID()
682
+			: $transaction_id;
683
+		$message_fields = [
684
+			'GRP_ID'           => $message_template_group->ID(),
685
+			'TXN_ID'           => $transaction_id,
686
+			'MSG_messenger'    => $this->_current_messenger->name,
687
+			'MSG_message_type' => $this->_current_message_type->name,
688
+			'MSG_context'      => $context,
689
+		];
690
+
691
+		// recipient id and type should be on the EE_Messages_Addressee object but if this is empty, let's try to grab
692
+		// the info from the att_obj found in the EE_Messages_Addressee object.
693
+		if (empty($recipient->recipient_id) || empty($recipient->recipient_type)) {
694
+			$message_fields['MSG_recipient_ID']   = $recipient->att_obj instanceof EE_Attendee
695
+				? $recipient->att_obj->ID()
696
+				: 0;
697
+			$message_fields['MSG_recipient_type'] = 'Attendee';
698
+		} else {
699
+			$message_fields['MSG_recipient_ID']   = $recipient->recipient_id;
700
+			$message_fields['MSG_recipient_type'] = $recipient->recipient_type;
701
+		}
702
+		$message = EE_Message_Factory::create($message_fields);
703
+
704
+		// grab valid shortcodes for shortcode parser
705
+		$mt_shortcodes = $this->_current_message_type->get_valid_shortcodes();
706
+		$m_shortcodes  = $this->_current_messenger->get_valid_shortcodes();
707
+
708
+		// if the 'to' field is empty or the context is inactive we skip EXCEPT if we're previewing
709
+		if (
710
+			! $this->_generation_queue->get_message_repository()->is_preview()
711
+			&& (
712
+				(empty($templates['to'][ $context ]) && ! $this->_current_messenger->allow_empty_to_field())
713
+				|| ! $message_template_group->is_context_active($context)
714
+			)
715
+		) {
716
+			// we silently exit here and do NOT record a fail because the message is "turned off" by having no "to"
717
+			// field.
718
+			return false;
719
+		}
720
+		$error_msg = [];
721
+		foreach ($templates as $field => $field_context) {
722
+			$error_msg = [];
723
+			// let's setup the valid shortcodes for the incoming context.
724
+			$valid_shortcodes = $mt_shortcodes[ $context ];
725
+			// merge in valid shortcodes for the field.
726
+			$shortcodes = isset($m_shortcodes[ $field ]) ? $m_shortcodes[ $field ] : $valid_shortcodes;
727
+			if (isset($field_context[ $context ])) {
728
+				// prefix field.
729
+				$column_name = 'MSG_' . $field;
730
+				try {
731
+					$content = $this->_shortcode_parser->parse_message_template(
732
+						$field_context[ $context ],
733
+						$recipient,
734
+						$shortcodes,
735
+						$this->_current_message_type,
736
+						$this->_current_messenger,
737
+						$message
738
+					);
739
+					// the model field removes slashes when setting (usually necessary when the input is from the
740
+					// request) but this value is from another model and has no slashes. So add them so it matches
741
+					// what the field expected (otherwise slashes will have been stripped from this an extra time)
742
+					$message->set_field_or_extra_meta($column_name, addslashes($content));
743
+				} catch (EE_Error $e) {
744
+					$error_msg[] = sprintf(
745
+					/* Translators: First place holder is message model field name.
746 746
                      * Second placeholder is exception error message */
747
-                        esc_html__(
748
-                            'There was a problem generating the content for the field %s: %s',
749
-                            'event_espresso'
750
-                        ),
751
-                        $field,
752
-                        $e->getMessage()
753
-                    );
754
-                    $message->set_STS_ID(EEM_Message::status_failed);
755
-                }
756
-            }
757
-        }
758
-
759
-        if ($message->STS_ID() === EEM_Message::status_failed) {
760
-            $error_msg = esc_html__('There were problems generating this message:', 'event_espresso')
761
-                         . "\n"
762
-                         . implode("\n", $error_msg);
763
-            $message->set_error_message($error_msg);
764
-        } else {
765
-            $message->set_STS_ID(EEM_Message::status_idle);
766
-        }
767
-        return $message;
768
-    }
769
-
770
-
771
-    /**
772
-     * This verifies that the incoming array has a EE_messenger object and a EE_message_type object and sets appropriate
773
-     * error message if either is missing.
774
-     *
775
-     * @return bool true means there were no errors, false means there were errors.
776
-     */
777
-    protected function _verify()
778
-    {
779
-        // reset error message to an empty array.
780
-        $this->_error_msg = [];
781
-        // set the verified flag so we know everything has been validated.
782
-        $this->_verified = $this->_validate_messenger_and_message_type() && $this->_validate_and_setup_data();
783
-        return $this->_verified;
784
-    }
785
-
786
-
787
-    /**
788
-     * This accepts an array and validates that it is an array indexed by context with each value being an array of
789
-     * EE_Messages_Addressee objects.
790
-     *
791
-     * @param array $addressees Keys correspond to contexts for the message type and values are EE_Messages_Addressee[]
792
-     * @return bool
793
-     */
794
-    protected function _valid_addressees($addressees)
795
-    {
796
-        if (! $addressees || ! is_array($addressees)) {
797
-            return false;
798
-        }
799
-
800
-        foreach ($addressees as $addressee_array) {
801
-            foreach ($addressee_array as $addressee) {
802
-                if (! $addressee instanceof EE_Messages_Addressee) {
803
-                    return false;
804
-                }
805
-            }
806
-        }
807
-        return true;
808
-    }
809
-
810
-
811
-    /**
812
-     * This validates the messenger, message type, and presences of generation data for the current EE_Message in the
813
-     * queue. This process sets error messages if something is wrong.
814
-     *
815
-     * @return bool   true is if there are no errors.  false is if there is.
816
-     */
817
-    protected function _validate_messenger_and_message_type()
818
-    {
819
-        // first are there any existing error messages?  If so then return.
820
-        if ($this->_error_msg) {
821
-            return false;
822
-        }
823
-        $message = $this->_generation_queue->get_message_repository()->current();
824
-        try {
825
-            $this->_current_messenger = $message->valid_messenger(true)
826
-                ? $message->messenger_object()
827
-                : null;
828
-        } catch (Exception $e) {
829
-            $this->_error_msg[] = $e->getMessage();
830
-        }
831
-        try {
832
-            $this->_current_message_type = $message->valid_message_type(true)
833
-                ? $message->message_type_object()
834
-                : null;
835
-        } catch (Exception $e) {
836
-            $this->_error_msg[] = $e->getMessage();
837
-        }
838
-
839
-        /**
840
-         * Check if there is any generation data, but only if this is not for a preview.
841
-         */
842
-        if (
843
-            ! $this->_generation_queue->get_message_repository()->get_generation_data()
844
-            && (
845
-                ! $this->_generation_queue->get_message_repository()->is_preview()
846
-                && $this->_generation_queue->get_message_repository()->get_data_handler()
847
-                   !== 'EE_Messages_Preview_incoming_data'
848
-            )
849
-        ) {
850
-            $this->_error_msg[] = esc_html__(
851
-                'There is no generation data for this message. Unable to generate.',
852
-                'event_espresso'
853
-            );
854
-        }
855
-
856
-        return empty($this->_error_msg);
857
-    }
858
-
859
-
860
-    /**
861
-     * This method retrieves the expected data handler for the message type and validates the generation data for that
862
-     * data handler.
863
-     *
864
-     * @return bool true means there are no errors.  false means there were errors (and handler did not get setup).
865
-     */
866
-    protected function _validate_and_setup_data()
867
-    {
868
-
869
-        // First, are there any existing error messages?  If so, return because if there were errors elsewhere this
870
-        // can't be used anyways.
871
-        if ($this->_error_msg) {
872
-            return false;
873
-        }
874
-
875
-        $generation_data = $this->_generation_queue->get_message_repository()->get_generation_data();
876
-
877
-        /** @type EE_Messages_incoming_data $data_handler_class_name - well not really... just the class name actually */
878
-        $data_handler_class_name = $this->_generation_queue->get_message_repository()->get_data_handler()
879
-            ? $this->_generation_queue->get_message_repository()->get_data_handler()
880
-            : 'EE_Messages_' . $this->_current_message_type->get_data_handler($generation_data) . '_incoming_data';
881
-
882
-        // If this EE_Message is for a preview, then let's switch out to the preview data handler.
883
-        if ($this->_generation_queue->get_message_repository()->is_preview()) {
884
-            $data_handler_class_name = 'EE_Messages_Preview_incoming_data';
885
-        }
886
-
887
-        // First get the class name for the data handler (and also verifies it exists.
888
-        if (! class_exists($data_handler_class_name)) {
889
-            $this->_error_msg[] = sprintf(
890
-            /* Translators: Both placeholders are the names of php classes. */
891
-                esc_html__(
892
-                    'The included data handler class name does not match any valid, accessible, "%1$s" classes.  Looking for %2$s.',
893
-                    'event_espresso'
894
-                ),
895
-                'EE_Messages_incoming_data',
896
-                $data_handler_class_name
897
-            );
898
-            return false;
899
-        }
900
-
901
-        // convert generation_data for data_handler_instantiation.
902
-        $generation_data = $data_handler_class_name::convert_data_from_persistent_storage($generation_data);
903
-
904
-        // note, this may set error messages as well.
905
-        $this->_set_data_handler($generation_data, $data_handler_class_name);
906
-
907
-        return empty($this->_error_msg);
908
-    }
909
-
910
-
911
-    /**
912
-     * Sets the $_current_data_handler property that is used for generating the current EE_Message in the queue, and
913
-     * adds it to the _data repository.
914
-     *
915
-     * @param mixed  $generating_data           This is data expected by the instantiated data handler.
916
-     * @param string $data_handler_class_name   This is the reference string indicating what data handler is being
917
-     *                                          instantiated.
918
-     */
919
-    protected function _set_data_handler($generating_data, $data_handler_class_name)
920
-    {
921
-        // valid classname for the data handler.  Now let's setup the key for the data handler repository to see if
922
-        // there is already a ready data handler in the repository.
923
-        $this->_current_data_handler = $this->_data_handler_collection->get_by_key(
924
-            $this->_data_handler_collection->get_key(
925
-                $data_handler_class_name,
926
-                $generating_data
927
-            )
928
-        );
929
-        if (! $this->_current_data_handler instanceof EE_Messages_incoming_data) {
930
-            // no saved data_handler in the repo so let's set one up and add it to the repo.
931
-            try {
932
-                $this->_current_data_handler = new $data_handler_class_name($generating_data);
933
-                $this->_data_handler_collection->add($this->_current_data_handler, $generating_data);
934
-            } catch (Exception $e) {
935
-                $this->_error_msg[] = $e->getMessage();
936
-            }
937
-        }
938
-    }
939
-
940
-
941
-    /**
942
-     * The queued EE_Message for generation does not save the data used for generation as objects
943
-     * because serialization of those objects could be problematic if the data is saved to the db.
944
-     * So this method calls the static method on the associated data_handler for the given message_type
945
-     * and that preps the data for later instantiation when generating.
946
-     *
947
-     * @param EE_Message_To_Generate $message_to_generate
948
-     * @param bool                   $preview Indicate whether this is being used for a preview or not.
949
-     * @return mixed Prepped data for persisting to the queue.  false is returned if unable to prep data.
950
-     */
951
-    protected function _prepare_data_for_queue(EE_Message_To_Generate $message_to_generate, $preview)
952
-    {
953
-        if (! $message_to_generate->valid()) {
954
-            return false; // unable to get the data because the info in the EE_Message_To_Generate class is invalid.
955
-        }
956
-        /** @type EE_Messages_incoming_data $data_handler - well not really... just the class name actually */
957
-        $data_handler = $message_to_generate->get_data_handler_class_name($preview);
958
-        return $data_handler::convert_data_for_persistent_storage($message_to_generate->data());
959
-    }
960
-
961
-
962
-    /**
963
-     * This sets up a EEM_Message::status_incomplete EE_Message object and adds it to the generation queue.
964
-     *
965
-     * @param EE_Message_To_Generate $message_to_generate
966
-     * @param bool                   $test_send Whether this is just a test send or not.  Typically used for previews.
967
-     * @return bool
968
-     * @throws InvalidArgumentException
969
-     * @throws InvalidDataTypeException
970
-     * @throws InvalidInterfaceException
971
-     */
972
-    public function create_and_add_message_to_queue(EE_Message_To_Generate $message_to_generate, $test_send = false)
973
-    {
974
-        // prep data
975
-        $data    = $this->_prepare_data_for_queue($message_to_generate, $message_to_generate->preview());
976
-        $request = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\RequestInterface');
977
-
978
-        $message = $message_to_generate->get_EE_Message();
979
-        $GRP_ID  = $request->getRequestParam('GRP_ID', 0, 'int');
980
-
981
-        $GRP_ID = apply_filters(
982
-            'FHEE__EE_Messages_Generator__create_and_add_message_to_queue_GRP_ID',
983
-            $GRP_ID > 0 ? $GRP_ID : $message->GRP_ID(),
984
-            $message,
985
-            $message_to_generate,
986
-            $test_send
987
-        );
988
-
989
-        if ($GRP_ID > 0) {
990
-            $message->set_GRP_ID($GRP_ID);
991
-        }
992
-
993
-        if ($data === false) {
994
-            $message->set_STS_ID(EEM_Message::status_failed);
995
-            $message->set_error_message(
996
-                esc_html__(
997
-                    'Unable to prepare data for persistence to the database.',
998
-                    'event_espresso'
999
-                )
1000
-            );
1001
-        } else {
1002
-            // make sure that the data handler is cached on the message as well
1003
-            $data['data_handler_class_name'] = $message_to_generate->get_data_handler_class_name();
1004
-        }
1005
-
1006
-        return $this->_generation_queue->add($message, $data, $message_to_generate->preview(), $test_send);
1007
-    }
747
+						esc_html__(
748
+							'There was a problem generating the content for the field %s: %s',
749
+							'event_espresso'
750
+						),
751
+						$field,
752
+						$e->getMessage()
753
+					);
754
+					$message->set_STS_ID(EEM_Message::status_failed);
755
+				}
756
+			}
757
+		}
758
+
759
+		if ($message->STS_ID() === EEM_Message::status_failed) {
760
+			$error_msg = esc_html__('There were problems generating this message:', 'event_espresso')
761
+						 . "\n"
762
+						 . implode("\n", $error_msg);
763
+			$message->set_error_message($error_msg);
764
+		} else {
765
+			$message->set_STS_ID(EEM_Message::status_idle);
766
+		}
767
+		return $message;
768
+	}
769
+
770
+
771
+	/**
772
+	 * This verifies that the incoming array has a EE_messenger object and a EE_message_type object and sets appropriate
773
+	 * error message if either is missing.
774
+	 *
775
+	 * @return bool true means there were no errors, false means there were errors.
776
+	 */
777
+	protected function _verify()
778
+	{
779
+		// reset error message to an empty array.
780
+		$this->_error_msg = [];
781
+		// set the verified flag so we know everything has been validated.
782
+		$this->_verified = $this->_validate_messenger_and_message_type() && $this->_validate_and_setup_data();
783
+		return $this->_verified;
784
+	}
785
+
786
+
787
+	/**
788
+	 * This accepts an array and validates that it is an array indexed by context with each value being an array of
789
+	 * EE_Messages_Addressee objects.
790
+	 *
791
+	 * @param array $addressees Keys correspond to contexts for the message type and values are EE_Messages_Addressee[]
792
+	 * @return bool
793
+	 */
794
+	protected function _valid_addressees($addressees)
795
+	{
796
+		if (! $addressees || ! is_array($addressees)) {
797
+			return false;
798
+		}
799
+
800
+		foreach ($addressees as $addressee_array) {
801
+			foreach ($addressee_array as $addressee) {
802
+				if (! $addressee instanceof EE_Messages_Addressee) {
803
+					return false;
804
+				}
805
+			}
806
+		}
807
+		return true;
808
+	}
809
+
810
+
811
+	/**
812
+	 * This validates the messenger, message type, and presences of generation data for the current EE_Message in the
813
+	 * queue. This process sets error messages if something is wrong.
814
+	 *
815
+	 * @return bool   true is if there are no errors.  false is if there is.
816
+	 */
817
+	protected function _validate_messenger_and_message_type()
818
+	{
819
+		// first are there any existing error messages?  If so then return.
820
+		if ($this->_error_msg) {
821
+			return false;
822
+		}
823
+		$message = $this->_generation_queue->get_message_repository()->current();
824
+		try {
825
+			$this->_current_messenger = $message->valid_messenger(true)
826
+				? $message->messenger_object()
827
+				: null;
828
+		} catch (Exception $e) {
829
+			$this->_error_msg[] = $e->getMessage();
830
+		}
831
+		try {
832
+			$this->_current_message_type = $message->valid_message_type(true)
833
+				? $message->message_type_object()
834
+				: null;
835
+		} catch (Exception $e) {
836
+			$this->_error_msg[] = $e->getMessage();
837
+		}
838
+
839
+		/**
840
+		 * Check if there is any generation data, but only if this is not for a preview.
841
+		 */
842
+		if (
843
+			! $this->_generation_queue->get_message_repository()->get_generation_data()
844
+			&& (
845
+				! $this->_generation_queue->get_message_repository()->is_preview()
846
+				&& $this->_generation_queue->get_message_repository()->get_data_handler()
847
+				   !== 'EE_Messages_Preview_incoming_data'
848
+			)
849
+		) {
850
+			$this->_error_msg[] = esc_html__(
851
+				'There is no generation data for this message. Unable to generate.',
852
+				'event_espresso'
853
+			);
854
+		}
855
+
856
+		return empty($this->_error_msg);
857
+	}
858
+
859
+
860
+	/**
861
+	 * This method retrieves the expected data handler for the message type and validates the generation data for that
862
+	 * data handler.
863
+	 *
864
+	 * @return bool true means there are no errors.  false means there were errors (and handler did not get setup).
865
+	 */
866
+	protected function _validate_and_setup_data()
867
+	{
868
+
869
+		// First, are there any existing error messages?  If so, return because if there were errors elsewhere this
870
+		// can't be used anyways.
871
+		if ($this->_error_msg) {
872
+			return false;
873
+		}
874
+
875
+		$generation_data = $this->_generation_queue->get_message_repository()->get_generation_data();
876
+
877
+		/** @type EE_Messages_incoming_data $data_handler_class_name - well not really... just the class name actually */
878
+		$data_handler_class_name = $this->_generation_queue->get_message_repository()->get_data_handler()
879
+			? $this->_generation_queue->get_message_repository()->get_data_handler()
880
+			: 'EE_Messages_' . $this->_current_message_type->get_data_handler($generation_data) . '_incoming_data';
881
+
882
+		// If this EE_Message is for a preview, then let's switch out to the preview data handler.
883
+		if ($this->_generation_queue->get_message_repository()->is_preview()) {
884
+			$data_handler_class_name = 'EE_Messages_Preview_incoming_data';
885
+		}
886
+
887
+		// First get the class name for the data handler (and also verifies it exists.
888
+		if (! class_exists($data_handler_class_name)) {
889
+			$this->_error_msg[] = sprintf(
890
+			/* Translators: Both placeholders are the names of php classes. */
891
+				esc_html__(
892
+					'The included data handler class name does not match any valid, accessible, "%1$s" classes.  Looking for %2$s.',
893
+					'event_espresso'
894
+				),
895
+				'EE_Messages_incoming_data',
896
+				$data_handler_class_name
897
+			);
898
+			return false;
899
+		}
900
+
901
+		// convert generation_data for data_handler_instantiation.
902
+		$generation_data = $data_handler_class_name::convert_data_from_persistent_storage($generation_data);
903
+
904
+		// note, this may set error messages as well.
905
+		$this->_set_data_handler($generation_data, $data_handler_class_name);
906
+
907
+		return empty($this->_error_msg);
908
+	}
909
+
910
+
911
+	/**
912
+	 * Sets the $_current_data_handler property that is used for generating the current EE_Message in the queue, and
913
+	 * adds it to the _data repository.
914
+	 *
915
+	 * @param mixed  $generating_data           This is data expected by the instantiated data handler.
916
+	 * @param string $data_handler_class_name   This is the reference string indicating what data handler is being
917
+	 *                                          instantiated.
918
+	 */
919
+	protected function _set_data_handler($generating_data, $data_handler_class_name)
920
+	{
921
+		// valid classname for the data handler.  Now let's setup the key for the data handler repository to see if
922
+		// there is already a ready data handler in the repository.
923
+		$this->_current_data_handler = $this->_data_handler_collection->get_by_key(
924
+			$this->_data_handler_collection->get_key(
925
+				$data_handler_class_name,
926
+				$generating_data
927
+			)
928
+		);
929
+		if (! $this->_current_data_handler instanceof EE_Messages_incoming_data) {
930
+			// no saved data_handler in the repo so let's set one up and add it to the repo.
931
+			try {
932
+				$this->_current_data_handler = new $data_handler_class_name($generating_data);
933
+				$this->_data_handler_collection->add($this->_current_data_handler, $generating_data);
934
+			} catch (Exception $e) {
935
+				$this->_error_msg[] = $e->getMessage();
936
+			}
937
+		}
938
+	}
939
+
940
+
941
+	/**
942
+	 * The queued EE_Message for generation does not save the data used for generation as objects
943
+	 * because serialization of those objects could be problematic if the data is saved to the db.
944
+	 * So this method calls the static method on the associated data_handler for the given message_type
945
+	 * and that preps the data for later instantiation when generating.
946
+	 *
947
+	 * @param EE_Message_To_Generate $message_to_generate
948
+	 * @param bool                   $preview Indicate whether this is being used for a preview or not.
949
+	 * @return mixed Prepped data for persisting to the queue.  false is returned if unable to prep data.
950
+	 */
951
+	protected function _prepare_data_for_queue(EE_Message_To_Generate $message_to_generate, $preview)
952
+	{
953
+		if (! $message_to_generate->valid()) {
954
+			return false; // unable to get the data because the info in the EE_Message_To_Generate class is invalid.
955
+		}
956
+		/** @type EE_Messages_incoming_data $data_handler - well not really... just the class name actually */
957
+		$data_handler = $message_to_generate->get_data_handler_class_name($preview);
958
+		return $data_handler::convert_data_for_persistent_storage($message_to_generate->data());
959
+	}
960
+
961
+
962
+	/**
963
+	 * This sets up a EEM_Message::status_incomplete EE_Message object and adds it to the generation queue.
964
+	 *
965
+	 * @param EE_Message_To_Generate $message_to_generate
966
+	 * @param bool                   $test_send Whether this is just a test send or not.  Typically used for previews.
967
+	 * @return bool
968
+	 * @throws InvalidArgumentException
969
+	 * @throws InvalidDataTypeException
970
+	 * @throws InvalidInterfaceException
971
+	 */
972
+	public function create_and_add_message_to_queue(EE_Message_To_Generate $message_to_generate, $test_send = false)
973
+	{
974
+		// prep data
975
+		$data    = $this->_prepare_data_for_queue($message_to_generate, $message_to_generate->preview());
976
+		$request = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\RequestInterface');
977
+
978
+		$message = $message_to_generate->get_EE_Message();
979
+		$GRP_ID  = $request->getRequestParam('GRP_ID', 0, 'int');
980
+
981
+		$GRP_ID = apply_filters(
982
+			'FHEE__EE_Messages_Generator__create_and_add_message_to_queue_GRP_ID',
983
+			$GRP_ID > 0 ? $GRP_ID : $message->GRP_ID(),
984
+			$message,
985
+			$message_to_generate,
986
+			$test_send
987
+		);
988
+
989
+		if ($GRP_ID > 0) {
990
+			$message->set_GRP_ID($GRP_ID);
991
+		}
992
+
993
+		if ($data === false) {
994
+			$message->set_STS_ID(EEM_Message::status_failed);
995
+			$message->set_error_message(
996
+				esc_html__(
997
+					'Unable to prepare data for persistence to the database.',
998
+					'event_espresso'
999
+				)
1000
+			);
1001
+		} else {
1002
+			// make sure that the data handler is cached on the message as well
1003
+			$data['data_handler_class_name'] = $message_to_generate->get_data_handler_class_name();
1004
+		}
1005
+
1006
+		return $this->_generation_queue->add($message, $data, $message_to_generate->preview(), $test_send);
1007
+	}
1008 1008
 }
Please login to merge, or discard this patch.
core/libraries/messages/EE_Message_To_Generate.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -297,8 +297,8 @@
 block discarded – undo
297 297
      */
298 298
     public static function verify_and_retrieve_class_name_for_data_handler_reference($data_handler_reference)
299 299
     {
300
-        $class_name = 'EE_Messages_' . $data_handler_reference . '_incoming_data';
301
-        if (! class_exists($class_name)) {
300
+        $class_name = 'EE_Messages_'.$data_handler_reference.'_incoming_data';
301
+        if ( ! class_exists($class_name)) {
302 302
             EE_Error::add_error(
303 303
                 sprintf(
304 304
                     esc_html__(
Please login to merge, or discard this patch.
Indentation   +304 added lines, -304 removed lines patch added patch discarded remove patch
@@ -11,308 +11,308 @@
 block discarded – undo
11 11
  */
12 12
 class EE_Message_To_Generate
13 13
 {
14
-    /**
15
-     * @var string name of EE_messenger
16
-     */
17
-    protected $_messenger_name = null;
18
-
19
-    /**
20
-     * @var string name of EE_message_type
21
-     */
22
-    protected $_message_type_name = null;
23
-
24
-    /**
25
-     * @var EE_messenger
26
-     */
27
-    protected $_messenger = null;
28
-
29
-    /**
30
-     * @var EE_message_type
31
-     */
32
-    protected $_message_type = null;
33
-
34
-    /**
35
-     * Identifier for the context the message is to be generated for.
36
-     *
37
-     * @var string
38
-     */
39
-    protected $_context = '';
40
-
41
-    /**
42
-     * Data that will be used to generate message.
43
-     *
44
-     * @var array
45
-     */
46
-    protected $_data = [];
47
-
48
-    /**
49
-     * Whether this message is for a preview or not.
50
-     *
51
-     * @var bool
52
-     */
53
-    protected $_preview = false;
54
-
55
-    /**
56
-     * @var EE_Message $_message
57
-     */
58
-    protected $_message = null;
59
-
60
-    /**
61
-     * This is set by the constructor to indicate whether the incoming messenger
62
-     * and message type are valid.  This can then be checked by callers to determine whether
63
-     * to generate this message or not.
64
-     *
65
-     * @var bool
66
-     */
67
-    protected $_valid = false;
68
-
69
-    /**
70
-     * If there are any errors (non exception errors) they get added to this array for callers to decide
71
-     * how to handle.
72
-     *
73
-     * @var array
74
-     */
75
-    protected $_error_msg = [];
76
-
77
-    /**
78
-     * Can be accessed via the send_now() method, this is set in the validation
79
-     * routine via the EE_messenger::send_now() method.
80
-     *
81
-     * @var bool
82
-     */
83
-    protected $_send_now = false;
84
-
85
-    /**
86
-     * Holds the classname for the data handler used by the current message type.
87
-     * This is set on the first call to the public `get_data_handler_class_name()` method.
88
-     *
89
-     * @var string
90
-     */
91
-    protected $_data_handler_class_name = '';
92
-
93
-    /**
94
-     * one of the message status constants on EEM_Message
95
-     *
96
-     * @var string
97
-     * @since 4.10.29.p
98
-     */
99
-    protected $_status = '';
100
-
101
-    /**
102
-     * use $_status var above
103
-     *
104
-     * @var string
105
-     * @deprecated 4.10.29.p
106
-     */
107
-    protected $_message_status = '';
108
-
109
-
110
-    /**
111
-     * Constructor
112
-     *
113
-     * @param string $messenger_name    Slug representing messenger
114
-     * @param string $message_type_name Slug representing message type.
115
-     * @param mixed  $data              Data used for generating message.
116
-     * @param string $context           Optional context to restrict message generated for.
117
-     * @param bool   $preview           Whether this is being used to generate a preview or not.
118
-     * @param string $status
119
-     */
120
-    public function __construct(
121
-        $messenger_name,
122
-        $message_type_name,
123
-        $data = [],
124
-        $context = '',
125
-        $preview = false,
126
-        $status = EEM_Message::status_incomplete
127
-    ) {
128
-        $this->_messenger_name    = $messenger_name;
129
-        $this->_message_type_name = $message_type_name;
130
-        $this->_data              = is_array($data) ? $data : [$data];
131
-        $this->_context           = $context;
132
-        $this->_preview           = $preview;
133
-        $this->_status            = $status;
134
-        // attempt to generate message immediately
135
-        $this->_message = $this->_generate_message();
136
-    }
137
-
138
-
139
-    /**
140
-     * @return string
141
-     */
142
-    public function context()
143
-    {
144
-        return $this->_context;
145
-    }
146
-
147
-
148
-    /**
149
-     * @return array
150
-     */
151
-    public function data()
152
-    {
153
-        return $this->_data;
154
-    }
155
-
156
-
157
-    /**
158
-     * @return EE_messenger
159
-     */
160
-    public function messenger()
161
-    {
162
-        return $this->_messenger;
163
-    }
164
-
165
-
166
-    /**
167
-     * @return EE_message_type
168
-     */
169
-    public function message_type()
170
-    {
171
-        return $this->_message_type;
172
-    }
173
-
174
-
175
-    /**
176
-     * @return boolean
177
-     */
178
-    public function preview()
179
-    {
180
-        return $this->_preview;
181
-    }
182
-
183
-
184
-    /**
185
-     * @param boolean $preview
186
-     */
187
-    public function set_preview($preview)
188
-    {
189
-        $this->_preview = filter_var($preview, FILTER_VALIDATE_BOOLEAN);
190
-    }
191
-
192
-
193
-    /**
194
-     * @return bool
195
-     */
196
-    public function send_now()
197
-    {
198
-        return $this->_send_now;
199
-    }
200
-
201
-
202
-    /**
203
-     * Simply returns the state of the $_valid property.
204
-     *
205
-     * @return bool
206
-     */
207
-    public function valid()
208
-    {
209
-        return $this->_valid;
210
-    }
211
-
212
-
213
-    /**
214
-     * generates an EE_Message using the supplied arguments and some defaults
215
-     *
216
-     * @param array $properties
217
-     * @return EE_Message
218
-     */
219
-    protected function _generate_message($properties = [])
220
-    {
221
-        $message = EE_Message_Factory::create(
222
-            array_merge(
223
-                [
224
-                    'MSG_messenger'    => $this->_messenger_name,
225
-                    'MSG_message_type' => $this->_message_type_name,
226
-                    'MSG_context'      => $this->_context,
227
-                    'STS_ID'           => $this->_status,
228
-                ],
229
-                $properties
230
-            )
231
-        );
232
-        // validate the message, and if it's good, set some properties
233
-        try {
234
-            $message->is_valid_for_sending_or_generation(true);
235
-            $this->_valid        = true;
236
-            $this->_messenger    = $message->messenger_object();
237
-            $this->_message_type = $message->message_type_object();
238
-            $this->_send_now     = $message->send_now();
239
-        } catch (Exception $e) {
240
-            $this->_valid       = false;
241
-            $this->_error_msg[] = $e->getMessage();
242
-        }
243
-        return $message;
244
-    }
245
-
246
-
247
-    /**
248
-     *  Returns an instantiated EE_Message object from the internal data.
249
-     *
250
-     * @return EE_Message
251
-     */
252
-    public function get_EE_Message()
253
-    {
254
-        // already set ?
255
-        if ($this->_message instanceof EE_Message) {
256
-            return $this->_message;
257
-        }
258
-        // no? then let's create one
259
-        $this->_message = $this->_generate_message();
260
-        return $this->_message;
261
-    }
262
-
263
-
264
-    /**
265
-     * This returns the data_handler class name for the internal message type set.
266
-     * Note: this also verifies that the data handler class exists.  If it doesn't then $_valid is set to false
267
-     * and the data_handler_class name is set to an empty string.
268
-     *
269
-     * @param bool $preview Used to indicate that the preview data handler is to be returned.
270
-     * @return  string
271
-     */
272
-    public function get_data_handler_class_name($preview = false)
273
-    {
274
-        if ($this->_data_handler_class_name === '' && $this->valid()) {
275
-            $ref = $preview ? 'Preview' : $this->_message_type->get_data_handler($this->_data);
276
-            // make sure internal data is updated.
277
-            $this->_data = $this->_message_type->get_data();
278
-
279
-            // verify
280
-            $this->_data_handler_class_name =
281
-                EE_Message_To_Generate::verify_and_retrieve_class_name_for_data_handler_reference($ref);
282
-            if ($this->_data_handler_class_name === '') {
283
-                $this->_valid = false;
284
-            }
285
-        }
286
-        return $this->_data_handler_class_name;
287
-    }
288
-
289
-
290
-    /**
291
-     * Validates the given string as a reference for an existing, accessible data handler and returns the class name
292
-     * For the handler the reference matches.
293
-     *
294
-     * @param string $data_handler_reference
295
-     * @return string
296
-     */
297
-    public static function verify_and_retrieve_class_name_for_data_handler_reference($data_handler_reference)
298
-    {
299
-        $class_name = 'EE_Messages_' . $data_handler_reference . '_incoming_data';
300
-        if (! class_exists($class_name)) {
301
-            EE_Error::add_error(
302
-                sprintf(
303
-                    esc_html__(
304
-                        'The included data handler reference (%s) does not match any valid, accessible, "EE_Messages_incoming_data" classes.  Looking for %s.',
305
-                        'event_espresso'
306
-                    ),
307
-                    $data_handler_reference,
308
-                    $class_name
309
-                ),
310
-                __FILE__,
311
-                __FUNCTION__,
312
-                __LINE__
313
-            );
314
-            $class_name = ''; // clear out class_name so caller knows this isn't valid.
315
-        }
316
-        return $class_name;
317
-    }
14
+	/**
15
+	 * @var string name of EE_messenger
16
+	 */
17
+	protected $_messenger_name = null;
18
+
19
+	/**
20
+	 * @var string name of EE_message_type
21
+	 */
22
+	protected $_message_type_name = null;
23
+
24
+	/**
25
+	 * @var EE_messenger
26
+	 */
27
+	protected $_messenger = null;
28
+
29
+	/**
30
+	 * @var EE_message_type
31
+	 */
32
+	protected $_message_type = null;
33
+
34
+	/**
35
+	 * Identifier for the context the message is to be generated for.
36
+	 *
37
+	 * @var string
38
+	 */
39
+	protected $_context = '';
40
+
41
+	/**
42
+	 * Data that will be used to generate message.
43
+	 *
44
+	 * @var array
45
+	 */
46
+	protected $_data = [];
47
+
48
+	/**
49
+	 * Whether this message is for a preview or not.
50
+	 *
51
+	 * @var bool
52
+	 */
53
+	protected $_preview = false;
54
+
55
+	/**
56
+	 * @var EE_Message $_message
57
+	 */
58
+	protected $_message = null;
59
+
60
+	/**
61
+	 * This is set by the constructor to indicate whether the incoming messenger
62
+	 * and message type are valid.  This can then be checked by callers to determine whether
63
+	 * to generate this message or not.
64
+	 *
65
+	 * @var bool
66
+	 */
67
+	protected $_valid = false;
68
+
69
+	/**
70
+	 * If there are any errors (non exception errors) they get added to this array for callers to decide
71
+	 * how to handle.
72
+	 *
73
+	 * @var array
74
+	 */
75
+	protected $_error_msg = [];
76
+
77
+	/**
78
+	 * Can be accessed via the send_now() method, this is set in the validation
79
+	 * routine via the EE_messenger::send_now() method.
80
+	 *
81
+	 * @var bool
82
+	 */
83
+	protected $_send_now = false;
84
+
85
+	/**
86
+	 * Holds the classname for the data handler used by the current message type.
87
+	 * This is set on the first call to the public `get_data_handler_class_name()` method.
88
+	 *
89
+	 * @var string
90
+	 */
91
+	protected $_data_handler_class_name = '';
92
+
93
+	/**
94
+	 * one of the message status constants on EEM_Message
95
+	 *
96
+	 * @var string
97
+	 * @since 4.10.29.p
98
+	 */
99
+	protected $_status = '';
100
+
101
+	/**
102
+	 * use $_status var above
103
+	 *
104
+	 * @var string
105
+	 * @deprecated 4.10.29.p
106
+	 */
107
+	protected $_message_status = '';
108
+
109
+
110
+	/**
111
+	 * Constructor
112
+	 *
113
+	 * @param string $messenger_name    Slug representing messenger
114
+	 * @param string $message_type_name Slug representing message type.
115
+	 * @param mixed  $data              Data used for generating message.
116
+	 * @param string $context           Optional context to restrict message generated for.
117
+	 * @param bool   $preview           Whether this is being used to generate a preview or not.
118
+	 * @param string $status
119
+	 */
120
+	public function __construct(
121
+		$messenger_name,
122
+		$message_type_name,
123
+		$data = [],
124
+		$context = '',
125
+		$preview = false,
126
+		$status = EEM_Message::status_incomplete
127
+	) {
128
+		$this->_messenger_name    = $messenger_name;
129
+		$this->_message_type_name = $message_type_name;
130
+		$this->_data              = is_array($data) ? $data : [$data];
131
+		$this->_context           = $context;
132
+		$this->_preview           = $preview;
133
+		$this->_status            = $status;
134
+		// attempt to generate message immediately
135
+		$this->_message = $this->_generate_message();
136
+	}
137
+
138
+
139
+	/**
140
+	 * @return string
141
+	 */
142
+	public function context()
143
+	{
144
+		return $this->_context;
145
+	}
146
+
147
+
148
+	/**
149
+	 * @return array
150
+	 */
151
+	public function data()
152
+	{
153
+		return $this->_data;
154
+	}
155
+
156
+
157
+	/**
158
+	 * @return EE_messenger
159
+	 */
160
+	public function messenger()
161
+	{
162
+		return $this->_messenger;
163
+	}
164
+
165
+
166
+	/**
167
+	 * @return EE_message_type
168
+	 */
169
+	public function message_type()
170
+	{
171
+		return $this->_message_type;
172
+	}
173
+
174
+
175
+	/**
176
+	 * @return boolean
177
+	 */
178
+	public function preview()
179
+	{
180
+		return $this->_preview;
181
+	}
182
+
183
+
184
+	/**
185
+	 * @param boolean $preview
186
+	 */
187
+	public function set_preview($preview)
188
+	{
189
+		$this->_preview = filter_var($preview, FILTER_VALIDATE_BOOLEAN);
190
+	}
191
+
192
+
193
+	/**
194
+	 * @return bool
195
+	 */
196
+	public function send_now()
197
+	{
198
+		return $this->_send_now;
199
+	}
200
+
201
+
202
+	/**
203
+	 * Simply returns the state of the $_valid property.
204
+	 *
205
+	 * @return bool
206
+	 */
207
+	public function valid()
208
+	{
209
+		return $this->_valid;
210
+	}
211
+
212
+
213
+	/**
214
+	 * generates an EE_Message using the supplied arguments and some defaults
215
+	 *
216
+	 * @param array $properties
217
+	 * @return EE_Message
218
+	 */
219
+	protected function _generate_message($properties = [])
220
+	{
221
+		$message = EE_Message_Factory::create(
222
+			array_merge(
223
+				[
224
+					'MSG_messenger'    => $this->_messenger_name,
225
+					'MSG_message_type' => $this->_message_type_name,
226
+					'MSG_context'      => $this->_context,
227
+					'STS_ID'           => $this->_status,
228
+				],
229
+				$properties
230
+			)
231
+		);
232
+		// validate the message, and if it's good, set some properties
233
+		try {
234
+			$message->is_valid_for_sending_or_generation(true);
235
+			$this->_valid        = true;
236
+			$this->_messenger    = $message->messenger_object();
237
+			$this->_message_type = $message->message_type_object();
238
+			$this->_send_now     = $message->send_now();
239
+		} catch (Exception $e) {
240
+			$this->_valid       = false;
241
+			$this->_error_msg[] = $e->getMessage();
242
+		}
243
+		return $message;
244
+	}
245
+
246
+
247
+	/**
248
+	 *  Returns an instantiated EE_Message object from the internal data.
249
+	 *
250
+	 * @return EE_Message
251
+	 */
252
+	public function get_EE_Message()
253
+	{
254
+		// already set ?
255
+		if ($this->_message instanceof EE_Message) {
256
+			return $this->_message;
257
+		}
258
+		// no? then let's create one
259
+		$this->_message = $this->_generate_message();
260
+		return $this->_message;
261
+	}
262
+
263
+
264
+	/**
265
+	 * This returns the data_handler class name for the internal message type set.
266
+	 * Note: this also verifies that the data handler class exists.  If it doesn't then $_valid is set to false
267
+	 * and the data_handler_class name is set to an empty string.
268
+	 *
269
+	 * @param bool $preview Used to indicate that the preview data handler is to be returned.
270
+	 * @return  string
271
+	 */
272
+	public function get_data_handler_class_name($preview = false)
273
+	{
274
+		if ($this->_data_handler_class_name === '' && $this->valid()) {
275
+			$ref = $preview ? 'Preview' : $this->_message_type->get_data_handler($this->_data);
276
+			// make sure internal data is updated.
277
+			$this->_data = $this->_message_type->get_data();
278
+
279
+			// verify
280
+			$this->_data_handler_class_name =
281
+				EE_Message_To_Generate::verify_and_retrieve_class_name_for_data_handler_reference($ref);
282
+			if ($this->_data_handler_class_name === '') {
283
+				$this->_valid = false;
284
+			}
285
+		}
286
+		return $this->_data_handler_class_name;
287
+	}
288
+
289
+
290
+	/**
291
+	 * Validates the given string as a reference for an existing, accessible data handler and returns the class name
292
+	 * For the handler the reference matches.
293
+	 *
294
+	 * @param string $data_handler_reference
295
+	 * @return string
296
+	 */
297
+	public static function verify_and_retrieve_class_name_for_data_handler_reference($data_handler_reference)
298
+	{
299
+		$class_name = 'EE_Messages_' . $data_handler_reference . '_incoming_data';
300
+		if (! class_exists($class_name)) {
301
+			EE_Error::add_error(
302
+				sprintf(
303
+					esc_html__(
304
+						'The included data handler reference (%s) does not match any valid, accessible, "EE_Messages_incoming_data" classes.  Looking for %s.',
305
+						'event_espresso'
306
+					),
307
+					$data_handler_reference,
308
+					$class_name
309
+				),
310
+				__FILE__,
311
+				__FUNCTION__,
312
+				__LINE__
313
+			);
314
+			$class_name = ''; // clear out class_name so caller knows this isn't valid.
315
+		}
316
+		return $class_name;
317
+	}
318 318
 }
Please login to merge, or discard this patch.
core/helpers/EEH_URL.helper.php 2 patches
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -27,12 +27,12 @@  discard block
 block discarded – undo
27 27
     public static function add_query_args_and_nonce($args = [], $url = '', $exclude_nonce = false)
28 28
     {
29 29
         // check that an action exists and add nonce
30
-        if (! $exclude_nonce) {
30
+        if ( ! $exclude_nonce) {
31 31
             if (isset($args['action']) && ! empty($args['action'])) {
32 32
                 $args = array_merge(
33 33
                     $args,
34 34
                     [
35
-                        $args['action'] . '_nonce' => wp_create_nonce($args['action'] . '_nonce'),
35
+                        $args['action'].'_nonce' => wp_create_nonce($args['action'].'_nonce'),
36 36
                     ]
37 37
                 );
38 38
             } else {
@@ -46,7 +46,7 @@  discard block
 block discarded – undo
46 46
             }
47 47
         }
48 48
 
49
-        $action  = EEH_URL::getRequest()->getRequestParam('action', '');
49
+        $action = EEH_URL::getRequest()->getRequestParam('action', '');
50 50
         // finally, let's always add a return address (if present) :)
51 51
         if ($action !== '') {
52 52
             $args['return'] = $action;
@@ -96,25 +96,25 @@  discard block
 block discarded – undo
96 96
         // break apart incoming URL
97 97
         $url_bits = parse_url($url);
98 98
         // HTTP or HTTPS ?
99
-        $scheme = isset($url_bits['scheme']) ? $url_bits['scheme'] . '://' : 'https://';
99
+        $scheme = isset($url_bits['scheme']) ? $url_bits['scheme'].'://' : 'https://';
100 100
         // domain
101 101
         $host = isset($url_bits['host']) ? $url_bits['host'] : '';
102 102
         // if only the base URL is requested, then return that now
103 103
         if ($base_url_only) {
104
-            return $scheme . $host;
104
+            return $scheme.$host;
105 105
         }
106
-        $port = isset($url_bits['port']) ? ':' . $url_bits['port'] : '';
106
+        $port = isset($url_bits['port']) ? ':'.$url_bits['port'] : '';
107 107
         $user = isset($url_bits['user']) ? $url_bits['user'] : '';
108
-        $pass = isset($url_bits['pass']) ? ':' . $url_bits['pass'] : '';
109
-        $pass = ($user || $pass) ? $pass . '@' : '';
108
+        $pass = isset($url_bits['pass']) ? ':'.$url_bits['pass'] : '';
109
+        $pass = ($user || $pass) ? $pass.'@' : '';
110 110
         $path = isset($url_bits['path']) ? $url_bits['path'] : '';
111 111
         // if the query string is not required, then return what we have so far
112 112
         if ($remove_query) {
113
-            return $scheme . $user . $pass . $host . $port . $path;
113
+            return $scheme.$user.$pass.$host.$port.$path;
114 114
         }
115
-        $query    = isset($url_bits['query']) ? '?' . $url_bits['query'] : '';
116
-        $fragment = isset($url_bits['fragment']) ? '#' . $url_bits['fragment'] : '';
117
-        return $scheme . $user . $pass . $host . $port . $path . $query . $fragment;
115
+        $query    = isset($url_bits['query']) ? '?'.$url_bits['query'] : '';
116
+        $fragment = isset($url_bits['fragment']) ? '#'.$url_bits['fragment'] : '';
117
+        return $scheme.$user.$pass.$host.$port.$path.$query.$fragment;
118 118
     }
119 119
 
120 120
 
@@ -134,7 +134,7 @@  discard block
 block discarded – undo
134 134
         // grab query string from URL
135 135
         $query = isset($url_bits['query']) ? $url_bits['query'] : '';
136 136
         // if we don't want the query string formatted into an array of key => value pairs, then just return it as is
137
-        if (! $as_array) {
137
+        if ( ! $as_array) {
138 138
             return $query;
139 139
         }
140 140
         // if no query string exists then just return an empty array now
@@ -150,7 +150,7 @@  discard block
 block discarded – undo
150 150
             // break apart the key value pairs
151 151
             $query_args = explode('=', $query_args);
152 152
             // and add to our results array
153
-            $query_params[ $query_args[0] ] = $query_args[1];
153
+            $query_params[$query_args[0]] = $query_args[1];
154 154
         }
155 155
         return $query_params;
156 156
     }
@@ -179,8 +179,8 @@  discard block
 block discarded – undo
179 179
      */
180 180
     public static function generate_unique_token($prefix = '')
181 181
     {
182
-        $token = md5(uniqid() . mt_rand());
183
-        return $prefix ? $prefix . '_' . $token : $token;
182
+        $token = md5(uniqid().mt_rand());
183
+        return $prefix ? $prefix.'_'.$token : $token;
184 184
     }
185 185
 
186 186
 
@@ -200,13 +200,13 @@  discard block
 block discarded – undo
200 200
             'HTTP_HOST'   => 1,
201 201
             'PHP_SELF'    => 1,
202 202
         ];
203
-        $server_variable  = strtoupper($server_variable);
203
+        $server_variable = strtoupper($server_variable);
204 204
         // whitelist INPUT_SERVER var
205
-        if (isset($server_variables[ $server_variable ])) {
205
+        if (isset($server_variables[$server_variable])) {
206 206
             $URL = filter_input(INPUT_SERVER, $server_variable, FILTER_SANITIZE_URL, FILTER_NULL_ON_FAILURE);
207
-            if (empty($URL) || $URL !== $_SERVER[ $server_variable ]) {
207
+            if (empty($URL) || $URL !== $_SERVER[$server_variable]) {
208 208
                 // fallback sanitization if the above fails or URL has changed after filtering
209
-                $URL = wp_sanitize_redirect($_SERVER[ $server_variable ]);
209
+                $URL = wp_sanitize_redirect($_SERVER[$server_variable]);
210 210
             }
211 211
         }
212 212
         return $URL;
@@ -285,7 +285,7 @@  discard block
 block discarded – undo
285 285
     protected static function getRequest()
286 286
     {
287 287
         static $request;
288
-        if (! $request instanceof RequestInterface) {
288
+        if ( ! $request instanceof RequestInterface) {
289 289
             $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
290 290
         }
291 291
         return $request;
Please login to merge, or discard this patch.
Indentation   +252 added lines, -252 removed lines patch added patch discarded remove patch
@@ -13,280 +13,280 @@
 block discarded – undo
13 13
  */
14 14
 class EEH_URL
15 15
 {
16
-    /**
17
-     * _add_query_arg
18
-     * adds nonce to array of arguments then calls WP add_query_arg function
19
-     *
20
-     * @access public
21
-     * @param array  $args
22
-     * @param string $url
23
-     * @param bool   $exclude_nonce If true then the nonce will be excluded from the generated url.
24
-     * @return string
25
-     */
26
-    public static function add_query_args_and_nonce($args = [], $url = '', $exclude_nonce = false)
27
-    {
28
-        // check that an action exists and add nonce
29
-        if (! $exclude_nonce) {
30
-            if (isset($args['action']) && ! empty($args['action'])) {
31
-                $args = array_merge(
32
-                    $args,
33
-                    [
34
-                        $args['action'] . '_nonce' => wp_create_nonce($args['action'] . '_nonce'),
35
-                    ]
36
-                );
37
-            } else {
38
-                $args = array_merge(
39
-                    $args,
40
-                    [
41
-                        'action'        => 'default',
42
-                        'default_nonce' => wp_create_nonce('default_nonce'),
43
-                    ]
44
-                );
45
-            }
46
-        }
16
+	/**
17
+	 * _add_query_arg
18
+	 * adds nonce to array of arguments then calls WP add_query_arg function
19
+	 *
20
+	 * @access public
21
+	 * @param array  $args
22
+	 * @param string $url
23
+	 * @param bool   $exclude_nonce If true then the nonce will be excluded from the generated url.
24
+	 * @return string
25
+	 */
26
+	public static function add_query_args_and_nonce($args = [], $url = '', $exclude_nonce = false)
27
+	{
28
+		// check that an action exists and add nonce
29
+		if (! $exclude_nonce) {
30
+			if (isset($args['action']) && ! empty($args['action'])) {
31
+				$args = array_merge(
32
+					$args,
33
+					[
34
+						$args['action'] . '_nonce' => wp_create_nonce($args['action'] . '_nonce'),
35
+					]
36
+				);
37
+			} else {
38
+				$args = array_merge(
39
+					$args,
40
+					[
41
+						'action'        => 'default',
42
+						'default_nonce' => wp_create_nonce('default_nonce'),
43
+					]
44
+				);
45
+			}
46
+		}
47 47
 
48
-        $action  = EEH_URL::getRequest()->getRequestParam('action', '');
49
-        // finally, let's always add a return address (if present) :)
50
-        if ($action !== '') {
51
-            $args['return'] = $action;
52
-        }
48
+		$action  = EEH_URL::getRequest()->getRequestParam('action', '');
49
+		// finally, let's always add a return address (if present) :)
50
+		if ($action !== '') {
51
+			$args['return'] = $action;
52
+		}
53 53
 
54
-        return add_query_arg($args, $url);
55
-    }
54
+		return add_query_arg($args, $url);
55
+	}
56 56
 
57 57
 
58
-    /**
59
-     * Returns whether not the remote file exists.
60
-     * Checking via GET because HEAD requests are blocked on some server configurations.
61
-     *
62
-     * @param string $url
63
-     * @param array  $args the arguments that should be passed through to the wp_remote_request call.
64
-     * @return boolean
65
-     */
66
-    public static function remote_file_exists($url, $args = [])
67
-    {
68
-        $results = wp_remote_request(
69
-            $url,
70
-            array_merge(
71
-                [
72
-                    'method'      => 'GET',
73
-                    'redirection' => 1,
74
-                ],
75
-                $args
76
-            )
77
-        );
78
-        return ! $results instanceof WP_Error
79
-               && isset($results['response']['code'])
80
-               && $results['response']['code'] == '200';
81
-    }
58
+	/**
59
+	 * Returns whether not the remote file exists.
60
+	 * Checking via GET because HEAD requests are blocked on some server configurations.
61
+	 *
62
+	 * @param string $url
63
+	 * @param array  $args the arguments that should be passed through to the wp_remote_request call.
64
+	 * @return boolean
65
+	 */
66
+	public static function remote_file_exists($url, $args = [])
67
+	{
68
+		$results = wp_remote_request(
69
+			$url,
70
+			array_merge(
71
+				[
72
+					'method'      => 'GET',
73
+					'redirection' => 1,
74
+				],
75
+				$args
76
+			)
77
+		);
78
+		return ! $results instanceof WP_Error
79
+			   && isset($results['response']['code'])
80
+			   && $results['response']['code'] == '200';
81
+	}
82 82
 
83 83
 
84
-    /**
85
-     * refactor_url
86
-     * primarily used for removing the query string from a URL
87
-     *
88
-     * @param string $url
89
-     * @param bool   $remove_query  - TRUE (default) will strip off any URL params, ie: ?this=1&that=2
90
-     * @param bool   $base_url_only - TRUE will only return the scheme and host with no other parameters
91
-     * @return string
92
-     */
93
-    public static function refactor_url($url = '', $remove_query = true, $base_url_only = false)
94
-    {
95
-        // break apart incoming URL
96
-        $url_bits = parse_url($url);
97
-        // HTTP or HTTPS ?
98
-        $scheme = isset($url_bits['scheme']) ? $url_bits['scheme'] . '://' : 'https://';
99
-        // domain
100
-        $host = isset($url_bits['host']) ? $url_bits['host'] : '';
101
-        // if only the base URL is requested, then return that now
102
-        if ($base_url_only) {
103
-            return $scheme . $host;
104
-        }
105
-        $port = isset($url_bits['port']) ? ':' . $url_bits['port'] : '';
106
-        $user = isset($url_bits['user']) ? $url_bits['user'] : '';
107
-        $pass = isset($url_bits['pass']) ? ':' . $url_bits['pass'] : '';
108
-        $pass = ($user || $pass) ? $pass . '@' : '';
109
-        $path = isset($url_bits['path']) ? $url_bits['path'] : '';
110
-        // if the query string is not required, then return what we have so far
111
-        if ($remove_query) {
112
-            return $scheme . $user . $pass . $host . $port . $path;
113
-        }
114
-        $query    = isset($url_bits['query']) ? '?' . $url_bits['query'] : '';
115
-        $fragment = isset($url_bits['fragment']) ? '#' . $url_bits['fragment'] : '';
116
-        return $scheme . $user . $pass . $host . $port . $path . $query . $fragment;
117
-    }
84
+	/**
85
+	 * refactor_url
86
+	 * primarily used for removing the query string from a URL
87
+	 *
88
+	 * @param string $url
89
+	 * @param bool   $remove_query  - TRUE (default) will strip off any URL params, ie: ?this=1&that=2
90
+	 * @param bool   $base_url_only - TRUE will only return the scheme and host with no other parameters
91
+	 * @return string
92
+	 */
93
+	public static function refactor_url($url = '', $remove_query = true, $base_url_only = false)
94
+	{
95
+		// break apart incoming URL
96
+		$url_bits = parse_url($url);
97
+		// HTTP or HTTPS ?
98
+		$scheme = isset($url_bits['scheme']) ? $url_bits['scheme'] . '://' : 'https://';
99
+		// domain
100
+		$host = isset($url_bits['host']) ? $url_bits['host'] : '';
101
+		// if only the base URL is requested, then return that now
102
+		if ($base_url_only) {
103
+			return $scheme . $host;
104
+		}
105
+		$port = isset($url_bits['port']) ? ':' . $url_bits['port'] : '';
106
+		$user = isset($url_bits['user']) ? $url_bits['user'] : '';
107
+		$pass = isset($url_bits['pass']) ? ':' . $url_bits['pass'] : '';
108
+		$pass = ($user || $pass) ? $pass . '@' : '';
109
+		$path = isset($url_bits['path']) ? $url_bits['path'] : '';
110
+		// if the query string is not required, then return what we have so far
111
+		if ($remove_query) {
112
+			return $scheme . $user . $pass . $host . $port . $path;
113
+		}
114
+		$query    = isset($url_bits['query']) ? '?' . $url_bits['query'] : '';
115
+		$fragment = isset($url_bits['fragment']) ? '#' . $url_bits['fragment'] : '';
116
+		return $scheme . $user . $pass . $host . $port . $path . $query . $fragment;
117
+	}
118 118
 
119 119
 
120
-    /**
121
-     * get_query_string
122
-     * returns just the query string from a URL, formatted by default into an array of key value pairs
123
-     *
124
-     * @param string $url
125
-     * @param bool   $as_array TRUE (default) will return query params as an array of key value pairs, FALSE will
126
-     *                         simply return the query string
127
-     * @return string|array
128
-     */
129
-    public static function get_query_string($url = '', $as_array = true)
130
-    {
131
-        // decode, then break apart incoming URL
132
-        $url_bits = parse_url(html_entity_decode($url));
133
-        // grab query string from URL
134
-        $query = isset($url_bits['query']) ? $url_bits['query'] : '';
135
-        // if we don't want the query string formatted into an array of key => value pairs, then just return it as is
136
-        if (! $as_array) {
137
-            return $query;
138
-        }
139
-        // if no query string exists then just return an empty array now
140
-        if (empty($query)) {
141
-            return [];
142
-        }
143
-        // empty array to hold results
144
-        $query_params = [];
145
-        // now break apart the query string into separate params
146
-        $query = explode('&', $query);
147
-        // loop thru our query params
148
-        foreach ($query as $query_args) {
149
-            // break apart the key value pairs
150
-            $query_args = explode('=', $query_args);
151
-            // and add to our results array
152
-            $query_params[ $query_args[0] ] = $query_args[1];
153
-        }
154
-        return $query_params;
155
-    }
120
+	/**
121
+	 * get_query_string
122
+	 * returns just the query string from a URL, formatted by default into an array of key value pairs
123
+	 *
124
+	 * @param string $url
125
+	 * @param bool   $as_array TRUE (default) will return query params as an array of key value pairs, FALSE will
126
+	 *                         simply return the query string
127
+	 * @return string|array
128
+	 */
129
+	public static function get_query_string($url = '', $as_array = true)
130
+	{
131
+		// decode, then break apart incoming URL
132
+		$url_bits = parse_url(html_entity_decode($url));
133
+		// grab query string from URL
134
+		$query = isset($url_bits['query']) ? $url_bits['query'] : '';
135
+		// if we don't want the query string formatted into an array of key => value pairs, then just return it as is
136
+		if (! $as_array) {
137
+			return $query;
138
+		}
139
+		// if no query string exists then just return an empty array now
140
+		if (empty($query)) {
141
+			return [];
142
+		}
143
+		// empty array to hold results
144
+		$query_params = [];
145
+		// now break apart the query string into separate params
146
+		$query = explode('&', $query);
147
+		// loop thru our query params
148
+		foreach ($query as $query_args) {
149
+			// break apart the key value pairs
150
+			$query_args = explode('=', $query_args);
151
+			// and add to our results array
152
+			$query_params[ $query_args[0] ] = $query_args[1];
153
+		}
154
+		return $query_params;
155
+	}
156 156
 
157 157
 
158
-    /**
159
-     * prevent_prefetching
160
-     *
161
-     * @return void
162
-     */
163
-    public static function prevent_prefetching()
164
-    {
165
-        // prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes
166
-        // with the registration process
167
-        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
168
-    }
158
+	/**
159
+	 * prevent_prefetching
160
+	 *
161
+	 * @return void
162
+	 */
163
+	public static function prevent_prefetching()
164
+	{
165
+		// prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes
166
+		// with the registration process
167
+		remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
168
+	}
169 169
 
170 170
 
171
-    /**
172
-     * This generates a unique site-specific string.
173
-     * An example usage for this string would be to save as a unique identifier for a record in the db for usage in
174
-     * urls.
175
-     *
176
-     * @param string $prefix Use this to prefix the string with something.
177
-     * @return string
178
-     */
179
-    public static function generate_unique_token($prefix = '')
180
-    {
181
-        $token = md5(uniqid() . mt_rand());
182
-        return $prefix ? $prefix . '_' . $token : $token;
183
-    }
171
+	/**
172
+	 * This generates a unique site-specific string.
173
+	 * An example usage for this string would be to save as a unique identifier for a record in the db for usage in
174
+	 * urls.
175
+	 *
176
+	 * @param string $prefix Use this to prefix the string with something.
177
+	 * @return string
178
+	 */
179
+	public static function generate_unique_token($prefix = '')
180
+	{
181
+		$token = md5(uniqid() . mt_rand());
182
+		return $prefix ? $prefix . '_' . $token : $token;
183
+	}
184 184
 
185 185
 
186
-    /**
187
-     * filter_input_server_url
188
-     * uses filter_input() to sanitize one of the INPUT_SERVER URL values
189
-     * but adds a backup in case filter_input() returns nothing, which can erringly happen on some servers
190
-     *
191
-     * @param string $server_variable
192
-     * @return string
193
-     */
194
-    public static function filter_input_server_url($server_variable = 'REQUEST_URI')
195
-    {
196
-        $URL              = '';
197
-        $server_variables = [
198
-            'REQUEST_URI' => 1,
199
-            'HTTP_HOST'   => 1,
200
-            'PHP_SELF'    => 1,
201
-        ];
202
-        $server_variable  = strtoupper($server_variable);
203
-        // whitelist INPUT_SERVER var
204
-        if (isset($server_variables[ $server_variable ])) {
205
-            $URL = filter_input(INPUT_SERVER, $server_variable, FILTER_SANITIZE_URL, FILTER_NULL_ON_FAILURE);
206
-            if (empty($URL) || $URL !== $_SERVER[ $server_variable ]) {
207
-                // fallback sanitization if the above fails or URL has changed after filtering
208
-                $URL = wp_sanitize_redirect($_SERVER[ $server_variable ]);
209
-            }
210
-        }
211
-        return $URL;
212
-    }
186
+	/**
187
+	 * filter_input_server_url
188
+	 * uses filter_input() to sanitize one of the INPUT_SERVER URL values
189
+	 * but adds a backup in case filter_input() returns nothing, which can erringly happen on some servers
190
+	 *
191
+	 * @param string $server_variable
192
+	 * @return string
193
+	 */
194
+	public static function filter_input_server_url($server_variable = 'REQUEST_URI')
195
+	{
196
+		$URL              = '';
197
+		$server_variables = [
198
+			'REQUEST_URI' => 1,
199
+			'HTTP_HOST'   => 1,
200
+			'PHP_SELF'    => 1,
201
+		];
202
+		$server_variable  = strtoupper($server_variable);
203
+		// whitelist INPUT_SERVER var
204
+		if (isset($server_variables[ $server_variable ])) {
205
+			$URL = filter_input(INPUT_SERVER, $server_variable, FILTER_SANITIZE_URL, FILTER_NULL_ON_FAILURE);
206
+			if (empty($URL) || $URL !== $_SERVER[ $server_variable ]) {
207
+				// fallback sanitization if the above fails or URL has changed after filtering
208
+				$URL = wp_sanitize_redirect($_SERVER[ $server_variable ]);
209
+			}
210
+		}
211
+		return $URL;
212
+	}
213 213
 
214 214
 
215
-    /**
216
-     * Gets the current page's full URL.
217
-     *
218
-     * @return string
219
-     */
220
-    public static function current_url()
221
-    {
222
-        $url = '';
223
-        if (
224
-            EEH_URL::getRequest()->serverParamIsSet('HTTP_HOST')
225
-            && EEH_URL::getRequest()->serverParamIsSet('REQUEST_URI')
226
-        ) {
227
-            $url = is_ssl() ? 'https://' : 'http://';
228
-            $url .= EEH_URL::filter_input_server_url('HTTP_HOST');
229
-            $url .= EEH_URL::filter_input_server_url();
230
-        }
231
-        return $url;
232
-    }
215
+	/**
216
+	 * Gets the current page's full URL.
217
+	 *
218
+	 * @return string
219
+	 */
220
+	public static function current_url()
221
+	{
222
+		$url = '';
223
+		if (
224
+			EEH_URL::getRequest()->serverParamIsSet('HTTP_HOST')
225
+			&& EEH_URL::getRequest()->serverParamIsSet('REQUEST_URI')
226
+		) {
227
+			$url = is_ssl() ? 'https://' : 'http://';
228
+			$url .= EEH_URL::filter_input_server_url('HTTP_HOST');
229
+			$url .= EEH_URL::filter_input_server_url();
230
+		}
231
+		return $url;
232
+	}
233 233
 
234 234
 
235
-    /**
236
-     * Identical in functionality to EEH_current_url except it removes any provided query_parameters from it.
237
-     *
238
-     * @param array $query_parameters An array of query_parameters to remove from the current url.
239
-     * @return string
240
-     * @since 4.9.46.rc.029
241
-     */
242
-    public static function current_url_without_query_paramaters(array $query_parameters)
243
-    {
244
-        return remove_query_arg($query_parameters, EEH_URL::current_url());
245
-    }
235
+	/**
236
+	 * Identical in functionality to EEH_current_url except it removes any provided query_parameters from it.
237
+	 *
238
+	 * @param array $query_parameters An array of query_parameters to remove from the current url.
239
+	 * @return string
240
+	 * @since 4.9.46.rc.029
241
+	 */
242
+	public static function current_url_without_query_paramaters(array $query_parameters)
243
+	{
244
+		return remove_query_arg($query_parameters, EEH_URL::current_url());
245
+	}
246 246
 
247 247
 
248
-    /**
249
-     * @param string $location
250
-     * @param int    $status
251
-     * @param string $exit_notice
252
-     */
253
-    public static function safeRedirectAndExit($location, $status = 302, $exit_notice = '')
254
-    {
255
-        EE_Error::get_notices(false, true);
256
-        wp_safe_redirect($location, $status);
257
-        exit($exit_notice);
258
-    }
248
+	/**
249
+	 * @param string $location
250
+	 * @param int    $status
251
+	 * @param string $exit_notice
252
+	 */
253
+	public static function safeRedirectAndExit($location, $status = 302, $exit_notice = '')
254
+	{
255
+		EE_Error::get_notices(false, true);
256
+		wp_safe_redirect($location, $status);
257
+		exit($exit_notice);
258
+	}
259 259
 
260 260
 
261
-    /**
262
-     * Slugifies text for usage in a URL.
263
-     *
264
-     * Currently, this isn't just calling `sanitize_title()` on it, because that percent-encodes unicode characters,
265
-     * and WordPress chokes on them when used as CPT and custom taxonomy slugs.
266
-     *
267
-     * @param string $text
268
-     * @param string $fallback
269
-     * @return string which can be used in a URL
270
-     * @since 4.9.66.p
271
-     */
272
-    public static function slugify($text, $fallback)
273
-    {
274
-        // url decode after sanitizing title to restore unicode characters,
275
-        // see https://github.com/eventespresso/event-espresso-core/issues/575
276
-        return urldecode(sanitize_title($text, $fallback));
277
-    }
261
+	/**
262
+	 * Slugifies text for usage in a URL.
263
+	 *
264
+	 * Currently, this isn't just calling `sanitize_title()` on it, because that percent-encodes unicode characters,
265
+	 * and WordPress chokes on them when used as CPT and custom taxonomy slugs.
266
+	 *
267
+	 * @param string $text
268
+	 * @param string $fallback
269
+	 * @return string which can be used in a URL
270
+	 * @since 4.9.66.p
271
+	 */
272
+	public static function slugify($text, $fallback)
273
+	{
274
+		// url decode after sanitizing title to restore unicode characters,
275
+		// see https://github.com/eventespresso/event-espresso-core/issues/575
276
+		return urldecode(sanitize_title($text, $fallback));
277
+	}
278 278
 
279 279
 
280
-    /**
281
-     * @return RequestInterface
282
-     * @since   4.10.14.p
283
-     */
284
-    protected static function getRequest()
285
-    {
286
-        static $request;
287
-        if (! $request instanceof RequestInterface) {
288
-            $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
289
-        }
290
-        return $request;
291
-    }
280
+	/**
281
+	 * @return RequestInterface
282
+	 * @since   4.10.14.p
283
+	 */
284
+	protected static function getRequest()
285
+	{
286
+		static $request;
287
+		if (! $request instanceof RequestInterface) {
288
+			$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
289
+		}
290
+		return $request;
291
+	}
292 292
 }
Please login to merge, or discard this patch.
core/libraries/batch/JobHandlers/PreviewEventDeletion.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -215,7 +215,7 @@  discard block
 block discarded – undo
215 215
             if ($units_processed >= $batch_size) {
216 216
                 break;
217 217
             }
218
-            if (!$root_node instanceof ModelObjNode) {
218
+            if ( ! $root_node instanceof ModelObjNode) {
219 219
                 throw new InvalidClassException('ModelObjNode');
220 220
             }
221 221
             if ($root_node->isComplete()) {
@@ -226,7 +226,7 @@  discard block
 block discarded – undo
226 226
         $job_parameters->mark_processed($units_processed);
227 227
         // If the most-recently processed root node is complete, we must be all done because we're doing them
228 228
         // sequentially.
229
-        if (! isset($root_node) || (isset($root_node) && $root_node instanceof ModelObjNode && $root_node->isComplete())) {
229
+        if ( ! isset($root_node) || (isset($root_node) && $root_node instanceof ModelObjNode && $root_node->isComplete())) {
230 230
             $job_parameters->set_status(JobParameters::status_complete);
231 231
             // Show a full progress bar.
232 232
             $job_parameters->set_units_processed($job_parameters->job_size());
Please login to merge, or discard this patch.
Indentation   +213 added lines, -213 removed lines patch added patch discarded remove patch
@@ -33,149 +33,149 @@  discard block
 block discarded – undo
33 33
  */
34 34
 class PreviewEventDeletion extends JobHandler
35 35
 {
36
-    /**
37
-     * @var NodeGroupDao
38
-     */
39
-    protected $model_obj_node_group_persister;
36
+	/**
37
+	 * @var NodeGroupDao
38
+	 */
39
+	protected $model_obj_node_group_persister;
40 40
 
41
-    public function __construct(NodeGroupDao $model_obj_node_group_persister)
42
-    {
43
-        $this->model_obj_node_group_persister = $model_obj_node_group_persister;
44
-    }
41
+	public function __construct(NodeGroupDao $model_obj_node_group_persister)
42
+	{
43
+		$this->model_obj_node_group_persister = $model_obj_node_group_persister;
44
+	}
45 45
 
46
-    // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
46
+	// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
47 47
 
48
-    /**
49
-     *
50
-     * @param JobParameters $job_parameters
51
-     * @return JobStepResponse
52
-     * @throws EE_Error
53
-     * @throws InvalidDataTypeException
54
-     * @throws InvalidInterfaceException
55
-     * @throws InvalidArgumentException
56
-     * @throws ReflectionException
57
-     */
58
-    public function create_job(JobParameters $job_parameters)
59
-    {
60
-        // Set the "root" model objects we will want to delete (record their ID and model)
61
-        $event_ids = $job_parameters->request_datum('EVT_IDs', array());
62
-        // Find all the root nodes to delete (this isn't just events, because there's other data, like related tickets,
63
-        // prices, message templates, etc, whose model definition doesn't make them dependent on events. But,
64
-        // we have no UI to access them independent of events, so they may as well get deleted too.)
65
-        $roots = [];
66
-        foreach ($event_ids as $event_id) {
67
-            $roots[] = new ModelObjNode(
68
-                $event_id,
69
-                EEM_Event::instance()
70
-            );
71
-            // Also, we want to delete their related, non-global, tickets, prices and message templates
72
-            $related_non_global_tickets = EEM_Ticket::instance()->get_all_deleted_and_undeleted(
73
-                [
74
-                    [
75
-                        'TKT_is_default' => false,
76
-                        'Datetime.EVT_ID' => $event_id
77
-                    ]
78
-                ]
79
-            );
80
-            foreach ($related_non_global_tickets as $ticket) {
81
-                $roots[] = new ModelObjNode(
82
-                    $ticket->ID(),
83
-                    $ticket->get_model(),
84
-                    ['Registration']
85
-                );
86
-            }
87
-            $related_non_global_prices = EEM_Price::instance()->get_all_deleted_and_undeleted(
88
-                [
89
-                    [
90
-                        'PRC_is_default' => false,
91
-                        'Ticket.Datetime.EVT_ID' => $event_id
92
-                    ]
93
-                ]
94
-            );
95
-            foreach ($related_non_global_prices as $price) {
96
-                $roots[] = new ModelObjNode(
97
-                    $price->ID(),
98
-                    $price->get_model()
99
-                );
100
-            }
101
-        }
102
-        $transactions_ids = $this->getTransactionsToDelete($event_ids);
103
-        foreach ($transactions_ids as $transaction_id) {
104
-            $roots[] = new ModelObjNode(
105
-                $transaction_id,
106
-                EEM_Transaction::instance(),
107
-                ['Registration']
108
-            );
109
-        }
110
-        $job_parameters->add_extra_data('roots', $roots);
111
-        // Set an estimate of how long this will take (we're discovering as we go, so it seems impossible to give
112
-        // an accurate count.)
113
-        $estimated_work_per_model_obj = 10;
114
-        $count_regs = EEM_Registration::instance()->count(
115
-            [
116
-                [
117
-                    'EVT_ID' => ['IN', $event_ids]
118
-                ]
119
-            ]
120
-        );
121
-        $job_parameters->set_job_size((count($roots) + $count_regs) * $estimated_work_per_model_obj);
122
-        return new JobStepResponse(
123
-            $job_parameters,
124
-            esc_html__('Generating preview of data to be deleted...', 'event_espresso')
125
-        );
126
-    }
48
+	/**
49
+	 *
50
+	 * @param JobParameters $job_parameters
51
+	 * @return JobStepResponse
52
+	 * @throws EE_Error
53
+	 * @throws InvalidDataTypeException
54
+	 * @throws InvalidInterfaceException
55
+	 * @throws InvalidArgumentException
56
+	 * @throws ReflectionException
57
+	 */
58
+	public function create_job(JobParameters $job_parameters)
59
+	{
60
+		// Set the "root" model objects we will want to delete (record their ID and model)
61
+		$event_ids = $job_parameters->request_datum('EVT_IDs', array());
62
+		// Find all the root nodes to delete (this isn't just events, because there's other data, like related tickets,
63
+		// prices, message templates, etc, whose model definition doesn't make them dependent on events. But,
64
+		// we have no UI to access them independent of events, so they may as well get deleted too.)
65
+		$roots = [];
66
+		foreach ($event_ids as $event_id) {
67
+			$roots[] = new ModelObjNode(
68
+				$event_id,
69
+				EEM_Event::instance()
70
+			);
71
+			// Also, we want to delete their related, non-global, tickets, prices and message templates
72
+			$related_non_global_tickets = EEM_Ticket::instance()->get_all_deleted_and_undeleted(
73
+				[
74
+					[
75
+						'TKT_is_default' => false,
76
+						'Datetime.EVT_ID' => $event_id
77
+					]
78
+				]
79
+			);
80
+			foreach ($related_non_global_tickets as $ticket) {
81
+				$roots[] = new ModelObjNode(
82
+					$ticket->ID(),
83
+					$ticket->get_model(),
84
+					['Registration']
85
+				);
86
+			}
87
+			$related_non_global_prices = EEM_Price::instance()->get_all_deleted_and_undeleted(
88
+				[
89
+					[
90
+						'PRC_is_default' => false,
91
+						'Ticket.Datetime.EVT_ID' => $event_id
92
+					]
93
+				]
94
+			);
95
+			foreach ($related_non_global_prices as $price) {
96
+				$roots[] = new ModelObjNode(
97
+					$price->ID(),
98
+					$price->get_model()
99
+				);
100
+			}
101
+		}
102
+		$transactions_ids = $this->getTransactionsToDelete($event_ids);
103
+		foreach ($transactions_ids as $transaction_id) {
104
+			$roots[] = new ModelObjNode(
105
+				$transaction_id,
106
+				EEM_Transaction::instance(),
107
+				['Registration']
108
+			);
109
+		}
110
+		$job_parameters->add_extra_data('roots', $roots);
111
+		// Set an estimate of how long this will take (we're discovering as we go, so it seems impossible to give
112
+		// an accurate count.)
113
+		$estimated_work_per_model_obj = 10;
114
+		$count_regs = EEM_Registration::instance()->count(
115
+			[
116
+				[
117
+					'EVT_ID' => ['IN', $event_ids]
118
+				]
119
+			]
120
+		);
121
+		$job_parameters->set_job_size((count($roots) + $count_regs) * $estimated_work_per_model_obj);
122
+		return new JobStepResponse(
123
+			$job_parameters,
124
+			esc_html__('Generating preview of data to be deleted...', 'event_espresso')
125
+		);
126
+	}
127 127
 
128
-    /**
129
-     * @since 4.10.12.p
130
-     * @param EE_Base_Class[] $model_objs
131
-     * @param array $dont_traverse_models
132
-     * @return array
133
-     * @throws EE_Error
134
-     * @throws InvalidArgumentException
135
-     * @throws InvalidDataTypeException
136
-     * @throws InvalidInterfaceException
137
-     * @throws ReflectionException
138
-     */
139
-    protected function createModelObjNodes($model_objs, array $dont_traverse_models = [])
140
-    {
141
-        $nodes = [];
142
-        foreach ($model_objs as $model_obj) {
143
-            $nodes[] = new ModelObjNode(
144
-                $model_obj->ID(),
145
-                $model_obj->get_model(),
146
-                $dont_traverse_models
147
-            );
148
-        }
149
-        return $nodes;
150
-    }
128
+	/**
129
+	 * @since 4.10.12.p
130
+	 * @param EE_Base_Class[] $model_objs
131
+	 * @param array $dont_traverse_models
132
+	 * @return array
133
+	 * @throws EE_Error
134
+	 * @throws InvalidArgumentException
135
+	 * @throws InvalidDataTypeException
136
+	 * @throws InvalidInterfaceException
137
+	 * @throws ReflectionException
138
+	 */
139
+	protected function createModelObjNodes($model_objs, array $dont_traverse_models = [])
140
+	{
141
+		$nodes = [];
142
+		foreach ($model_objs as $model_obj) {
143
+			$nodes[] = new ModelObjNode(
144
+				$model_obj->ID(),
145
+				$model_obj->get_model(),
146
+				$dont_traverse_models
147
+			);
148
+		}
149
+		return $nodes;
150
+	}
151 151
 
152
-    /**
153
-     * Gets all the transactions related to these events that aren't related to other events. They'll be deleted too.
154
-     * (Ones that are related to other events can stay around until those other events are deleted too.)
155
-     * @since 4.10.12.p
156
-     * @param $event_ids
157
-     * @return array of transaction IDs
158
-     */
159
-    protected function getTransactionsToDelete($event_ids)
160
-    {
161
-        if (empty($event_ids)) {
162
-            return [];
163
-        }
164
-        global $wpdb;
165
-        $event_ids = array_map(
166
-            'intval',
167
-            $event_ids
168
-        );
169
-        $imploded_sanitized_event_ids = implode(',', $event_ids);
170
-        // Select transactions with registrations for the events $event_ids which also don't have registrations
171
-        // for any events NOT in $event_ids.
172
-        // Notice the outer query searched for transactions whose registrations ARE in $event_ids,
173
-        // whereas the inner query checks if the outer query's transaction has any registrations that are
174
-        // NOT IN $event_ids (ie, don't have registrations for events we're not just about to delete.)
175
-        return array_map(
176
-            'intval',
177
-            $wpdb->get_col(
178
-                "SELECT 
152
+	/**
153
+	 * Gets all the transactions related to these events that aren't related to other events. They'll be deleted too.
154
+	 * (Ones that are related to other events can stay around until those other events are deleted too.)
155
+	 * @since 4.10.12.p
156
+	 * @param $event_ids
157
+	 * @return array of transaction IDs
158
+	 */
159
+	protected function getTransactionsToDelete($event_ids)
160
+	{
161
+		if (empty($event_ids)) {
162
+			return [];
163
+		}
164
+		global $wpdb;
165
+		$event_ids = array_map(
166
+			'intval',
167
+			$event_ids
168
+		);
169
+		$imploded_sanitized_event_ids = implode(',', $event_ids);
170
+		// Select transactions with registrations for the events $event_ids which also don't have registrations
171
+		// for any events NOT in $event_ids.
172
+		// Notice the outer query searched for transactions whose registrations ARE in $event_ids,
173
+		// whereas the inner query checks if the outer query's transaction has any registrations that are
174
+		// NOT IN $event_ids (ie, don't have registrations for events we're not just about to delete.)
175
+		return array_map(
176
+			'intval',
177
+			$wpdb->get_col(
178
+				"SELECT 
179 179
                       DISTINCT t.TXN_ID
180 180
                     FROM 
181 181
                       {$wpdb->prefix}esp_transaction t INNER JOIN 
@@ -193,83 +193,83 @@  discard block
 block discarded – undo
193 193
                            tsub.TXN_ID=t.TXN_ID AND
194 194
                            rsub.EVT_ID NOT IN ({$imploded_sanitized_event_ids})
195 195
                        )"
196
-            )
197
-        );
198
-    }
196
+			)
197
+		);
198
+	}
199 199
 
200
-    /**
201
-     * Performs another step of the job
202
-     * @param JobParameters $job_parameters
203
-     * @param int $batch_size
204
-     * @return JobStepResponse
205
-     */
206
-    public function continue_job(JobParameters $job_parameters, $batch_size = 50)
207
-    {
208
-        // Serializing and unserializing is what really makes this drag on (eg on localhost, the ajax requests took
209
-        // about 4 seconds when the batch size was 250, but 3 seconds when the batch size was 50. So like
210
-        // 50% of the request is just serializing and unserializing.) So, make the batches much bigger.
211
-        $batch_size *= 3;
212
-        $units_processed = 0;
213
-        foreach ($job_parameters->extra_datum('roots', array()) as $root_node) {
214
-            if ($units_processed >= $batch_size) {
215
-                break;
216
-            }
217
-            if (!$root_node instanceof ModelObjNode) {
218
-                throw new InvalidClassException('ModelObjNode');
219
-            }
220
-            if ($root_node->isComplete()) {
221
-                continue;
222
-            }
223
-            $units_processed += $root_node->visit($batch_size - $units_processed);
224
-        }
225
-        $job_parameters->mark_processed($units_processed);
226
-        // If the most-recently processed root node is complete, we must be all done because we're doing them
227
-        // sequentially.
228
-        if (! isset($root_node) || (isset($root_node) && $root_node instanceof ModelObjNode && $root_node->isComplete())) {
229
-            $job_parameters->set_status(JobParameters::status_complete);
230
-            // Show a full progress bar.
231
-            $job_parameters->set_units_processed($job_parameters->job_size());
232
-            $deletion_job_code = $job_parameters->request_datum('deletion_job_code');
233
-            $this->model_obj_node_group_persister->persistModelObjNodesGroup(
234
-                $job_parameters->extra_datum('roots'),
235
-                $deletion_job_code
236
-            );
237
-            return new JobStepResponse(
238
-                $job_parameters,
239
-                esc_html__('Finished identifying items for deletion.', 'event_espresso'),
240
-                [
241
-                    'deletion_job_code' => $deletion_job_code
242
-                ]
243
-            );
244
-        } else {
245
-            // Because the job size was a guess, it may have likely been proven wrong. We don't want to show more work
246
-            // done than we originally said there would be. So adjust the estimate.
247
-            if (($job_parameters->units_processed() / $job_parameters->job_size()) > .8) {
248
-                $job_parameters->set_job_size($job_parameters->job_size() * 2);
249
-            }
250
-            return new JobStepResponse(
251
-                $job_parameters,
252
-                sprintf(
253
-                    esc_html__('Identified %d items for deletion.', 'event_espresso'),
254
-                    $units_processed
255
-                )
256
-            );
257
-        }
258
-    }
200
+	/**
201
+	 * Performs another step of the job
202
+	 * @param JobParameters $job_parameters
203
+	 * @param int $batch_size
204
+	 * @return JobStepResponse
205
+	 */
206
+	public function continue_job(JobParameters $job_parameters, $batch_size = 50)
207
+	{
208
+		// Serializing and unserializing is what really makes this drag on (eg on localhost, the ajax requests took
209
+		// about 4 seconds when the batch size was 250, but 3 seconds when the batch size was 50. So like
210
+		// 50% of the request is just serializing and unserializing.) So, make the batches much bigger.
211
+		$batch_size *= 3;
212
+		$units_processed = 0;
213
+		foreach ($job_parameters->extra_datum('roots', array()) as $root_node) {
214
+			if ($units_processed >= $batch_size) {
215
+				break;
216
+			}
217
+			if (!$root_node instanceof ModelObjNode) {
218
+				throw new InvalidClassException('ModelObjNode');
219
+			}
220
+			if ($root_node->isComplete()) {
221
+				continue;
222
+			}
223
+			$units_processed += $root_node->visit($batch_size - $units_processed);
224
+		}
225
+		$job_parameters->mark_processed($units_processed);
226
+		// If the most-recently processed root node is complete, we must be all done because we're doing them
227
+		// sequentially.
228
+		if (! isset($root_node) || (isset($root_node) && $root_node instanceof ModelObjNode && $root_node->isComplete())) {
229
+			$job_parameters->set_status(JobParameters::status_complete);
230
+			// Show a full progress bar.
231
+			$job_parameters->set_units_processed($job_parameters->job_size());
232
+			$deletion_job_code = $job_parameters->request_datum('deletion_job_code');
233
+			$this->model_obj_node_group_persister->persistModelObjNodesGroup(
234
+				$job_parameters->extra_datum('roots'),
235
+				$deletion_job_code
236
+			);
237
+			return new JobStepResponse(
238
+				$job_parameters,
239
+				esc_html__('Finished identifying items for deletion.', 'event_espresso'),
240
+				[
241
+					'deletion_job_code' => $deletion_job_code
242
+				]
243
+			);
244
+		} else {
245
+			// Because the job size was a guess, it may have likely been proven wrong. We don't want to show more work
246
+			// done than we originally said there would be. So adjust the estimate.
247
+			if (($job_parameters->units_processed() / $job_parameters->job_size()) > .8) {
248
+				$job_parameters->set_job_size($job_parameters->job_size() * 2);
249
+			}
250
+			return new JobStepResponse(
251
+				$job_parameters,
252
+				sprintf(
253
+					esc_html__('Identified %d items for deletion.', 'event_espresso'),
254
+					$units_processed
255
+				)
256
+			);
257
+		}
258
+	}
259 259
 
260
-    /**
261
-     * Performs any clean-up logic when we know the job is completed
262
-     * @param JobParameters $job_parameters
263
-     * @return JobStepResponse
264
-     */
265
-    public function cleanup_job(JobParameters $job_parameters)
266
-    {
267
-        // Nothing much to do. We can't delete the option with the built tree because we may need it in a moment for the deletion
268
-        return new JobStepResponse(
269
-            $job_parameters,
270
-            esc_html__('All done', 'event_espresso')
271
-        );
272
-    }
260
+	/**
261
+	 * Performs any clean-up logic when we know the job is completed
262
+	 * @param JobParameters $job_parameters
263
+	 * @return JobStepResponse
264
+	 */
265
+	public function cleanup_job(JobParameters $job_parameters)
266
+	{
267
+		// Nothing much to do. We can't delete the option with the built tree because we may need it in a moment for the deletion
268
+		return new JobStepResponse(
269
+			$job_parameters,
270
+			esc_html__('All done', 'event_espresso')
271
+		);
272
+	}
273 273
 }
274 274
 // End of file EventDeletion.php
275 275
 // Location: EventEspressoBatchRequest\JobHandlers/EventDeletion.php
Please login to merge, or discard this patch.
modules/event_single/EED_Event_Single.module.php 2 patches
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -83,8 +83,8 @@  discard block
 block discarded – undo
83 83
      */
84 84
     public static function set_definitions()
85 85
     {
86
-        define('EVENT_SINGLE_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/');
87
-        define('EVENT_SINGLE_TEMPLATES_PATH', plugin_dir_path(__FILE__) . 'templates/');
86
+        define('EVENT_SINGLE_ASSETS_URL', plugin_dir_url(__FILE__).'assets/');
87
+        define('EVENT_SINGLE_TEMPLATES_PATH', plugin_dir_path(__FILE__).'templates/');
88 88
     }
89 89
 
90 90
 
@@ -225,7 +225,7 @@  discard block
 block discarded – undo
225 225
     {
226 226
         global $post;
227 227
         return ((function_exists('wp_is_block_theme') && wp_is_block_theme()) || in_the_loop()) && $post->ID === (int) $id
228
-            ? espresso_event_status_banner($post->ID) . $title
228
+            ? espresso_event_status_banner($post->ID).$title
229 229
             : $title;
230 230
     }
231 231
 
@@ -382,7 +382,7 @@  discard block
 block discarded – undo
382 382
      */
383 383
     public static function event_datetimes($content)
384 384
     {
385
-        return EEH_Template::locate_template('content-espresso_events-datetimes.php') . $content;
385
+        return EEH_Template::locate_template('content-espresso_events-datetimes.php').$content;
386 386
     }
387 387
 
388 388
 
@@ -394,7 +394,7 @@  discard block
 block discarded – undo
394 394
      */
395 395
     public static function event_tickets($content)
396 396
     {
397
-        return EEH_Template::locate_template('content-espresso_events-tickets.php') . $content;
397
+        return EEH_Template::locate_template('content-espresso_events-tickets.php').$content;
398 398
     }
399 399
 
400 400
 
@@ -418,7 +418,7 @@  discard block
 block discarded – undo
418 418
      */
419 419
     public static function event_venues($content)
420 420
     {
421
-        return $content . EEH_Template::locate_template('content-espresso_events-venues.php');
421
+        return $content.EEH_Template::locate_template('content-espresso_events-venues.php');
422 422
     }
423 423
 
424 424
 
@@ -448,16 +448,16 @@  discard block
 block discarded – undo
448 448
             && apply_filters('FHEE__EED_Event_Single__wp_enqueue_scripts__enable_css', true)
449 449
         ) {
450 450
             // first check uploads folder
451
-            if (is_readable(get_stylesheet_directory() . $this->theme . '/style.css')) {
451
+            if (is_readable(get_stylesheet_directory().$this->theme.'/style.css')) {
452 452
                 wp_register_style(
453 453
                     $this->theme,
454
-                    get_stylesheet_directory_uri() . $this->theme . '/style.css',
454
+                    get_stylesheet_directory_uri().$this->theme.'/style.css',
455 455
                     array('dashicons', 'espresso_default')
456 456
                 );
457 457
             } else {
458 458
                 wp_register_style(
459 459
                     $this->theme,
460
-                    EE_TEMPLATES_URL . $this->theme . '/style.css',
460
+                    EE_TEMPLATES_URL.$this->theme.'/style.css',
461 461
                     array('dashicons', 'espresso_default')
462 462
                 );
463 463
             }
Please login to merge, or discard this patch.
Indentation   +469 added lines, -469 removed lines patch added patch discarded remove patch
@@ -13,474 +13,474 @@  discard block
 block discarded – undo
13 13
  */
14 14
 class EED_Event_Single extends EED_Module
15 15
 {
16
-    const EVENT_DETAILS_PRIORITY = 100;
17
-    const EVENT_DATETIMES_PRIORITY = 110;
18
-    const EVENT_TICKETS_PRIORITY = 120;
19
-    const EVENT_VENUES_PRIORITY = 130;
20
-
21
-    /**
22
-     * @type bool $using_get_the_excerpt
23
-     */
24
-    protected static $using_get_the_excerpt = false;
25
-
26
-
27
-    /**
28
-     * @type EE_Template_Part_Manager $template_parts
29
-     */
30
-    protected $template_parts;
31
-
32
-
33
-    /**
34
-     * @return EED_Module|EED_Event_Single
35
-     */
36
-    public static function instance()
37
-    {
38
-        return parent::get_instance(__CLASS__);
39
-    }
40
-
41
-
42
-    /**
43
-     * set_hooks - for hooking into EE Core, other modules, etc
44
-     *
45
-     * @return void
46
-     * @throws InvalidArgumentException
47
-     * @throws InvalidDataTypeException
48
-     * @throws InvalidInterfaceException
49
-     */
50
-    public static function set_hooks()
51
-    {
52
-        add_filter('FHEE_run_EE_wp', '__return_true');
53
-        add_action('wp_loaded', array('EED_Event_Single', 'set_definitions'), 2);
54
-        /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_type_definitions */
55
-        $custom_post_type_definitions = LoaderFactory::getLoader()->getShared(
56
-            'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
57
-        );
58
-        $custom_post_types = $custom_post_type_definitions->getDefinitions();
59
-        EE_Config::register_route(
60
-            $custom_post_types['espresso_events']['singular_slug'],
61
-            'Event_Single',
62
-            'run'
63
-        );
64
-    }
65
-
66
-    /**
67
-     * set_hooks_admin - for hooking into EE Admin Core, other modules, etc
68
-     *
69
-     * @return    void
70
-     */
71
-    public static function set_hooks_admin()
72
-    {
73
-        add_action('wp_loaded', array('EED_Event_Single', 'set_definitions'), 2);
74
-    }
75
-
76
-
77
-    /**
78
-     * set_definitions
79
-     *
80
-     * @static
81
-     * @return void
82
-     */
83
-    public static function set_definitions()
84
-    {
85
-        define('EVENT_SINGLE_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/');
86
-        define('EVENT_SINGLE_TEMPLATES_PATH', plugin_dir_path(__FILE__) . 'templates/');
87
-    }
88
-
89
-
90
-    /**
91
-     * set_config
92
-     *
93
-     * @void
94
-     */
95
-    protected function set_config()
96
-    {
97
-        $this->set_config_section('template_settings');
98
-        $this->set_config_class('EE_Event_Single_Config');
99
-        $this->set_config_name('EED_Event_Single');
100
-    }
101
-
102
-
103
-    /**
104
-     * initialize_template_parts
105
-     *
106
-     * @param EE_Config_Base|EE_Event_Single_Config $config
107
-     * @return EE_Template_Part_Manager
108
-     */
109
-    public function initialize_template_parts(EE_Event_Single_Config $config = null)
110
-    {
111
-        /** @type EE_Event_Single_Config $config */
112
-        $config = $config instanceof EE_Event_Single_Config ? $config : $this->config();
113
-        EEH_Autoloader::instance()->register_template_part_autoloaders();
114
-        $template_parts = new EE_Template_Part_Manager();
115
-        $template_parts->add_template_part(
116
-            'tickets',
117
-            esc_html__('Ticket Selector', 'event_espresso'),
118
-            'content-espresso_events-tickets.php',
119
-            $config->display_order_tickets
120
-        );
121
-        $template_parts->add_template_part(
122
-            'datetimes',
123
-            esc_html__('Dates and Times', 'event_espresso'),
124
-            'content-espresso_events-datetimes.php',
125
-            $config->display_order_datetimes
126
-        );
127
-        $template_parts->add_template_part(
128
-            'event',
129
-            esc_html__('Event Description', 'event_espresso'),
130
-            'content-espresso_events-details.php',
131
-            $config->display_order_event
132
-        );
133
-        $template_parts->add_template_part(
134
-            'venue',
135
-            esc_html__('Venue Information', 'event_espresso'),
136
-            'content-espresso_events-venues.php',
137
-            $config->display_order_venue
138
-        );
139
-        do_action('AHEE__EED_Event_Single__initialize_template_parts', $template_parts);
140
-        return $template_parts;
141
-    }
142
-
143
-
144
-    /**
145
-     * run - initial module setup
146
-     *
147
-     * @param WP $WP
148
-     * @return    void
149
-     */
150
-    public function run($WP)
151
-    {
152
-        // ensure valid EE_Events_Single_Config() object exists
153
-        $this->set_config();
154
-        // check what template is loaded
155
-        add_filter('template_include', array($this, 'template_include'), 999, 1);
156
-        add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
157
-        // load css
158
-        add_action('wp_enqueue_scripts', array($this, 'wp_enqueue_scripts'), 10);
159
-    }
160
-
161
-
162
-    /**
163
-     * template_include
164
-     *
165
-     * @param    string $template
166
-     * @return    string
167
-     */
168
-    public function template_include($template)
169
-    {
170
-        global $post;
171
-        /** @type EE_Event_Single_Config $config */
172
-        $config = $this->config();
173
-        if ($config->display_status_banner_single) {
174
-            add_filter('the_title', array('EED_Event_Single', 'the_title'), 100, 2);
175
-        }
176
-        // not a custom template?
177
-        if (
178
-            ! post_password_required($post)
179
-            && (
180
-                apply_filters('FHEE__EED_Event_Single__template_include__allow_custom_selected_template', false)
181
-                || EE_Registry::instance()
182
-                              ->load_core('Front_Controller')
183
-                              ->get_selected_template() !== 'single-espresso_events.php'
184
-            )
185
-        ) {
186
-            EEH_Template::load_espresso_theme_functions();
187
-            // then add extra event data via hooks
188
-            add_action('loop_start', array('EED_Event_Single', 'loop_start'));
189
-            add_filter('get_the_excerpt', array('EED_Event_Single', 'get_the_excerpt'), 1, 1);
190
-            add_filter(
191
-                'the_content',
192
-                array('EED_Event_Single', 'event_details'),
193
-                EED_Event_Single::EVENT_DETAILS_PRIORITY
194
-            );
195
-            add_action('loop_end', array('EED_Event_Single', 'loop_end'));
196
-            // don't display entry meta because the existing theme will take car of that
197
-            add_filter('FHEE__content_espresso_events_details_template__display_entry_meta', '__return_false');
198
-        }
199
-        return $template;
200
-    }
201
-
202
-
203
-    /**
204
-     * loop_start
205
-     *
206
-     * @param    array $wp_query_array an array containing the WP_Query object
207
-     * @return    void
208
-     */
209
-    public static function loop_start($wp_query_array)
210
-    {
211
-        global $post;
212
-        do_action('AHEE_event_details_before_post', $post, $wp_query_array);
213
-    }
214
-
215
-
216
-    /**
217
-     * the_title
218
-     *
219
-     * @param    string $title
220
-     * @param    int    $id
221
-     * @return    string
222
-     */
223
-    public static function the_title($title = '', $id = 0)
224
-    {
225
-        global $post;
226
-        return ((function_exists('wp_is_block_theme') && wp_is_block_theme()) || in_the_loop()) && $post->ID === (int) $id
227
-            ? espresso_event_status_banner($post->ID) . $title
228
-            : $title;
229
-    }
230
-
231
-
232
-    /**
233
-     * get_the_excerpt
234
-     * kinda hacky, but if a theme is using get_the_excerpt(),
235
-     * then we need to remove our filters on the_content()
236
-     *
237
-     * @param        string $excerpt
238
-     * @return        string
239
-     */
240
-    public static function get_the_excerpt($excerpt = '')
241
-    {
242
-        EED_Event_Single::$using_get_the_excerpt = true;
243
-        add_filter('wp_trim_excerpt', array('EED_Event_Single', 'end_get_the_excerpt'), 999, 1);
244
-        return $excerpt;
245
-    }
246
-
247
-
248
-    /**
249
-     * end_get_the_excerpt
250
-     *
251
-     * @param  string $text
252
-     * @return string
253
-     */
254
-    public static function end_get_the_excerpt($text = '')
255
-    {
256
-        EED_Event_Single::$using_get_the_excerpt = false;
257
-        return $text;
258
-    }
259
-
260
-
261
-    /**
262
-     * event_details
263
-     *
264
-     * @param    string $content
265
-     * @return    string
266
-     */
267
-    public static function event_details($content)
268
-    {
269
-        global $post;
270
-        static $current_post_ID = 0;
271
-        if (
272
-            $current_post_ID !== $post->ID
273
-            && $post->post_type === 'espresso_events'
274
-            && ! EED_Event_Single::$using_get_the_excerpt
275
-            && ! post_password_required()
276
-        ) {
277
-            // Set current post ID to prevent showing content twice, but only if headers have definitely been sent.
278
-            // Reason being is that some plugins, like Yoast, need to run through a copy of the loop early
279
-            // BEFORE headers are sent in order to examine the post content and generate content for the HTML header.
280
-            // We want to allow those plugins to still do their thing and have access to our content, but depending on
281
-            // how your event content is being displayed (shortcode, CPT route, etc), this filter can get applied twice,
282
-            // so the following allows this filter to be applied multiple times, but only once for real
283
-            $current_post_ID = did_action('loop_start') ? $post->ID : 0;
284
-            if (EE_Registry::instance()->CFG->template_settings->EED_Event_Single->use_sortable_display_order) {
285
-                // we need to first remove this callback from being applied to the_content()
286
-                // (otherwise it will recurse and blow up the interweb)
287
-                remove_filter(
288
-                    'the_content',
289
-                    array('EED_Event_Single', 'event_details'),
290
-                    EED_Event_Single::EVENT_DETAILS_PRIORITY
291
-                );
292
-                EED_Event_Single::instance()->template_parts = EED_Event_Single::instance()->initialize_template_parts(
293
-                );
294
-                $content = EEH_Template::locate_template('content-espresso_events-details.php');
295
-                $content = EED_Event_Single::instance()->template_parts->apply_template_part_filters($content);
296
-                add_filter(
297
-                    'the_content',
298
-                    array('EED_Event_Single', 'event_details'),
299
-                    EED_Event_Single::EVENT_DETAILS_PRIORITY
300
-                );
301
-            } else {
302
-                $content = EED_Event_Single::use_filterable_display_order();
303
-            }
304
-        }
305
-        return $content;
306
-    }
307
-
308
-
309
-    /**
310
-     * use_filterable_display_order
311
-     *
312
-     * @return string
313
-     */
314
-    protected static function use_filterable_display_order()
315
-    {
316
-        // since the 'content-espresso_events-details.php' template might be used directly from within a theme,
317
-        // it uses the_content() for displaying the $post->post_content
318
-        // so in order to load a template that uses the_content()
319
-        // from within a callback being used to filter the_content(),
320
-        // we need to first remove this callback from being applied to the_content()
321
-        // (otherwise it will recurse and blow up the interweb)
322
-        remove_filter(
323
-            'the_content',
324
-            array('EED_Event_Single', 'event_details'),
325
-            EED_Event_Single::EVENT_DETAILS_PRIORITY
326
-        );
327
-        // now add additional content
328
-        add_filter(
329
-            'the_content',
330
-            array('EED_Event_Single', 'event_datetimes'),
331
-            EED_Event_Single::EVENT_DATETIMES_PRIORITY,
332
-            1
333
-        );
334
-        add_filter(
335
-            'the_content',
336
-            array('EED_Event_Single', 'event_tickets'),
337
-            EED_Event_Single::EVENT_TICKETS_PRIORITY,
338
-            1
339
-        );
340
-        add_filter(
341
-            'the_content',
342
-            array('EED_Event_Single', 'event_venues'),
343
-            EED_Event_Single::EVENT_VENUES_PRIORITY,
344
-            1
345
-        );
346
-        do_action('AHEE__EED_Event_Single__use_filterable_display_order__after_add_filters');
347
-        // now load our template
348
-        $content = EEH_Template::locate_template('content-espresso_events-details.php');
349
-        // now add our filter back in, plus some others
350
-        add_filter(
351
-            'the_content',
352
-            array('EED_Event_Single', 'event_details'),
353
-            EED_Event_Single::EVENT_DETAILS_PRIORITY
354
-        );
355
-        remove_filter(
356
-            'the_content',
357
-            array('EED_Event_Single', 'event_datetimes'),
358
-            EED_Event_Single::EVENT_DATETIMES_PRIORITY
359
-        );
360
-        remove_filter(
361
-            'the_content',
362
-            array('EED_Event_Single', 'event_tickets'),
363
-            EED_Event_Single::EVENT_TICKETS_PRIORITY
364
-        );
365
-        remove_filter(
366
-            'the_content',
367
-            array('EED_Event_Single', 'event_venues'),
368
-            EED_Event_Single::EVENT_VENUES_PRIORITY
369
-        );
370
-        do_action('AHEE__EED_Event_Single__use_filterable_display_order__after_remove_filters');
371
-        // we're not returning the $content directly because the template we are loading uses the_content (or the_excerpt)
372
-        return $content;
373
-    }
374
-
375
-
376
-    /**
377
-     * event_datetimes - adds datetimes ABOVE content
378
-     *
379
-     * @param        string $content
380
-     * @return        string
381
-     */
382
-    public static function event_datetimes($content)
383
-    {
384
-        return EEH_Template::locate_template('content-espresso_events-datetimes.php') . $content;
385
-    }
386
-
387
-
388
-    /**
389
-     * event_tickets - adds tickets ABOVE content (which includes datetimes)
390
-     *
391
-     * @param        string $content
392
-     * @return        string
393
-     */
394
-    public static function event_tickets($content)
395
-    {
396
-        return EEH_Template::locate_template('content-espresso_events-tickets.php') . $content;
397
-    }
398
-
399
-
400
-    /**
401
-     * event_venues
402
-     *
403
-     * @param    string $content
404
-     * @return    string
405
-     */
406
-    public static function event_venue($content)
407
-    {
408
-        return EED_Event_Single::event_venues($content);
409
-    }
410
-
411
-
412
-    /**
413
-     * event_venues - adds venues BELOW content
414
-     *
415
-     * @param        string $content
416
-     * @return        string
417
-     */
418
-    public static function event_venues($content)
419
-    {
420
-        return $content . EEH_Template::locate_template('content-espresso_events-venues.php');
421
-    }
422
-
423
-
424
-    /**
425
-     * loop_end
426
-     *
427
-     * @param        array $wp_query_array an array containing the WP_Query object
428
-     * @return        void
429
-     */
430
-    public static function loop_end($wp_query_array)
431
-    {
432
-        global $post;
433
-        do_action('AHEE_event_details_after_post', $post, $wp_query_array);
434
-    }
435
-
436
-
437
-    /**
438
-     * wp_enqueue_scripts
439
-     *
440
-     * @return    void
441
-     */
442
-    public function wp_enqueue_scripts()
443
-    {
444
-        // get some style
445
-        if (
446
-            apply_filters('FHEE_enable_default_espresso_css', true)
447
-            && apply_filters('FHEE__EED_Event_Single__wp_enqueue_scripts__enable_css', true)
448
-        ) {
449
-            // first check uploads folder
450
-            if (is_readable(get_stylesheet_directory() . $this->theme . '/style.css')) {
451
-                wp_register_style(
452
-                    $this->theme,
453
-                    get_stylesheet_directory_uri() . $this->theme . '/style.css',
454
-                    array('dashicons', 'espresso_default')
455
-                );
456
-            } else {
457
-                wp_register_style(
458
-                    $this->theme,
459
-                    EE_TEMPLATES_URL . $this->theme . '/style.css',
460
-                    array('dashicons', 'espresso_default')
461
-                );
462
-            }
463
-            wp_enqueue_script($this->theme);
464
-            if (EE_Registry::instance()->CFG->map_settings->use_google_maps) {
465
-                add_action('wp_enqueue_scripts', array('EEH_Maps', 'espresso_google_map_js'), 11);
466
-            }
467
-        }
468
-    }
469
-
470
-
471
-    /**
472
-     * display_venue
473
-     *
474
-     * @return    bool
475
-     */
476
-    public static function display_venue()
477
-    {
478
-        /** @type EE_Event_Single_Config $config */
479
-        $config = EED_Event_Single::instance()->config();
480
-        $display_venue = $config->display_venue === null ? true : $config->display_venue;
481
-        $venue_name = EEH_Venue_View::venue_name();
482
-        return $display_venue && ! empty($venue_name);
483
-    }
16
+	const EVENT_DETAILS_PRIORITY = 100;
17
+	const EVENT_DATETIMES_PRIORITY = 110;
18
+	const EVENT_TICKETS_PRIORITY = 120;
19
+	const EVENT_VENUES_PRIORITY = 130;
20
+
21
+	/**
22
+	 * @type bool $using_get_the_excerpt
23
+	 */
24
+	protected static $using_get_the_excerpt = false;
25
+
26
+
27
+	/**
28
+	 * @type EE_Template_Part_Manager $template_parts
29
+	 */
30
+	protected $template_parts;
31
+
32
+
33
+	/**
34
+	 * @return EED_Module|EED_Event_Single
35
+	 */
36
+	public static function instance()
37
+	{
38
+		return parent::get_instance(__CLASS__);
39
+	}
40
+
41
+
42
+	/**
43
+	 * set_hooks - for hooking into EE Core, other modules, etc
44
+	 *
45
+	 * @return void
46
+	 * @throws InvalidArgumentException
47
+	 * @throws InvalidDataTypeException
48
+	 * @throws InvalidInterfaceException
49
+	 */
50
+	public static function set_hooks()
51
+	{
52
+		add_filter('FHEE_run_EE_wp', '__return_true');
53
+		add_action('wp_loaded', array('EED_Event_Single', 'set_definitions'), 2);
54
+		/** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_type_definitions */
55
+		$custom_post_type_definitions = LoaderFactory::getLoader()->getShared(
56
+			'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
57
+		);
58
+		$custom_post_types = $custom_post_type_definitions->getDefinitions();
59
+		EE_Config::register_route(
60
+			$custom_post_types['espresso_events']['singular_slug'],
61
+			'Event_Single',
62
+			'run'
63
+		);
64
+	}
65
+
66
+	/**
67
+	 * set_hooks_admin - for hooking into EE Admin Core, other modules, etc
68
+	 *
69
+	 * @return    void
70
+	 */
71
+	public static function set_hooks_admin()
72
+	{
73
+		add_action('wp_loaded', array('EED_Event_Single', 'set_definitions'), 2);
74
+	}
75
+
76
+
77
+	/**
78
+	 * set_definitions
79
+	 *
80
+	 * @static
81
+	 * @return void
82
+	 */
83
+	public static function set_definitions()
84
+	{
85
+		define('EVENT_SINGLE_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/');
86
+		define('EVENT_SINGLE_TEMPLATES_PATH', plugin_dir_path(__FILE__) . 'templates/');
87
+	}
88
+
89
+
90
+	/**
91
+	 * set_config
92
+	 *
93
+	 * @void
94
+	 */
95
+	protected function set_config()
96
+	{
97
+		$this->set_config_section('template_settings');
98
+		$this->set_config_class('EE_Event_Single_Config');
99
+		$this->set_config_name('EED_Event_Single');
100
+	}
101
+
102
+
103
+	/**
104
+	 * initialize_template_parts
105
+	 *
106
+	 * @param EE_Config_Base|EE_Event_Single_Config $config
107
+	 * @return EE_Template_Part_Manager
108
+	 */
109
+	public function initialize_template_parts(EE_Event_Single_Config $config = null)
110
+	{
111
+		/** @type EE_Event_Single_Config $config */
112
+		$config = $config instanceof EE_Event_Single_Config ? $config : $this->config();
113
+		EEH_Autoloader::instance()->register_template_part_autoloaders();
114
+		$template_parts = new EE_Template_Part_Manager();
115
+		$template_parts->add_template_part(
116
+			'tickets',
117
+			esc_html__('Ticket Selector', 'event_espresso'),
118
+			'content-espresso_events-tickets.php',
119
+			$config->display_order_tickets
120
+		);
121
+		$template_parts->add_template_part(
122
+			'datetimes',
123
+			esc_html__('Dates and Times', 'event_espresso'),
124
+			'content-espresso_events-datetimes.php',
125
+			$config->display_order_datetimes
126
+		);
127
+		$template_parts->add_template_part(
128
+			'event',
129
+			esc_html__('Event Description', 'event_espresso'),
130
+			'content-espresso_events-details.php',
131
+			$config->display_order_event
132
+		);
133
+		$template_parts->add_template_part(
134
+			'venue',
135
+			esc_html__('Venue Information', 'event_espresso'),
136
+			'content-espresso_events-venues.php',
137
+			$config->display_order_venue
138
+		);
139
+		do_action('AHEE__EED_Event_Single__initialize_template_parts', $template_parts);
140
+		return $template_parts;
141
+	}
142
+
143
+
144
+	/**
145
+	 * run - initial module setup
146
+	 *
147
+	 * @param WP $WP
148
+	 * @return    void
149
+	 */
150
+	public function run($WP)
151
+	{
152
+		// ensure valid EE_Events_Single_Config() object exists
153
+		$this->set_config();
154
+		// check what template is loaded
155
+		add_filter('template_include', array($this, 'template_include'), 999, 1);
156
+		add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
157
+		// load css
158
+		add_action('wp_enqueue_scripts', array($this, 'wp_enqueue_scripts'), 10);
159
+	}
160
+
161
+
162
+	/**
163
+	 * template_include
164
+	 *
165
+	 * @param    string $template
166
+	 * @return    string
167
+	 */
168
+	public function template_include($template)
169
+	{
170
+		global $post;
171
+		/** @type EE_Event_Single_Config $config */
172
+		$config = $this->config();
173
+		if ($config->display_status_banner_single) {
174
+			add_filter('the_title', array('EED_Event_Single', 'the_title'), 100, 2);
175
+		}
176
+		// not a custom template?
177
+		if (
178
+			! post_password_required($post)
179
+			&& (
180
+				apply_filters('FHEE__EED_Event_Single__template_include__allow_custom_selected_template', false)
181
+				|| EE_Registry::instance()
182
+							  ->load_core('Front_Controller')
183
+							  ->get_selected_template() !== 'single-espresso_events.php'
184
+			)
185
+		) {
186
+			EEH_Template::load_espresso_theme_functions();
187
+			// then add extra event data via hooks
188
+			add_action('loop_start', array('EED_Event_Single', 'loop_start'));
189
+			add_filter('get_the_excerpt', array('EED_Event_Single', 'get_the_excerpt'), 1, 1);
190
+			add_filter(
191
+				'the_content',
192
+				array('EED_Event_Single', 'event_details'),
193
+				EED_Event_Single::EVENT_DETAILS_PRIORITY
194
+			);
195
+			add_action('loop_end', array('EED_Event_Single', 'loop_end'));
196
+			// don't display entry meta because the existing theme will take car of that
197
+			add_filter('FHEE__content_espresso_events_details_template__display_entry_meta', '__return_false');
198
+		}
199
+		return $template;
200
+	}
201
+
202
+
203
+	/**
204
+	 * loop_start
205
+	 *
206
+	 * @param    array $wp_query_array an array containing the WP_Query object
207
+	 * @return    void
208
+	 */
209
+	public static function loop_start($wp_query_array)
210
+	{
211
+		global $post;
212
+		do_action('AHEE_event_details_before_post', $post, $wp_query_array);
213
+	}
214
+
215
+
216
+	/**
217
+	 * the_title
218
+	 *
219
+	 * @param    string $title
220
+	 * @param    int    $id
221
+	 * @return    string
222
+	 */
223
+	public static function the_title($title = '', $id = 0)
224
+	{
225
+		global $post;
226
+		return ((function_exists('wp_is_block_theme') && wp_is_block_theme()) || in_the_loop()) && $post->ID === (int) $id
227
+			? espresso_event_status_banner($post->ID) . $title
228
+			: $title;
229
+	}
230
+
231
+
232
+	/**
233
+	 * get_the_excerpt
234
+	 * kinda hacky, but if a theme is using get_the_excerpt(),
235
+	 * then we need to remove our filters on the_content()
236
+	 *
237
+	 * @param        string $excerpt
238
+	 * @return        string
239
+	 */
240
+	public static function get_the_excerpt($excerpt = '')
241
+	{
242
+		EED_Event_Single::$using_get_the_excerpt = true;
243
+		add_filter('wp_trim_excerpt', array('EED_Event_Single', 'end_get_the_excerpt'), 999, 1);
244
+		return $excerpt;
245
+	}
246
+
247
+
248
+	/**
249
+	 * end_get_the_excerpt
250
+	 *
251
+	 * @param  string $text
252
+	 * @return string
253
+	 */
254
+	public static function end_get_the_excerpt($text = '')
255
+	{
256
+		EED_Event_Single::$using_get_the_excerpt = false;
257
+		return $text;
258
+	}
259
+
260
+
261
+	/**
262
+	 * event_details
263
+	 *
264
+	 * @param    string $content
265
+	 * @return    string
266
+	 */
267
+	public static function event_details($content)
268
+	{
269
+		global $post;
270
+		static $current_post_ID = 0;
271
+		if (
272
+			$current_post_ID !== $post->ID
273
+			&& $post->post_type === 'espresso_events'
274
+			&& ! EED_Event_Single::$using_get_the_excerpt
275
+			&& ! post_password_required()
276
+		) {
277
+			// Set current post ID to prevent showing content twice, but only if headers have definitely been sent.
278
+			// Reason being is that some plugins, like Yoast, need to run through a copy of the loop early
279
+			// BEFORE headers are sent in order to examine the post content and generate content for the HTML header.
280
+			// We want to allow those plugins to still do their thing and have access to our content, but depending on
281
+			// how your event content is being displayed (shortcode, CPT route, etc), this filter can get applied twice,
282
+			// so the following allows this filter to be applied multiple times, but only once for real
283
+			$current_post_ID = did_action('loop_start') ? $post->ID : 0;
284
+			if (EE_Registry::instance()->CFG->template_settings->EED_Event_Single->use_sortable_display_order) {
285
+				// we need to first remove this callback from being applied to the_content()
286
+				// (otherwise it will recurse and blow up the interweb)
287
+				remove_filter(
288
+					'the_content',
289
+					array('EED_Event_Single', 'event_details'),
290
+					EED_Event_Single::EVENT_DETAILS_PRIORITY
291
+				);
292
+				EED_Event_Single::instance()->template_parts = EED_Event_Single::instance()->initialize_template_parts(
293
+				);
294
+				$content = EEH_Template::locate_template('content-espresso_events-details.php');
295
+				$content = EED_Event_Single::instance()->template_parts->apply_template_part_filters($content);
296
+				add_filter(
297
+					'the_content',
298
+					array('EED_Event_Single', 'event_details'),
299
+					EED_Event_Single::EVENT_DETAILS_PRIORITY
300
+				);
301
+			} else {
302
+				$content = EED_Event_Single::use_filterable_display_order();
303
+			}
304
+		}
305
+		return $content;
306
+	}
307
+
308
+
309
+	/**
310
+	 * use_filterable_display_order
311
+	 *
312
+	 * @return string
313
+	 */
314
+	protected static function use_filterable_display_order()
315
+	{
316
+		// since the 'content-espresso_events-details.php' template might be used directly from within a theme,
317
+		// it uses the_content() for displaying the $post->post_content
318
+		// so in order to load a template that uses the_content()
319
+		// from within a callback being used to filter the_content(),
320
+		// we need to first remove this callback from being applied to the_content()
321
+		// (otherwise it will recurse and blow up the interweb)
322
+		remove_filter(
323
+			'the_content',
324
+			array('EED_Event_Single', 'event_details'),
325
+			EED_Event_Single::EVENT_DETAILS_PRIORITY
326
+		);
327
+		// now add additional content
328
+		add_filter(
329
+			'the_content',
330
+			array('EED_Event_Single', 'event_datetimes'),
331
+			EED_Event_Single::EVENT_DATETIMES_PRIORITY,
332
+			1
333
+		);
334
+		add_filter(
335
+			'the_content',
336
+			array('EED_Event_Single', 'event_tickets'),
337
+			EED_Event_Single::EVENT_TICKETS_PRIORITY,
338
+			1
339
+		);
340
+		add_filter(
341
+			'the_content',
342
+			array('EED_Event_Single', 'event_venues'),
343
+			EED_Event_Single::EVENT_VENUES_PRIORITY,
344
+			1
345
+		);
346
+		do_action('AHEE__EED_Event_Single__use_filterable_display_order__after_add_filters');
347
+		// now load our template
348
+		$content = EEH_Template::locate_template('content-espresso_events-details.php');
349
+		// now add our filter back in, plus some others
350
+		add_filter(
351
+			'the_content',
352
+			array('EED_Event_Single', 'event_details'),
353
+			EED_Event_Single::EVENT_DETAILS_PRIORITY
354
+		);
355
+		remove_filter(
356
+			'the_content',
357
+			array('EED_Event_Single', 'event_datetimes'),
358
+			EED_Event_Single::EVENT_DATETIMES_PRIORITY
359
+		);
360
+		remove_filter(
361
+			'the_content',
362
+			array('EED_Event_Single', 'event_tickets'),
363
+			EED_Event_Single::EVENT_TICKETS_PRIORITY
364
+		);
365
+		remove_filter(
366
+			'the_content',
367
+			array('EED_Event_Single', 'event_venues'),
368
+			EED_Event_Single::EVENT_VENUES_PRIORITY
369
+		);
370
+		do_action('AHEE__EED_Event_Single__use_filterable_display_order__after_remove_filters');
371
+		// we're not returning the $content directly because the template we are loading uses the_content (or the_excerpt)
372
+		return $content;
373
+	}
374
+
375
+
376
+	/**
377
+	 * event_datetimes - adds datetimes ABOVE content
378
+	 *
379
+	 * @param        string $content
380
+	 * @return        string
381
+	 */
382
+	public static function event_datetimes($content)
383
+	{
384
+		return EEH_Template::locate_template('content-espresso_events-datetimes.php') . $content;
385
+	}
386
+
387
+
388
+	/**
389
+	 * event_tickets - adds tickets ABOVE content (which includes datetimes)
390
+	 *
391
+	 * @param        string $content
392
+	 * @return        string
393
+	 */
394
+	public static function event_tickets($content)
395
+	{
396
+		return EEH_Template::locate_template('content-espresso_events-tickets.php') . $content;
397
+	}
398
+
399
+
400
+	/**
401
+	 * event_venues
402
+	 *
403
+	 * @param    string $content
404
+	 * @return    string
405
+	 */
406
+	public static function event_venue($content)
407
+	{
408
+		return EED_Event_Single::event_venues($content);
409
+	}
410
+
411
+
412
+	/**
413
+	 * event_venues - adds venues BELOW content
414
+	 *
415
+	 * @param        string $content
416
+	 * @return        string
417
+	 */
418
+	public static function event_venues($content)
419
+	{
420
+		return $content . EEH_Template::locate_template('content-espresso_events-venues.php');
421
+	}
422
+
423
+
424
+	/**
425
+	 * loop_end
426
+	 *
427
+	 * @param        array $wp_query_array an array containing the WP_Query object
428
+	 * @return        void
429
+	 */
430
+	public static function loop_end($wp_query_array)
431
+	{
432
+		global $post;
433
+		do_action('AHEE_event_details_after_post', $post, $wp_query_array);
434
+	}
435
+
436
+
437
+	/**
438
+	 * wp_enqueue_scripts
439
+	 *
440
+	 * @return    void
441
+	 */
442
+	public function wp_enqueue_scripts()
443
+	{
444
+		// get some style
445
+		if (
446
+			apply_filters('FHEE_enable_default_espresso_css', true)
447
+			&& apply_filters('FHEE__EED_Event_Single__wp_enqueue_scripts__enable_css', true)
448
+		) {
449
+			// first check uploads folder
450
+			if (is_readable(get_stylesheet_directory() . $this->theme . '/style.css')) {
451
+				wp_register_style(
452
+					$this->theme,
453
+					get_stylesheet_directory_uri() . $this->theme . '/style.css',
454
+					array('dashicons', 'espresso_default')
455
+				);
456
+			} else {
457
+				wp_register_style(
458
+					$this->theme,
459
+					EE_TEMPLATES_URL . $this->theme . '/style.css',
460
+					array('dashicons', 'espresso_default')
461
+				);
462
+			}
463
+			wp_enqueue_script($this->theme);
464
+			if (EE_Registry::instance()->CFG->map_settings->use_google_maps) {
465
+				add_action('wp_enqueue_scripts', array('EEH_Maps', 'espresso_google_map_js'), 11);
466
+			}
467
+		}
468
+	}
469
+
470
+
471
+	/**
472
+	 * display_venue
473
+	 *
474
+	 * @return    bool
475
+	 */
476
+	public static function display_venue()
477
+	{
478
+		/** @type EE_Event_Single_Config $config */
479
+		$config = EED_Event_Single::instance()->config();
480
+		$display_venue = $config->display_venue === null ? true : $config->display_venue;
481
+		$venue_name = EEH_Venue_View::venue_name();
482
+		return $display_venue && ! empty($venue_name);
483
+	}
484 484
 }
485 485
 
486 486
 
@@ -492,5 +492,5 @@  discard block
 block discarded – undo
492 492
  */
493 493
 function espresso_display_venue_in_event_details()
494 494
 {
495
-    return EED_Event_Single::display_venue();
495
+	return EED_Event_Single::display_venue();
496 496
 }
Please login to merge, or discard this patch.
core/business/EE_Registration_Processor.class.php 2 patches
Spacing   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -81,8 +81,8 @@  discard block
 block discarded – undo
81 81
     public static function instance(RequestInterface $request = null)
82 82
     {
83 83
         // check if class object is instantiated
84
-        if (! self::$_instance instanceof EE_Registration_Processor) {
85
-            if (! $request instanceof RequestInterface) {
84
+        if ( ! self::$_instance instanceof EE_Registration_Processor) {
85
+            if ( ! $request instanceof RequestInterface) {
86 86
                 $request = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\Request');
87 87
             }
88 88
             self::$_instance = new self($request);
@@ -108,7 +108,7 @@  discard block
 block discarded – undo
108 108
      */
109 109
     public function old_reg_status($REG_ID)
110 110
     {
111
-        return isset($this->_old_reg_status[ $REG_ID ]) ? $this->_old_reg_status[ $REG_ID ] : null;
111
+        return isset($this->_old_reg_status[$REG_ID]) ? $this->_old_reg_status[$REG_ID] : null;
112 112
     }
113 113
 
114 114
 
@@ -119,8 +119,8 @@  discard block
 block discarded – undo
119 119
     public function set_old_reg_status($REG_ID, $old_reg_status)
120 120
     {
121 121
         // only set the first time
122
-        if (! isset($this->_old_reg_status[ $REG_ID ])) {
123
-            $this->_old_reg_status[ $REG_ID ] = $old_reg_status;
122
+        if ( ! isset($this->_old_reg_status[$REG_ID])) {
123
+            $this->_old_reg_status[$REG_ID] = $old_reg_status;
124 124
         }
125 125
     }
126 126
 
@@ -131,7 +131,7 @@  discard block
 block discarded – undo
131 131
      */
132 132
     public function new_reg_status($REG_ID)
133 133
     {
134
-        return isset($this->_new_reg_status[ $REG_ID ]) ? $this->_new_reg_status[ $REG_ID ] : null;
134
+        return isset($this->_new_reg_status[$REG_ID]) ? $this->_new_reg_status[$REG_ID] : null;
135 135
     }
136 136
 
137 137
 
@@ -141,7 +141,7 @@  discard block
 block discarded – undo
141 141
      */
142 142
     public function set_new_reg_status($REG_ID, $new_reg_status)
143 143
     {
144
-        $this->_new_reg_status[ $REG_ID ] = $new_reg_status;
144
+        $this->_new_reg_status[$REG_ID] = $new_reg_status;
145 145
     }
146 146
 
147 147
 
@@ -208,7 +208,7 @@  discard block
 block discarded – undo
208 208
         if (
209 209
             $this->reg_status_updated($registration->ID())
210 210
             && (
211
-                (! $this->request->isAdmin() || $this->request->isFrontAjax())
211
+                ( ! $this->request->isAdmin() || $this->request->isFrontAjax())
212 212
                 || EE_Registry::instance()->CAP->current_user_can(
213 213
                     'ee_edit_registration',
214 214
                     'toggle_registration_status',
@@ -271,7 +271,7 @@  discard block
 block discarded – undo
271 271
                 $registration->save();
272 272
             }
273 273
             // don't trigger notifications during IPNs because they will get triggered by EE_Payment_Processor
274
-            if (! EE_Processor_Base::$IPN) {
274
+            if ( ! EE_Processor_Base::$IPN) {
275 275
                 // otherwise, send out notifications
276 276
                 add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true', 10);
277 277
             }
@@ -330,7 +330,7 @@  discard block
 block discarded – undo
330 330
                 $registration->save();
331 331
             }
332 332
             // don't trigger notifications during IPNs because they will get triggered by EE_Payment_Processor
333
-            if (! EE_Processor_Base::$IPN) {
333
+            if ( ! EE_Processor_Base::$IPN) {
334 334
                 // otherwise, send out notifications
335 335
                 add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true', 10);
336 336
             }
@@ -378,7 +378,7 @@  discard block
 block discarded – undo
378 378
         // set initial REG_Status
379 379
         $this->set_old_reg_status($registration->ID(), $registration->status_ID());
380 380
         // was a payment just made ?
381
-        $payment    = isset($additional_details['payment_updates'], $additional_details['last_payment'])
381
+        $payment = isset($additional_details['payment_updates'], $additional_details['last_payment'])
382 382
                       && $additional_details['payment_updates']
383 383
                       && $additional_details['last_payment'] instanceof EE_Payment
384 384
             ? $additional_details['last_payment']
@@ -403,14 +403,14 @@  discard block
 block discarded – undo
403 403
                 || (
404 404
                     $payment instanceof EE_Payment && $payment->is_approved()
405 405
                     && // this specific registration has not yet been paid for
406
-                    ! isset(self::$_amount_paid[ $registration->ID() ])
406
+                    ! isset(self::$_amount_paid[$registration->ID()])
407 407
                     && // payment amount, less what we have already attributed to other registrations, is greater than this reg's final price
408 408
                     $payment->amount() - $total_paid >= $registration->final_price()
409 409
                 )
410 410
             )
411 411
         ) {
412 412
             // mark as paid
413
-            self::$_amount_paid[ $registration->ID() ] = $registration->final_price();
413
+            self::$_amount_paid[$registration->ID()] = $registration->final_price();
414 414
             // track new REG_Status
415 415
             $this->set_new_reg_status($registration->ID(), EEM_Registration::status_id_approved);
416 416
             // toggle status to approved
@@ -419,7 +419,7 @@  discard block
 block discarded – undo
419 419
                 $registration->save();
420 420
             }
421 421
             // don't trigger notifications during IPNs because they will get triggered by EE_Payment_Processor
422
-            if (! EE_Processor_Base::$IPN) {
422
+            if ( ! EE_Processor_Base::$IPN) {
423 423
                 // otherwise, send out notifications
424 424
                 add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true', 10);
425 425
             }
@@ -453,7 +453,7 @@  discard block
 block discarded – undo
453 453
     public function trigger_registration_update_notifications($registration, array $additional_details = [])
454 454
     {
455 455
         try {
456
-            if (! $registration instanceof EE_Registration) {
456
+            if ( ! $registration instanceof EE_Registration) {
457 457
                 throw new EE_Error(
458 458
                     esc_html__('An invalid registration was received.', 'event_espresso')
459 459
                 );
@@ -544,8 +544,8 @@  discard block
 block discarded – undo
544 544
         foreach ($transaction->registrations() as $registration) {
545 545
             /** @var EE_Line_Item $line_item */
546 546
             $line_item = EEM_Line_Item::instance()->get_line_item_for_registration($registration);
547
-            if (isset($reg_final_price_per_ticket_line_item[ $line_item->ID() ])) {
548
-                $registration->set_final_price($reg_final_price_per_ticket_line_item[ $line_item->ID() ]);
547
+            if (isset($reg_final_price_per_ticket_line_item[$line_item->ID()])) {
548
+                $registration->set_final_price($reg_final_price_per_ticket_line_item[$line_item->ID()]);
549 549
                 if ($save_regs) {
550 550
                     $registration->save();
551 551
                 }
@@ -585,7 +585,7 @@  discard block
 block discarded – undo
585 585
             ],
586 586
             'REG_final_price'
587 587
         );
588
-        $diff                = $transaction->total() - $reg_final_price_sum;
588
+        $diff = $transaction->total() - $reg_final_price_sum;
589 589
         // ok then, just grab one of the registrations
590 590
         if ($diff !== (float) 0) {
591 591
             $a_reg = EEM_Registration::instance()->get_one(
@@ -622,11 +622,11 @@  discard block
 block discarded – undo
622 622
         $closed_reg_statuses = ! empty($closed_reg_statuses)
623 623
             ? $closed_reg_statuses
624 624
             : EEM_Registration::closed_reg_statuses();
625
-        if (! in_array($registration->status_ID(), $closed_reg_statuses, true)) {
625
+        if ( ! in_array($registration->status_ID(), $closed_reg_statuses, true)) {
626 626
             return false;
627 627
         }
628 628
         // release a reserved ticket by decrementing ticket and datetime reserved values
629
-        $registration->release_reserved_ticket(true, 'RegProcessor:' . __LINE__);
629
+        $registration->release_reserved_ticket(true, 'RegProcessor:'.__LINE__);
630 630
         $registration->set_final_price(0);
631 631
         if ($update_reg) {
632 632
             $registration->save();
@@ -658,7 +658,7 @@  discard block
 block discarded – undo
658 658
             return false;
659 659
         }
660 660
         $ticket = $registration->ticket();
661
-        if (! $ticket instanceof EE_Ticket) {
661
+        if ( ! $ticket instanceof EE_Ticket) {
662 662
             throw new EE_Error(
663 663
                 sprintf(
664 664
                     esc_html__(
@@ -708,7 +708,7 @@  discard block
 block discarded – undo
708 708
         $total_ticket_count = 1
709 709
     ) {
710 710
         EE_Error::doing_it_wrong(
711
-            __CLASS__ . '::' . __FUNCTION__,
711
+            __CLASS__.'::'.__FUNCTION__,
712 712
             sprintf(
713 713
                 esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'),
714 714
                 '\EventEspresso\core\domain\services\registration\CreateRegistrationService::create()'
@@ -718,7 +718,7 @@  discard block
 block discarded – undo
718 718
         );
719 719
         // grab the related ticket object for this line_item
720 720
         $ticket = $line_item->ticket();
721
-        if (! $ticket instanceof EE_Ticket) {
721
+        if ( ! $ticket instanceof EE_Ticket) {
722 722
             EE_Error::add_error(
723 723
                 sprintf(
724 724
                     esc_html__('Line item %s did not contain a valid ticket', 'event_espresso'),
@@ -756,7 +756,7 @@  discard block
 block discarded – undo
756 756
     public function generate_reg_url_link($att_nmbr, $item)
757 757
     {
758 758
         EE_Error::doing_it_wrong(
759
-            __CLASS__ . '::' . __FUNCTION__,
759
+            __CLASS__.'::'.__FUNCTION__,
760 760
             sprintf(
761 761
                 esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'),
762 762
                 'EventEspresso\core\domain\entities\RegUrlLink'
@@ -782,7 +782,7 @@  discard block
 block discarded – undo
782 782
     public function generate_reg_code(EE_Registration $registration)
783 783
     {
784 784
         EE_Error::doing_it_wrong(
785
-            __CLASS__ . '::' . __FUNCTION__,
785
+            __CLASS__.'::'.__FUNCTION__,
786 786
             sprintf(
787 787
                 esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'),
788 788
                 'EventEspresso\core\domain\entities\RegCode'
Please login to merge, or discard this patch.
Indentation   +773 added lines, -773 removed lines patch added patch discarded remove patch
@@ -25,778 +25,778 @@
 block discarded – undo
25 25
  */
26 26
 class EE_Registration_Processor extends EE_Processor_Base
27 27
 {
28
-    /**
29
-     * @var EE_Registration_Processor $_instance
30
-     * @access    private
31
-     */
32
-    private static $_instance;
33
-
34
-    /**
35
-     * initial reg status at the beginning of this request.
36
-     * indexed by registration ID
37
-     *
38
-     * @var array
39
-     */
40
-    protected $_old_reg_status = [];
41
-
42
-    /**
43
-     * reg status at the end of the request after all processing.
44
-     * indexed by registration ID
45
-     *
46
-     * @var array
47
-     */
48
-    protected $_new_reg_status = [];
49
-
50
-    /**
51
-     * amounts paid at the end of the request after all processing.
52
-     * indexed by registration ID
53
-     *
54
-     * @var array
55
-     */
56
-    protected static $_amount_paid = [];
57
-
58
-    /**
59
-     * Cache of the reg final price for registrations corresponding to a ticket line item
60
-     *
61
-     * @deprecated
62
-     * @var array @see EEH_Line_Item::calculate_reg_final_prices_per_line_item()'s return value
63
-     */
64
-    protected $_reg_final_price_per_tkt_line_item;
65
-
66
-    /**
67
-     * @var RequestInterface $request
68
-     */
69
-    protected $request;
70
-
71
-
72
-    /**
73
-     * @singleton method used to instantiate class object
74
-     * @param RequestInterface|null $request
75
-     * @return EE_Registration_Processor instance
76
-     * @throws InvalidArgumentException
77
-     * @throws InvalidInterfaceException
78
-     * @throws InvalidDataTypeException
79
-     */
80
-    public static function instance(RequestInterface $request = null)
81
-    {
82
-        // check if class object is instantiated
83
-        if (! self::$_instance instanceof EE_Registration_Processor) {
84
-            if (! $request instanceof RequestInterface) {
85
-                $request = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\Request');
86
-            }
87
-            self::$_instance = new self($request);
88
-        }
89
-        return self::$_instance;
90
-    }
91
-
92
-
93
-    /**
94
-     * EE_Registration_Processor constructor.
95
-     *
96
-     * @param RequestInterface $request
97
-     */
98
-    public function __construct(RequestInterface $request)
99
-    {
100
-        $this->request = $request;
101
-    }
102
-
103
-
104
-    /**
105
-     * @param int $REG_ID
106
-     * @return string
107
-     */
108
-    public function old_reg_status($REG_ID)
109
-    {
110
-        return isset($this->_old_reg_status[ $REG_ID ]) ? $this->_old_reg_status[ $REG_ID ] : null;
111
-    }
112
-
113
-
114
-    /**
115
-     * @param int    $REG_ID
116
-     * @param string $old_reg_status
117
-     */
118
-    public function set_old_reg_status($REG_ID, $old_reg_status)
119
-    {
120
-        // only set the first time
121
-        if (! isset($this->_old_reg_status[ $REG_ID ])) {
122
-            $this->_old_reg_status[ $REG_ID ] = $old_reg_status;
123
-        }
124
-    }
125
-
126
-
127
-    /**
128
-     * @param int $REG_ID
129
-     * @return string
130
-     */
131
-    public function new_reg_status($REG_ID)
132
-    {
133
-        return isset($this->_new_reg_status[ $REG_ID ]) ? $this->_new_reg_status[ $REG_ID ] : null;
134
-    }
135
-
136
-
137
-    /**
138
-     * @param int    $REG_ID
139
-     * @param string $new_reg_status
140
-     */
141
-    public function set_new_reg_status($REG_ID, $new_reg_status)
142
-    {
143
-        $this->_new_reg_status[ $REG_ID ] = $new_reg_status;
144
-    }
145
-
146
-
147
-    /**
148
-     * reg_status_updated
149
-     *
150
-     * @param int $REG_ID
151
-     * @return bool
152
-     */
153
-    public function reg_status_updated($REG_ID)
154
-    {
155
-        return $this->new_reg_status($REG_ID) !== $this->old_reg_status($REG_ID);
156
-    }
157
-
158
-
159
-    /**
160
-     * @param EE_Registration $registration
161
-     * @throws EE_Error
162
-     * @throws EntityNotFoundException
163
-     * @throws InvalidArgumentException
164
-     * @throws InvalidDataTypeException
165
-     * @throws InvalidInterfaceException
166
-     * @throws ReflectionException
167
-     * @throws RuntimeException
168
-     */
169
-    public function update_registration_status_and_trigger_notifications(EE_Registration $registration)
170
-    {
171
-        $this->toggle_incomplete_registration_status_to_default($registration, false);
172
-        $this->toggle_registration_status_for_default_approved_events($registration, false);
173
-        $this->toggle_registration_status_if_no_monies_owing($registration, false);
174
-        $registration->save();
175
-        // trigger notifications
176
-        $this->trigger_registration_update_notifications($registration);
177
-    }
178
-
179
-
180
-    /**
181
-     *    manually_update_registration_status
182
-     *
183
-     * @access public
184
-     * @param EE_Registration $registration
185
-     * @param string          $new_reg_status
186
-     * @param bool            $save TRUE will save the registration if the status is updated, FALSE will leave that up
187
-     *                              to client code
188
-     * @return bool
189
-     * @throws EE_Error
190
-     * @throws EntityNotFoundException
191
-     * @throws InvalidArgumentException
192
-     * @throws InvalidDataTypeException
193
-     * @throws InvalidInterfaceException
194
-     * @throws ReflectionException
195
-     * @throws RuntimeException
196
-     */
197
-    public function manually_update_registration_status(
198
-        EE_Registration $registration,
199
-        $new_reg_status = '',
200
-        $save = true
201
-    ) {
202
-        // set initial REG_Status
203
-        $this->set_old_reg_status($registration->ID(), $registration->status_ID());
204
-        // set incoming REG_Status
205
-        $this->set_new_reg_status($registration->ID(), $new_reg_status);
206
-        // toggle reg status but only if it has changed and the user can do so
207
-        if (
208
-            $this->reg_status_updated($registration->ID())
209
-            && (
210
-                (! $this->request->isAdmin() || $this->request->isFrontAjax())
211
-                || EE_Registry::instance()->CAP->current_user_can(
212
-                    'ee_edit_registration',
213
-                    'toggle_registration_status',
214
-                    $registration->ID()
215
-                )
216
-            )
217
-        ) {
218
-            // change status to new value
219
-            $updated = $registration->set_status($this->new_reg_status($registration->ID()));
220
-            if ($updated && $save) {
221
-                $registration->save();
222
-            }
223
-            return true;
224
-        }
225
-        return false;
226
-    }
227
-
228
-
229
-    /**
230
-     *    toggle_incomplete_registration_status_to_default
231
-     *        changes any incomplete registrations to either the event or global default registration status
232
-     *
233
-     * @access public
234
-     * @param EE_Registration       $registration
235
-     * @param bool                  $save TRUE will save the registration if the status is updated, FALSE will leave
236
-     *                                    that up to client code
237
-     * @param ContextInterface|null $context
238
-     * @return void
239
-     * @throws EE_Error
240
-     * @throws InvalidArgumentException
241
-     * @throws ReflectionException
242
-     * @throws RuntimeException
243
-     * @throws EntityNotFoundException
244
-     * @throws InvalidDataTypeException
245
-     * @throws InvalidInterfaceException
246
-     */
247
-    public function toggle_incomplete_registration_status_to_default(
248
-        EE_Registration $registration,
249
-        $save = true,
250
-        ContextInterface $context = null
251
-    ) {
252
-        $existing_reg_status = $registration->status_ID();
253
-        // set initial REG_Status
254
-        $this->set_old_reg_status($registration->ID(), $existing_reg_status);
255
-        // is the registration currently incomplete ?
256
-        if ($registration->status_ID() === EEM_Registration::status_id_incomplete) {
257
-            // grab default reg status for the event, if set
258
-            $event_default_registration_status = $registration->event()->default_registration_status();
259
-            // if no default reg status is set for the event, then use the global value
260
-            $STS_ID = ! empty($event_default_registration_status)
261
-                ? $event_default_registration_status
262
-                : EE_Registry::instance()->CFG->registration->default_STS_ID;
263
-            // if the event default reg status is approved, then downgrade temporarily to payment pending to ensure that payments are triggered
264
-            $STS_ID = $STS_ID === EEM_Registration::status_id_approved ? EEM_Registration::status_id_pending_payment
265
-                : $STS_ID;
266
-            // set incoming REG_Status
267
-            $this->set_new_reg_status($registration->ID(), $STS_ID);
268
-            $registration->set_status($STS_ID, false, $context);
269
-            if ($save) {
270
-                $registration->save();
271
-            }
272
-            // don't trigger notifications during IPNs because they will get triggered by EE_Payment_Processor
273
-            if (! EE_Processor_Base::$IPN) {
274
-                // otherwise, send out notifications
275
-                add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true', 10);
276
-            }
277
-            // DEBUG LOG
278
-            // $this->log(
279
-            //     __CLASS__,
280
-            //     __FUNCTION__,
281
-            //     __LINE__,
282
-            //     $registration->transaction(),
283
-            //     array(
284
-            //         'IPN' => EE_Processor_Base::$IPN,
285
-            //         'deliver_notifications' => has_filter(
286
-            //             'FHEE__EED_Messages___maybe_registration__deliver_notifications'
287
-            //         ),
288
-            //     )
289
-            // );
290
-        }
291
-    }
292
-
293
-
294
-    /**
295
-     *    toggle_registration_status_for_default_approved_events
296
-     *
297
-     * @access public
298
-     * @param EE_Registration $registration
299
-     * @param bool            $save TRUE will save the registration if the status is updated, FALSE will leave that up
300
-     *                              to client code
301
-     * @return bool
302
-     * @throws EE_Error
303
-     * @throws EntityNotFoundException
304
-     * @throws InvalidArgumentException
305
-     * @throws InvalidDataTypeException
306
-     * @throws InvalidInterfaceException
307
-     * @throws ReflectionException
308
-     * @throws RuntimeException
309
-     */
310
-    public function toggle_registration_status_for_default_approved_events(EE_Registration $registration, $save = true)
311
-    {
312
-        $reg_status = $registration->status_ID();
313
-        // set initial REG_Status
314
-        $this->set_old_reg_status($registration->ID(), $reg_status);
315
-        // if not already, toggle reg status to approved IF the event default reg status is approved
316
-        // ( as long as the registration wasn't cancelled or declined at some point )
317
-        if (
318
-            $reg_status !== EEM_Registration::status_id_cancelled
319
-            && $reg_status
320
-               !== EEM_Registration::status_id_declined
321
-            && $reg_status !== EEM_Registration::status_id_approved
322
-            && $registration->event()->default_registration_status() === EEM_Registration::status_id_approved
323
-        ) {
324
-            // set incoming REG_Status
325
-            $this->set_new_reg_status($registration->ID(), EEM_Registration::status_id_approved);
326
-            // toggle status to approved
327
-            $registration->set_status(EEM_Registration::status_id_approved);
328
-            if ($save) {
329
-                $registration->save();
330
-            }
331
-            // don't trigger notifications during IPNs because they will get triggered by EE_Payment_Processor
332
-            if (! EE_Processor_Base::$IPN) {
333
-                // otherwise, send out notifications
334
-                add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true', 10);
335
-            }
336
-            // DEBUG LOG
337
-            // $this->log(
338
-            //     __CLASS__,
339
-            //     __FUNCTION__,
340
-            //     __LINE__,
341
-            //     $registration->transaction(),
342
-            //     array(
343
-            //         'IPN' => EE_Processor_Base::$IPN,
344
-            //         'deliver_notifications' => has_filter(
345
-            //             'FHEE__EED_Messages___maybe_registration__deliver_notifications'
346
-            //         ),
347
-            //     )
348
-            // );
349
-            return true;
350
-        }
351
-        return false;
352
-    }
353
-
354
-
355
-    /**
356
-     *    toggle_registration_statuses_if_no_monies_owing
357
-     *
358
-     * @access public
359
-     * @param EE_Registration $registration
360
-     * @param bool            $save TRUE will save the registration if the status is updated, FALSE will leave that up
361
-     *                              to client code
362
-     * @param array           $additional_details
363
-     * @return bool
364
-     * @throws EE_Error
365
-     * @throws EntityNotFoundException
366
-     * @throws InvalidArgumentException
367
-     * @throws InvalidDataTypeException
368
-     * @throws InvalidInterfaceException
369
-     * @throws ReflectionException
370
-     * @throws RuntimeException
371
-     */
372
-    public function toggle_registration_status_if_no_monies_owing(
373
-        EE_Registration $registration,
374
-        $save = true,
375
-        array $additional_details = []
376
-    ) {
377
-        // set initial REG_Status
378
-        $this->set_old_reg_status($registration->ID(), $registration->status_ID());
379
-        // was a payment just made ?
380
-        $payment    = isset($additional_details['payment_updates'], $additional_details['last_payment'])
381
-                      && $additional_details['payment_updates']
382
-                      && $additional_details['last_payment'] instanceof EE_Payment
383
-            ? $additional_details['last_payment']
384
-            : null;
385
-        $total_paid = array_sum(self::$_amount_paid);
386
-        // toggle reg status to approved IF
387
-        if (
28
+	/**
29
+	 * @var EE_Registration_Processor $_instance
30
+	 * @access    private
31
+	 */
32
+	private static $_instance;
33
+
34
+	/**
35
+	 * initial reg status at the beginning of this request.
36
+	 * indexed by registration ID
37
+	 *
38
+	 * @var array
39
+	 */
40
+	protected $_old_reg_status = [];
41
+
42
+	/**
43
+	 * reg status at the end of the request after all processing.
44
+	 * indexed by registration ID
45
+	 *
46
+	 * @var array
47
+	 */
48
+	protected $_new_reg_status = [];
49
+
50
+	/**
51
+	 * amounts paid at the end of the request after all processing.
52
+	 * indexed by registration ID
53
+	 *
54
+	 * @var array
55
+	 */
56
+	protected static $_amount_paid = [];
57
+
58
+	/**
59
+	 * Cache of the reg final price for registrations corresponding to a ticket line item
60
+	 *
61
+	 * @deprecated
62
+	 * @var array @see EEH_Line_Item::calculate_reg_final_prices_per_line_item()'s return value
63
+	 */
64
+	protected $_reg_final_price_per_tkt_line_item;
65
+
66
+	/**
67
+	 * @var RequestInterface $request
68
+	 */
69
+	protected $request;
70
+
71
+
72
+	/**
73
+	 * @singleton method used to instantiate class object
74
+	 * @param RequestInterface|null $request
75
+	 * @return EE_Registration_Processor instance
76
+	 * @throws InvalidArgumentException
77
+	 * @throws InvalidInterfaceException
78
+	 * @throws InvalidDataTypeException
79
+	 */
80
+	public static function instance(RequestInterface $request = null)
81
+	{
82
+		// check if class object is instantiated
83
+		if (! self::$_instance instanceof EE_Registration_Processor) {
84
+			if (! $request instanceof RequestInterface) {
85
+				$request = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\Request');
86
+			}
87
+			self::$_instance = new self($request);
88
+		}
89
+		return self::$_instance;
90
+	}
91
+
92
+
93
+	/**
94
+	 * EE_Registration_Processor constructor.
95
+	 *
96
+	 * @param RequestInterface $request
97
+	 */
98
+	public function __construct(RequestInterface $request)
99
+	{
100
+		$this->request = $request;
101
+	}
102
+
103
+
104
+	/**
105
+	 * @param int $REG_ID
106
+	 * @return string
107
+	 */
108
+	public function old_reg_status($REG_ID)
109
+	{
110
+		return isset($this->_old_reg_status[ $REG_ID ]) ? $this->_old_reg_status[ $REG_ID ] : null;
111
+	}
112
+
113
+
114
+	/**
115
+	 * @param int    $REG_ID
116
+	 * @param string $old_reg_status
117
+	 */
118
+	public function set_old_reg_status($REG_ID, $old_reg_status)
119
+	{
120
+		// only set the first time
121
+		if (! isset($this->_old_reg_status[ $REG_ID ])) {
122
+			$this->_old_reg_status[ $REG_ID ] = $old_reg_status;
123
+		}
124
+	}
125
+
126
+
127
+	/**
128
+	 * @param int $REG_ID
129
+	 * @return string
130
+	 */
131
+	public function new_reg_status($REG_ID)
132
+	{
133
+		return isset($this->_new_reg_status[ $REG_ID ]) ? $this->_new_reg_status[ $REG_ID ] : null;
134
+	}
135
+
136
+
137
+	/**
138
+	 * @param int    $REG_ID
139
+	 * @param string $new_reg_status
140
+	 */
141
+	public function set_new_reg_status($REG_ID, $new_reg_status)
142
+	{
143
+		$this->_new_reg_status[ $REG_ID ] = $new_reg_status;
144
+	}
145
+
146
+
147
+	/**
148
+	 * reg_status_updated
149
+	 *
150
+	 * @param int $REG_ID
151
+	 * @return bool
152
+	 */
153
+	public function reg_status_updated($REG_ID)
154
+	{
155
+		return $this->new_reg_status($REG_ID) !== $this->old_reg_status($REG_ID);
156
+	}
157
+
158
+
159
+	/**
160
+	 * @param EE_Registration $registration
161
+	 * @throws EE_Error
162
+	 * @throws EntityNotFoundException
163
+	 * @throws InvalidArgumentException
164
+	 * @throws InvalidDataTypeException
165
+	 * @throws InvalidInterfaceException
166
+	 * @throws ReflectionException
167
+	 * @throws RuntimeException
168
+	 */
169
+	public function update_registration_status_and_trigger_notifications(EE_Registration $registration)
170
+	{
171
+		$this->toggle_incomplete_registration_status_to_default($registration, false);
172
+		$this->toggle_registration_status_for_default_approved_events($registration, false);
173
+		$this->toggle_registration_status_if_no_monies_owing($registration, false);
174
+		$registration->save();
175
+		// trigger notifications
176
+		$this->trigger_registration_update_notifications($registration);
177
+	}
178
+
179
+
180
+	/**
181
+	 *    manually_update_registration_status
182
+	 *
183
+	 * @access public
184
+	 * @param EE_Registration $registration
185
+	 * @param string          $new_reg_status
186
+	 * @param bool            $save TRUE will save the registration if the status is updated, FALSE will leave that up
187
+	 *                              to client code
188
+	 * @return bool
189
+	 * @throws EE_Error
190
+	 * @throws EntityNotFoundException
191
+	 * @throws InvalidArgumentException
192
+	 * @throws InvalidDataTypeException
193
+	 * @throws InvalidInterfaceException
194
+	 * @throws ReflectionException
195
+	 * @throws RuntimeException
196
+	 */
197
+	public function manually_update_registration_status(
198
+		EE_Registration $registration,
199
+		$new_reg_status = '',
200
+		$save = true
201
+	) {
202
+		// set initial REG_Status
203
+		$this->set_old_reg_status($registration->ID(), $registration->status_ID());
204
+		// set incoming REG_Status
205
+		$this->set_new_reg_status($registration->ID(), $new_reg_status);
206
+		// toggle reg status but only if it has changed and the user can do so
207
+		if (
208
+			$this->reg_status_updated($registration->ID())
209
+			&& (
210
+				(! $this->request->isAdmin() || $this->request->isFrontAjax())
211
+				|| EE_Registry::instance()->CAP->current_user_can(
212
+					'ee_edit_registration',
213
+					'toggle_registration_status',
214
+					$registration->ID()
215
+				)
216
+			)
217
+		) {
218
+			// change status to new value
219
+			$updated = $registration->set_status($this->new_reg_status($registration->ID()));
220
+			if ($updated && $save) {
221
+				$registration->save();
222
+			}
223
+			return true;
224
+		}
225
+		return false;
226
+	}
227
+
228
+
229
+	/**
230
+	 *    toggle_incomplete_registration_status_to_default
231
+	 *        changes any incomplete registrations to either the event or global default registration status
232
+	 *
233
+	 * @access public
234
+	 * @param EE_Registration       $registration
235
+	 * @param bool                  $save TRUE will save the registration if the status is updated, FALSE will leave
236
+	 *                                    that up to client code
237
+	 * @param ContextInterface|null $context
238
+	 * @return void
239
+	 * @throws EE_Error
240
+	 * @throws InvalidArgumentException
241
+	 * @throws ReflectionException
242
+	 * @throws RuntimeException
243
+	 * @throws EntityNotFoundException
244
+	 * @throws InvalidDataTypeException
245
+	 * @throws InvalidInterfaceException
246
+	 */
247
+	public function toggle_incomplete_registration_status_to_default(
248
+		EE_Registration $registration,
249
+		$save = true,
250
+		ContextInterface $context = null
251
+	) {
252
+		$existing_reg_status = $registration->status_ID();
253
+		// set initial REG_Status
254
+		$this->set_old_reg_status($registration->ID(), $existing_reg_status);
255
+		// is the registration currently incomplete ?
256
+		if ($registration->status_ID() === EEM_Registration::status_id_incomplete) {
257
+			// grab default reg status for the event, if set
258
+			$event_default_registration_status = $registration->event()->default_registration_status();
259
+			// if no default reg status is set for the event, then use the global value
260
+			$STS_ID = ! empty($event_default_registration_status)
261
+				? $event_default_registration_status
262
+				: EE_Registry::instance()->CFG->registration->default_STS_ID;
263
+			// if the event default reg status is approved, then downgrade temporarily to payment pending to ensure that payments are triggered
264
+			$STS_ID = $STS_ID === EEM_Registration::status_id_approved ? EEM_Registration::status_id_pending_payment
265
+				: $STS_ID;
266
+			// set incoming REG_Status
267
+			$this->set_new_reg_status($registration->ID(), $STS_ID);
268
+			$registration->set_status($STS_ID, false, $context);
269
+			if ($save) {
270
+				$registration->save();
271
+			}
272
+			// don't trigger notifications during IPNs because they will get triggered by EE_Payment_Processor
273
+			if (! EE_Processor_Base::$IPN) {
274
+				// otherwise, send out notifications
275
+				add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true', 10);
276
+			}
277
+			// DEBUG LOG
278
+			// $this->log(
279
+			//     __CLASS__,
280
+			//     __FUNCTION__,
281
+			//     __LINE__,
282
+			//     $registration->transaction(),
283
+			//     array(
284
+			//         'IPN' => EE_Processor_Base::$IPN,
285
+			//         'deliver_notifications' => has_filter(
286
+			//             'FHEE__EED_Messages___maybe_registration__deliver_notifications'
287
+			//         ),
288
+			//     )
289
+			// );
290
+		}
291
+	}
292
+
293
+
294
+	/**
295
+	 *    toggle_registration_status_for_default_approved_events
296
+	 *
297
+	 * @access public
298
+	 * @param EE_Registration $registration
299
+	 * @param bool            $save TRUE will save the registration if the status is updated, FALSE will leave that up
300
+	 *                              to client code
301
+	 * @return bool
302
+	 * @throws EE_Error
303
+	 * @throws EntityNotFoundException
304
+	 * @throws InvalidArgumentException
305
+	 * @throws InvalidDataTypeException
306
+	 * @throws InvalidInterfaceException
307
+	 * @throws ReflectionException
308
+	 * @throws RuntimeException
309
+	 */
310
+	public function toggle_registration_status_for_default_approved_events(EE_Registration $registration, $save = true)
311
+	{
312
+		$reg_status = $registration->status_ID();
313
+		// set initial REG_Status
314
+		$this->set_old_reg_status($registration->ID(), $reg_status);
315
+		// if not already, toggle reg status to approved IF the event default reg status is approved
316
+		// ( as long as the registration wasn't cancelled or declined at some point )
317
+		if (
318
+			$reg_status !== EEM_Registration::status_id_cancelled
319
+			&& $reg_status
320
+			   !== EEM_Registration::status_id_declined
321
+			&& $reg_status !== EEM_Registration::status_id_approved
322
+			&& $registration->event()->default_registration_status() === EEM_Registration::status_id_approved
323
+		) {
324
+			// set incoming REG_Status
325
+			$this->set_new_reg_status($registration->ID(), EEM_Registration::status_id_approved);
326
+			// toggle status to approved
327
+			$registration->set_status(EEM_Registration::status_id_approved);
328
+			if ($save) {
329
+				$registration->save();
330
+			}
331
+			// don't trigger notifications during IPNs because they will get triggered by EE_Payment_Processor
332
+			if (! EE_Processor_Base::$IPN) {
333
+				// otherwise, send out notifications
334
+				add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true', 10);
335
+			}
336
+			// DEBUG LOG
337
+			// $this->log(
338
+			//     __CLASS__,
339
+			//     __FUNCTION__,
340
+			//     __LINE__,
341
+			//     $registration->transaction(),
342
+			//     array(
343
+			//         'IPN' => EE_Processor_Base::$IPN,
344
+			//         'deliver_notifications' => has_filter(
345
+			//             'FHEE__EED_Messages___maybe_registration__deliver_notifications'
346
+			//         ),
347
+			//     )
348
+			// );
349
+			return true;
350
+		}
351
+		return false;
352
+	}
353
+
354
+
355
+	/**
356
+	 *    toggle_registration_statuses_if_no_monies_owing
357
+	 *
358
+	 * @access public
359
+	 * @param EE_Registration $registration
360
+	 * @param bool            $save TRUE will save the registration if the status is updated, FALSE will leave that up
361
+	 *                              to client code
362
+	 * @param array           $additional_details
363
+	 * @return bool
364
+	 * @throws EE_Error
365
+	 * @throws EntityNotFoundException
366
+	 * @throws InvalidArgumentException
367
+	 * @throws InvalidDataTypeException
368
+	 * @throws InvalidInterfaceException
369
+	 * @throws ReflectionException
370
+	 * @throws RuntimeException
371
+	 */
372
+	public function toggle_registration_status_if_no_monies_owing(
373
+		EE_Registration $registration,
374
+		$save = true,
375
+		array $additional_details = []
376
+	) {
377
+		// set initial REG_Status
378
+		$this->set_old_reg_status($registration->ID(), $registration->status_ID());
379
+		// was a payment just made ?
380
+		$payment    = isset($additional_details['payment_updates'], $additional_details['last_payment'])
381
+					  && $additional_details['payment_updates']
382
+					  && $additional_details['last_payment'] instanceof EE_Payment
383
+			? $additional_details['last_payment']
384
+			: null;
385
+		$total_paid = array_sum(self::$_amount_paid);
386
+		// toggle reg status to approved IF
387
+		if (
388 388
 // REG status is pending payment
389
-            $registration->status_ID() === EEM_Registration::status_id_pending_payment
390
-            // AND no monies are owing
391
-            && (
392
-                (
393
-                    $registration->transaction()->is_completed()
394
-                    || $registration->transaction()->is_overpaid()
395
-                    || $registration->transaction()->is_free()
396
-                    || apply_filters(
397
-                        'FHEE__EE_Registration_Processor__toggle_registration_status_if_no_monies_owing',
398
-                        false,
399
-                        $registration
400
-                    )
401
-                )
402
-                || (
403
-                    $payment instanceof EE_Payment && $payment->is_approved()
404
-                    && // this specific registration has not yet been paid for
405
-                    ! isset(self::$_amount_paid[ $registration->ID() ])
406
-                    && // payment amount, less what we have already attributed to other registrations, is greater than this reg's final price
407
-                    $payment->amount() - $total_paid >= $registration->final_price()
408
-                )
409
-            )
410
-        ) {
411
-            // mark as paid
412
-            self::$_amount_paid[ $registration->ID() ] = $registration->final_price();
413
-            // track new REG_Status
414
-            $this->set_new_reg_status($registration->ID(), EEM_Registration::status_id_approved);
415
-            // toggle status to approved
416
-            $registration->set_status(EEM_Registration::status_id_approved);
417
-            if ($save) {
418
-                $registration->save();
419
-            }
420
-            // don't trigger notifications during IPNs because they will get triggered by EE_Payment_Processor
421
-            if (! EE_Processor_Base::$IPN) {
422
-                // otherwise, send out notifications
423
-                add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true', 10);
424
-            }
425
-            // DEBUG LOG
426
-            // $this->log(
427
-            //     __CLASS__,
428
-            //     __FUNCTION__,
429
-            //     __LINE__,
430
-            //     $registration->transaction(),
431
-            //     array(
432
-            //         'IPN' => EE_Processor_Base::$IPN,
433
-            //         'deliver_notifications' => has_filter(
434
-            //             'FHEE__EED_Messages___maybe_registration__deliver_notifications'
435
-            //         ),
436
-            //     )
437
-            // );
438
-            return true;
439
-        }
440
-        return false;
441
-    }
442
-
443
-
444
-    /**
445
-     *    registration_status_changed
446
-     *
447
-     * @access public
448
-     * @param EE_Registration $registration
449
-     * @param array           $additional_details
450
-     * @return void
451
-     */
452
-    public function trigger_registration_update_notifications($registration, array $additional_details = [])
453
-    {
454
-        try {
455
-            if (! $registration instanceof EE_Registration) {
456
-                throw new EE_Error(
457
-                    esc_html__('An invalid registration was received.', 'event_espresso')
458
-                );
459
-            }
460
-            // EE_Registry::instance()->load_helper('Debug_Tools');
461
-            // EEH_Debug_Tools::log(
462
-            //     __CLASS__,
463
-            //     __FUNCTION__,
464
-            //     __LINE__,
465
-            //     array($registration->transaction(), $additional_details),
466
-            //     false,
467
-            //     'EE_Transaction: ' . $registration->transaction()->ID()
468
-            // );
469
-            if (
470
-                ! $this->request->getRequestParam('non_primary_reg_notification', 0, 'int')
471
-                && ! $registration->is_primary_registrant()
472
-            ) {
473
-                return;
474
-            }
475
-            do_action(
476
-                'AHEE__EE_Registration_Processor__trigger_registration_update_notifications',
477
-                $registration,
478
-                $additional_details
479
-            );
480
-        } catch (Exception $e) {
481
-            EE_Error::add_error($e->getMessage(), $e->getFile(), 'unknown_function_from_exception', $e->getLine());
482
-        }
483
-    }
484
-
485
-
486
-    /**
487
-     * sets reg status based either on passed param or on transaction status and event pre-approval setting
488
-     *
489
-     * @param EE_Registration $registration
490
-     * @param array           $additional_details
491
-     * @return bool
492
-     * @throws EE_Error
493
-     * @throws EntityNotFoundException
494
-     * @throws InvalidArgumentException
495
-     * @throws InvalidDataTypeException
496
-     * @throws InvalidInterfaceException
497
-     * @throws ReflectionException
498
-     * @throws RuntimeException
499
-     */
500
-    public function update_registration_after_checkout_or_payment(
501
-        EE_Registration $registration,
502
-        array $additional_details = []
503
-    ) {
504
-        // set initial REG_Status
505
-        $this->set_old_reg_status($registration->ID(), $registration->status_ID());
506
-        // if the registration status gets updated, then save the registration
507
-        if (
508
-            $this->toggle_registration_status_for_default_approved_events($registration, false)
509
-            || $this->toggle_registration_status_if_no_monies_owing(
510
-                $registration,
511
-                false,
512
-                $additional_details
513
-            )
514
-        ) {
515
-            $registration->save();
516
-        }
517
-        // set new  REG_Status
518
-        $this->set_new_reg_status($registration->ID(), $registration->status_ID());
519
-        return $this->reg_status_updated($registration->ID())
520
-               && $this->new_reg_status($registration->ID()) === EEM_Registration::status_id_approved;
521
-    }
522
-
523
-
524
-    /**
525
-     * Updates the registration' final prices based on the current line item tree (taking into account
526
-     * discounts, taxes, and other line items unrelated to tickets.)
527
-     *
528
-     * @param EE_Transaction $transaction
529
-     * @param boolean        $save_regs whether to immediately save registrations in this function or not
530
-     * @return void
531
-     * @throws EE_Error
532
-     * @throws InvalidArgumentException
533
-     * @throws InvalidDataTypeException
534
-     * @throws InvalidInterfaceException
535
-     * @throws RuntimeException
536
-     * @throws ReflectionException
537
-     */
538
-    public function update_registration_final_prices($transaction, $save_regs = true)
539
-    {
540
-        $reg_final_price_per_ticket_line_item = EEH_Line_Item::calculate_reg_final_prices_per_line_item(
541
-            $transaction->total_line_item()
542
-        );
543
-        foreach ($transaction->registrations() as $registration) {
544
-            /** @var EE_Line_Item $line_item */
545
-            $line_item = EEM_Line_Item::instance()->get_line_item_for_registration($registration);
546
-            if (isset($reg_final_price_per_ticket_line_item[ $line_item->ID() ])) {
547
-                $registration->set_final_price($reg_final_price_per_ticket_line_item[ $line_item->ID() ]);
548
-                if ($save_regs) {
549
-                    $registration->save();
550
-                }
551
-            }
552
-        }
553
-        // and make sure there's no rounding problem
554
-        $this->fix_reg_final_price_rounding_issue($transaction);
555
-    }
556
-
557
-
558
-    /**
559
-     * Makes sure there is no rounding errors for the REG_final_prices.
560
-     * Eg, if we have 3 registrations for $1, and there is a $0.01 discount between the three of them,
561
-     * they will each be for $0.99333333, which gets rounded to $1 again.
562
-     * So the transaction total will be $2.99, but each registration will be for $1,
563
-     * so if each registrant paid individually they will have overpaid by $0.01.
564
-     * So in order to overcome this, we check for any difference, and if there is a difference
565
-     * we just grab one registrant at random and make them responsible for it.
566
-     * This should be used after setting REG_final_prices (it's done automatically as part of
567
-     * EE_Registration_Processor::update_registration_final_prices())
568
-     *
569
-     * @param EE_Transaction $transaction
570
-     * @return bool success verifying that there is NO difference after this method is done
571
-     * @throws EE_Error
572
-     * @throws InvalidArgumentException
573
-     * @throws InvalidDataTypeException
574
-     * @throws InvalidInterfaceException
575
-     * @throws ReflectionException
576
-     */
577
-    public function fix_reg_final_price_rounding_issue($transaction)
578
-    {
579
-        $reg_final_price_sum = EEM_Registration::instance()->sum(
580
-            [
581
-                [
582
-                    'TXN_ID' => $transaction->ID(),
583
-                ],
584
-            ],
585
-            'REG_final_price'
586
-        );
587
-        $diff                = $transaction->total() - $reg_final_price_sum;
588
-        // ok then, just grab one of the registrations
589
-        if ($diff !== (float) 0) {
590
-            $a_reg = EEM_Registration::instance()->get_one(
591
-                [
592
-                    [
593
-                        'TXN_ID' => $transaction->ID(),
594
-                    ],
595
-                ]
596
-            );
597
-            return $a_reg instanceof EE_Registration
598
-                   && $a_reg->save(['REG_final_price' => $a_reg->final_price() + $diff]);
599
-        }
600
-        return true;
601
-    }
602
-
603
-
604
-    /**
605
-     * update_registration_after_being_canceled_or_declined
606
-     *
607
-     * @param EE_Registration $registration
608
-     * @param array           $closed_reg_statuses
609
-     * @param bool            $update_reg
610
-     * @return bool
611
-     * @throws EE_Error
612
-     * @throws RuntimeException
613
-     * @throws ReflectionException
614
-     */
615
-    public function update_registration_after_being_canceled_or_declined(
616
-        EE_Registration $registration,
617
-        array $closed_reg_statuses = [],
618
-        $update_reg = true
619
-    ) {
620
-        // these reg statuses should not be considered in any calculations involving monies owing
621
-        $closed_reg_statuses = ! empty($closed_reg_statuses)
622
-            ? $closed_reg_statuses
623
-            : EEM_Registration::closed_reg_statuses();
624
-        if (! in_array($registration->status_ID(), $closed_reg_statuses, true)) {
625
-            return false;
626
-        }
627
-        // release a reserved ticket by decrementing ticket and datetime reserved values
628
-        $registration->release_reserved_ticket(true, 'RegProcessor:' . __LINE__);
629
-        $registration->set_final_price(0);
630
-        if ($update_reg) {
631
-            $registration->save();
632
-        }
633
-        return true;
634
-    }
635
-
636
-
637
-    /**
638
-     * update_canceled_or_declined_registration_after_being_reinstated
639
-     *
640
-     * @param EE_Registration $registration
641
-     * @param array           $closed_reg_statuses
642
-     * @param bool            $update_reg
643
-     * @return bool
644
-     * @throws EE_Error
645
-     * @throws RuntimeException
646
-     * @throws ReflectionException
647
-     */
648
-    public function update_canceled_or_declined_registration_after_being_reinstated(
649
-        EE_Registration $registration,
650
-        array $closed_reg_statuses = [],
651
-        $update_reg = true
652
-    ) {
653
-        // these reg statuses should not be considered in any calculations involving monies owing
654
-        $closed_reg_statuses = ! empty($closed_reg_statuses) ? $closed_reg_statuses
655
-            : EEM_Registration::closed_reg_statuses();
656
-        if (in_array($registration->status_ID(), $closed_reg_statuses, true)) {
657
-            return false;
658
-        }
659
-        $ticket = $registration->ticket();
660
-        if (! $ticket instanceof EE_Ticket) {
661
-            throw new EE_Error(
662
-                sprintf(
663
-                    esc_html__(
664
-                        'The Ticket for Registration %1$d was not found or is invalid.',
665
-                        'event_espresso'
666
-                    ),
667
-                    $registration->ticket_ID()
668
-                )
669
-            );
670
-        }
671
-        $registration->set_final_price($ticket->price());
672
-        if ($update_reg) {
673
-            $registration->save();
674
-        }
675
-        return true;
676
-    }
677
-
678
-
679
-    /**
680
-     * generate_ONE_registration_from_line_item
681
-     * Although a ticket line item may have a quantity greater than 1,
682
-     * this method will ONLY CREATE ONE REGISTRATION !!!
683
-     * Regardless of the ticket line item quantity.
684
-     * This means that any code calling this method is responsible for ensuring
685
-     * that the final registration count matches the ticket line item quantity.
686
-     * This was done to make it easier to match the number of registrations
687
-     * to the number of tickets in the cart, when the cart has been edited
688
-     * after SPCO has already been initialized. So if an additional ticket was added to the cart, you can simply pass
689
-     * the line item to this method to add a second ticket, and in this case, you would not want to add 2 tickets.
690
-     *
691
-     * @param EE_Line_Item   $line_item
692
-     * @param EE_Transaction $transaction
693
-     * @param int            $att_nmbr
694
-     * @param int            $total_ticket_count
695
-     * @return EE_Registration | null
696
-     * @throws OutOfRangeException
697
-     * @throws UnexpectedEntityException
698
-     * @throws EE_Error
699
-     * @throws ReflectionException
700
-     * @deprecated
701
-     * @since 4.9.1
702
-     */
703
-    public function generate_ONE_registration_from_line_item(
704
-        EE_Line_Item $line_item,
705
-        EE_Transaction $transaction,
706
-        $att_nmbr = 1,
707
-        $total_ticket_count = 1
708
-    ) {
709
-        EE_Error::doing_it_wrong(
710
-            __CLASS__ . '::' . __FUNCTION__,
711
-            sprintf(
712
-                esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'),
713
-                '\EventEspresso\core\domain\services\registration\CreateRegistrationService::create()'
714
-            ),
715
-            '4.9.1',
716
-            '5.0.0'
717
-        );
718
-        // grab the related ticket object for this line_item
719
-        $ticket = $line_item->ticket();
720
-        if (! $ticket instanceof EE_Ticket) {
721
-            EE_Error::add_error(
722
-                sprintf(
723
-                    esc_html__('Line item %s did not contain a valid ticket', 'event_espresso'),
724
-                    $line_item->ID()
725
-                ),
726
-                __FILE__,
727
-                __FUNCTION__,
728
-                __LINE__
729
-            );
730
-            return null;
731
-        }
732
-        $registration_service = new CreateRegistrationService();
733
-        // then generate a new registration from that
734
-        return $registration_service->create(
735
-            $ticket->get_related_event(),
736
-            $transaction,
737
-            $ticket,
738
-            $line_item,
739
-            $att_nmbr,
740
-            $total_ticket_count
741
-        );
742
-    }
743
-
744
-
745
-    /**
746
-     * generates reg_url_link
747
-     *
748
-     * @param int                   $att_nmbr
749
-     * @param EE_Line_Item | string $item
750
-     * @return RegUrlLink
751
-     * @throws InvalidArgumentException
752
-     * @deprecated
753
-     * @since 4.9.1
754
-     */
755
-    public function generate_reg_url_link($att_nmbr, $item)
756
-    {
757
-        EE_Error::doing_it_wrong(
758
-            __CLASS__ . '::' . __FUNCTION__,
759
-            sprintf(
760
-                esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'),
761
-                'EventEspresso\core\domain\entities\RegUrlLink'
762
-            ),
763
-            '4.9.1',
764
-            '5.0.0'
765
-        );
766
-        return new RegUrlLink($att_nmbr, $item);
767
-    }
768
-
769
-
770
-    /**
771
-     * generates reg code
772
-     *
773
-     * @param EE_Registration $registration
774
-     * @return RegCode
775
-     * @throws EE_Error
776
-     * @throws EntityNotFoundException
777
-     * @throws InvalidArgumentException
778
-     * @since 4.9.1
779
-     * @deprecated
780
-     */
781
-    public function generate_reg_code(EE_Registration $registration)
782
-    {
783
-        EE_Error::doing_it_wrong(
784
-            __CLASS__ . '::' . __FUNCTION__,
785
-            sprintf(
786
-                esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'),
787
-                'EventEspresso\core\domain\entities\RegCode'
788
-            ),
789
-            '4.9.1',
790
-            '5.0.0'
791
-        );
792
-        return apply_filters(
793
-            'FHEE__EE_Registration_Processor___generate_reg_code__new_reg_code',
794
-            new RegCode(
795
-                RegUrlLink::fromRegistration($registration),
796
-                $registration->transaction(),
797
-                $registration->ticket()
798
-            ),
799
-            $registration
800
-        );
801
-    }
389
+			$registration->status_ID() === EEM_Registration::status_id_pending_payment
390
+			// AND no monies are owing
391
+			&& (
392
+				(
393
+					$registration->transaction()->is_completed()
394
+					|| $registration->transaction()->is_overpaid()
395
+					|| $registration->transaction()->is_free()
396
+					|| apply_filters(
397
+						'FHEE__EE_Registration_Processor__toggle_registration_status_if_no_monies_owing',
398
+						false,
399
+						$registration
400
+					)
401
+				)
402
+				|| (
403
+					$payment instanceof EE_Payment && $payment->is_approved()
404
+					&& // this specific registration has not yet been paid for
405
+					! isset(self::$_amount_paid[ $registration->ID() ])
406
+					&& // payment amount, less what we have already attributed to other registrations, is greater than this reg's final price
407
+					$payment->amount() - $total_paid >= $registration->final_price()
408
+				)
409
+			)
410
+		) {
411
+			// mark as paid
412
+			self::$_amount_paid[ $registration->ID() ] = $registration->final_price();
413
+			// track new REG_Status
414
+			$this->set_new_reg_status($registration->ID(), EEM_Registration::status_id_approved);
415
+			// toggle status to approved
416
+			$registration->set_status(EEM_Registration::status_id_approved);
417
+			if ($save) {
418
+				$registration->save();
419
+			}
420
+			// don't trigger notifications during IPNs because they will get triggered by EE_Payment_Processor
421
+			if (! EE_Processor_Base::$IPN) {
422
+				// otherwise, send out notifications
423
+				add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true', 10);
424
+			}
425
+			// DEBUG LOG
426
+			// $this->log(
427
+			//     __CLASS__,
428
+			//     __FUNCTION__,
429
+			//     __LINE__,
430
+			//     $registration->transaction(),
431
+			//     array(
432
+			//         'IPN' => EE_Processor_Base::$IPN,
433
+			//         'deliver_notifications' => has_filter(
434
+			//             'FHEE__EED_Messages___maybe_registration__deliver_notifications'
435
+			//         ),
436
+			//     )
437
+			// );
438
+			return true;
439
+		}
440
+		return false;
441
+	}
442
+
443
+
444
+	/**
445
+	 *    registration_status_changed
446
+	 *
447
+	 * @access public
448
+	 * @param EE_Registration $registration
449
+	 * @param array           $additional_details
450
+	 * @return void
451
+	 */
452
+	public function trigger_registration_update_notifications($registration, array $additional_details = [])
453
+	{
454
+		try {
455
+			if (! $registration instanceof EE_Registration) {
456
+				throw new EE_Error(
457
+					esc_html__('An invalid registration was received.', 'event_espresso')
458
+				);
459
+			}
460
+			// EE_Registry::instance()->load_helper('Debug_Tools');
461
+			// EEH_Debug_Tools::log(
462
+			//     __CLASS__,
463
+			//     __FUNCTION__,
464
+			//     __LINE__,
465
+			//     array($registration->transaction(), $additional_details),
466
+			//     false,
467
+			//     'EE_Transaction: ' . $registration->transaction()->ID()
468
+			// );
469
+			if (
470
+				! $this->request->getRequestParam('non_primary_reg_notification', 0, 'int')
471
+				&& ! $registration->is_primary_registrant()
472
+			) {
473
+				return;
474
+			}
475
+			do_action(
476
+				'AHEE__EE_Registration_Processor__trigger_registration_update_notifications',
477
+				$registration,
478
+				$additional_details
479
+			);
480
+		} catch (Exception $e) {
481
+			EE_Error::add_error($e->getMessage(), $e->getFile(), 'unknown_function_from_exception', $e->getLine());
482
+		}
483
+	}
484
+
485
+
486
+	/**
487
+	 * sets reg status based either on passed param or on transaction status and event pre-approval setting
488
+	 *
489
+	 * @param EE_Registration $registration
490
+	 * @param array           $additional_details
491
+	 * @return bool
492
+	 * @throws EE_Error
493
+	 * @throws EntityNotFoundException
494
+	 * @throws InvalidArgumentException
495
+	 * @throws InvalidDataTypeException
496
+	 * @throws InvalidInterfaceException
497
+	 * @throws ReflectionException
498
+	 * @throws RuntimeException
499
+	 */
500
+	public function update_registration_after_checkout_or_payment(
501
+		EE_Registration $registration,
502
+		array $additional_details = []
503
+	) {
504
+		// set initial REG_Status
505
+		$this->set_old_reg_status($registration->ID(), $registration->status_ID());
506
+		// if the registration status gets updated, then save the registration
507
+		if (
508
+			$this->toggle_registration_status_for_default_approved_events($registration, false)
509
+			|| $this->toggle_registration_status_if_no_monies_owing(
510
+				$registration,
511
+				false,
512
+				$additional_details
513
+			)
514
+		) {
515
+			$registration->save();
516
+		}
517
+		// set new  REG_Status
518
+		$this->set_new_reg_status($registration->ID(), $registration->status_ID());
519
+		return $this->reg_status_updated($registration->ID())
520
+			   && $this->new_reg_status($registration->ID()) === EEM_Registration::status_id_approved;
521
+	}
522
+
523
+
524
+	/**
525
+	 * Updates the registration' final prices based on the current line item tree (taking into account
526
+	 * discounts, taxes, and other line items unrelated to tickets.)
527
+	 *
528
+	 * @param EE_Transaction $transaction
529
+	 * @param boolean        $save_regs whether to immediately save registrations in this function or not
530
+	 * @return void
531
+	 * @throws EE_Error
532
+	 * @throws InvalidArgumentException
533
+	 * @throws InvalidDataTypeException
534
+	 * @throws InvalidInterfaceException
535
+	 * @throws RuntimeException
536
+	 * @throws ReflectionException
537
+	 */
538
+	public function update_registration_final_prices($transaction, $save_regs = true)
539
+	{
540
+		$reg_final_price_per_ticket_line_item = EEH_Line_Item::calculate_reg_final_prices_per_line_item(
541
+			$transaction->total_line_item()
542
+		);
543
+		foreach ($transaction->registrations() as $registration) {
544
+			/** @var EE_Line_Item $line_item */
545
+			$line_item = EEM_Line_Item::instance()->get_line_item_for_registration($registration);
546
+			if (isset($reg_final_price_per_ticket_line_item[ $line_item->ID() ])) {
547
+				$registration->set_final_price($reg_final_price_per_ticket_line_item[ $line_item->ID() ]);
548
+				if ($save_regs) {
549
+					$registration->save();
550
+				}
551
+			}
552
+		}
553
+		// and make sure there's no rounding problem
554
+		$this->fix_reg_final_price_rounding_issue($transaction);
555
+	}
556
+
557
+
558
+	/**
559
+	 * Makes sure there is no rounding errors for the REG_final_prices.
560
+	 * Eg, if we have 3 registrations for $1, and there is a $0.01 discount between the three of them,
561
+	 * they will each be for $0.99333333, which gets rounded to $1 again.
562
+	 * So the transaction total will be $2.99, but each registration will be for $1,
563
+	 * so if each registrant paid individually they will have overpaid by $0.01.
564
+	 * So in order to overcome this, we check for any difference, and if there is a difference
565
+	 * we just grab one registrant at random and make them responsible for it.
566
+	 * This should be used after setting REG_final_prices (it's done automatically as part of
567
+	 * EE_Registration_Processor::update_registration_final_prices())
568
+	 *
569
+	 * @param EE_Transaction $transaction
570
+	 * @return bool success verifying that there is NO difference after this method is done
571
+	 * @throws EE_Error
572
+	 * @throws InvalidArgumentException
573
+	 * @throws InvalidDataTypeException
574
+	 * @throws InvalidInterfaceException
575
+	 * @throws ReflectionException
576
+	 */
577
+	public function fix_reg_final_price_rounding_issue($transaction)
578
+	{
579
+		$reg_final_price_sum = EEM_Registration::instance()->sum(
580
+			[
581
+				[
582
+					'TXN_ID' => $transaction->ID(),
583
+				],
584
+			],
585
+			'REG_final_price'
586
+		);
587
+		$diff                = $transaction->total() - $reg_final_price_sum;
588
+		// ok then, just grab one of the registrations
589
+		if ($diff !== (float) 0) {
590
+			$a_reg = EEM_Registration::instance()->get_one(
591
+				[
592
+					[
593
+						'TXN_ID' => $transaction->ID(),
594
+					],
595
+				]
596
+			);
597
+			return $a_reg instanceof EE_Registration
598
+				   && $a_reg->save(['REG_final_price' => $a_reg->final_price() + $diff]);
599
+		}
600
+		return true;
601
+	}
602
+
603
+
604
+	/**
605
+	 * update_registration_after_being_canceled_or_declined
606
+	 *
607
+	 * @param EE_Registration $registration
608
+	 * @param array           $closed_reg_statuses
609
+	 * @param bool            $update_reg
610
+	 * @return bool
611
+	 * @throws EE_Error
612
+	 * @throws RuntimeException
613
+	 * @throws ReflectionException
614
+	 */
615
+	public function update_registration_after_being_canceled_or_declined(
616
+		EE_Registration $registration,
617
+		array $closed_reg_statuses = [],
618
+		$update_reg = true
619
+	) {
620
+		// these reg statuses should not be considered in any calculations involving monies owing
621
+		$closed_reg_statuses = ! empty($closed_reg_statuses)
622
+			? $closed_reg_statuses
623
+			: EEM_Registration::closed_reg_statuses();
624
+		if (! in_array($registration->status_ID(), $closed_reg_statuses, true)) {
625
+			return false;
626
+		}
627
+		// release a reserved ticket by decrementing ticket and datetime reserved values
628
+		$registration->release_reserved_ticket(true, 'RegProcessor:' . __LINE__);
629
+		$registration->set_final_price(0);
630
+		if ($update_reg) {
631
+			$registration->save();
632
+		}
633
+		return true;
634
+	}
635
+
636
+
637
+	/**
638
+	 * update_canceled_or_declined_registration_after_being_reinstated
639
+	 *
640
+	 * @param EE_Registration $registration
641
+	 * @param array           $closed_reg_statuses
642
+	 * @param bool            $update_reg
643
+	 * @return bool
644
+	 * @throws EE_Error
645
+	 * @throws RuntimeException
646
+	 * @throws ReflectionException
647
+	 */
648
+	public function update_canceled_or_declined_registration_after_being_reinstated(
649
+		EE_Registration $registration,
650
+		array $closed_reg_statuses = [],
651
+		$update_reg = true
652
+	) {
653
+		// these reg statuses should not be considered in any calculations involving monies owing
654
+		$closed_reg_statuses = ! empty($closed_reg_statuses) ? $closed_reg_statuses
655
+			: EEM_Registration::closed_reg_statuses();
656
+		if (in_array($registration->status_ID(), $closed_reg_statuses, true)) {
657
+			return false;
658
+		}
659
+		$ticket = $registration->ticket();
660
+		if (! $ticket instanceof EE_Ticket) {
661
+			throw new EE_Error(
662
+				sprintf(
663
+					esc_html__(
664
+						'The Ticket for Registration %1$d was not found or is invalid.',
665
+						'event_espresso'
666
+					),
667
+					$registration->ticket_ID()
668
+				)
669
+			);
670
+		}
671
+		$registration->set_final_price($ticket->price());
672
+		if ($update_reg) {
673
+			$registration->save();
674
+		}
675
+		return true;
676
+	}
677
+
678
+
679
+	/**
680
+	 * generate_ONE_registration_from_line_item
681
+	 * Although a ticket line item may have a quantity greater than 1,
682
+	 * this method will ONLY CREATE ONE REGISTRATION !!!
683
+	 * Regardless of the ticket line item quantity.
684
+	 * This means that any code calling this method is responsible for ensuring
685
+	 * that the final registration count matches the ticket line item quantity.
686
+	 * This was done to make it easier to match the number of registrations
687
+	 * to the number of tickets in the cart, when the cart has been edited
688
+	 * after SPCO has already been initialized. So if an additional ticket was added to the cart, you can simply pass
689
+	 * the line item to this method to add a second ticket, and in this case, you would not want to add 2 tickets.
690
+	 *
691
+	 * @param EE_Line_Item   $line_item
692
+	 * @param EE_Transaction $transaction
693
+	 * @param int            $att_nmbr
694
+	 * @param int            $total_ticket_count
695
+	 * @return EE_Registration | null
696
+	 * @throws OutOfRangeException
697
+	 * @throws UnexpectedEntityException
698
+	 * @throws EE_Error
699
+	 * @throws ReflectionException
700
+	 * @deprecated
701
+	 * @since 4.9.1
702
+	 */
703
+	public function generate_ONE_registration_from_line_item(
704
+		EE_Line_Item $line_item,
705
+		EE_Transaction $transaction,
706
+		$att_nmbr = 1,
707
+		$total_ticket_count = 1
708
+	) {
709
+		EE_Error::doing_it_wrong(
710
+			__CLASS__ . '::' . __FUNCTION__,
711
+			sprintf(
712
+				esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'),
713
+				'\EventEspresso\core\domain\services\registration\CreateRegistrationService::create()'
714
+			),
715
+			'4.9.1',
716
+			'5.0.0'
717
+		);
718
+		// grab the related ticket object for this line_item
719
+		$ticket = $line_item->ticket();
720
+		if (! $ticket instanceof EE_Ticket) {
721
+			EE_Error::add_error(
722
+				sprintf(
723
+					esc_html__('Line item %s did not contain a valid ticket', 'event_espresso'),
724
+					$line_item->ID()
725
+				),
726
+				__FILE__,
727
+				__FUNCTION__,
728
+				__LINE__
729
+			);
730
+			return null;
731
+		}
732
+		$registration_service = new CreateRegistrationService();
733
+		// then generate a new registration from that
734
+		return $registration_service->create(
735
+			$ticket->get_related_event(),
736
+			$transaction,
737
+			$ticket,
738
+			$line_item,
739
+			$att_nmbr,
740
+			$total_ticket_count
741
+		);
742
+	}
743
+
744
+
745
+	/**
746
+	 * generates reg_url_link
747
+	 *
748
+	 * @param int                   $att_nmbr
749
+	 * @param EE_Line_Item | string $item
750
+	 * @return RegUrlLink
751
+	 * @throws InvalidArgumentException
752
+	 * @deprecated
753
+	 * @since 4.9.1
754
+	 */
755
+	public function generate_reg_url_link($att_nmbr, $item)
756
+	{
757
+		EE_Error::doing_it_wrong(
758
+			__CLASS__ . '::' . __FUNCTION__,
759
+			sprintf(
760
+				esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'),
761
+				'EventEspresso\core\domain\entities\RegUrlLink'
762
+			),
763
+			'4.9.1',
764
+			'5.0.0'
765
+		);
766
+		return new RegUrlLink($att_nmbr, $item);
767
+	}
768
+
769
+
770
+	/**
771
+	 * generates reg code
772
+	 *
773
+	 * @param EE_Registration $registration
774
+	 * @return RegCode
775
+	 * @throws EE_Error
776
+	 * @throws EntityNotFoundException
777
+	 * @throws InvalidArgumentException
778
+	 * @since 4.9.1
779
+	 * @deprecated
780
+	 */
781
+	public function generate_reg_code(EE_Registration $registration)
782
+	{
783
+		EE_Error::doing_it_wrong(
784
+			__CLASS__ . '::' . __FUNCTION__,
785
+			sprintf(
786
+				esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'),
787
+				'EventEspresso\core\domain\entities\RegCode'
788
+			),
789
+			'4.9.1',
790
+			'5.0.0'
791
+		);
792
+		return apply_filters(
793
+			'FHEE__EE_Registration_Processor___generate_reg_code__new_reg_code',
794
+			new RegCode(
795
+				RegUrlLink::fromRegistration($registration),
796
+				$registration->transaction(),
797
+				$registration->ticket()
798
+			),
799
+			$registration
800
+		);
801
+	}
802 802
 }
Please login to merge, or discard this patch.
modules/messages/EED_Messages.module.php 2 patches
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -205,7 +205,7 @@  discard block
 block discarded – undo
205 205
                 'event_espresso'
206 206
             );
207 207
             // add specific message for developers if WP_DEBUG in on
208
-            $error_msg .= '||' . $e->getMessage();
208
+            $error_msg .= '||'.$e->getMessage();
209 209
             EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
210 210
         }
211 211
     }
@@ -291,7 +291,7 @@  discard block
 block discarded – undo
291 291
                 'event_espresso'
292 292
             );
293 293
             // add specific message for developers if WP_DEBUG in on
294
-            $error_msg .= '||' . $e->getMessage();
294
+            $error_msg .= '||'.$e->getMessage();
295 295
             EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
296 296
         }
297 297
     }
@@ -323,7 +323,7 @@  discard block
 block discarded – undo
323 323
         $transient_key = $request->getRequestParam('key');
324 324
 
325 325
         // now let's verify transient, if not valid exit immediately
326
-        if (! get_transient($transient_key)) {
326
+        if ( ! get_transient($transient_key)) {
327 327
             /**
328 328
              * trigger error so this gets in the error logs.  This is important because it happens on a non-user
329 329
              * request.
@@ -335,7 +335,7 @@  discard block
 block discarded – undo
335 335
         delete_transient($transient_key);
336 336
 
337 337
         if (apply_filters('FHEE__EED_Messages__run_cron__use_wp_cron', true)) {
338
-            $method = 'batch_' . $cron_type . '_from_queue';
338
+            $method = 'batch_'.$cron_type.'_from_queue';
339 339
             if (method_exists(self::$_MSG_PROCESSOR, $method)) {
340 340
                 self::$_MSG_PROCESSOR->$method();
341 341
             } else {
@@ -402,7 +402,7 @@  discard block
 block discarded – undo
402 402
         $template_pack_collection->rewind();
403 403
         $template_packs = [];
404 404
         while ($template_pack_collection->valid()) {
405
-            $template_packs[ $template_pack_collection->current()->dbref ] = $template_pack_collection->current();
405
+            $template_packs[$template_pack_collection->current()->dbref] = $template_pack_collection->current();
406 406
             $template_pack_collection->next();
407 407
         }
408 408
         return $template_packs;
@@ -450,9 +450,9 @@  discard block
 block discarded – undo
450 450
             'messages/validators/html',
451 451
             'shortcodes',
452 452
         ];
453
-        $paths   = [];
453
+        $paths = [];
454 454
         foreach ($dir_ref as $index => $dir) {
455
-            $paths[ $index ] = EE_LIBRARIES . $dir;
455
+            $paths[$index] = EE_LIBRARIES.$dir;
456 456
         }
457 457
         self::$_MSG_PATHS = apply_filters('FHEE__EED_Messages___set_messages_paths___MSG_PATHS', $paths);
458 458
     }
@@ -471,7 +471,7 @@  discard block
 block discarded – undo
471 471
      */
472 472
     protected static function _load_controller()
473 473
     {
474
-        if (! self::$_MSG_PROCESSOR instanceof EE_Messages_Processor) {
474
+        if ( ! self::$_MSG_PROCESSOR instanceof EE_Messages_Processor) {
475 475
             EE_Registry::instance()->load_core('Request_Handler');
476 476
             self::set_autoloaders();
477 477
             self::$_EEMSG                    = EE_Registry::instance()->load_lib('messages');
@@ -512,7 +512,7 @@  discard block
 block discarded – undo
512 512
     public static function payment(EE_Transaction $transaction, EE_Payment $payment = null)
513 513
     {
514 514
         // if there's no payment object, then we cannot do a payment type message!
515
-        if (! $payment instanceof EE_Payment) {
515
+        if ( ! $payment instanceof EE_Payment) {
516 516
             return;
517 517
         }
518 518
         self::_load_controller();
@@ -559,7 +559,7 @@  discard block
 block discarded – undo
559 559
     public static function maybe_registration(EE_Registration $registration, $extra_details = [])
560 560
     {
561 561
 
562
-        if (! self::_verify_registration_notification_send($registration, $extra_details)) {
562
+        if ( ! self::_verify_registration_notification_send($registration, $extra_details)) {
563 563
             // no messages please
564 564
             return;
565 565
         }
@@ -650,7 +650,7 @@  discard block
 block discarded – undo
650 650
         } else {
651 651
             // frontend request (either regular or via AJAX)
652 652
             // TXN is NOT finalized ?
653
-            if (! isset($extra_details['finalized']) || $extra_details['finalized'] === false) {
653
+            if ( ! isset($extra_details['finalized']) || $extra_details['finalized'] === false) {
654 654
                 return false;
655 655
             }
656 656
             // return visit but nothing changed ???
@@ -742,7 +742,7 @@  discard block
 block discarded – undo
742 742
 
743 743
         // make sure any incoming request data is set on the request so that it gets picked up later.
744 744
         foreach ((array) $req_data as $request_key => $request_value) {
745
-            if (! $request->requestParamIsSet($request_key)) {
745
+            if ( ! $request->requestParamIsSet($request_key)) {
746 746
                 $request->setRequestParam($request_key, $request_value);
747 747
             }
748 748
         }
@@ -782,7 +782,7 @@  discard block
 block discarded – undo
782 782
         self::_load_controller();
783 783
 
784 784
         $msgID = self::getRequest()->getRequestParam('MSG_ID', 0, 'int');
785
-        if (! $msgID) {
785
+        if ( ! $msgID) {
786 786
             EE_Error::add_error(
787 787
                 esc_html__(
788 788
                     'Something went wrong because there is no "MSG_ID" value in the request',
@@ -975,14 +975,14 @@  discard block
 block discarded – undo
975 975
             // get the message template group.
976 976
             $msg_template_group = EEM_Message_Template_Group::instance()->get_one([$template_query_params]);
977 977
             // if we don't have an EE_Message_Template_Group then return
978
-            if (! $msg_template_group instanceof EE_Message_Template_Group) {
978
+            if ( ! $msg_template_group instanceof EE_Message_Template_Group) {
979 979
                 // remove EVT_ID from query params so that global templates get picked up
980 980
                 unset($template_query_params['Event.EVT_ID']);
981 981
                 // get global template as the fallback
982 982
                 $msg_template_group = EEM_Message_Template_Group::instance()->get_one([$template_query_params]);
983 983
             }
984 984
             // if we don't have an EE_Message_Template_Group then return
985
-            if (! $msg_template_group instanceof EE_Message_Template_Group) {
985
+            if ( ! $msg_template_group instanceof EE_Message_Template_Group) {
986 986
                 return '';
987 987
             }
988 988
             // generate the URL
@@ -1018,7 +1018,7 @@  discard block
 block discarded – undo
1018 1018
     public static function preview_message($type, $context, $messenger, $send = false)
1019 1019
     {
1020 1020
         self::_load_controller();
1021
-        $message_to_generate     = new EE_Message_To_Generate(
1021
+        $message_to_generate = new EE_Message_To_Generate(
1022 1022
             $messenger,
1023 1023
             $type,
1024 1024
             [],
@@ -1100,7 +1100,7 @@  discard block
 block discarded – undo
1100 1100
     public static function generate_now($message_ids)
1101 1101
     {
1102 1102
         self::_load_controller();
1103
-        $messages        = EEM_Message::instance()->get_all(
1103
+        $messages = EEM_Message::instance()->get_all(
1104 1104
             [
1105 1105
                 0 => [
1106 1106
                     'MSG_ID' => ['IN', $message_ids],
@@ -1113,7 +1113,7 @@  discard block
 block discarded – undo
1113 1113
             $generated_queue = self::$_MSG_PROCESSOR->batch_generate_from_queue($messages);
1114 1114
         }
1115 1115
 
1116
-        if (! $generated_queue instanceof EE_Messages_Queue) {
1116
+        if ( ! $generated_queue instanceof EE_Messages_Queue) {
1117 1117
             EE_Error::add_error(
1118 1118
                 esc_html__(
1119 1119
                     'The messages were not generated. This could mean there is already a batch being generated on a separate request, or because the selected messages are not ready for generation. Please wait a minute or two and try again.',
@@ -1144,7 +1144,7 @@  discard block
 block discarded – undo
1144 1144
     public static function send_now($message_ids)
1145 1145
     {
1146 1146
         self::_load_controller();
1147
-        $messages   = EEM_Message::instance()->get_all(
1147
+        $messages = EEM_Message::instance()->get_all(
1148 1148
             [
1149 1149
                 0 => [
1150 1150
                     'MSG_ID' => ['IN', $message_ids],
@@ -1160,7 +1160,7 @@  discard block
 block discarded – undo
1160 1160
             $sent_queue = self::$_MSG_PROCESSOR->batch_send_from_queue($messages);
1161 1161
         }
1162 1162
 
1163
-        if (! $sent_queue instanceof EE_Messages_Queue) {
1163
+        if ( ! $sent_queue instanceof EE_Messages_Queue) {
1164 1164
             EE_Error::add_error(
1165 1165
                 esc_html__(
1166 1166
                     'The messages were not sent. This could mean there is already a batch being sent on a separate request, or because the selected messages are not sendable. Please wait a minute or two and try again.',
@@ -1348,7 +1348,7 @@  discard block
 block discarded – undo
1348 1348
                 $info['TXN_status']    = $transaction->status_ID();
1349 1349
                 $info['TXN_reg_steps'] = $transaction->reg_steps();
1350 1350
                 if ($transaction->ID()) {
1351
-                    $index = 'EE_Transaction: ' . $transaction->ID();
1351
+                    $index = 'EE_Transaction: '.$transaction->ID();
1352 1352
                     EEH_Debug_Tools::log($class, $func, $line, $info, $display_request, $index);
1353 1353
                 }
1354 1354
             }
Please login to merge, or discard this patch.
Indentation   +1343 added lines, -1343 removed lines patch added patch discarded remove patch
@@ -16,1356 +16,1356 @@
 block discarded – undo
16 16
  */
17 17
 class EED_Messages extends EED_Module
18 18
 {
19
-    /**
20
-     * This holds the EE_messages controller
21
-     *
22
-     * @deprecated 4.9.0
23
-     * @var EE_messages $_EEMSG
24
-     */
25
-    protected static $_EEMSG;
26
-
27
-    /**
28
-     * @type EE_Message_Resource_Manager $_message_resource_manager
29
-     */
30
-    protected static $_message_resource_manager;
31
-
32
-    /**
33
-     * This holds the EE_Messages_Processor business class.
34
-     *
35
-     * @type EE_Messages_Processor
36
-     */
37
-    protected static $_MSG_PROCESSOR;
38
-
39
-    /**
40
-     * holds all the paths for various messages components.
41
-     * Utilized by autoloader registry
42
-     *
43
-     * @var array
44
-     */
45
-    protected static $_MSG_PATHS;
46
-
47
-
48
-    /**
49
-     * This will hold an array of messages template packs that are registered in the messages system.
50
-     * Format is:
51
-     * array(
52
-     *    'template_pack_dbref' => EE_Messages_Template_Pack (instance)
53
-     * )
54
-     *
55
-     * @var EE_Messages_Template_Pack[]
56
-     */
57
-    protected static $_TMP_PACKS = [];
58
-
59
-
60
-    /**
61
-     * @return EED_Messages|EED_Module
62
-     * @throws EE_Error
63
-     * @throws ReflectionException
64
-     */
65
-    public static function instance()
66
-    {
67
-        return parent::get_instance(__CLASS__);
68
-    }
69
-
70
-
71
-    /**
72
-     *  set_hooks - for hooking into EE Core, other modules, etc
73
-     *
74
-     * @return    void
75
-     * @since 4.5.0
76
-     */
77
-    public static function set_hooks()
78
-    {
79
-        // actions
80
-        add_action('AHEE__EE_Payment_Processor__update_txn_based_on_payment', ['EED_Messages', 'payment'], 10, 2);
81
-        add_action(
82
-            'AHEE__EE_Registration_Processor__trigger_registration_update_notifications',
83
-            ['EED_Messages', 'maybe_registration'],
84
-            10,
85
-            2
86
-        );
87
-        // filters
88
-        add_filter(
89
-            'FHEE__EE_Registration__receipt_url__receipt_url',
90
-            ['EED_Messages', 'registration_message_trigger_url'],
91
-            10,
92
-            4
93
-        );
94
-        add_filter(
95
-            'FHEE__EE_Registration__invoice_url__invoice_url',
96
-            ['EED_Messages', 'registration_message_trigger_url'],
97
-            10,
98
-            4
99
-        );
100
-        // register routes
101
-        self::_register_routes();
102
-    }
103
-
104
-
105
-    /**
106
-     *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
107
-     *
108
-     * @access    public
109
-     * @return    void
110
-     */
111
-    public static function set_hooks_admin()
112
-    {
113
-        // actions
114
-        add_action('AHEE__EE_Payment_Processor__update_txn_based_on_payment', ['EED_Messages', 'payment'], 10, 2);
115
-        add_action(
116
-            'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
117
-            ['EED_Messages', 'payment_reminder'],
118
-            10
119
-        );
120
-        add_action(
121
-            'AHEE__EE_Registration_Processor__trigger_registration_update_notifications',
122
-            ['EED_Messages', 'maybe_registration'],
123
-            10,
124
-            3
125
-        );
126
-        add_action(
127
-            'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send__with_registrations',
128
-            ['EED_Messages', 'send_newsletter_message'],
129
-            10,
130
-            2
131
-        );
132
-        add_action(
133
-            'AHEE__EES_Espresso_Cancelled__process_shortcode__transaction',
134
-            ['EED_Messages', 'cancelled_registration'],
135
-            10
136
-        );
137
-        add_action(
138
-            'AHEE__EE_Admin_Page___process_admin_payment_notification',
139
-            ['EED_Messages', 'process_admin_payment'],
140
-            10,
141
-            1
142
-        );
143
-        // filters
144
-        add_filter(
145
-            'FHEE__EE_Admin_Page___process_resend_registration__success',
146
-            ['EED_Messages', 'process_resend'],
147
-            10,
148
-            2
149
-        );
150
-        add_filter(
151
-            'FHEE__EE_Registration__receipt_url__receipt_url',
152
-            ['EED_Messages', 'registration_message_trigger_url'],
153
-            10,
154
-            4
155
-        );
156
-        add_filter(
157
-            'FHEE__EE_Registration__invoice_url__invoice_url',
158
-            ['EED_Messages', 'registration_message_trigger_url'],
159
-            10,
160
-            4
161
-        );
162
-    }
163
-
164
-
165
-    /**
166
-     * All the message triggers done by route go in here.
167
-     *
168
-     * @return void
169
-     * @since 4.5.0
170
-     */
171
-    protected static function _register_routes()
172
-    {
173
-        EE_Config::register_route('msg_url_trigger', 'Messages', 'run');
174
-        EE_Config::register_route('msg_cron_trigger', 'Messages', 'execute_batch_request');
175
-        EE_Config::register_route('msg_browser_trigger', 'Messages', 'browser_trigger');
176
-        EE_Config::register_route('msg_browser_error_trigger', 'Messages', 'browser_error_trigger');
177
-        do_action('AHEE__EED_Messages___register_routes');
178
-    }
179
-
180
-
181
-    /**
182
-     * This is called when a browser display trigger is executed.
183
-     * The browser display trigger is typically used when a already generated message is displayed directly in the
184
-     * browser.
185
-     *
186
-     * @param WP $WP
187
-     * @throws EE_Error
188
-     * @throws InvalidArgumentException
189
-     * @throws ReflectionException
190
-     * @throws InvalidDataTypeException
191
-     * @throws InvalidInterfaceException
192
-     * @since 4.9.0
193
-     */
194
-    public function browser_trigger($WP)
195
-    {
196
-        // ensure controller is loaded
197
-        self::_load_controller();
198
-        $token = self::getRequest()->getRequestParam('token');
199
-        try {
200
-            $mtg = new EE_Message_Generated_From_Token($token, 'html', self::$_message_resource_manager);
201
-            self::$_MSG_PROCESSOR->generate_and_send_now($mtg);
202
-        } catch (EE_Error $e) {
203
-            $error_msg = esc_html__(
204
-                'Please note that a system message failed to send due to a technical issue.',
205
-                'event_espresso'
206
-            );
207
-            // add specific message for developers if WP_DEBUG in on
208
-            $error_msg .= '||' . $e->getMessage();
209
-            EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
210
-        }
211
-    }
212
-
213
-
214
-    /**
215
-     * This is called when a browser error trigger is executed.
216
-     * When triggered this will grab the EE_Message matching the token in the request and use that to get the error
217
-     * message and display it.
218
-     *
219
-     * @param $WP
220
-     * @throws EE_Error
221
-     * @throws InvalidArgumentException
222
-     * @throws InvalidDataTypeException
223
-     * @throws InvalidInterfaceException
224
-     * @since 4.9.0
225
-     */
226
-    public function browser_error_trigger($WP)
227
-    {
228
-        $token = self::getRequest()->getRequestParam('token');
229
-        if ($token) {
230
-            $message = EEM_Message::instance()->get_one_by_token($token);
231
-            if ($message instanceof EE_Message) {
232
-                header('HTTP/1.1 200 OK');
233
-                $error_msg = nl2br($message->error_message());
234
-                ?>
19
+	/**
20
+	 * This holds the EE_messages controller
21
+	 *
22
+	 * @deprecated 4.9.0
23
+	 * @var EE_messages $_EEMSG
24
+	 */
25
+	protected static $_EEMSG;
26
+
27
+	/**
28
+	 * @type EE_Message_Resource_Manager $_message_resource_manager
29
+	 */
30
+	protected static $_message_resource_manager;
31
+
32
+	/**
33
+	 * This holds the EE_Messages_Processor business class.
34
+	 *
35
+	 * @type EE_Messages_Processor
36
+	 */
37
+	protected static $_MSG_PROCESSOR;
38
+
39
+	/**
40
+	 * holds all the paths for various messages components.
41
+	 * Utilized by autoloader registry
42
+	 *
43
+	 * @var array
44
+	 */
45
+	protected static $_MSG_PATHS;
46
+
47
+
48
+	/**
49
+	 * This will hold an array of messages template packs that are registered in the messages system.
50
+	 * Format is:
51
+	 * array(
52
+	 *    'template_pack_dbref' => EE_Messages_Template_Pack (instance)
53
+	 * )
54
+	 *
55
+	 * @var EE_Messages_Template_Pack[]
56
+	 */
57
+	protected static $_TMP_PACKS = [];
58
+
59
+
60
+	/**
61
+	 * @return EED_Messages|EED_Module
62
+	 * @throws EE_Error
63
+	 * @throws ReflectionException
64
+	 */
65
+	public static function instance()
66
+	{
67
+		return parent::get_instance(__CLASS__);
68
+	}
69
+
70
+
71
+	/**
72
+	 *  set_hooks - for hooking into EE Core, other modules, etc
73
+	 *
74
+	 * @return    void
75
+	 * @since 4.5.0
76
+	 */
77
+	public static function set_hooks()
78
+	{
79
+		// actions
80
+		add_action('AHEE__EE_Payment_Processor__update_txn_based_on_payment', ['EED_Messages', 'payment'], 10, 2);
81
+		add_action(
82
+			'AHEE__EE_Registration_Processor__trigger_registration_update_notifications',
83
+			['EED_Messages', 'maybe_registration'],
84
+			10,
85
+			2
86
+		);
87
+		// filters
88
+		add_filter(
89
+			'FHEE__EE_Registration__receipt_url__receipt_url',
90
+			['EED_Messages', 'registration_message_trigger_url'],
91
+			10,
92
+			4
93
+		);
94
+		add_filter(
95
+			'FHEE__EE_Registration__invoice_url__invoice_url',
96
+			['EED_Messages', 'registration_message_trigger_url'],
97
+			10,
98
+			4
99
+		);
100
+		// register routes
101
+		self::_register_routes();
102
+	}
103
+
104
+
105
+	/**
106
+	 *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
107
+	 *
108
+	 * @access    public
109
+	 * @return    void
110
+	 */
111
+	public static function set_hooks_admin()
112
+	{
113
+		// actions
114
+		add_action('AHEE__EE_Payment_Processor__update_txn_based_on_payment', ['EED_Messages', 'payment'], 10, 2);
115
+		add_action(
116
+			'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
117
+			['EED_Messages', 'payment_reminder'],
118
+			10
119
+		);
120
+		add_action(
121
+			'AHEE__EE_Registration_Processor__trigger_registration_update_notifications',
122
+			['EED_Messages', 'maybe_registration'],
123
+			10,
124
+			3
125
+		);
126
+		add_action(
127
+			'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send__with_registrations',
128
+			['EED_Messages', 'send_newsletter_message'],
129
+			10,
130
+			2
131
+		);
132
+		add_action(
133
+			'AHEE__EES_Espresso_Cancelled__process_shortcode__transaction',
134
+			['EED_Messages', 'cancelled_registration'],
135
+			10
136
+		);
137
+		add_action(
138
+			'AHEE__EE_Admin_Page___process_admin_payment_notification',
139
+			['EED_Messages', 'process_admin_payment'],
140
+			10,
141
+			1
142
+		);
143
+		// filters
144
+		add_filter(
145
+			'FHEE__EE_Admin_Page___process_resend_registration__success',
146
+			['EED_Messages', 'process_resend'],
147
+			10,
148
+			2
149
+		);
150
+		add_filter(
151
+			'FHEE__EE_Registration__receipt_url__receipt_url',
152
+			['EED_Messages', 'registration_message_trigger_url'],
153
+			10,
154
+			4
155
+		);
156
+		add_filter(
157
+			'FHEE__EE_Registration__invoice_url__invoice_url',
158
+			['EED_Messages', 'registration_message_trigger_url'],
159
+			10,
160
+			4
161
+		);
162
+	}
163
+
164
+
165
+	/**
166
+	 * All the message triggers done by route go in here.
167
+	 *
168
+	 * @return void
169
+	 * @since 4.5.0
170
+	 */
171
+	protected static function _register_routes()
172
+	{
173
+		EE_Config::register_route('msg_url_trigger', 'Messages', 'run');
174
+		EE_Config::register_route('msg_cron_trigger', 'Messages', 'execute_batch_request');
175
+		EE_Config::register_route('msg_browser_trigger', 'Messages', 'browser_trigger');
176
+		EE_Config::register_route('msg_browser_error_trigger', 'Messages', 'browser_error_trigger');
177
+		do_action('AHEE__EED_Messages___register_routes');
178
+	}
179
+
180
+
181
+	/**
182
+	 * This is called when a browser display trigger is executed.
183
+	 * The browser display trigger is typically used when a already generated message is displayed directly in the
184
+	 * browser.
185
+	 *
186
+	 * @param WP $WP
187
+	 * @throws EE_Error
188
+	 * @throws InvalidArgumentException
189
+	 * @throws ReflectionException
190
+	 * @throws InvalidDataTypeException
191
+	 * @throws InvalidInterfaceException
192
+	 * @since 4.9.0
193
+	 */
194
+	public function browser_trigger($WP)
195
+	{
196
+		// ensure controller is loaded
197
+		self::_load_controller();
198
+		$token = self::getRequest()->getRequestParam('token');
199
+		try {
200
+			$mtg = new EE_Message_Generated_From_Token($token, 'html', self::$_message_resource_manager);
201
+			self::$_MSG_PROCESSOR->generate_and_send_now($mtg);
202
+		} catch (EE_Error $e) {
203
+			$error_msg = esc_html__(
204
+				'Please note that a system message failed to send due to a technical issue.',
205
+				'event_espresso'
206
+			);
207
+			// add specific message for developers if WP_DEBUG in on
208
+			$error_msg .= '||' . $e->getMessage();
209
+			EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
210
+		}
211
+	}
212
+
213
+
214
+	/**
215
+	 * This is called when a browser error trigger is executed.
216
+	 * When triggered this will grab the EE_Message matching the token in the request and use that to get the error
217
+	 * message and display it.
218
+	 *
219
+	 * @param $WP
220
+	 * @throws EE_Error
221
+	 * @throws InvalidArgumentException
222
+	 * @throws InvalidDataTypeException
223
+	 * @throws InvalidInterfaceException
224
+	 * @since 4.9.0
225
+	 */
226
+	public function browser_error_trigger($WP)
227
+	{
228
+		$token = self::getRequest()->getRequestParam('token');
229
+		if ($token) {
230
+			$message = EEM_Message::instance()->get_one_by_token($token);
231
+			if ($message instanceof EE_Message) {
232
+				header('HTTP/1.1 200 OK');
233
+				$error_msg = nl2br($message->error_message());
234
+				?>
235 235
                 <!DOCTYPE html>
236 236
                 <html>
237 237
                 <head></head>
238 238
                 <body>
239 239
                 <?php echo empty($error_msg)
240
-                    ? esc_html__(
241
-                        'Unfortunately, we were unable to capture the error message for this message.',
242
-                        'event_espresso'
243
-                    )
244
-                    : wp_kses(
245
-                        $error_msg,
246
-                        [
247
-                            'a'      => [
248
-                                'href'  => [],
249
-                                'title' => [],
250
-                            ],
251
-                            'span'   => [],
252
-                            'div'    => [],
253
-                            'p'      => [],
254
-                            'strong' => [],
255
-                            'em'     => [],
256
-                            'br'     => [],
257
-                        ]
258
-                    ); ?>
240
+					? esc_html__(
241
+						'Unfortunately, we were unable to capture the error message for this message.',
242
+						'event_espresso'
243
+					)
244
+					: wp_kses(
245
+						$error_msg,
246
+						[
247
+							'a'      => [
248
+								'href'  => [],
249
+								'title' => [],
250
+							],
251
+							'span'   => [],
252
+							'div'    => [],
253
+							'p'      => [],
254
+							'strong' => [],
255
+							'em'     => [],
256
+							'br'     => [],
257
+						]
258
+					); ?>
259 259
                 </body>
260 260
                 </html>
261 261
                 <?php
262
-                exit;
263
-            }
264
-        }
265
-    }
266
-
267
-
268
-    /**
269
-     *  This runs when the msg_url_trigger route has initiated.
270
-     *
271
-     * @param WP $WP
272
-     * @throws EE_Error
273
-     * @throws InvalidArgumentException
274
-     * @throws ReflectionException
275
-     * @throws InvalidDataTypeException
276
-     * @throws InvalidInterfaceException
277
-     * @since 4.5.0
278
-     */
279
-    public function run($WP)
280
-    {
281
-        // ensure controller is loaded
282
-        self::_load_controller();
283
-        // attempt to process message
284
-        try {
285
-            /** @type EE_Message_To_Generate_From_Request $message_to_generate */
286
-            $message_to_generate = EE_Registry::instance()->load_lib('Message_To_Generate_From_Request');
287
-            self::$_MSG_PROCESSOR->generate_and_send_now($message_to_generate);
288
-        } catch (EE_Error $e) {
289
-            $error_msg = esc_html__(
290
-                'Please note that a system message failed to send due to a technical issue.',
291
-                'event_espresso'
292
-            );
293
-            // add specific message for developers if WP_DEBUG in on
294
-            $error_msg .= '||' . $e->getMessage();
295
-            EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
296
-        }
297
-    }
298
-
299
-
300
-    /**
301
-     * This is triggered by the 'msg_cron_trigger' route.
302
-     *
303
-     * @param WP $WP
304
-     */
305
-    public function execute_batch_request($WP)
306
-    {
307
-        $this->run_cron();
308
-        header('HTTP/1.1 200 OK');
309
-        exit();
310
-    }
311
-
312
-
313
-    /**
314
-     * This gets executed on wp_cron jobs or when a batch request is initiated on its own separate non regular wp
315
-     * request.
316
-     */
317
-    public function run_cron()
318
-    {
319
-        self::_load_controller();
320
-        $request = self::getRequest();
321
-        // get required vars
322
-        $cron_type     = $request->getRequestParam('type');
323
-        $transient_key = $request->getRequestParam('key');
324
-
325
-        // now let's verify transient, if not valid exit immediately
326
-        if (! get_transient($transient_key)) {
327
-            /**
328
-             * trigger error so this gets in the error logs.  This is important because it happens on a non-user
329
-             * request.
330
-             */
331
-            trigger_error(esc_attr__('Invalid Request (Transient does not exist)', 'event_espresso'));
332
-        }
333
-
334
-        // if made it here, lets' delete the transient to keep the db clean
335
-        delete_transient($transient_key);
336
-
337
-        if (apply_filters('FHEE__EED_Messages__run_cron__use_wp_cron', true)) {
338
-            $method = 'batch_' . $cron_type . '_from_queue';
339
-            if (method_exists(self::$_MSG_PROCESSOR, $method)) {
340
-                self::$_MSG_PROCESSOR->$method();
341
-            } else {
342
-                // no matching task
343
-                /**
344
-                 * trigger error so this gets in the error logs.  This is important because it happens on a non user
345
-                 * request.
346
-                 */
347
-                trigger_error(
348
-                    esc_attr(
349
-                        sprintf(
350
-                            esc_html__('There is no task corresponding to this route %s', 'event_espresso'),
351
-                            $cron_type
352
-                        )
353
-                    )
354
-                );
355
-            }
356
-        }
357
-
358
-        do_action('FHEE__EED_Messages__run_cron__end');
359
-    }
360
-
361
-
362
-    /**
363
-     * This is used to retrieve the template pack for the given name.
364
-     * Retrieved packs are cached on the static $_TMP_PACKS array.  If there is no class matching the given name then
365
-     * the default template pack is returned.
366
-     *
367
-     * @param string $template_pack_name This should correspond to the dbref of the template pack (which is also used
368
-     *                                   in generating the Pack class name).
369
-     * @return EE_Messages_Template_Pack
370
-     * @throws EE_Error
371
-     * @throws InvalidArgumentException
372
-     * @throws ReflectionException
373
-     * @throws InvalidDataTypeException
374
-     * @throws InvalidInterfaceException
375
-     * @deprecated 4.9.0  @see EEH_MSG_Template::get_template_pack()
376
-     */
377
-    public static function get_template_pack($template_pack_name)
378
-    {
379
-        EE_Registry::instance()->load_helper('MSG_Template');
380
-        return EEH_MSG_Template::get_template_pack($template_pack_name);
381
-    }
382
-
383
-
384
-    /**
385
-     * Retrieves an array of all template packs.
386
-     * Array is in the format array( 'dbref' => EE_Messages_Template_Pack )
387
-     *
388
-     * @return EE_Messages_Template_Pack[]
389
-     * @throws EE_Error
390
-     * @throws InvalidArgumentException
391
-     * @throws ReflectionException
392
-     * @throws InvalidDataTypeException
393
-     * @throws InvalidInterfaceException
394
-     * @deprecated 4.9.0  @see EEH_MSG_Template_Pack::get_template_pack_collection
395
-     */
396
-    public static function get_template_packs()
397
-    {
398
-        EE_Registry::instance()->load_helper('MSG_Template');
399
-
400
-        // for backward compat, let's make sure this returns in the same format as originally.
401
-        $template_pack_collection = EEH_MSG_Template::get_template_pack_collection();
402
-        $template_pack_collection->rewind();
403
-        $template_packs = [];
404
-        while ($template_pack_collection->valid()) {
405
-            $template_packs[ $template_pack_collection->current()->dbref ] = $template_pack_collection->current();
406
-            $template_pack_collection->next();
407
-        }
408
-        return $template_packs;
409
-    }
410
-
411
-
412
-    /**
413
-     * This simply makes sure the autoloaders are registered for the EE_messages system.
414
-     *
415
-     * @return void
416
-     * @throws EE_Error
417
-     * @since 4.5.0
418
-     */
419
-    public static function set_autoloaders()
420
-    {
421
-        if (empty(self::$_MSG_PATHS)) {
422
-            self::_set_messages_paths();
423
-            foreach (self::$_MSG_PATHS as $path) {
424
-                EEH_Autoloader::register_autoloaders_for_each_file_in_folder($path);
425
-            }
426
-            // add aliases
427
-            EEH_Autoloader::add_alias('EE_messages', 'EE_messages');
428
-            EEH_Autoloader::add_alias('EE_messenger', 'EE_messenger');
429
-        }
430
-    }
431
-
432
-
433
-    /**
434
-     * Take care of adding all the paths for the messages components to the $_MSG_PATHS property
435
-     * for use by the Messages Autoloaders
436
-     *
437
-     * @return void.
438
-     * @since 4.5.0
439
-     */
440
-    protected static function _set_messages_paths()
441
-    {
442
-        $dir_ref = [
443
-            'messages/message_type',
444
-            'messages/messenger',
445
-            'messages/defaults',
446
-            'messages/defaults/email',
447
-            'messages/data_class',
448
-            'messages/validators',
449
-            'messages/validators/email',
450
-            'messages/validators/html',
451
-            'shortcodes',
452
-        ];
453
-        $paths   = [];
454
-        foreach ($dir_ref as $index => $dir) {
455
-            $paths[ $index ] = EE_LIBRARIES . $dir;
456
-        }
457
-        self::$_MSG_PATHS = apply_filters('FHEE__EED_Messages___set_messages_paths___MSG_PATHS', $paths);
458
-    }
459
-
460
-
461
-    /**
462
-     * Takes care of loading dependencies
463
-     *
464
-     * @return void
465
-     * @throws EE_Error
466
-     * @throws InvalidArgumentException
467
-     * @throws ReflectionException
468
-     * @throws InvalidDataTypeException
469
-     * @throws InvalidInterfaceException
470
-     * @since 4.5.0
471
-     */
472
-    protected static function _load_controller()
473
-    {
474
-        if (! self::$_MSG_PROCESSOR instanceof EE_Messages_Processor) {
475
-            EE_Registry::instance()->load_core('Request_Handler');
476
-            self::set_autoloaders();
477
-            self::$_EEMSG                    = EE_Registry::instance()->load_lib('messages');
478
-            self::$_MSG_PROCESSOR            = EE_Registry::instance()->load_lib('Messages_Processor');
479
-            self::$_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
480
-        }
481
-    }
482
-
483
-
484
-    /**
485
-     * @param EE_Transaction $transaction
486
-     * @throws EE_Error
487
-     * @throws InvalidArgumentException
488
-     * @throws InvalidDataTypeException
489
-     * @throws InvalidInterfaceException
490
-     * @throws ReflectionException
491
-     */
492
-    public static function payment_reminder(EE_Transaction $transaction)
493
-    {
494
-        self::_load_controller();
495
-        $data = [$transaction, null];
496
-        self::$_MSG_PROCESSOR->generate_for_all_active_messengers('payment_reminder', $data);
497
-    }
498
-
499
-
500
-    /**
501
-     * Any messages triggers for after successful gateway payments should go in here.
502
-     *
503
-     * @param EE_Transaction  $transaction object
504
-     * @param EE_Payment|null $payment     object
505
-     * @return void
506
-     * @throws EE_Error
507
-     * @throws InvalidArgumentException
508
-     * @throws ReflectionException
509
-     * @throws InvalidDataTypeException
510
-     * @throws InvalidInterfaceException
511
-     */
512
-    public static function payment(EE_Transaction $transaction, EE_Payment $payment = null)
513
-    {
514
-        // if there's no payment object, then we cannot do a payment type message!
515
-        if (! $payment instanceof EE_Payment) {
516
-            return;
517
-        }
518
-        self::_load_controller();
519
-        $data = [$transaction, $payment];
520
-        EE_Registry::instance()->load_helper('MSG_Template');
521
-        $message_type = EEH_MSG_Template::convert_payment_status_to_message_type($payment->STS_ID());
522
-        // if payment amount is less than 0 then switch to payment_refund message type.
523
-        $message_type = $payment->amount() < 0 ? 'payment_refund' : $message_type;
524
-        self::$_MSG_PROCESSOR->generate_for_all_active_messengers($message_type, $data);
525
-    }
526
-
527
-
528
-    /**
529
-     * @param EE_Transaction $transaction
530
-     * @throws EE_Error
531
-     * @throws InvalidArgumentException
532
-     * @throws InvalidDataTypeException
533
-     * @throws InvalidInterfaceException
534
-     * @throws ReflectionException
535
-     */
536
-    public static function cancelled_registration(EE_Transaction $transaction)
537
-    {
538
-        self::_load_controller();
539
-        $data = [$transaction, null];
540
-        self::$_MSG_PROCESSOR->generate_for_all_active_messengers('cancelled_registration', $data);
541
-    }
542
-
543
-
544
-    /**
545
-     * Trigger for Registration messages
546
-     * Note that what registration message type is sent depends on what the reg status is for the registrations on the
547
-     * incoming transaction.
548
-     *
549
-     * @param EE_Registration $registration
550
-     * @param array           $extra_details
551
-     * @return void
552
-     * @throws EE_Error
553
-     * @throws InvalidArgumentException
554
-     * @throws InvalidDataTypeException
555
-     * @throws InvalidInterfaceException
556
-     * @throws ReflectionException
557
-     * @throws EntityNotFoundException
558
-     */
559
-    public static function maybe_registration(EE_Registration $registration, $extra_details = [])
560
-    {
561
-
562
-        if (! self::_verify_registration_notification_send($registration, $extra_details)) {
563
-            // no messages please
564
-            return;
565
-        }
566
-
567
-        // get all non-trashed registrations so we make sure we send messages for the right status.
568
-        $all_registrations = $registration->transaction()->registrations(
569
-            [
570
-                ['REG_deleted' => false],
571
-                'order_by' => [
572
-                    'Event.EVT_name'     => 'ASC',
573
-                    'Attendee.ATT_lname' => 'ASC',
574
-                    'Attendee.ATT_fname' => 'ASC',
575
-                ],
576
-            ]
577
-        );
578
-        // cached array of statuses so we only trigger messages once per status.
579
-        $statuses_sent = [];
580
-        self::_load_controller();
581
-        $mtgs = [];
582
-
583
-        // loop through registrations and trigger messages once per status.
584
-        foreach ($all_registrations as $reg) {
585
-            // already triggered?
586
-            if (in_array($reg->status_ID(), $statuses_sent)) {
587
-                continue;
588
-            }
589
-
590
-            $message_type    = EEH_MSG_Template::convert_reg_status_to_message_type($reg->status_ID());
591
-            $mtgs            = array_merge(
592
-                $mtgs,
593
-                self::$_MSG_PROCESSOR->setup_mtgs_for_all_active_messengers(
594
-                    $message_type,
595
-                    [$registration->transaction(), null, $reg->status_ID()]
596
-                )
597
-            );
598
-            $statuses_sent[] = $reg->status_ID();
599
-        }
600
-
601
-        if (count($statuses_sent) > 1) {
602
-            $mtgs = array_merge(
603
-                $mtgs,
604
-                self::$_MSG_PROCESSOR->setup_mtgs_for_all_active_messengers(
605
-                    'registration_summary',
606
-                    [$registration->transaction(), null]
607
-                )
608
-            );
609
-        }
610
-
611
-        // batch queue and initiate request
612
-        self::$_MSG_PROCESSOR->batch_queue_for_generation_and_persist($mtgs);
613
-        self::$_MSG_PROCESSOR->get_queue()->initiate_request_by_priority();
614
-    }
615
-
616
-
617
-    /**
618
-     * This is a helper method used to very whether a registration notification should be sent or
619
-     * not.  Prevents duplicate notifications going out for registration context notifications.
620
-     *
621
-     * @param EE_Registration $registration  [description]
622
-     * @param array           $extra_details [description]
623
-     * @return bool          true = send away, false = nope halt the presses.
624
-     */
625
-    protected static function _verify_registration_notification_send(
626
-        EE_Registration $registration,
627
-        $extra_details = []
628
-    ) {
629
-        $request = self::getRequest();
630
-        if (
631
-            ! $request->getRequestParam('non_primary_reg_notification', 0, 'int')
632
-            && ! $registration->is_primary_registrant()
633
-        ) {
634
-            return false;
635
-        }
636
-        // first we check if we're in admin and not doing front ajax
637
-        if (
638
-            ($request->isAdmin() || $request->isAdminAjax())
639
-            && ! $request->isFrontAjax()
640
-        ) {
641
-            $status_change = $request->getRequestParam('txn_reg_status_change', [], 'int', true);
642
-            // make sure appropriate admin params are set for sending messages
643
-            if (
644
-                ! isset($status_change['send_notifications'])
645
-                || (isset($status_change['send_notifications']) && ! $status_change['send_notifications'])
646
-            ) {
647
-                // no messages sent please.
648
-                return false;
649
-            }
650
-        } else {
651
-            // frontend request (either regular or via AJAX)
652
-            // TXN is NOT finalized ?
653
-            if (! isset($extra_details['finalized']) || $extra_details['finalized'] === false) {
654
-                return false;
655
-            }
656
-            // return visit but nothing changed ???
657
-            if (
658
-                isset($extra_details['revisit'], $extra_details['status_updates'])
659
-                && $extra_details['revisit']
660
-                && ! $extra_details['status_updates']
661
-            ) {
662
-                return false;
663
-            }
664
-            // NOT sending messages && reg status is something other than "Not-Approved"
665
-            if (
666
-                ! apply_filters('FHEE__EED_Messages___maybe_registration__deliver_notifications', false)
667
-                && $registration->status_ID() !== EEM_Registration::status_id_not_approved
668
-            ) {
669
-                return false;
670
-            }
671
-        }
672
-        // release the kraken
673
-        return true;
674
-    }
675
-
676
-
677
-    /**
678
-     * Simply returns an array indexed by Registration Status ID and the related message_type name associated with that
679
-     * status id.
680
-     *
681
-     * @param string $reg_status
682
-     * @return array
683
-     * @throws EE_Error
684
-     * @throws InvalidArgumentException
685
-     * @throws ReflectionException
686
-     * @throws InvalidDataTypeException
687
-     * @throws InvalidInterfaceException
688
-     * @deprecated        4.9.0  Use EEH_MSG_Template::reg_status_to_message_type_array()
689
-     *                    or EEH_MSG_Template::convert_reg_status_to_message_type
690
-     */
691
-    protected static function _get_reg_status_array($reg_status = '')
692
-    {
693
-        EE_Registry::instance()->load_helper('MSG_Template');
694
-        return EEH_MSG_Template::convert_reg_status_to_message_type($reg_status)
695
-            ? EEH_MSG_Template::convert_reg_status_to_message_type($reg_status)
696
-            : EEH_MSG_Template::reg_status_to_message_type_array();
697
-    }
698
-
699
-
700
-    /**
701
-     * Simply returns the payment message type for the given payment status.
702
-     *
703
-     * @param string $payment_status The payment status being matched.
704
-     * @return bool|string The payment message type slug matching the status or false if no match.
705
-     * @throws EE_Error
706
-     * @throws InvalidArgumentException
707
-     * @throws ReflectionException
708
-     * @throws InvalidDataTypeException
709
-     * @throws InvalidInterfaceException
710
-     * @deprecated       4.9.0 Use EEH_MSG_Template::payment_status_to_message_type_array
711
-     *                   or EEH_MSG_Template::convert_payment_status_to_message_type
712
-     */
713
-    protected static function _get_payment_message_type($payment_status)
714
-    {
715
-        EE_Registry::instance()->load_helper('MSG_Template');
716
-        return EEH_MSG_Template::convert_payment_status_to_message_type($payment_status)
717
-            ? EEH_MSG_Template::convert_payment_status_to_message_type($payment_status)
718
-            : false;
719
-    }
720
-
721
-
722
-    /**
723
-     * Message triggers for a resending already sent message(s) (via EE_Message list table)
724
-     *
725
-     * @access public
726
-     * @param array $req_data This is the $_POST & $_GET data sent from EE_Admin Pages
727
-     * @return bool success/fail
728
-     * @throws EE_Error
729
-     * @throws InvalidArgumentException
730
-     * @throws InvalidDataTypeException
731
-     * @throws InvalidInterfaceException
732
-     * @throws ReflectionException
733
-     */
734
-    public static function process_resend(array $req_data = [])
735
-    {
736
-        self::_load_controller();
737
-        $request = self::getRequest();
738
-        // if $msgID in this request then skip to the new resend_message
739
-        if ($request->getRequestParam('MSG_ID')) {
740
-            return self::resend_message();
741
-        }
742
-
743
-        // make sure any incoming request data is set on the request so that it gets picked up later.
744
-        foreach ((array) $req_data as $request_key => $request_value) {
745
-            if (! $request->requestParamIsSet($request_key)) {
746
-                $request->setRequestParam($request_key, $request_value);
747
-            }
748
-        }
749
-
750
-        if (
751
-            ! $messages_to_send = self::$_MSG_PROCESSOR->setup_messages_to_generate_from_registration_ids_in_request()
752
-        ) {
753
-            return false;
754
-        }
755
-
756
-        try {
757
-            self::$_MSG_PROCESSOR->batch_queue_for_generation_and_persist($messages_to_send);
758
-            self::$_MSG_PROCESSOR->get_queue()->initiate_request_by_priority();
759
-        } catch (EE_Error $e) {
760
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
761
-            return false;
762
-        }
763
-        EE_Error::add_success(
764
-            esc_html__('Messages have been successfully queued for generation and sending.', 'event_espresso')
765
-        );
766
-        return true; // everything got queued.
767
-    }
768
-
769
-
770
-    /**
771
-     * Message triggers for a resending already sent message(s) (via EE_Message list table)
772
-     *
773
-     * @return bool
774
-     * @throws EE_Error
775
-     * @throws InvalidArgumentException
776
-     * @throws InvalidDataTypeException
777
-     * @throws InvalidInterfaceException
778
-     * @throws ReflectionException
779
-     */
780
-    public static function resend_message()
781
-    {
782
-        self::_load_controller();
783
-
784
-        $msgID = self::getRequest()->getRequestParam('MSG_ID', 0, 'int');
785
-        if (! $msgID) {
786
-            EE_Error::add_error(
787
-                esc_html__(
788
-                    'Something went wrong because there is no "MSG_ID" value in the request',
789
-                    'event_espresso'
790
-                ),
791
-                __FILE__,
792
-                __FUNCTION__,
793
-                __LINE__
794
-            );
795
-            return false;
796
-        }
797
-
798
-        self::$_MSG_PROCESSOR->setup_messages_from_ids_and_send((array) $msgID);
799
-
800
-        // setup success message.
801
-        $count_ready_for_resend = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(EEM_Message::status_resend);
802
-        EE_Error::add_success(
803
-            sprintf(
804
-                _n(
805
-                    'There was %d message queued for resending.',
806
-                    'There were %d messages queued for resending.',
807
-                    $count_ready_for_resend,
808
-                    'event_espresso'
809
-                ),
810
-                $count_ready_for_resend
811
-            )
812
-        );
813
-        return true;
814
-    }
815
-
816
-
817
-    /**
818
-     * Message triggers for manual payment applied by admin
819
-     *
820
-     * @param EE_Payment $payment EE_payment object
821
-     * @return bool success/fail
822
-     * @throws EE_Error
823
-     * @throws InvalidArgumentException
824
-     * @throws ReflectionException
825
-     * @throws InvalidDataTypeException
826
-     * @throws InvalidInterfaceException
827
-     */
828
-    public static function process_admin_payment(EE_Payment $payment)
829
-    {
830
-        EE_Registry::instance()->load_helper('MSG_Template');
831
-        // we need to get the transaction object
832
-        $transaction = $payment->transaction();
833
-        if ($transaction instanceof EE_Transaction) {
834
-            $data         = [$transaction, $payment];
835
-            $message_type = EEH_MSG_Template::convert_payment_status_to_message_type($payment->STS_ID());
836
-
837
-            // if payment amount is less than 0 then switch to payment_refund message type.
838
-            $message_type = $payment->amount() < 0 ? 'payment_refund' : $message_type;
839
-
840
-            // if payment_refund is selected, but the status is NOT accepted.  Then change message type to false so NO message notification goes out.
841
-            $message_type = $message_type == 'payment_refund' && $payment->STS_ID() != EEM_Payment::status_id_approved
842
-                ? false : $message_type;
843
-
844
-            self::_load_controller();
845
-
846
-            self::$_MSG_PROCESSOR->generate_for_all_active_messengers($message_type, $data);
847
-
848
-            // get count of queued for generation
849
-            $count_to_generate = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(
850
-                [
851
-                    EEM_Message::status_incomplete,
852
-                    EEM_Message::status_idle,
853
-                ]
854
-            );
855
-
856
-            if ($count_to_generate > 0 && self::$_MSG_PROCESSOR->get_queue()->get_message_repository()->count() !== 0) {
857
-                add_filter('FHEE__EE_Admin_Page___process_admin_payment_notification__success', '__return_true');
858
-                return true;
859
-            } else {
860
-                $count_failed = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(
861
-                    EEM_Message::instance()->stati_indicating_failed_sending()
862
-                );
863
-                /**
864
-                 * Verify that there are actually errors.  If not then we return a success message because the queue might have been emptied due to successful
865
-                 * IMMEDIATE generation.
866
-                 */
867
-                if ($count_failed > 0) {
868
-                    EE_Error::add_error(
869
-                        sprintf(
870
-                            _n(
871
-                                'The payment notification generation failed.',
872
-                                '%d payment notifications failed being sent.',
873
-                                $count_failed,
874
-                                'event_espresso'
875
-                            ),
876
-                            $count_failed
877
-                        ),
878
-                        __FILE__,
879
-                        __FUNCTION__,
880
-                        __LINE__
881
-                    );
882
-
883
-                    return false;
884
-                } else {
885
-                    add_filter('FHEE__EE_Admin_Page___process_admin_payment_notification__success', '__return_true');
886
-                    return true;
887
-                }
888
-            }
889
-        } else {
890
-            EE_Error::add_error(
891
-                'Unable to generate the payment notification because the given value for the transaction is invalid.',
892
-                'event_espresso'
893
-            );
894
-            return false;
895
-        }
896
-    }
897
-
898
-
899
-    /**
900
-     * Callback for AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send_with_registrations trigger
901
-     *
902
-     * @param EE_Registration[] $registrations an array of EE_Registration objects
903
-     * @param int               $grp_id        a specific message template group id.
904
-     * @return void
905
-     * @throws EE_Error
906
-     * @throws InvalidArgumentException
907
-     * @throws InvalidDataTypeException
908
-     * @throws InvalidInterfaceException
909
-     * @throws ReflectionException
910
-     * @since   4.3.0
911
-     */
912
-    public static function send_newsletter_message($registrations, $grp_id)
913
-    {
914
-        // make sure mtp is id and set it in the request later messages setup.
915
-        self::getRequest()->setRequestParam('GRP_ID', (int) $grp_id);
916
-        self::_load_controller();
917
-        self::$_MSG_PROCESSOR->generate_for_all_active_messengers('newsletter', $registrations);
918
-    }
919
-
920
-
921
-    /**
922
-     * Callback for FHEE__EE_Registration__invoice_url__invoice_url or FHEE__EE_Registration__receipt_url__receipt_url
923
-     *
924
-     * @param string          $registration_message_trigger_url
925
-     * @param EE_Registration $registration
926
-     * @param string          $messenger
927
-     * @param string          $message_type
928
-     * @return string
929
-     * @throws EE_Error
930
-     * @throws InvalidArgumentException
931
-     * @throws InvalidDataTypeException
932
-     * @throws InvalidInterfaceException
933
-     * @since   4.3.0
934
-     */
935
-    public static function registration_message_trigger_url(
936
-        $registration_message_trigger_url,
937
-        EE_Registration $registration,
938
-        $messenger = 'html',
939
-        $message_type = 'invoice'
940
-    ) {
941
-        // whitelist $messenger
942
-        switch ($messenger) {
943
-            case 'pdf':
944
-                $sending_messenger    = 'pdf';
945
-                $generating_messenger = 'html';
946
-                break;
947
-            case 'html':
948
-            default:
949
-                $sending_messenger    = 'html';
950
-                $generating_messenger = 'html';
951
-                break;
952
-        }
953
-        // whitelist $message_type
954
-        switch ($message_type) {
955
-            case 'receipt':
956
-                $message_type = 'receipt';
957
-                break;
958
-            case 'invoice':
959
-            default:
960
-                $message_type = 'invoice';
961
-                break;
962
-        }
963
-        // verify that both the messenger AND the message type are active
964
-        if (
965
-            EEH_MSG_Template::is_messenger_active($sending_messenger)
966
-            && EEH_MSG_Template::is_mt_active($message_type)
967
-        ) {
968
-            // need to get the correct message template group for this (i.e. is there a custom invoice for the event this registration is registered for?)
969
-            $template_query_params = [
970
-                'MTP_is_active'    => true,
971
-                'MTP_messenger'    => $generating_messenger,
972
-                'MTP_message_type' => $message_type,
973
-                'Event.EVT_ID'     => $registration->event_ID(),
974
-            ];
975
-            // get the message template group.
976
-            $msg_template_group = EEM_Message_Template_Group::instance()->get_one([$template_query_params]);
977
-            // if we don't have an EE_Message_Template_Group then return
978
-            if (! $msg_template_group instanceof EE_Message_Template_Group) {
979
-                // remove EVT_ID from query params so that global templates get picked up
980
-                unset($template_query_params['Event.EVT_ID']);
981
-                // get global template as the fallback
982
-                $msg_template_group = EEM_Message_Template_Group::instance()->get_one([$template_query_params]);
983
-            }
984
-            // if we don't have an EE_Message_Template_Group then return
985
-            if (! $msg_template_group instanceof EE_Message_Template_Group) {
986
-                return '';
987
-            }
988
-            // generate the URL
989
-            $registration_message_trigger_url = EEH_MSG_Template::generate_url_trigger(
990
-                $sending_messenger,
991
-                $generating_messenger,
992
-                'purchaser',
993
-                $message_type,
994
-                $registration,
995
-                $msg_template_group->ID(),
996
-                $registration->transaction_ID()
997
-            );
998
-        }
999
-        return $registration_message_trigger_url;
1000
-    }
1001
-
1002
-
1003
-    /**
1004
-     * Use to generate and return a message preview!
1005
-     *
1006
-     * @param string $type       This should correspond with a valid message type
1007
-     * @param string $context    This should correspond with a valid context for the message type
1008
-     * @param string $messenger  This should correspond with a valid messenger.
1009
-     * @param bool   $send       true we will do a test send using the messenger delivery, false we just do a regular
1010
-     *                           preview
1011
-     * @return bool|string The body of the message or if send is requested, sends.
1012
-     * @throws EE_Error
1013
-     * @throws InvalidArgumentException
1014
-     * @throws InvalidDataTypeException
1015
-     * @throws InvalidInterfaceException
1016
-     * @throws ReflectionException
1017
-     */
1018
-    public static function preview_message($type, $context, $messenger, $send = false)
1019
-    {
1020
-        self::_load_controller();
1021
-        $message_to_generate     = new EE_Message_To_Generate(
1022
-            $messenger,
1023
-            $type,
1024
-            [],
1025
-            $context,
1026
-            true
1027
-        );
1028
-        $generated_preview_queue = self::$_MSG_PROCESSOR->generate_for_preview($message_to_generate, $send);
1029
-
1030
-        if ($generated_preview_queue instanceof EE_Messages_Queue) {
1031
-            // loop through all content for the preview and remove any persisted records.
1032
-            $content = '';
1033
-            foreach ($generated_preview_queue->get_message_repository() as $message) {
1034
-                $content = $message->content();
1035
-                if ($message->ID() > 0 && $message->STS_ID() !== EEM_Message::status_failed) {
1036
-                    $message->delete();
1037
-                }
1038
-            }
1039
-            return $content;
1040
-        }
1041
-        return $generated_preview_queue;
1042
-    }
1043
-
1044
-
1045
-    /**
1046
-     * This is a method that allows for sending a message using a messenger matching the string given and the provided
1047
-     * EE_Message_Queue object.  The EE_Message_Queue object is used to create a single aggregate EE_Message via the
1048
-     * content found in the EE_Message objects in the queue.
1049
-     *
1050
-     * @param string            $messenger            a string matching a valid active messenger in the system
1051
-     * @param string            $message_type         Although it seems contrary to the name of the method, a message
1052
-     *                                                type name is still required to send along the message type to the
1053
-     *                                                messenger because this is used for determining what specific
1054
-     *                                                variations might be loaded for the generated message.
1055
-     * @param EE_Messages_Queue $queue
1056
-     * @param string            $custom_subject       Can be used to set what the custom subject string will be on the
1057
-     *                                                aggregate EE_Message object.
1058
-     * @return bool success or fail.
1059
-     * @throws EE_Error
1060
-     * @throws InvalidArgumentException
1061
-     * @throws ReflectionException
1062
-     * @throws InvalidDataTypeException
1063
-     * @throws InvalidInterfaceException
1064
-     * @since 4.9.0
1065
-     */
1066
-    public static function send_message_with_messenger_only(
1067
-        $messenger,
1068
-        $message_type,
1069
-        EE_Messages_Queue $queue,
1070
-        $custom_subject = ''
1071
-    ) {
1072
-        self::_load_controller();
1073
-        /** @type EE_Message_To_Generate_From_Queue $message_to_generate */
1074
-        $message_to_generate = EE_Registry::instance()->load_lib(
1075
-            'Message_To_Generate_From_Queue',
1076
-            [
1077
-                $messenger,
1078
-                $message_type,
1079
-                $queue,
1080
-                $custom_subject,
1081
-            ]
1082
-        );
1083
-        return self::$_MSG_PROCESSOR->queue_for_sending($message_to_generate);
1084
-    }
1085
-
1086
-
1087
-    /**
1088
-     * Generates Messages immediately for EE_Message IDs (but only for the correct status for generation)
1089
-     *
1090
-     * @param array $message_ids An array of message ids
1091
-     * @return bool|EE_Messages_Queue false if nothing was generated, EE_Messages_Queue containing generated
1092
-     *                           messages.
1093
-     * @throws EE_Error
1094
-     * @throws InvalidArgumentException
1095
-     * @throws InvalidDataTypeException
1096
-     * @throws InvalidInterfaceException
1097
-     * @throws ReflectionException
1098
-     * @since 4.9.0
1099
-     */
1100
-    public static function generate_now($message_ids)
1101
-    {
1102
-        self::_load_controller();
1103
-        $messages        = EEM_Message::instance()->get_all(
1104
-            [
1105
-                0 => [
1106
-                    'MSG_ID' => ['IN', $message_ids],
1107
-                    'STS_ID' => EEM_Message::status_incomplete,
1108
-                ],
1109
-            ]
1110
-        );
1111
-        $generated_queue = false;
1112
-        if ($messages) {
1113
-            $generated_queue = self::$_MSG_PROCESSOR->batch_generate_from_queue($messages);
1114
-        }
1115
-
1116
-        if (! $generated_queue instanceof EE_Messages_Queue) {
1117
-            EE_Error::add_error(
1118
-                esc_html__(
1119
-                    'The messages were not generated. This could mean there is already a batch being generated on a separate request, or because the selected messages are not ready for generation. Please wait a minute or two and try again.',
1120
-                    'event_espresso'
1121
-                ),
1122
-                __FILE__,
1123
-                __FUNCTION__,
1124
-                __LINE__
1125
-            );
1126
-        }
1127
-        return $generated_queue;
1128
-    }
1129
-
1130
-
1131
-    /**
1132
-     * Sends messages immediately for the incoming message_ids that have the status of EEM_Message::status_resend or,
1133
-     * EEM_Message::status_idle
1134
-     *
1135
-     * @param $message_ids
1136
-     * @return bool|EE_Messages_Queue false if no messages sent.
1137
-     * @throws EE_Error
1138
-     * @throws InvalidArgumentException
1139
-     * @throws InvalidDataTypeException
1140
-     * @throws InvalidInterfaceException
1141
-     * @throws ReflectionException
1142
-     * @since 4.9.0
1143
-     */
1144
-    public static function send_now($message_ids)
1145
-    {
1146
-        self::_load_controller();
1147
-        $messages   = EEM_Message::instance()->get_all(
1148
-            [
1149
-                0 => [
1150
-                    'MSG_ID' => ['IN', $message_ids],
1151
-                    'STS_ID' => [
1152
-                        'IN',
1153
-                        [EEM_Message::status_idle, EEM_Message::status_resend, EEM_Message::status_retry],
1154
-                    ],
1155
-                ],
1156
-            ]
1157
-        );
1158
-        $sent_queue = false;
1159
-        if ($messages) {
1160
-            $sent_queue = self::$_MSG_PROCESSOR->batch_send_from_queue($messages);
1161
-        }
1162
-
1163
-        if (! $sent_queue instanceof EE_Messages_Queue) {
1164
-            EE_Error::add_error(
1165
-                esc_html__(
1166
-                    'The messages were not sent. This could mean there is already a batch being sent on a separate request, or because the selected messages are not sendable. Please wait a minute or two and try again.',
1167
-                    'event_espresso'
1168
-                ),
1169
-                __FILE__,
1170
-                __FUNCTION__,
1171
-                __LINE__
1172
-            );
1173
-        } else {
1174
-            // can count how many sent by using the messages in the queue
1175
-            $sent_count = $sent_queue->count_STS_in_queue(EEM_Message::instance()->stati_indicating_sent());
1176
-            if ($sent_count > 0) {
1177
-                EE_Error::add_success(
1178
-                    sprintf(
1179
-                        _n(
1180
-                            'There was %d message successfully sent.',
1181
-                            'There were %d messages successfully sent.',
1182
-                            $sent_count,
1183
-                            'event_espresso'
1184
-                        ),
1185
-                        $sent_count
1186
-                    )
1187
-                );
1188
-            } else {
1189
-                EE_Error::overwrite_errors();
1190
-                EE_Error::add_error(
1191
-                    esc_html__(
1192
-                        'No message was sent because of problems with sending. Either all the messages you selected were not a sendable message, they were ALREADY sent on a different scheduled task, or there was an error.
262
+				exit;
263
+			}
264
+		}
265
+	}
266
+
267
+
268
+	/**
269
+	 *  This runs when the msg_url_trigger route has initiated.
270
+	 *
271
+	 * @param WP $WP
272
+	 * @throws EE_Error
273
+	 * @throws InvalidArgumentException
274
+	 * @throws ReflectionException
275
+	 * @throws InvalidDataTypeException
276
+	 * @throws InvalidInterfaceException
277
+	 * @since 4.5.0
278
+	 */
279
+	public function run($WP)
280
+	{
281
+		// ensure controller is loaded
282
+		self::_load_controller();
283
+		// attempt to process message
284
+		try {
285
+			/** @type EE_Message_To_Generate_From_Request $message_to_generate */
286
+			$message_to_generate = EE_Registry::instance()->load_lib('Message_To_Generate_From_Request');
287
+			self::$_MSG_PROCESSOR->generate_and_send_now($message_to_generate);
288
+		} catch (EE_Error $e) {
289
+			$error_msg = esc_html__(
290
+				'Please note that a system message failed to send due to a technical issue.',
291
+				'event_espresso'
292
+			);
293
+			// add specific message for developers if WP_DEBUG in on
294
+			$error_msg .= '||' . $e->getMessage();
295
+			EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
296
+		}
297
+	}
298
+
299
+
300
+	/**
301
+	 * This is triggered by the 'msg_cron_trigger' route.
302
+	 *
303
+	 * @param WP $WP
304
+	 */
305
+	public function execute_batch_request($WP)
306
+	{
307
+		$this->run_cron();
308
+		header('HTTP/1.1 200 OK');
309
+		exit();
310
+	}
311
+
312
+
313
+	/**
314
+	 * This gets executed on wp_cron jobs or when a batch request is initiated on its own separate non regular wp
315
+	 * request.
316
+	 */
317
+	public function run_cron()
318
+	{
319
+		self::_load_controller();
320
+		$request = self::getRequest();
321
+		// get required vars
322
+		$cron_type     = $request->getRequestParam('type');
323
+		$transient_key = $request->getRequestParam('key');
324
+
325
+		// now let's verify transient, if not valid exit immediately
326
+		if (! get_transient($transient_key)) {
327
+			/**
328
+			 * trigger error so this gets in the error logs.  This is important because it happens on a non-user
329
+			 * request.
330
+			 */
331
+			trigger_error(esc_attr__('Invalid Request (Transient does not exist)', 'event_espresso'));
332
+		}
333
+
334
+		// if made it here, lets' delete the transient to keep the db clean
335
+		delete_transient($transient_key);
336
+
337
+		if (apply_filters('FHEE__EED_Messages__run_cron__use_wp_cron', true)) {
338
+			$method = 'batch_' . $cron_type . '_from_queue';
339
+			if (method_exists(self::$_MSG_PROCESSOR, $method)) {
340
+				self::$_MSG_PROCESSOR->$method();
341
+			} else {
342
+				// no matching task
343
+				/**
344
+				 * trigger error so this gets in the error logs.  This is important because it happens on a non user
345
+				 * request.
346
+				 */
347
+				trigger_error(
348
+					esc_attr(
349
+						sprintf(
350
+							esc_html__('There is no task corresponding to this route %s', 'event_espresso'),
351
+							$cron_type
352
+						)
353
+					)
354
+				);
355
+			}
356
+		}
357
+
358
+		do_action('FHEE__EED_Messages__run_cron__end');
359
+	}
360
+
361
+
362
+	/**
363
+	 * This is used to retrieve the template pack for the given name.
364
+	 * Retrieved packs are cached on the static $_TMP_PACKS array.  If there is no class matching the given name then
365
+	 * the default template pack is returned.
366
+	 *
367
+	 * @param string $template_pack_name This should correspond to the dbref of the template pack (which is also used
368
+	 *                                   in generating the Pack class name).
369
+	 * @return EE_Messages_Template_Pack
370
+	 * @throws EE_Error
371
+	 * @throws InvalidArgumentException
372
+	 * @throws ReflectionException
373
+	 * @throws InvalidDataTypeException
374
+	 * @throws InvalidInterfaceException
375
+	 * @deprecated 4.9.0  @see EEH_MSG_Template::get_template_pack()
376
+	 */
377
+	public static function get_template_pack($template_pack_name)
378
+	{
379
+		EE_Registry::instance()->load_helper('MSG_Template');
380
+		return EEH_MSG_Template::get_template_pack($template_pack_name);
381
+	}
382
+
383
+
384
+	/**
385
+	 * Retrieves an array of all template packs.
386
+	 * Array is in the format array( 'dbref' => EE_Messages_Template_Pack )
387
+	 *
388
+	 * @return EE_Messages_Template_Pack[]
389
+	 * @throws EE_Error
390
+	 * @throws InvalidArgumentException
391
+	 * @throws ReflectionException
392
+	 * @throws InvalidDataTypeException
393
+	 * @throws InvalidInterfaceException
394
+	 * @deprecated 4.9.0  @see EEH_MSG_Template_Pack::get_template_pack_collection
395
+	 */
396
+	public static function get_template_packs()
397
+	{
398
+		EE_Registry::instance()->load_helper('MSG_Template');
399
+
400
+		// for backward compat, let's make sure this returns in the same format as originally.
401
+		$template_pack_collection = EEH_MSG_Template::get_template_pack_collection();
402
+		$template_pack_collection->rewind();
403
+		$template_packs = [];
404
+		while ($template_pack_collection->valid()) {
405
+			$template_packs[ $template_pack_collection->current()->dbref ] = $template_pack_collection->current();
406
+			$template_pack_collection->next();
407
+		}
408
+		return $template_packs;
409
+	}
410
+
411
+
412
+	/**
413
+	 * This simply makes sure the autoloaders are registered for the EE_messages system.
414
+	 *
415
+	 * @return void
416
+	 * @throws EE_Error
417
+	 * @since 4.5.0
418
+	 */
419
+	public static function set_autoloaders()
420
+	{
421
+		if (empty(self::$_MSG_PATHS)) {
422
+			self::_set_messages_paths();
423
+			foreach (self::$_MSG_PATHS as $path) {
424
+				EEH_Autoloader::register_autoloaders_for_each_file_in_folder($path);
425
+			}
426
+			// add aliases
427
+			EEH_Autoloader::add_alias('EE_messages', 'EE_messages');
428
+			EEH_Autoloader::add_alias('EE_messenger', 'EE_messenger');
429
+		}
430
+	}
431
+
432
+
433
+	/**
434
+	 * Take care of adding all the paths for the messages components to the $_MSG_PATHS property
435
+	 * for use by the Messages Autoloaders
436
+	 *
437
+	 * @return void.
438
+	 * @since 4.5.0
439
+	 */
440
+	protected static function _set_messages_paths()
441
+	{
442
+		$dir_ref = [
443
+			'messages/message_type',
444
+			'messages/messenger',
445
+			'messages/defaults',
446
+			'messages/defaults/email',
447
+			'messages/data_class',
448
+			'messages/validators',
449
+			'messages/validators/email',
450
+			'messages/validators/html',
451
+			'shortcodes',
452
+		];
453
+		$paths   = [];
454
+		foreach ($dir_ref as $index => $dir) {
455
+			$paths[ $index ] = EE_LIBRARIES . $dir;
456
+		}
457
+		self::$_MSG_PATHS = apply_filters('FHEE__EED_Messages___set_messages_paths___MSG_PATHS', $paths);
458
+	}
459
+
460
+
461
+	/**
462
+	 * Takes care of loading dependencies
463
+	 *
464
+	 * @return void
465
+	 * @throws EE_Error
466
+	 * @throws InvalidArgumentException
467
+	 * @throws ReflectionException
468
+	 * @throws InvalidDataTypeException
469
+	 * @throws InvalidInterfaceException
470
+	 * @since 4.5.0
471
+	 */
472
+	protected static function _load_controller()
473
+	{
474
+		if (! self::$_MSG_PROCESSOR instanceof EE_Messages_Processor) {
475
+			EE_Registry::instance()->load_core('Request_Handler');
476
+			self::set_autoloaders();
477
+			self::$_EEMSG                    = EE_Registry::instance()->load_lib('messages');
478
+			self::$_MSG_PROCESSOR            = EE_Registry::instance()->load_lib('Messages_Processor');
479
+			self::$_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
480
+		}
481
+	}
482
+
483
+
484
+	/**
485
+	 * @param EE_Transaction $transaction
486
+	 * @throws EE_Error
487
+	 * @throws InvalidArgumentException
488
+	 * @throws InvalidDataTypeException
489
+	 * @throws InvalidInterfaceException
490
+	 * @throws ReflectionException
491
+	 */
492
+	public static function payment_reminder(EE_Transaction $transaction)
493
+	{
494
+		self::_load_controller();
495
+		$data = [$transaction, null];
496
+		self::$_MSG_PROCESSOR->generate_for_all_active_messengers('payment_reminder', $data);
497
+	}
498
+
499
+
500
+	/**
501
+	 * Any messages triggers for after successful gateway payments should go in here.
502
+	 *
503
+	 * @param EE_Transaction  $transaction object
504
+	 * @param EE_Payment|null $payment     object
505
+	 * @return void
506
+	 * @throws EE_Error
507
+	 * @throws InvalidArgumentException
508
+	 * @throws ReflectionException
509
+	 * @throws InvalidDataTypeException
510
+	 * @throws InvalidInterfaceException
511
+	 */
512
+	public static function payment(EE_Transaction $transaction, EE_Payment $payment = null)
513
+	{
514
+		// if there's no payment object, then we cannot do a payment type message!
515
+		if (! $payment instanceof EE_Payment) {
516
+			return;
517
+		}
518
+		self::_load_controller();
519
+		$data = [$transaction, $payment];
520
+		EE_Registry::instance()->load_helper('MSG_Template');
521
+		$message_type = EEH_MSG_Template::convert_payment_status_to_message_type($payment->STS_ID());
522
+		// if payment amount is less than 0 then switch to payment_refund message type.
523
+		$message_type = $payment->amount() < 0 ? 'payment_refund' : $message_type;
524
+		self::$_MSG_PROCESSOR->generate_for_all_active_messengers($message_type, $data);
525
+	}
526
+
527
+
528
+	/**
529
+	 * @param EE_Transaction $transaction
530
+	 * @throws EE_Error
531
+	 * @throws InvalidArgumentException
532
+	 * @throws InvalidDataTypeException
533
+	 * @throws InvalidInterfaceException
534
+	 * @throws ReflectionException
535
+	 */
536
+	public static function cancelled_registration(EE_Transaction $transaction)
537
+	{
538
+		self::_load_controller();
539
+		$data = [$transaction, null];
540
+		self::$_MSG_PROCESSOR->generate_for_all_active_messengers('cancelled_registration', $data);
541
+	}
542
+
543
+
544
+	/**
545
+	 * Trigger for Registration messages
546
+	 * Note that what registration message type is sent depends on what the reg status is for the registrations on the
547
+	 * incoming transaction.
548
+	 *
549
+	 * @param EE_Registration $registration
550
+	 * @param array           $extra_details
551
+	 * @return void
552
+	 * @throws EE_Error
553
+	 * @throws InvalidArgumentException
554
+	 * @throws InvalidDataTypeException
555
+	 * @throws InvalidInterfaceException
556
+	 * @throws ReflectionException
557
+	 * @throws EntityNotFoundException
558
+	 */
559
+	public static function maybe_registration(EE_Registration $registration, $extra_details = [])
560
+	{
561
+
562
+		if (! self::_verify_registration_notification_send($registration, $extra_details)) {
563
+			// no messages please
564
+			return;
565
+		}
566
+
567
+		// get all non-trashed registrations so we make sure we send messages for the right status.
568
+		$all_registrations = $registration->transaction()->registrations(
569
+			[
570
+				['REG_deleted' => false],
571
+				'order_by' => [
572
+					'Event.EVT_name'     => 'ASC',
573
+					'Attendee.ATT_lname' => 'ASC',
574
+					'Attendee.ATT_fname' => 'ASC',
575
+				],
576
+			]
577
+		);
578
+		// cached array of statuses so we only trigger messages once per status.
579
+		$statuses_sent = [];
580
+		self::_load_controller();
581
+		$mtgs = [];
582
+
583
+		// loop through registrations and trigger messages once per status.
584
+		foreach ($all_registrations as $reg) {
585
+			// already triggered?
586
+			if (in_array($reg->status_ID(), $statuses_sent)) {
587
+				continue;
588
+			}
589
+
590
+			$message_type    = EEH_MSG_Template::convert_reg_status_to_message_type($reg->status_ID());
591
+			$mtgs            = array_merge(
592
+				$mtgs,
593
+				self::$_MSG_PROCESSOR->setup_mtgs_for_all_active_messengers(
594
+					$message_type,
595
+					[$registration->transaction(), null, $reg->status_ID()]
596
+				)
597
+			);
598
+			$statuses_sent[] = $reg->status_ID();
599
+		}
600
+
601
+		if (count($statuses_sent) > 1) {
602
+			$mtgs = array_merge(
603
+				$mtgs,
604
+				self::$_MSG_PROCESSOR->setup_mtgs_for_all_active_messengers(
605
+					'registration_summary',
606
+					[$registration->transaction(), null]
607
+				)
608
+			);
609
+		}
610
+
611
+		// batch queue and initiate request
612
+		self::$_MSG_PROCESSOR->batch_queue_for_generation_and_persist($mtgs);
613
+		self::$_MSG_PROCESSOR->get_queue()->initiate_request_by_priority();
614
+	}
615
+
616
+
617
+	/**
618
+	 * This is a helper method used to very whether a registration notification should be sent or
619
+	 * not.  Prevents duplicate notifications going out for registration context notifications.
620
+	 *
621
+	 * @param EE_Registration $registration  [description]
622
+	 * @param array           $extra_details [description]
623
+	 * @return bool          true = send away, false = nope halt the presses.
624
+	 */
625
+	protected static function _verify_registration_notification_send(
626
+		EE_Registration $registration,
627
+		$extra_details = []
628
+	) {
629
+		$request = self::getRequest();
630
+		if (
631
+			! $request->getRequestParam('non_primary_reg_notification', 0, 'int')
632
+			&& ! $registration->is_primary_registrant()
633
+		) {
634
+			return false;
635
+		}
636
+		// first we check if we're in admin and not doing front ajax
637
+		if (
638
+			($request->isAdmin() || $request->isAdminAjax())
639
+			&& ! $request->isFrontAjax()
640
+		) {
641
+			$status_change = $request->getRequestParam('txn_reg_status_change', [], 'int', true);
642
+			// make sure appropriate admin params are set for sending messages
643
+			if (
644
+				! isset($status_change['send_notifications'])
645
+				|| (isset($status_change['send_notifications']) && ! $status_change['send_notifications'])
646
+			) {
647
+				// no messages sent please.
648
+				return false;
649
+			}
650
+		} else {
651
+			// frontend request (either regular or via AJAX)
652
+			// TXN is NOT finalized ?
653
+			if (! isset($extra_details['finalized']) || $extra_details['finalized'] === false) {
654
+				return false;
655
+			}
656
+			// return visit but nothing changed ???
657
+			if (
658
+				isset($extra_details['revisit'], $extra_details['status_updates'])
659
+				&& $extra_details['revisit']
660
+				&& ! $extra_details['status_updates']
661
+			) {
662
+				return false;
663
+			}
664
+			// NOT sending messages && reg status is something other than "Not-Approved"
665
+			if (
666
+				! apply_filters('FHEE__EED_Messages___maybe_registration__deliver_notifications', false)
667
+				&& $registration->status_ID() !== EEM_Registration::status_id_not_approved
668
+			) {
669
+				return false;
670
+			}
671
+		}
672
+		// release the kraken
673
+		return true;
674
+	}
675
+
676
+
677
+	/**
678
+	 * Simply returns an array indexed by Registration Status ID and the related message_type name associated with that
679
+	 * status id.
680
+	 *
681
+	 * @param string $reg_status
682
+	 * @return array
683
+	 * @throws EE_Error
684
+	 * @throws InvalidArgumentException
685
+	 * @throws ReflectionException
686
+	 * @throws InvalidDataTypeException
687
+	 * @throws InvalidInterfaceException
688
+	 * @deprecated        4.9.0  Use EEH_MSG_Template::reg_status_to_message_type_array()
689
+	 *                    or EEH_MSG_Template::convert_reg_status_to_message_type
690
+	 */
691
+	protected static function _get_reg_status_array($reg_status = '')
692
+	{
693
+		EE_Registry::instance()->load_helper('MSG_Template');
694
+		return EEH_MSG_Template::convert_reg_status_to_message_type($reg_status)
695
+			? EEH_MSG_Template::convert_reg_status_to_message_type($reg_status)
696
+			: EEH_MSG_Template::reg_status_to_message_type_array();
697
+	}
698
+
699
+
700
+	/**
701
+	 * Simply returns the payment message type for the given payment status.
702
+	 *
703
+	 * @param string $payment_status The payment status being matched.
704
+	 * @return bool|string The payment message type slug matching the status or false if no match.
705
+	 * @throws EE_Error
706
+	 * @throws InvalidArgumentException
707
+	 * @throws ReflectionException
708
+	 * @throws InvalidDataTypeException
709
+	 * @throws InvalidInterfaceException
710
+	 * @deprecated       4.9.0 Use EEH_MSG_Template::payment_status_to_message_type_array
711
+	 *                   or EEH_MSG_Template::convert_payment_status_to_message_type
712
+	 */
713
+	protected static function _get_payment_message_type($payment_status)
714
+	{
715
+		EE_Registry::instance()->load_helper('MSG_Template');
716
+		return EEH_MSG_Template::convert_payment_status_to_message_type($payment_status)
717
+			? EEH_MSG_Template::convert_payment_status_to_message_type($payment_status)
718
+			: false;
719
+	}
720
+
721
+
722
+	/**
723
+	 * Message triggers for a resending already sent message(s) (via EE_Message list table)
724
+	 *
725
+	 * @access public
726
+	 * @param array $req_data This is the $_POST & $_GET data sent from EE_Admin Pages
727
+	 * @return bool success/fail
728
+	 * @throws EE_Error
729
+	 * @throws InvalidArgumentException
730
+	 * @throws InvalidDataTypeException
731
+	 * @throws InvalidInterfaceException
732
+	 * @throws ReflectionException
733
+	 */
734
+	public static function process_resend(array $req_data = [])
735
+	{
736
+		self::_load_controller();
737
+		$request = self::getRequest();
738
+		// if $msgID in this request then skip to the new resend_message
739
+		if ($request->getRequestParam('MSG_ID')) {
740
+			return self::resend_message();
741
+		}
742
+
743
+		// make sure any incoming request data is set on the request so that it gets picked up later.
744
+		foreach ((array) $req_data as $request_key => $request_value) {
745
+			if (! $request->requestParamIsSet($request_key)) {
746
+				$request->setRequestParam($request_key, $request_value);
747
+			}
748
+		}
749
+
750
+		if (
751
+			! $messages_to_send = self::$_MSG_PROCESSOR->setup_messages_to_generate_from_registration_ids_in_request()
752
+		) {
753
+			return false;
754
+		}
755
+
756
+		try {
757
+			self::$_MSG_PROCESSOR->batch_queue_for_generation_and_persist($messages_to_send);
758
+			self::$_MSG_PROCESSOR->get_queue()->initiate_request_by_priority();
759
+		} catch (EE_Error $e) {
760
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
761
+			return false;
762
+		}
763
+		EE_Error::add_success(
764
+			esc_html__('Messages have been successfully queued for generation and sending.', 'event_espresso')
765
+		);
766
+		return true; // everything got queued.
767
+	}
768
+
769
+
770
+	/**
771
+	 * Message triggers for a resending already sent message(s) (via EE_Message list table)
772
+	 *
773
+	 * @return bool
774
+	 * @throws EE_Error
775
+	 * @throws InvalidArgumentException
776
+	 * @throws InvalidDataTypeException
777
+	 * @throws InvalidInterfaceException
778
+	 * @throws ReflectionException
779
+	 */
780
+	public static function resend_message()
781
+	{
782
+		self::_load_controller();
783
+
784
+		$msgID = self::getRequest()->getRequestParam('MSG_ID', 0, 'int');
785
+		if (! $msgID) {
786
+			EE_Error::add_error(
787
+				esc_html__(
788
+					'Something went wrong because there is no "MSG_ID" value in the request',
789
+					'event_espresso'
790
+				),
791
+				__FILE__,
792
+				__FUNCTION__,
793
+				__LINE__
794
+			);
795
+			return false;
796
+		}
797
+
798
+		self::$_MSG_PROCESSOR->setup_messages_from_ids_and_send((array) $msgID);
799
+
800
+		// setup success message.
801
+		$count_ready_for_resend = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(EEM_Message::status_resend);
802
+		EE_Error::add_success(
803
+			sprintf(
804
+				_n(
805
+					'There was %d message queued for resending.',
806
+					'There were %d messages queued for resending.',
807
+					$count_ready_for_resend,
808
+					'event_espresso'
809
+				),
810
+				$count_ready_for_resend
811
+			)
812
+		);
813
+		return true;
814
+	}
815
+
816
+
817
+	/**
818
+	 * Message triggers for manual payment applied by admin
819
+	 *
820
+	 * @param EE_Payment $payment EE_payment object
821
+	 * @return bool success/fail
822
+	 * @throws EE_Error
823
+	 * @throws InvalidArgumentException
824
+	 * @throws ReflectionException
825
+	 * @throws InvalidDataTypeException
826
+	 * @throws InvalidInterfaceException
827
+	 */
828
+	public static function process_admin_payment(EE_Payment $payment)
829
+	{
830
+		EE_Registry::instance()->load_helper('MSG_Template');
831
+		// we need to get the transaction object
832
+		$transaction = $payment->transaction();
833
+		if ($transaction instanceof EE_Transaction) {
834
+			$data         = [$transaction, $payment];
835
+			$message_type = EEH_MSG_Template::convert_payment_status_to_message_type($payment->STS_ID());
836
+
837
+			// if payment amount is less than 0 then switch to payment_refund message type.
838
+			$message_type = $payment->amount() < 0 ? 'payment_refund' : $message_type;
839
+
840
+			// if payment_refund is selected, but the status is NOT accepted.  Then change message type to false so NO message notification goes out.
841
+			$message_type = $message_type == 'payment_refund' && $payment->STS_ID() != EEM_Payment::status_id_approved
842
+				? false : $message_type;
843
+
844
+			self::_load_controller();
845
+
846
+			self::$_MSG_PROCESSOR->generate_for_all_active_messengers($message_type, $data);
847
+
848
+			// get count of queued for generation
849
+			$count_to_generate = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(
850
+				[
851
+					EEM_Message::status_incomplete,
852
+					EEM_Message::status_idle,
853
+				]
854
+			);
855
+
856
+			if ($count_to_generate > 0 && self::$_MSG_PROCESSOR->get_queue()->get_message_repository()->count() !== 0) {
857
+				add_filter('FHEE__EE_Admin_Page___process_admin_payment_notification__success', '__return_true');
858
+				return true;
859
+			} else {
860
+				$count_failed = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(
861
+					EEM_Message::instance()->stati_indicating_failed_sending()
862
+				);
863
+				/**
864
+				 * Verify that there are actually errors.  If not then we return a success message because the queue might have been emptied due to successful
865
+				 * IMMEDIATE generation.
866
+				 */
867
+				if ($count_failed > 0) {
868
+					EE_Error::add_error(
869
+						sprintf(
870
+							_n(
871
+								'The payment notification generation failed.',
872
+								'%d payment notifications failed being sent.',
873
+								$count_failed,
874
+								'event_espresso'
875
+							),
876
+							$count_failed
877
+						),
878
+						__FILE__,
879
+						__FUNCTION__,
880
+						__LINE__
881
+					);
882
+
883
+					return false;
884
+				} else {
885
+					add_filter('FHEE__EE_Admin_Page___process_admin_payment_notification__success', '__return_true');
886
+					return true;
887
+				}
888
+			}
889
+		} else {
890
+			EE_Error::add_error(
891
+				'Unable to generate the payment notification because the given value for the transaction is invalid.',
892
+				'event_espresso'
893
+			);
894
+			return false;
895
+		}
896
+	}
897
+
898
+
899
+	/**
900
+	 * Callback for AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send_with_registrations trigger
901
+	 *
902
+	 * @param EE_Registration[] $registrations an array of EE_Registration objects
903
+	 * @param int               $grp_id        a specific message template group id.
904
+	 * @return void
905
+	 * @throws EE_Error
906
+	 * @throws InvalidArgumentException
907
+	 * @throws InvalidDataTypeException
908
+	 * @throws InvalidInterfaceException
909
+	 * @throws ReflectionException
910
+	 * @since   4.3.0
911
+	 */
912
+	public static function send_newsletter_message($registrations, $grp_id)
913
+	{
914
+		// make sure mtp is id and set it in the request later messages setup.
915
+		self::getRequest()->setRequestParam('GRP_ID', (int) $grp_id);
916
+		self::_load_controller();
917
+		self::$_MSG_PROCESSOR->generate_for_all_active_messengers('newsletter', $registrations);
918
+	}
919
+
920
+
921
+	/**
922
+	 * Callback for FHEE__EE_Registration__invoice_url__invoice_url or FHEE__EE_Registration__receipt_url__receipt_url
923
+	 *
924
+	 * @param string          $registration_message_trigger_url
925
+	 * @param EE_Registration $registration
926
+	 * @param string          $messenger
927
+	 * @param string          $message_type
928
+	 * @return string
929
+	 * @throws EE_Error
930
+	 * @throws InvalidArgumentException
931
+	 * @throws InvalidDataTypeException
932
+	 * @throws InvalidInterfaceException
933
+	 * @since   4.3.0
934
+	 */
935
+	public static function registration_message_trigger_url(
936
+		$registration_message_trigger_url,
937
+		EE_Registration $registration,
938
+		$messenger = 'html',
939
+		$message_type = 'invoice'
940
+	) {
941
+		// whitelist $messenger
942
+		switch ($messenger) {
943
+			case 'pdf':
944
+				$sending_messenger    = 'pdf';
945
+				$generating_messenger = 'html';
946
+				break;
947
+			case 'html':
948
+			default:
949
+				$sending_messenger    = 'html';
950
+				$generating_messenger = 'html';
951
+				break;
952
+		}
953
+		// whitelist $message_type
954
+		switch ($message_type) {
955
+			case 'receipt':
956
+				$message_type = 'receipt';
957
+				break;
958
+			case 'invoice':
959
+			default:
960
+				$message_type = 'invoice';
961
+				break;
962
+		}
963
+		// verify that both the messenger AND the message type are active
964
+		if (
965
+			EEH_MSG_Template::is_messenger_active($sending_messenger)
966
+			&& EEH_MSG_Template::is_mt_active($message_type)
967
+		) {
968
+			// need to get the correct message template group for this (i.e. is there a custom invoice for the event this registration is registered for?)
969
+			$template_query_params = [
970
+				'MTP_is_active'    => true,
971
+				'MTP_messenger'    => $generating_messenger,
972
+				'MTP_message_type' => $message_type,
973
+				'Event.EVT_ID'     => $registration->event_ID(),
974
+			];
975
+			// get the message template group.
976
+			$msg_template_group = EEM_Message_Template_Group::instance()->get_one([$template_query_params]);
977
+			// if we don't have an EE_Message_Template_Group then return
978
+			if (! $msg_template_group instanceof EE_Message_Template_Group) {
979
+				// remove EVT_ID from query params so that global templates get picked up
980
+				unset($template_query_params['Event.EVT_ID']);
981
+				// get global template as the fallback
982
+				$msg_template_group = EEM_Message_Template_Group::instance()->get_one([$template_query_params]);
983
+			}
984
+			// if we don't have an EE_Message_Template_Group then return
985
+			if (! $msg_template_group instanceof EE_Message_Template_Group) {
986
+				return '';
987
+			}
988
+			// generate the URL
989
+			$registration_message_trigger_url = EEH_MSG_Template::generate_url_trigger(
990
+				$sending_messenger,
991
+				$generating_messenger,
992
+				'purchaser',
993
+				$message_type,
994
+				$registration,
995
+				$msg_template_group->ID(),
996
+				$registration->transaction_ID()
997
+			);
998
+		}
999
+		return $registration_message_trigger_url;
1000
+	}
1001
+
1002
+
1003
+	/**
1004
+	 * Use to generate and return a message preview!
1005
+	 *
1006
+	 * @param string $type       This should correspond with a valid message type
1007
+	 * @param string $context    This should correspond with a valid context for the message type
1008
+	 * @param string $messenger  This should correspond with a valid messenger.
1009
+	 * @param bool   $send       true we will do a test send using the messenger delivery, false we just do a regular
1010
+	 *                           preview
1011
+	 * @return bool|string The body of the message or if send is requested, sends.
1012
+	 * @throws EE_Error
1013
+	 * @throws InvalidArgumentException
1014
+	 * @throws InvalidDataTypeException
1015
+	 * @throws InvalidInterfaceException
1016
+	 * @throws ReflectionException
1017
+	 */
1018
+	public static function preview_message($type, $context, $messenger, $send = false)
1019
+	{
1020
+		self::_load_controller();
1021
+		$message_to_generate     = new EE_Message_To_Generate(
1022
+			$messenger,
1023
+			$type,
1024
+			[],
1025
+			$context,
1026
+			true
1027
+		);
1028
+		$generated_preview_queue = self::$_MSG_PROCESSOR->generate_for_preview($message_to_generate, $send);
1029
+
1030
+		if ($generated_preview_queue instanceof EE_Messages_Queue) {
1031
+			// loop through all content for the preview and remove any persisted records.
1032
+			$content = '';
1033
+			foreach ($generated_preview_queue->get_message_repository() as $message) {
1034
+				$content = $message->content();
1035
+				if ($message->ID() > 0 && $message->STS_ID() !== EEM_Message::status_failed) {
1036
+					$message->delete();
1037
+				}
1038
+			}
1039
+			return $content;
1040
+		}
1041
+		return $generated_preview_queue;
1042
+	}
1043
+
1044
+
1045
+	/**
1046
+	 * This is a method that allows for sending a message using a messenger matching the string given and the provided
1047
+	 * EE_Message_Queue object.  The EE_Message_Queue object is used to create a single aggregate EE_Message via the
1048
+	 * content found in the EE_Message objects in the queue.
1049
+	 *
1050
+	 * @param string            $messenger            a string matching a valid active messenger in the system
1051
+	 * @param string            $message_type         Although it seems contrary to the name of the method, a message
1052
+	 *                                                type name is still required to send along the message type to the
1053
+	 *                                                messenger because this is used for determining what specific
1054
+	 *                                                variations might be loaded for the generated message.
1055
+	 * @param EE_Messages_Queue $queue
1056
+	 * @param string            $custom_subject       Can be used to set what the custom subject string will be on the
1057
+	 *                                                aggregate EE_Message object.
1058
+	 * @return bool success or fail.
1059
+	 * @throws EE_Error
1060
+	 * @throws InvalidArgumentException
1061
+	 * @throws ReflectionException
1062
+	 * @throws InvalidDataTypeException
1063
+	 * @throws InvalidInterfaceException
1064
+	 * @since 4.9.0
1065
+	 */
1066
+	public static function send_message_with_messenger_only(
1067
+		$messenger,
1068
+		$message_type,
1069
+		EE_Messages_Queue $queue,
1070
+		$custom_subject = ''
1071
+	) {
1072
+		self::_load_controller();
1073
+		/** @type EE_Message_To_Generate_From_Queue $message_to_generate */
1074
+		$message_to_generate = EE_Registry::instance()->load_lib(
1075
+			'Message_To_Generate_From_Queue',
1076
+			[
1077
+				$messenger,
1078
+				$message_type,
1079
+				$queue,
1080
+				$custom_subject,
1081
+			]
1082
+		);
1083
+		return self::$_MSG_PROCESSOR->queue_for_sending($message_to_generate);
1084
+	}
1085
+
1086
+
1087
+	/**
1088
+	 * Generates Messages immediately for EE_Message IDs (but only for the correct status for generation)
1089
+	 *
1090
+	 * @param array $message_ids An array of message ids
1091
+	 * @return bool|EE_Messages_Queue false if nothing was generated, EE_Messages_Queue containing generated
1092
+	 *                           messages.
1093
+	 * @throws EE_Error
1094
+	 * @throws InvalidArgumentException
1095
+	 * @throws InvalidDataTypeException
1096
+	 * @throws InvalidInterfaceException
1097
+	 * @throws ReflectionException
1098
+	 * @since 4.9.0
1099
+	 */
1100
+	public static function generate_now($message_ids)
1101
+	{
1102
+		self::_load_controller();
1103
+		$messages        = EEM_Message::instance()->get_all(
1104
+			[
1105
+				0 => [
1106
+					'MSG_ID' => ['IN', $message_ids],
1107
+					'STS_ID' => EEM_Message::status_incomplete,
1108
+				],
1109
+			]
1110
+		);
1111
+		$generated_queue = false;
1112
+		if ($messages) {
1113
+			$generated_queue = self::$_MSG_PROCESSOR->batch_generate_from_queue($messages);
1114
+		}
1115
+
1116
+		if (! $generated_queue instanceof EE_Messages_Queue) {
1117
+			EE_Error::add_error(
1118
+				esc_html__(
1119
+					'The messages were not generated. This could mean there is already a batch being generated on a separate request, or because the selected messages are not ready for generation. Please wait a minute or two and try again.',
1120
+					'event_espresso'
1121
+				),
1122
+				__FILE__,
1123
+				__FUNCTION__,
1124
+				__LINE__
1125
+			);
1126
+		}
1127
+		return $generated_queue;
1128
+	}
1129
+
1130
+
1131
+	/**
1132
+	 * Sends messages immediately for the incoming message_ids that have the status of EEM_Message::status_resend or,
1133
+	 * EEM_Message::status_idle
1134
+	 *
1135
+	 * @param $message_ids
1136
+	 * @return bool|EE_Messages_Queue false if no messages sent.
1137
+	 * @throws EE_Error
1138
+	 * @throws InvalidArgumentException
1139
+	 * @throws InvalidDataTypeException
1140
+	 * @throws InvalidInterfaceException
1141
+	 * @throws ReflectionException
1142
+	 * @since 4.9.0
1143
+	 */
1144
+	public static function send_now($message_ids)
1145
+	{
1146
+		self::_load_controller();
1147
+		$messages   = EEM_Message::instance()->get_all(
1148
+			[
1149
+				0 => [
1150
+					'MSG_ID' => ['IN', $message_ids],
1151
+					'STS_ID' => [
1152
+						'IN',
1153
+						[EEM_Message::status_idle, EEM_Message::status_resend, EEM_Message::status_retry],
1154
+					],
1155
+				],
1156
+			]
1157
+		);
1158
+		$sent_queue = false;
1159
+		if ($messages) {
1160
+			$sent_queue = self::$_MSG_PROCESSOR->batch_send_from_queue($messages);
1161
+		}
1162
+
1163
+		if (! $sent_queue instanceof EE_Messages_Queue) {
1164
+			EE_Error::add_error(
1165
+				esc_html__(
1166
+					'The messages were not sent. This could mean there is already a batch being sent on a separate request, or because the selected messages are not sendable. Please wait a minute or two and try again.',
1167
+					'event_espresso'
1168
+				),
1169
+				__FILE__,
1170
+				__FUNCTION__,
1171
+				__LINE__
1172
+			);
1173
+		} else {
1174
+			// can count how many sent by using the messages in the queue
1175
+			$sent_count = $sent_queue->count_STS_in_queue(EEM_Message::instance()->stati_indicating_sent());
1176
+			if ($sent_count > 0) {
1177
+				EE_Error::add_success(
1178
+					sprintf(
1179
+						_n(
1180
+							'There was %d message successfully sent.',
1181
+							'There were %d messages successfully sent.',
1182
+							$sent_count,
1183
+							'event_espresso'
1184
+						),
1185
+						$sent_count
1186
+					)
1187
+				);
1188
+			} else {
1189
+				EE_Error::overwrite_errors();
1190
+				EE_Error::add_error(
1191
+					esc_html__(
1192
+						'No message was sent because of problems with sending. Either all the messages you selected were not a sendable message, they were ALREADY sent on a different scheduled task, or there was an error.
1193 1193
 					If there was an error, you can look at the messages in the message activity list table for any error messages.',
1194
-                        'event_espresso'
1195
-                    ),
1196
-                    __FILE__,
1197
-                    __FUNCTION__,
1198
-                    __LINE__
1199
-                );
1200
-            }
1201
-        }
1202
-        return $sent_queue;
1203
-    }
1204
-
1205
-
1206
-    /**
1207
-     * Generate and send immediately from the given $message_ids
1208
-     *
1209
-     * @param array $message_ids EE_Message entity ids.
1210
-     * @throws EE_Error
1211
-     * @throws InvalidArgumentException
1212
-     * @throws InvalidDataTypeException
1213
-     * @throws InvalidInterfaceException
1214
-     * @throws ReflectionException
1215
-     */
1216
-    public static function generate_and_send_now(array $message_ids)
1217
-    {
1218
-        $generated_queue = self::generate_now($message_ids);
1219
-        // now let's just trigger sending immediately from this queue.
1220
-        $messages_sent = $generated_queue instanceof EE_Messages_Queue
1221
-            ? $generated_queue->execute()
1222
-            : 0;
1223
-        if ($messages_sent) {
1224
-            EE_Error::add_success(
1225
-                esc_html(
1226
-                    sprintf(
1227
-                        _n(
1228
-                            'There was %d message successfully generated and sent.',
1229
-                            'There were %d messages successfully generated and sent.',
1230
-                            $messages_sent,
1231
-                            'event_espresso'
1232
-                        ),
1233
-                        $messages_sent
1234
-                    )
1235
-                )
1236
-            );
1237
-            // errors would be added via the generate_now method.
1238
-        }
1239
-    }
1240
-
1241
-
1242
-    /**
1243
-     * This will queue the incoming message ids for resending.
1244
-     * Note, only message_ids corresponding to messages with the status of EEM_Message::sent will be queued.
1245
-     *
1246
-     * @param array $message_ids An array of EE_Message IDs
1247
-     * @return bool true means messages were successfully queued for resending, false means none were queued for
1248
-     *                           resending.
1249
-     * @throws EE_Error
1250
-     * @throws InvalidArgumentException
1251
-     * @throws InvalidDataTypeException
1252
-     * @throws InvalidInterfaceException
1253
-     * @throws ReflectionException
1254
-     * @since 4.9.0
1255
-     */
1256
-    public static function queue_for_resending($message_ids)
1257
-    {
1258
-        self::_load_controller();
1259
-        self::$_MSG_PROCESSOR->setup_messages_from_ids_and_send($message_ids);
1260
-
1261
-        // get queue and count
1262
-        $queue_count = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(EEM_Message::status_resend);
1263
-
1264
-        if (
1265
-            $queue_count > 0
1266
-        ) {
1267
-            EE_Error::add_success(
1268
-                sprintf(
1269
-                    _n(
1270
-                        '%d message successfully queued for resending.',
1271
-                        '%d messages successfully queued for resending.',
1272
-                        $queue_count,
1273
-                        'event_espresso'
1274
-                    ),
1275
-                    $queue_count
1276
-                )
1277
-            );
1278
-            /**
1279
-             * @see filter usage in EE_Messages_Queue::initiate_request_by_priority
1280
-             */
1281
-        } elseif (
1282
-            apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', true)
1283
-            || EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
1284
-        ) {
1285
-            $queue_count = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(EEM_Message::status_sent);
1286
-            if ($queue_count > 0) {
1287
-                EE_Error::add_success(
1288
-                    sprintf(
1289
-                        _n(
1290
-                            '%d message successfully sent.',
1291
-                            '%d messages successfully sent.',
1292
-                            $queue_count,
1293
-                            'event_espresso'
1294
-                        ),
1295
-                        $queue_count
1296
-                    )
1297
-                );
1298
-            } else {
1299
-                EE_Error::add_error(
1300
-                    esc_html__(
1301
-                        'No messages were queued for resending. This usually only happens when all the messages flagged for resending are not a status that can be resent.',
1302
-                        'event_espresso'
1303
-                    ),
1304
-                    __FILE__,
1305
-                    __FUNCTION__,
1306
-                    __LINE__
1307
-                );
1308
-            }
1309
-        } else {
1310
-            EE_Error::add_error(
1311
-                esc_html__(
1312
-                    'No messages were queued for resending. This usually only happens when all the messages flagged for resending are not a status that can be resent.',
1313
-                    'event_espresso'
1314
-                ),
1315
-                __FILE__,
1316
-                __FUNCTION__,
1317
-                __LINE__
1318
-            );
1319
-        }
1320
-        return (bool) $queue_count;
1321
-    }
1322
-
1323
-
1324
-    /**
1325
-     * debug
1326
-     *
1327
-     * @param string              $class
1328
-     * @param string              $func
1329
-     * @param string              $line
1330
-     * @param EE_Transaction|null $transaction
1331
-     * @param array               $info
1332
-     * @param bool                $display_request
1333
-     * @throws EE_Error
1334
-     * @throws ReflectionException
1335
-     * @throws InvalidSessionDataException
1336
-     */
1337
-    protected static function log(
1338
-        $class = '',
1339
-        $func = '',
1340
-        $line = '',
1341
-        EE_Transaction $transaction = null,
1342
-        $info = array(),
1343
-        $display_request = false
1344
-    ) {
1345
-        if (defined('EE_DEBUG') && EE_DEBUG) {
1346
-            if ($transaction instanceof EE_Transaction) {
1347
-                // don't serialize objects
1348
-                $info                  = EEH_Debug_Tools::strip_objects($info);
1349
-                $info['TXN_status']    = $transaction->status_ID();
1350
-                $info['TXN_reg_steps'] = $transaction->reg_steps();
1351
-                if ($transaction->ID()) {
1352
-                    $index = 'EE_Transaction: ' . $transaction->ID();
1353
-                    EEH_Debug_Tools::log($class, $func, $line, $info, $display_request, $index);
1354
-                }
1355
-            }
1356
-        }
1357
-    }
1358
-
1359
-
1360
-    /**
1361
-     *  Resets all the static properties in this class when called.
1362
-     */
1363
-    public static function reset()
1364
-    {
1365
-        self::$_EEMSG                    = null;
1366
-        self::$_message_resource_manager = null;
1367
-        self::$_MSG_PROCESSOR            = null;
1368
-        self::$_MSG_PATHS                = null;
1369
-        self::$_TMP_PACKS                = [];
1370
-    }
1194
+						'event_espresso'
1195
+					),
1196
+					__FILE__,
1197
+					__FUNCTION__,
1198
+					__LINE__
1199
+				);
1200
+			}
1201
+		}
1202
+		return $sent_queue;
1203
+	}
1204
+
1205
+
1206
+	/**
1207
+	 * Generate and send immediately from the given $message_ids
1208
+	 *
1209
+	 * @param array $message_ids EE_Message entity ids.
1210
+	 * @throws EE_Error
1211
+	 * @throws InvalidArgumentException
1212
+	 * @throws InvalidDataTypeException
1213
+	 * @throws InvalidInterfaceException
1214
+	 * @throws ReflectionException
1215
+	 */
1216
+	public static function generate_and_send_now(array $message_ids)
1217
+	{
1218
+		$generated_queue = self::generate_now($message_ids);
1219
+		// now let's just trigger sending immediately from this queue.
1220
+		$messages_sent = $generated_queue instanceof EE_Messages_Queue
1221
+			? $generated_queue->execute()
1222
+			: 0;
1223
+		if ($messages_sent) {
1224
+			EE_Error::add_success(
1225
+				esc_html(
1226
+					sprintf(
1227
+						_n(
1228
+							'There was %d message successfully generated and sent.',
1229
+							'There were %d messages successfully generated and sent.',
1230
+							$messages_sent,
1231
+							'event_espresso'
1232
+						),
1233
+						$messages_sent
1234
+					)
1235
+				)
1236
+			);
1237
+			// errors would be added via the generate_now method.
1238
+		}
1239
+	}
1240
+
1241
+
1242
+	/**
1243
+	 * This will queue the incoming message ids for resending.
1244
+	 * Note, only message_ids corresponding to messages with the status of EEM_Message::sent will be queued.
1245
+	 *
1246
+	 * @param array $message_ids An array of EE_Message IDs
1247
+	 * @return bool true means messages were successfully queued for resending, false means none were queued for
1248
+	 *                           resending.
1249
+	 * @throws EE_Error
1250
+	 * @throws InvalidArgumentException
1251
+	 * @throws InvalidDataTypeException
1252
+	 * @throws InvalidInterfaceException
1253
+	 * @throws ReflectionException
1254
+	 * @since 4.9.0
1255
+	 */
1256
+	public static function queue_for_resending($message_ids)
1257
+	{
1258
+		self::_load_controller();
1259
+		self::$_MSG_PROCESSOR->setup_messages_from_ids_and_send($message_ids);
1260
+
1261
+		// get queue and count
1262
+		$queue_count = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(EEM_Message::status_resend);
1263
+
1264
+		if (
1265
+			$queue_count > 0
1266
+		) {
1267
+			EE_Error::add_success(
1268
+				sprintf(
1269
+					_n(
1270
+						'%d message successfully queued for resending.',
1271
+						'%d messages successfully queued for resending.',
1272
+						$queue_count,
1273
+						'event_espresso'
1274
+					),
1275
+					$queue_count
1276
+				)
1277
+			);
1278
+			/**
1279
+			 * @see filter usage in EE_Messages_Queue::initiate_request_by_priority
1280
+			 */
1281
+		} elseif (
1282
+			apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', true)
1283
+			|| EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
1284
+		) {
1285
+			$queue_count = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(EEM_Message::status_sent);
1286
+			if ($queue_count > 0) {
1287
+				EE_Error::add_success(
1288
+					sprintf(
1289
+						_n(
1290
+							'%d message successfully sent.',
1291
+							'%d messages successfully sent.',
1292
+							$queue_count,
1293
+							'event_espresso'
1294
+						),
1295
+						$queue_count
1296
+					)
1297
+				);
1298
+			} else {
1299
+				EE_Error::add_error(
1300
+					esc_html__(
1301
+						'No messages were queued for resending. This usually only happens when all the messages flagged for resending are not a status that can be resent.',
1302
+						'event_espresso'
1303
+					),
1304
+					__FILE__,
1305
+					__FUNCTION__,
1306
+					__LINE__
1307
+				);
1308
+			}
1309
+		} else {
1310
+			EE_Error::add_error(
1311
+				esc_html__(
1312
+					'No messages were queued for resending. This usually only happens when all the messages flagged for resending are not a status that can be resent.',
1313
+					'event_espresso'
1314
+				),
1315
+				__FILE__,
1316
+				__FUNCTION__,
1317
+				__LINE__
1318
+			);
1319
+		}
1320
+		return (bool) $queue_count;
1321
+	}
1322
+
1323
+
1324
+	/**
1325
+	 * debug
1326
+	 *
1327
+	 * @param string              $class
1328
+	 * @param string              $func
1329
+	 * @param string              $line
1330
+	 * @param EE_Transaction|null $transaction
1331
+	 * @param array               $info
1332
+	 * @param bool                $display_request
1333
+	 * @throws EE_Error
1334
+	 * @throws ReflectionException
1335
+	 * @throws InvalidSessionDataException
1336
+	 */
1337
+	protected static function log(
1338
+		$class = '',
1339
+		$func = '',
1340
+		$line = '',
1341
+		EE_Transaction $transaction = null,
1342
+		$info = array(),
1343
+		$display_request = false
1344
+	) {
1345
+		if (defined('EE_DEBUG') && EE_DEBUG) {
1346
+			if ($transaction instanceof EE_Transaction) {
1347
+				// don't serialize objects
1348
+				$info                  = EEH_Debug_Tools::strip_objects($info);
1349
+				$info['TXN_status']    = $transaction->status_ID();
1350
+				$info['TXN_reg_steps'] = $transaction->reg_steps();
1351
+				if ($transaction->ID()) {
1352
+					$index = 'EE_Transaction: ' . $transaction->ID();
1353
+					EEH_Debug_Tools::log($class, $func, $line, $info, $display_request, $index);
1354
+				}
1355
+			}
1356
+		}
1357
+	}
1358
+
1359
+
1360
+	/**
1361
+	 *  Resets all the static properties in this class when called.
1362
+	 */
1363
+	public static function reset()
1364
+	{
1365
+		self::$_EEMSG                    = null;
1366
+		self::$_message_resource_manager = null;
1367
+		self::$_MSG_PROCESSOR            = null;
1368
+		self::$_MSG_PATHS                = null;
1369
+		self::$_TMP_PACKS                = [];
1370
+	}
1371 1371
 }
Please login to merge, or discard this patch.