Completed
Branch BUG-10381-asset-loading (5e9d4d)
by
unknown
14:17
created
core/db_models/EEM_Message.model.php 2 patches
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -127,7 +127,7 @@  discard block
 block discarded – undo
127 127
             self::priority_low    => __('low', 'event_espresso'),
128 128
         );
129 129
 
130
-        $this->_fields          = array(
130
+        $this->_fields = array(
131 131
             'Message' => array(
132 132
                 'MSG_ID'             => new EE_Primary_Key_Int_Field('MSG_ID', __('Message ID', 'event_espresso')),
133 133
                 'MSG_token'          => new EE_Plain_Text_Field('MSG_token',
@@ -357,7 +357,7 @@  discard block
 block discarded – undo
357 357
                         );
358 358
                         break;
359 359
                     default :
360
-                        $query_params[0]['AND**filter_by']['OR**filter_by_' . $request_key][$model_name . '.' . $request_key] = $request_value;
360
+                        $query_params[0]['AND**filter_by']['OR**filter_by_'.$request_key][$model_name.'.'.$request_key] = $request_value;
361 361
                         break;
362 362
                 }
363 363
             }
@@ -420,7 +420,7 @@  discard block
 block discarded – undo
420 420
             //prepend to the last element of $label_parts an "and".
421 421
             if (count($label_parts) > 1) {
422 422
                 $label_parts_index_to_prepend               = count($label_parts) - 1;
423
-                $label_parts[$label_parts_index_to_prepend] = 'and' . $label_parts[$label_parts_index_to_prepend];
423
+                $label_parts[$label_parts_index_to_prepend] = 'and'.$label_parts[$label_parts_index_to_prepend];
424 424
             }
425 425
 
426 426
             $pretty_label .= sprintf(
@@ -541,13 +541,13 @@  discard block
 block discarded – undo
541 541
             )
542 542
         );
543 543
 
544
-        if(! empty($message_ids_to_delete) && is_array($message_ids_to_delete)) {
544
+        if ( ! empty($message_ids_to_delete) && is_array($message_ids_to_delete)) {
545 545
             global $wpdb;
546 546
             $number_deleted = $wpdb->query('
547 547
                 DELETE
548
-                FROM ' . $this->table() . '
548
+                FROM ' . $this->table().'
549 549
                 WHERE
550
-                    MSG_ID IN (' . implode(",", $message_ids_to_delete) . ')
550
+                    MSG_ID IN (' . implode(",", $message_ids_to_delete).')
551 551
             ');
552 552
         }
553 553
 
Please login to merge, or discard this patch.
Indentation   +542 added lines, -542 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 
5 5
 /**
@@ -12,556 +12,556 @@  discard block
 block discarded – undo
12 12
 class EEM_Message extends EEM_Base implements EEI_Query_Filter
13 13
 {
14 14
 
15
-    // private instance of the Message object
16
-    protected static $_instance = null;
15
+	// private instance of the Message object
16
+	protected static $_instance = null;
17 17
 
18 18
 
19
-    /**
20
-     * This priority indicates a message should be generated and sent ASAP
21
-     *
22
-     * @type int
23
-     */
24
-    const priority_high = 10;
19
+	/**
20
+	 * This priority indicates a message should be generated and sent ASAP
21
+	 *
22
+	 * @type int
23
+	 */
24
+	const priority_high = 10;
25 25
 
26 26
 
27
-    /**
28
-     * This priority indicates a message should be generated ASAP and queued for sending.
29
-     *
30
-     * @type
31
-     */
32
-    const priority_medium = 20;
33
-
34
-
35
-    /**
36
-     * This priority indicates a message should be queued for generating.
37
-     *
38
-     * @type int
39
-     */
40
-    const priority_low = 30;
41
-
42
-
43
-    /**
44
-     * indicates this message was sent at the time modified
45
-     */
46
-    const status_sent = 'MSN';
47
-
48
-
49
-    /**
50
-     * indicates this message is waiting to be sent
51
-     */
52
-    const status_idle = 'MID';
53
-
54
-
55
-    /**
56
-     * indicates an attempt was a made to send this message
57
-     * at the scheduled time, but it failed at the time modified.  This differs from MDO status in that it will ALWAYS
58
-     * appear to the end user.
59
-     */
60
-    const status_failed = 'MFL';
61
-
62
-
63
-    /**
64
-     * indicates the message has been flagged for resending (at the time modified).
65
-     */
66
-    const status_resend = 'MRS';
67
-
68
-
69
-    /**
70
-     * indicates the message has been flagged for generation but has not been generated yet.  Messages always start as
71
-     * this status when added to the queue.
72
-     */
73
-    const status_incomplete = 'MIC';
74
-
75
-
76
-    /**
77
-     * Indicates everything was generated fine for the message, however, the messenger was unable to send.
78
-     * This status means that its possible to retry sending the message.
79
-     */
80
-    const status_retry = 'MRT';
81
-
82
-
83
-    /**
84
-     * This is used for more informational messages that may not indicate anything is broken but still cannot be
85
-     * generated or sent correctly. An example of a message that would get flagged this way would be when a not
86
-     * approved message was queued for generation, but at time of generation, the attached registration(s) are
87
-     * approved. So the message queued for generation is no longer valid.  Messages for this status will only persist
88
-     * in the db and be viewable in the message activity list table when the messages system is in debug mode.
89
-     *
90
-     * @see EEM_Message::debug()
91
-     */
92
-    const status_debug_only = 'MDO';
93
-
94
-
95
-    /**
96
-     * This status is given to messages it is processed by the messenger send method.
97
-     * Messages with this status should rarely be seen in the Message List table, but if they are, that's usually
98
-     * indicative of a PHP timeout or memory limit issue.
99
-     */
100
-    const status_messenger_executing = 'MEX';
101
-
102
-
103
-    /**
104
-     *    Private constructor to prevent direct creation.
105
-     *
106
-     * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and
107
-     *                         any incoming timezone data that gets saved).  Note this just sends the timezone info to
108
-     *                         the date time model field objects.  Default is null (and will be assumed using the set
109
-     *                         timezone in the 'timezone_string' wp option)
110
-     * @return EEM_Message
111
-     */
112
-    protected function __construct($timezone = null)
113
-    {
114
-        $this->singular_item = __('Message', 'event_espresso');
115
-        $this->plural_item   = __('Messages', 'event_espresso');
116
-
117
-        //used for token generator
118
-        EE_Registry::instance()->load_helper('URL');
119
-
120
-        $this->_tables = array(
121
-            'Message' => new EE_Primary_Table('esp_message', 'MSG_ID'),
122
-        );
123
-
124
-        $allowed_priority = array(
125
-            self::priority_high   => __('high', 'event_espresso'),
126
-            self::priority_medium => __('medium', 'event_espresso'),
127
-            self::priority_low    => __('low', 'event_espresso'),
128
-        );
129
-
130
-        $this->_fields          = array(
131
-            'Message' => array(
132
-                'MSG_ID'             => new EE_Primary_Key_Int_Field('MSG_ID', __('Message ID', 'event_espresso')),
133
-                'MSG_token'          => new EE_Plain_Text_Field('MSG_token',
134
-                    __('Unique Token used to represent this row in publicly viewable contexts (eg. a url).',
135
-                        'event_espresso'), false, EEH_URL::generate_unique_token()),
136
-                'GRP_ID'             => new EE_Foreign_Key_Int_Field('GRP_ID',
137
-                    __('Foreign key to the EEM_Message_Template_Group table.', 'event_espresso'), true, 0,
138
-                    'Message_Template_Group'),
139
-                'TXN_ID'             => new EE_Foreign_Key_Int_Field('TXN_ID',
140
-                    __('Foreign key to the related EE_Transaction.  This is required to give context for regenerating the specific message',
141
-                        'event_espresso'), true, 0, 'Transaction'),
142
-                'MSG_messenger'      => new EE_Plain_Text_Field('MSG_messenger',
143
-                    __('Corresponds to the EE_messenger::name used to send this message. This will also be used to attempt any resending of the message.',
144
-                        'event_espresso'), false, 'email'),
145
-                'MSG_message_type'   => new EE_Plain_Text_Field('MSG_message_type',
146
-                    __('Corresponds to the EE_message_type::name used to generate this message.', 'event_espresso'),
147
-                    false, 'receipt'),
148
-                'MSG_context'        => new EE_Plain_Text_Field('MSG_context', __('Context', 'event_espresso'), false),
149
-                'MSG_recipient_ID'   => new EE_Foreign_Key_Int_Field('MSG_recipient_ID',
150
-                    __('Recipient ID', 'event_espresso'), true, null, array('Registration', 'Attendee', 'WP_User')),
151
-                'MSG_recipient_type' => new EE_Any_Foreign_Model_Name_Field('MSG_recipient_type',
152
-                    __('Recipient Type', 'event_espresso'), true, null, array('Registration', 'Attendee', 'WP_User')),
153
-                'MSG_content'        => new EE_Maybe_Serialized_Text_Field('MSG_content',
154
-                    __('Content', 'event_espresso'), true, ''),
155
-                'MSG_to'             => new EE_Maybe_Serialized_Text_Field('MSG_to', __('Address To', 'event_espresso'),
156
-                    true),
157
-                'MSG_from'           => new EE_Maybe_Serialized_Text_Field('MSG_from',
158
-                    __('Address From', 'event_espresso'), true),
159
-                'MSG_subject'        => new EE_Maybe_Serialized_Text_Field('MSG_subject',
160
-                    __('Subject', 'event_espresso'), true, ''),
161
-                'MSG_priority'       => new EE_Enum_Integer_Field('MSG_priority', __('Priority', 'event_espresso'),
162
-                    false, self::priority_low, $allowed_priority),
163
-                'STS_ID'             => new EE_Foreign_Key_String_Field('STS_ID', __('Status', 'event_espresso'), false,
164
-                    self::status_incomplete, 'Status'),
165
-                'MSG_created'        => new EE_Datetime_Field('MSG_created', __('Created', 'event_espresso'), false,
166
-                    EE_Datetime_Field::now),
167
-                'MSG_modified'       => new EE_Datetime_Field('MSG_modified', __('Modified', 'event_espresso'), true,
168
-                    EE_Datetime_Field::now),
169
-            ),
170
-        );
171
-        $this->_model_relations = array(
172
-            'Attendee'               => new EE_Belongs_To_Any_Relation(),
173
-            'Registration'           => new EE_Belongs_To_Any_Relation(),
174
-            'WP_User'                => new EE_Belongs_To_Any_Relation(),
175
-            'Message_Template_Group' => new EE_Belongs_To_Relation(),
176
-            'Transaction'            => new EE_Belongs_To_Relation(),
177
-        );
178
-        parent::__construct($timezone);
179
-    }
180
-
181
-
182
-    /**
183
-     * @return \EE_Message
184
-     */
185
-    public function create_default_object()
186
-    {
187
-        /** @type EE_Message $message */
188
-        $message = parent::create_default_object();
189
-        if ($message instanceof EE_Message) {
190
-            return EE_Message_Factory::set_messenger_and_message_type($message);
191
-        }
192
-        return null;
193
-    }
194
-
195
-
196
-    /**
197
-     * @param mixed $cols_n_values
198
-     * @return \EE_Message
199
-     */
200
-    public function instantiate_class_from_array_or_object($cols_n_values)
201
-    {
202
-        /** @type EE_Message $message */
203
-        $message = parent::instantiate_class_from_array_or_object($cols_n_values);
204
-        if ($message instanceof EE_Message) {
205
-            return EE_Message_Factory::set_messenger_and_message_type($message);
206
-        }
207
-        return null;
208
-    }
209
-
210
-
211
-    /**
212
-     * Returns whether or not a message of that type was sent for a given attendee.
213
-     *
214
-     * @param EE_Attendee|int $attendee
215
-     * @param string          $message_type the message type slug
216
-     * @return boolean
217
-     */
218
-    public function message_sent_for_attendee($attendee, $message_type)
219
-    {
220
-        $attendee_ID = EEM_Attendee::instance()->ensure_is_ID($attendee);
221
-        return $this->exists(array(
222
-            array(
223
-                'Attendee.ATT_ID'  => $attendee_ID,
224
-                'MSG_message_type' => $message_type,
225
-                'STS_ID'           => array('IN', $this->stati_indicating_sent()),
226
-            ),
227
-        ));
228
-    }
229
-
230
-
231
-    /**
232
-     * Returns whether or not a message of that type was sent for a given registration
233
-     *
234
-     * @param EE_Registration|int $registration
235
-     * @param string              $message_type the message type slug
236
-     * @return boolean
237
-     */
238
-    public function message_sent_for_registration($registration, $message_type)
239
-    {
240
-        $registrationID = EEM_Registration::instance()->ensure_is_ID($registration);
241
-        return $this->exists(array(
242
-            array(
243
-                'Registration.REG_ID' => $registrationID,
244
-                'MSG_message_type'    => $message_type,
245
-                'STS_ID'              => array('IN', $this->stati_indicating_sent()),
246
-            ),
247
-        ));
248
-    }
249
-
250
-
251
-    /**
252
-     * This retrieves an EE_Message object from the db matching the given token string.
253
-     *
254
-     * @param string $token
255
-     * @return EE_Message
256
-     */
257
-    public function get_one_by_token($token)
258
-    {
259
-        return $this->get_one(array(
260
-            array(
261
-                'MSG_token' => $token,
262
-            ),
263
-        ));
264
-    }
265
-
266
-
267
-    /**
268
-     * Returns stati that indicate the message HAS been sent
269
-     *
270
-     * @return array of strings for possible stati
271
-     */
272
-    public function stati_indicating_sent()
273
-    {
274
-        return apply_filters('FHEE__EEM_Message__stati_indicating_sent', array(self::status_sent));
275
-    }
276
-
277
-
278
-    /**
279
-     * Returns stati that indicate the message is waiting to be sent.
280
-     *
281
-     * @return array of strings for possible stati.
282
-     */
283
-    public function stati_indicating_to_send()
284
-    {
285
-        return apply_filters('FHEE__EEM_Message__stati_indicating_to_send',
286
-            array(self::status_idle, self::status_resend));
287
-    }
288
-
289
-
290
-    /**
291
-     * Returns stati that indicate the message has failed sending
292
-     *
293
-     * @return array  array of strings for possible stati.
294
-     */
295
-    public function stati_indicating_failed_sending()
296
-    {
297
-        $failed_stati = array(
298
-            self::status_failed,
299
-            self::status_retry,
300
-            self::status_messenger_executing,
301
-        );
302
-        //if WP_DEBUG is set, then let's include debug_only fails
303
-        if (WP_DEBUG) {
304
-            $failed_stati[] = self::status_debug_only;
305
-        }
306
-        return apply_filters('FHEE__EEM_Message__stati_indicating_failed_sending', $failed_stati);
307
-    }
308
-
309
-
310
-    /**
311
-     * Returns filterable array of all EEM_Message statuses.
312
-     *
313
-     * @return array
314
-     */
315
-    public function all_statuses()
316
-    {
317
-        return apply_filters(
318
-            'FHEE__EEM_Message__all_statuses',
319
-            array(
320
-                EEM_Message::status_sent,
321
-                EEM_Message::status_incomplete,
322
-                EEM_Message::status_idle,
323
-                EEM_Message::status_resend,
324
-                EEM_Message::status_retry,
325
-                EEM_Message::status_failed,
326
-                EEM_Message::status_messenger_executing,
327
-                EEM_Message::status_debug_only,
328
-            )
329
-        );
330
-    }
331
-
332
-    /**
333
-     * Detects any specific query variables in the request and uses those to setup appropriate
334
-     * filter for any queries.
335
-     *
336
-     * @return array
337
-     */
338
-    public function filter_by_query_params()
339
-    {
340
-        // expected possible query_vars, the key in this array matches an expected key in the request,
341
-        // the value, matches the corresponding EEM_Base child reference.
342
-        $expected_vars   = $this->_expected_vars_for_query_inject();
343
-        $query_params[0] = array();
344
-        foreach ($expected_vars as $request_key => $model_name) {
345
-            $request_value = EE_Registry::instance()->REQ->get($request_key);
346
-            if ($request_value) {
347
-                //special case
348
-                switch ($request_key) {
349
-                    case '_REG_ID' :
350
-                        $query_params[0]['AND**filter_by']['OR**filter_by_REG_ID'] = array(
351
-                            'Transaction.Registration.REG_ID' => $request_value,
352
-                        );
353
-                        break;
354
-                    case 'EVT_ID' :
355
-                        $query_params[0]['AND**filter_by']['OR**filter_by_EVT_ID'] = array(
356
-                            'Transaction.Registration.EVT_ID' => $request_value,
357
-                        );
358
-                        break;
359
-                    default :
360
-                        $query_params[0]['AND**filter_by']['OR**filter_by_' . $request_key][$model_name . '.' . $request_key] = $request_value;
361
-                        break;
362
-                }
363
-            }
364
-        }
365
-        return $query_params;
366
-    }
367
-
368
-
369
-    /**
370
-     * @return string
371
-     */
372
-    public function get_pretty_label_for_results()
373
-    {
374
-        $expected_vars = $this->_expected_vars_for_query_inject();
375
-        $pretty_label  = '';
376
-        $label_parts   = array();
377
-        foreach ($expected_vars as $request_key => $model_name) {
378
-            $model = EE_Registry::instance()->load_model($model_name);
379
-            if ($model_field_value = EE_Registry::instance()->REQ->get($request_key)) {
380
-                switch ($request_key) {
381
-                    case '_REG_ID' :
382
-                        $label_parts[] = sprintf(
383
-                            esc_html__('Registration with the ID: %s', 'event_espresso'),
384
-                            $model_field_value
385
-                        );
386
-                        break;
387
-                    case 'ATT_ID' :
388
-                        /** @var EE_Attendee $attendee */
389
-                        $attendee      = $model->get_one_by_ID($model_field_value);
390
-                        $label_parts[] = $attendee instanceof EE_Attendee
391
-                            ? sprintf(esc_html__('Attendee %s', 'event_espresso'), $attendee->full_name())
392
-                            : sprintf(esc_html__('Attendee ID: %s', 'event_espresso'), $model_field_value);
393
-                        break;
394
-                    case 'ID' :
395
-                        /** @var EE_WP_User $wpUser */
396
-                        $wpUser        = $model->get_one_by_ID($model_field_value);
397
-                        $label_parts[] = $wpUser instanceof EE_WP_User
398
-                            ? sprintf(esc_html__('WP User: %s', 'event_espresso'), $wpUser->name())
399
-                            : sprintf(esc_html__('WP User ID: %s', 'event_espresso'), $model_field_value);
400
-                        break;
401
-                    case 'TXN_ID' :
402
-                        $label_parts[] = sprintf(
403
-                            esc_html__('Transaction with the ID: %s', 'event_espresso'),
404
-                            $model_field_value
405
-                        );
406
-                        break;
407
-                    case 'EVT_ID' :
408
-                        /** @var EE_Event $Event */
409
-                        $Event         = $model->get_one_by_ID($model_field_value);
410
-                        $label_parts[] = $Event instanceof EE_Event
411
-                            ? sprintf(esc_html__('for the Event: %s', 'event_espresso'), $Event->name())
412
-                            : sprintf(esc_html__('for the Event with ID: %s', 'event_espresso'), $model_field_value);
413
-                        break;
414
-                }
415
-            }
416
-        }
417
-
418
-        if ($label_parts) {
419
-
420
-            //prepend to the last element of $label_parts an "and".
421
-            if (count($label_parts) > 1) {
422
-                $label_parts_index_to_prepend               = count($label_parts) - 1;
423
-                $label_parts[$label_parts_index_to_prepend] = 'and' . $label_parts[$label_parts_index_to_prepend];
424
-            }
425
-
426
-            $pretty_label .= sprintf(
427
-                esc_html_x(
428
-                    'Showing messages for %s',
429
-                    'A label for the messages returned in a query that are filtered by items in the query. This could be Transaction, Event, Attendee, Registration, or WP_User.',
430
-                    'event_espresso'
431
-                ),
432
-                implode(', ', $label_parts)
433
-            );
434
-        }
435
-        return $pretty_label;
436
-    }
437
-
438
-
439
-    /**
440
-     * This returns the array of expected variables for the EEI_Query_Filter methods being implemented
441
-     * The array is in the format:
442
-     * array(
443
-     *  {$field_name} => {$model_name}
444
-     * );
445
-     *
446
-     * @since 4.9.0
447
-     * @return array
448
-     */
449
-    protected function _expected_vars_for_query_inject()
450
-    {
451
-        return array(
452
-            '_REG_ID' => 'Registration',
453
-            'ATT_ID'  => 'Attendee',
454
-            'ID'      => 'WP_User',
455
-            'TXN_ID'  => 'Transaction',
456
-            'EVT_ID'  => 'Event',
457
-        );
458
-    }
459
-
460
-
461
-    /**
462
-     * This returns whether EEM_Message is in debug mode or not.
463
-     * Currently "debug mode" is used to control the handling of the EEM_Message::debug_only status when
464
-     * generating/sending messages. Debug mode can be set by either:
465
-     * 1. Sending in a value for the $set_debug argument
466
-     * 2. Defining `EE_DEBUG_MESSAGES` constant in wp-config.php
467
-     * 3. Overriding the above via the provided filter.
468
-     *
469
-     * @param bool|null $set_debug      If provided, then the debug mode will be set internally until reset via the
470
-     *                                  provided boolean. When no argument is provided (default null) then the debug
471
-     *                                  mode will be returned.
472
-     * @return bool         true means Messages is in debug mode.  false means messages system is not in debug mode.
473
-     */
474
-    public static function debug($set_debug = null)
475
-    {
476
-        static $is_debugging = null;
477
-
478
-        //initialize (use constant if set).
479
-        if (is_null($set_debug) && is_null($is_debugging)) {
480
-            $is_debugging = defined('EE_DEBUG_MESSAGES') && EE_DEBUG_MESSAGES;
481
-        }
482
-
483
-        if ( ! is_null($set_debug)) {
484
-            $is_debugging = filter_var($set_debug, FILTER_VALIDATE_BOOLEAN);
485
-        }
486
-
487
-        //return filtered value
488
-        return apply_filters('FHEE__EEM_Message__debug', $is_debugging);
489
-    }
490
-
491
-
492
-    /**
493
-     * Deletes old messages meeting certain criteria for removal from the database.
494
-     * By default, this will delete messages that:
495
-     * - are older than the value of the delete_threshold in months.
496
-     * - have a STS_ID other than EEM_Message::status_idle
497
-     *
498
-     * @param int $delete_threshold  This integer will be used to set the boundary for what messages are deleted in months.
499
-     * @return bool|false|int Either the number of records affected or false if there was an error (you can call
500
-     *                         $wpdb->last_error to find out what the error was.
501
-     */
502
-    public function delete_old_messages($delete_threshold = 6)
503
-    {
504
-        $number_deleted = 0;
505
-        /**
506
-         * Allows code to change the boundary for what messages are kept.
507
-         * Uses the value of the `delete_threshold` variable by default.
508
-         *
509
-         * @param int $seconds seconds that will be subtracted from the timestamp for now.
510
-         * @return int
511
-         */
512
-        $time_to_leave_alone = absint(
513
-            apply_filters(
514
-                'FHEE__EEM_Message__delete_old_messages__time_to_leave_alone',
515
-                ((int) $delete_threshold) * MONTH_IN_SECONDS
516
-            )
517
-        );
518
-
519
-
520
-        /**
521
-         * Allows code to change what message stati are ignored when deleting.
522
-         * Defaults to only ignore EEM_Message::status_idle messages.
523
-         *
524
-         * @param string $message_stati_to_keep  An array of message statuses that will be ignored when deleting.
525
-         */
526
-        $message_stati_to_keep = (array) apply_filters(
527
-            'FHEE__EEM_Message__delete_old_messages__message_stati_to_keep',
528
-            array(
529
-                EEM_Message::status_idle
530
-            )
531
-        );
532
-
533
-        //first get all the ids of messages being deleted
534
-        $message_ids_to_delete = EEM_Message::instance()->get_col(
535
-            array(
536
-                0 => array(
537
-                    'STS_ID' => array('NOT_IN', $message_stati_to_keep),
538
-                    'MSG_modified' => array('<', time() - $time_to_leave_alone)
539
-                )
540
-            )
541
-        );
542
-
543
-        if(! empty($message_ids_to_delete) && is_array($message_ids_to_delete)) {
544
-            global $wpdb;
545
-            $number_deleted = $wpdb->query('
27
+	/**
28
+	 * This priority indicates a message should be generated ASAP and queued for sending.
29
+	 *
30
+	 * @type
31
+	 */
32
+	const priority_medium = 20;
33
+
34
+
35
+	/**
36
+	 * This priority indicates a message should be queued for generating.
37
+	 *
38
+	 * @type int
39
+	 */
40
+	const priority_low = 30;
41
+
42
+
43
+	/**
44
+	 * indicates this message was sent at the time modified
45
+	 */
46
+	const status_sent = 'MSN';
47
+
48
+
49
+	/**
50
+	 * indicates this message is waiting to be sent
51
+	 */
52
+	const status_idle = 'MID';
53
+
54
+
55
+	/**
56
+	 * indicates an attempt was a made to send this message
57
+	 * at the scheduled time, but it failed at the time modified.  This differs from MDO status in that it will ALWAYS
58
+	 * appear to the end user.
59
+	 */
60
+	const status_failed = 'MFL';
61
+
62
+
63
+	/**
64
+	 * indicates the message has been flagged for resending (at the time modified).
65
+	 */
66
+	const status_resend = 'MRS';
67
+
68
+
69
+	/**
70
+	 * indicates the message has been flagged for generation but has not been generated yet.  Messages always start as
71
+	 * this status when added to the queue.
72
+	 */
73
+	const status_incomplete = 'MIC';
74
+
75
+
76
+	/**
77
+	 * Indicates everything was generated fine for the message, however, the messenger was unable to send.
78
+	 * This status means that its possible to retry sending the message.
79
+	 */
80
+	const status_retry = 'MRT';
81
+
82
+
83
+	/**
84
+	 * This is used for more informational messages that may not indicate anything is broken but still cannot be
85
+	 * generated or sent correctly. An example of a message that would get flagged this way would be when a not
86
+	 * approved message was queued for generation, but at time of generation, the attached registration(s) are
87
+	 * approved. So the message queued for generation is no longer valid.  Messages for this status will only persist
88
+	 * in the db and be viewable in the message activity list table when the messages system is in debug mode.
89
+	 *
90
+	 * @see EEM_Message::debug()
91
+	 */
92
+	const status_debug_only = 'MDO';
93
+
94
+
95
+	/**
96
+	 * This status is given to messages it is processed by the messenger send method.
97
+	 * Messages with this status should rarely be seen in the Message List table, but if they are, that's usually
98
+	 * indicative of a PHP timeout or memory limit issue.
99
+	 */
100
+	const status_messenger_executing = 'MEX';
101
+
102
+
103
+	/**
104
+	 *    Private constructor to prevent direct creation.
105
+	 *
106
+	 * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and
107
+	 *                         any incoming timezone data that gets saved).  Note this just sends the timezone info to
108
+	 *                         the date time model field objects.  Default is null (and will be assumed using the set
109
+	 *                         timezone in the 'timezone_string' wp option)
110
+	 * @return EEM_Message
111
+	 */
112
+	protected function __construct($timezone = null)
113
+	{
114
+		$this->singular_item = __('Message', 'event_espresso');
115
+		$this->plural_item   = __('Messages', 'event_espresso');
116
+
117
+		//used for token generator
118
+		EE_Registry::instance()->load_helper('URL');
119
+
120
+		$this->_tables = array(
121
+			'Message' => new EE_Primary_Table('esp_message', 'MSG_ID'),
122
+		);
123
+
124
+		$allowed_priority = array(
125
+			self::priority_high   => __('high', 'event_espresso'),
126
+			self::priority_medium => __('medium', 'event_espresso'),
127
+			self::priority_low    => __('low', 'event_espresso'),
128
+		);
129
+
130
+		$this->_fields          = array(
131
+			'Message' => array(
132
+				'MSG_ID'             => new EE_Primary_Key_Int_Field('MSG_ID', __('Message ID', 'event_espresso')),
133
+				'MSG_token'          => new EE_Plain_Text_Field('MSG_token',
134
+					__('Unique Token used to represent this row in publicly viewable contexts (eg. a url).',
135
+						'event_espresso'), false, EEH_URL::generate_unique_token()),
136
+				'GRP_ID'             => new EE_Foreign_Key_Int_Field('GRP_ID',
137
+					__('Foreign key to the EEM_Message_Template_Group table.', 'event_espresso'), true, 0,
138
+					'Message_Template_Group'),
139
+				'TXN_ID'             => new EE_Foreign_Key_Int_Field('TXN_ID',
140
+					__('Foreign key to the related EE_Transaction.  This is required to give context for regenerating the specific message',
141
+						'event_espresso'), true, 0, 'Transaction'),
142
+				'MSG_messenger'      => new EE_Plain_Text_Field('MSG_messenger',
143
+					__('Corresponds to the EE_messenger::name used to send this message. This will also be used to attempt any resending of the message.',
144
+						'event_espresso'), false, 'email'),
145
+				'MSG_message_type'   => new EE_Plain_Text_Field('MSG_message_type',
146
+					__('Corresponds to the EE_message_type::name used to generate this message.', 'event_espresso'),
147
+					false, 'receipt'),
148
+				'MSG_context'        => new EE_Plain_Text_Field('MSG_context', __('Context', 'event_espresso'), false),
149
+				'MSG_recipient_ID'   => new EE_Foreign_Key_Int_Field('MSG_recipient_ID',
150
+					__('Recipient ID', 'event_espresso'), true, null, array('Registration', 'Attendee', 'WP_User')),
151
+				'MSG_recipient_type' => new EE_Any_Foreign_Model_Name_Field('MSG_recipient_type',
152
+					__('Recipient Type', 'event_espresso'), true, null, array('Registration', 'Attendee', 'WP_User')),
153
+				'MSG_content'        => new EE_Maybe_Serialized_Text_Field('MSG_content',
154
+					__('Content', 'event_espresso'), true, ''),
155
+				'MSG_to'             => new EE_Maybe_Serialized_Text_Field('MSG_to', __('Address To', 'event_espresso'),
156
+					true),
157
+				'MSG_from'           => new EE_Maybe_Serialized_Text_Field('MSG_from',
158
+					__('Address From', 'event_espresso'), true),
159
+				'MSG_subject'        => new EE_Maybe_Serialized_Text_Field('MSG_subject',
160
+					__('Subject', 'event_espresso'), true, ''),
161
+				'MSG_priority'       => new EE_Enum_Integer_Field('MSG_priority', __('Priority', 'event_espresso'),
162
+					false, self::priority_low, $allowed_priority),
163
+				'STS_ID'             => new EE_Foreign_Key_String_Field('STS_ID', __('Status', 'event_espresso'), false,
164
+					self::status_incomplete, 'Status'),
165
+				'MSG_created'        => new EE_Datetime_Field('MSG_created', __('Created', 'event_espresso'), false,
166
+					EE_Datetime_Field::now),
167
+				'MSG_modified'       => new EE_Datetime_Field('MSG_modified', __('Modified', 'event_espresso'), true,
168
+					EE_Datetime_Field::now),
169
+			),
170
+		);
171
+		$this->_model_relations = array(
172
+			'Attendee'               => new EE_Belongs_To_Any_Relation(),
173
+			'Registration'           => new EE_Belongs_To_Any_Relation(),
174
+			'WP_User'                => new EE_Belongs_To_Any_Relation(),
175
+			'Message_Template_Group' => new EE_Belongs_To_Relation(),
176
+			'Transaction'            => new EE_Belongs_To_Relation(),
177
+		);
178
+		parent::__construct($timezone);
179
+	}
180
+
181
+
182
+	/**
183
+	 * @return \EE_Message
184
+	 */
185
+	public function create_default_object()
186
+	{
187
+		/** @type EE_Message $message */
188
+		$message = parent::create_default_object();
189
+		if ($message instanceof EE_Message) {
190
+			return EE_Message_Factory::set_messenger_and_message_type($message);
191
+		}
192
+		return null;
193
+	}
194
+
195
+
196
+	/**
197
+	 * @param mixed $cols_n_values
198
+	 * @return \EE_Message
199
+	 */
200
+	public function instantiate_class_from_array_or_object($cols_n_values)
201
+	{
202
+		/** @type EE_Message $message */
203
+		$message = parent::instantiate_class_from_array_or_object($cols_n_values);
204
+		if ($message instanceof EE_Message) {
205
+			return EE_Message_Factory::set_messenger_and_message_type($message);
206
+		}
207
+		return null;
208
+	}
209
+
210
+
211
+	/**
212
+	 * Returns whether or not a message of that type was sent for a given attendee.
213
+	 *
214
+	 * @param EE_Attendee|int $attendee
215
+	 * @param string          $message_type the message type slug
216
+	 * @return boolean
217
+	 */
218
+	public function message_sent_for_attendee($attendee, $message_type)
219
+	{
220
+		$attendee_ID = EEM_Attendee::instance()->ensure_is_ID($attendee);
221
+		return $this->exists(array(
222
+			array(
223
+				'Attendee.ATT_ID'  => $attendee_ID,
224
+				'MSG_message_type' => $message_type,
225
+				'STS_ID'           => array('IN', $this->stati_indicating_sent()),
226
+			),
227
+		));
228
+	}
229
+
230
+
231
+	/**
232
+	 * Returns whether or not a message of that type was sent for a given registration
233
+	 *
234
+	 * @param EE_Registration|int $registration
235
+	 * @param string              $message_type the message type slug
236
+	 * @return boolean
237
+	 */
238
+	public function message_sent_for_registration($registration, $message_type)
239
+	{
240
+		$registrationID = EEM_Registration::instance()->ensure_is_ID($registration);
241
+		return $this->exists(array(
242
+			array(
243
+				'Registration.REG_ID' => $registrationID,
244
+				'MSG_message_type'    => $message_type,
245
+				'STS_ID'              => array('IN', $this->stati_indicating_sent()),
246
+			),
247
+		));
248
+	}
249
+
250
+
251
+	/**
252
+	 * This retrieves an EE_Message object from the db matching the given token string.
253
+	 *
254
+	 * @param string $token
255
+	 * @return EE_Message
256
+	 */
257
+	public function get_one_by_token($token)
258
+	{
259
+		return $this->get_one(array(
260
+			array(
261
+				'MSG_token' => $token,
262
+			),
263
+		));
264
+	}
265
+
266
+
267
+	/**
268
+	 * Returns stati that indicate the message HAS been sent
269
+	 *
270
+	 * @return array of strings for possible stati
271
+	 */
272
+	public function stati_indicating_sent()
273
+	{
274
+		return apply_filters('FHEE__EEM_Message__stati_indicating_sent', array(self::status_sent));
275
+	}
276
+
277
+
278
+	/**
279
+	 * Returns stati that indicate the message is waiting to be sent.
280
+	 *
281
+	 * @return array of strings for possible stati.
282
+	 */
283
+	public function stati_indicating_to_send()
284
+	{
285
+		return apply_filters('FHEE__EEM_Message__stati_indicating_to_send',
286
+			array(self::status_idle, self::status_resend));
287
+	}
288
+
289
+
290
+	/**
291
+	 * Returns stati that indicate the message has failed sending
292
+	 *
293
+	 * @return array  array of strings for possible stati.
294
+	 */
295
+	public function stati_indicating_failed_sending()
296
+	{
297
+		$failed_stati = array(
298
+			self::status_failed,
299
+			self::status_retry,
300
+			self::status_messenger_executing,
301
+		);
302
+		//if WP_DEBUG is set, then let's include debug_only fails
303
+		if (WP_DEBUG) {
304
+			$failed_stati[] = self::status_debug_only;
305
+		}
306
+		return apply_filters('FHEE__EEM_Message__stati_indicating_failed_sending', $failed_stati);
307
+	}
308
+
309
+
310
+	/**
311
+	 * Returns filterable array of all EEM_Message statuses.
312
+	 *
313
+	 * @return array
314
+	 */
315
+	public function all_statuses()
316
+	{
317
+		return apply_filters(
318
+			'FHEE__EEM_Message__all_statuses',
319
+			array(
320
+				EEM_Message::status_sent,
321
+				EEM_Message::status_incomplete,
322
+				EEM_Message::status_idle,
323
+				EEM_Message::status_resend,
324
+				EEM_Message::status_retry,
325
+				EEM_Message::status_failed,
326
+				EEM_Message::status_messenger_executing,
327
+				EEM_Message::status_debug_only,
328
+			)
329
+		);
330
+	}
331
+
332
+	/**
333
+	 * Detects any specific query variables in the request and uses those to setup appropriate
334
+	 * filter for any queries.
335
+	 *
336
+	 * @return array
337
+	 */
338
+	public function filter_by_query_params()
339
+	{
340
+		// expected possible query_vars, the key in this array matches an expected key in the request,
341
+		// the value, matches the corresponding EEM_Base child reference.
342
+		$expected_vars   = $this->_expected_vars_for_query_inject();
343
+		$query_params[0] = array();
344
+		foreach ($expected_vars as $request_key => $model_name) {
345
+			$request_value = EE_Registry::instance()->REQ->get($request_key);
346
+			if ($request_value) {
347
+				//special case
348
+				switch ($request_key) {
349
+					case '_REG_ID' :
350
+						$query_params[0]['AND**filter_by']['OR**filter_by_REG_ID'] = array(
351
+							'Transaction.Registration.REG_ID' => $request_value,
352
+						);
353
+						break;
354
+					case 'EVT_ID' :
355
+						$query_params[0]['AND**filter_by']['OR**filter_by_EVT_ID'] = array(
356
+							'Transaction.Registration.EVT_ID' => $request_value,
357
+						);
358
+						break;
359
+					default :
360
+						$query_params[0]['AND**filter_by']['OR**filter_by_' . $request_key][$model_name . '.' . $request_key] = $request_value;
361
+						break;
362
+				}
363
+			}
364
+		}
365
+		return $query_params;
366
+	}
367
+
368
+
369
+	/**
370
+	 * @return string
371
+	 */
372
+	public function get_pretty_label_for_results()
373
+	{
374
+		$expected_vars = $this->_expected_vars_for_query_inject();
375
+		$pretty_label  = '';
376
+		$label_parts   = array();
377
+		foreach ($expected_vars as $request_key => $model_name) {
378
+			$model = EE_Registry::instance()->load_model($model_name);
379
+			if ($model_field_value = EE_Registry::instance()->REQ->get($request_key)) {
380
+				switch ($request_key) {
381
+					case '_REG_ID' :
382
+						$label_parts[] = sprintf(
383
+							esc_html__('Registration with the ID: %s', 'event_espresso'),
384
+							$model_field_value
385
+						);
386
+						break;
387
+					case 'ATT_ID' :
388
+						/** @var EE_Attendee $attendee */
389
+						$attendee      = $model->get_one_by_ID($model_field_value);
390
+						$label_parts[] = $attendee instanceof EE_Attendee
391
+							? sprintf(esc_html__('Attendee %s', 'event_espresso'), $attendee->full_name())
392
+							: sprintf(esc_html__('Attendee ID: %s', 'event_espresso'), $model_field_value);
393
+						break;
394
+					case 'ID' :
395
+						/** @var EE_WP_User $wpUser */
396
+						$wpUser        = $model->get_one_by_ID($model_field_value);
397
+						$label_parts[] = $wpUser instanceof EE_WP_User
398
+							? sprintf(esc_html__('WP User: %s', 'event_espresso'), $wpUser->name())
399
+							: sprintf(esc_html__('WP User ID: %s', 'event_espresso'), $model_field_value);
400
+						break;
401
+					case 'TXN_ID' :
402
+						$label_parts[] = sprintf(
403
+							esc_html__('Transaction with the ID: %s', 'event_espresso'),
404
+							$model_field_value
405
+						);
406
+						break;
407
+					case 'EVT_ID' :
408
+						/** @var EE_Event $Event */
409
+						$Event         = $model->get_one_by_ID($model_field_value);
410
+						$label_parts[] = $Event instanceof EE_Event
411
+							? sprintf(esc_html__('for the Event: %s', 'event_espresso'), $Event->name())
412
+							: sprintf(esc_html__('for the Event with ID: %s', 'event_espresso'), $model_field_value);
413
+						break;
414
+				}
415
+			}
416
+		}
417
+
418
+		if ($label_parts) {
419
+
420
+			//prepend to the last element of $label_parts an "and".
421
+			if (count($label_parts) > 1) {
422
+				$label_parts_index_to_prepend               = count($label_parts) - 1;
423
+				$label_parts[$label_parts_index_to_prepend] = 'and' . $label_parts[$label_parts_index_to_prepend];
424
+			}
425
+
426
+			$pretty_label .= sprintf(
427
+				esc_html_x(
428
+					'Showing messages for %s',
429
+					'A label for the messages returned in a query that are filtered by items in the query. This could be Transaction, Event, Attendee, Registration, or WP_User.',
430
+					'event_espresso'
431
+				),
432
+				implode(', ', $label_parts)
433
+			);
434
+		}
435
+		return $pretty_label;
436
+	}
437
+
438
+
439
+	/**
440
+	 * This returns the array of expected variables for the EEI_Query_Filter methods being implemented
441
+	 * The array is in the format:
442
+	 * array(
443
+	 *  {$field_name} => {$model_name}
444
+	 * );
445
+	 *
446
+	 * @since 4.9.0
447
+	 * @return array
448
+	 */
449
+	protected function _expected_vars_for_query_inject()
450
+	{
451
+		return array(
452
+			'_REG_ID' => 'Registration',
453
+			'ATT_ID'  => 'Attendee',
454
+			'ID'      => 'WP_User',
455
+			'TXN_ID'  => 'Transaction',
456
+			'EVT_ID'  => 'Event',
457
+		);
458
+	}
459
+
460
+
461
+	/**
462
+	 * This returns whether EEM_Message is in debug mode or not.
463
+	 * Currently "debug mode" is used to control the handling of the EEM_Message::debug_only status when
464
+	 * generating/sending messages. Debug mode can be set by either:
465
+	 * 1. Sending in a value for the $set_debug argument
466
+	 * 2. Defining `EE_DEBUG_MESSAGES` constant in wp-config.php
467
+	 * 3. Overriding the above via the provided filter.
468
+	 *
469
+	 * @param bool|null $set_debug      If provided, then the debug mode will be set internally until reset via the
470
+	 *                                  provided boolean. When no argument is provided (default null) then the debug
471
+	 *                                  mode will be returned.
472
+	 * @return bool         true means Messages is in debug mode.  false means messages system is not in debug mode.
473
+	 */
474
+	public static function debug($set_debug = null)
475
+	{
476
+		static $is_debugging = null;
477
+
478
+		//initialize (use constant if set).
479
+		if (is_null($set_debug) && is_null($is_debugging)) {
480
+			$is_debugging = defined('EE_DEBUG_MESSAGES') && EE_DEBUG_MESSAGES;
481
+		}
482
+
483
+		if ( ! is_null($set_debug)) {
484
+			$is_debugging = filter_var($set_debug, FILTER_VALIDATE_BOOLEAN);
485
+		}
486
+
487
+		//return filtered value
488
+		return apply_filters('FHEE__EEM_Message__debug', $is_debugging);
489
+	}
490
+
491
+
492
+	/**
493
+	 * Deletes old messages meeting certain criteria for removal from the database.
494
+	 * By default, this will delete messages that:
495
+	 * - are older than the value of the delete_threshold in months.
496
+	 * - have a STS_ID other than EEM_Message::status_idle
497
+	 *
498
+	 * @param int $delete_threshold  This integer will be used to set the boundary for what messages are deleted in months.
499
+	 * @return bool|false|int Either the number of records affected or false if there was an error (you can call
500
+	 *                         $wpdb->last_error to find out what the error was.
501
+	 */
502
+	public function delete_old_messages($delete_threshold = 6)
503
+	{
504
+		$number_deleted = 0;
505
+		/**
506
+		 * Allows code to change the boundary for what messages are kept.
507
+		 * Uses the value of the `delete_threshold` variable by default.
508
+		 *
509
+		 * @param int $seconds seconds that will be subtracted from the timestamp for now.
510
+		 * @return int
511
+		 */
512
+		$time_to_leave_alone = absint(
513
+			apply_filters(
514
+				'FHEE__EEM_Message__delete_old_messages__time_to_leave_alone',
515
+				((int) $delete_threshold) * MONTH_IN_SECONDS
516
+			)
517
+		);
518
+
519
+
520
+		/**
521
+		 * Allows code to change what message stati are ignored when deleting.
522
+		 * Defaults to only ignore EEM_Message::status_idle messages.
523
+		 *
524
+		 * @param string $message_stati_to_keep  An array of message statuses that will be ignored when deleting.
525
+		 */
526
+		$message_stati_to_keep = (array) apply_filters(
527
+			'FHEE__EEM_Message__delete_old_messages__message_stati_to_keep',
528
+			array(
529
+				EEM_Message::status_idle
530
+			)
531
+		);
532
+
533
+		//first get all the ids of messages being deleted
534
+		$message_ids_to_delete = EEM_Message::instance()->get_col(
535
+			array(
536
+				0 => array(
537
+					'STS_ID' => array('NOT_IN', $message_stati_to_keep),
538
+					'MSG_modified' => array('<', time() - $time_to_leave_alone)
539
+				)
540
+			)
541
+		);
542
+
543
+		if(! empty($message_ids_to_delete) && is_array($message_ids_to_delete)) {
544
+			global $wpdb;
545
+			$number_deleted = $wpdb->query('
546 546
                 DELETE
547 547
                 FROM ' . $this->table() . '
548 548
                 WHERE
549 549
                     MSG_ID IN (' . implode(",", $message_ids_to_delete) . ')
550 550
             ');
551
-        }
552
-
553
-        /**
554
-         * This will get called if the number of records deleted 0 or greater.  So a successful deletion is one where
555
-         * there were no errors.  An unsuccessful deletion is where there were errors.  Keep that in mind for the actions
556
-         * below.
557
-         */
558
-        if ($number_deleted !== false) {
559
-            do_action('AHEE__EEM_Message__delete_old_messages__after_successful_deletion', $message_ids_to_delete, $number_deleted);
560
-        } else {
561
-            do_action('AHEE__EEM_Message__delete_old_messages__after_deletion_fail', $message_ids_to_delete, $number_deleted);
562
-        }
563
-        return $number_deleted;
564
-    }
551
+		}
552
+
553
+		/**
554
+		 * This will get called if the number of records deleted 0 or greater.  So a successful deletion is one where
555
+		 * there were no errors.  An unsuccessful deletion is where there were errors.  Keep that in mind for the actions
556
+		 * below.
557
+		 */
558
+		if ($number_deleted !== false) {
559
+			do_action('AHEE__EEM_Message__delete_old_messages__after_successful_deletion', $message_ids_to_delete, $number_deleted);
560
+		} else {
561
+			do_action('AHEE__EEM_Message__delete_old_messages__after_deletion_fail', $message_ids_to_delete, $number_deleted);
562
+		}
563
+		return $number_deleted;
564
+	}
565 565
 
566 566
 }
567 567
 // End of file EEM_Message.model.php
Please login to merge, or discard this patch.
core/libraries/messages/EE_Messages_Scheduler.lib.php 2 patches
Indentation   +194 added lines, -194 removed lines patch added patch discarded remove patch
@@ -12,199 +12,199 @@
 block discarded – undo
12 12
 class EE_Messages_Scheduler extends EE_Base
13 13
 {
14 14
 
15
-    /**
16
-     * Number of seconds between batch sends/generates on the cron job.
17
-     * Defaults to 5 minutes in seconds.  If you want to change this interval, you can use the native WordPress
18
-     * `cron_schedules` filter and modify the existing custom `ee_message_cron` schedule interval added.
19
-     *
20
-     * @type int
21
-     */
22
-    const message_cron_schedule = 300;
23
-
24
-    /**
25
-     * Constructor
26
-     */
27
-    public function __construct()
28
-    {
29
-        //register tasks (and make sure only registered once).
30
-        if (! has_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'))) {
31
-            add_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'), 10);
32
-        }
33
-
34
-        //register callbacks for scheduled events (but make sure they are set only once).
35
-        if (! has_action(
36
-            'AHEE__EE_Messages_Scheduler__generation',
37
-            array('EE_Messages_Scheduler', 'batch_generation')
38
-        )) {
39
-            add_action('AHEE__EE_Messages_Scheduler__generation', array('EE_Messages_Scheduler', 'batch_generation'));
40
-            add_action('AHEE__EE_Messages_Scheduler__sending', array('EE_Messages_Scheduler', 'batch_sending'));
41
-            add_action('AHEE__EE_Messages_Scheduler__cleanup', array('EE_Messages_Scheduler', 'cleanup'));
42
-        }
43
-
44
-        //add custom schedules
45
-        add_filter('cron_schedules', array($this, 'custom_schedules'));
46
-    }
47
-
48
-
49
-    /**
50
-     * Add custom schedules for wp_cron
51
-     *
52
-     * @param $schedules
53
-     */
54
-    public function custom_schedules($schedules)
55
-    {
56
-        $schedules['ee_message_cron'] = array(
57
-            'interval' => self::message_cron_schedule,
58
-            'display'  => __(
59
-                'This is the cron time interval for EE Message schedules (defaults to once every 5 minutes)',
60
-                'event_espresso'
61
-            ),
62
-        );
63
-        return $schedules;
64
-    }
65
-
66
-
67
-    /**
68
-     * Callback for FHEE__EEH_Activation__get_cron_tasks that is used to retrieve scheduled Cron events to add and
69
-     * remove.
70
-     *
71
-     * @param array $tasks already existing scheduled tasks
72
-     * @return array
73
-     */
74
-    public function register_scheduled_tasks($tasks)
75
-    {
76
-        EE_Registry::instance()->load_helper('DTT_Helper');
77
-        $tasks['AHEE__EE_Messages_Scheduler__generation'] = 'ee_message_cron';
78
-        $tasks['AHEE__EE_Messages_Scheduler__sending']    = 'ee_message_cron';
79
-        $tasks['AHEE__EE_Messages_Scheduler__cleanup'] = array( EEH_DTT_Helper::tomorrow(), 'daily');
80
-        return $tasks;
81
-    }
82
-
83
-
84
-    /**
85
-     * This initiates a non-blocking separate request to execute on a scheduled task.
86
-     * Note: The EED_Messages module has the handlers for these requests.
87
-     *
88
-     * @param string $task The task the request is being generated for.
89
-     */
90
-    public static function initiate_scheduled_non_blocking_request($task)
91
-    {
92
-        if (apply_filters(
93
-            'EE_Messages_Scheduler__initiate_scheduled_non_blocking_request__do_separate_request',
94
-            true
95
-        )) {
96
-            $request_url  = add_query_arg(
97
-                array_merge(
98
-                    array('ee' => 'msg_cron_trigger'),
99
-                    EE_Messages_Scheduler::get_request_params($task)
100
-                ),
101
-                site_url()
102
-            );
103
-            $request_args = array(
104
-                'timeout'     => 300,
105
-                'blocking'    => (defined('DOING_CRON') && DOING_CRON) || (defined('DOING_AJAX') && DOING_AJAX) ? true : false,
106
-                'sslverify'   => false,
107
-                'redirection' => 10,
108
-            );
109
-            $response     = wp_remote_get($request_url, $request_args);
110
-            if (is_wp_error($response)) {
111
-                trigger_error($response->get_error_message());
112
-            }
113
-        } else {
114
-            EE_Messages_Scheduler::initiate_immediate_request_on_cron($task);
115
-        }
116
-    }
117
-
118
-
119
-    /**
120
-     * This returns
121
-     * the request params used for a scheduled message task request.
122
-     *
123
-     * @param string $task The task the request is for.
124
-     * @return array
125
-     */
126
-    public static function get_request_params($task)
127
-    {
128
-        //transient is used for flood control on msg_cron_trigger requests
129
-        $transient_key = 'ee_trans_' . uniqid($task);
130
-        set_transient($transient_key, 1, 5 * MINUTE_IN_SECONDS);
131
-        return array(
132
-            'type' => $task,
133
-            'key'  => $transient_key,
134
-        );
135
-    }
136
-
137
-
138
-    /**
139
-     * This is used to execute an immediate call to the run_cron task performed by EED_Messages
140
-     *
141
-     * @param string $task The task the request is being generated for.
142
-     */
143
-    public static function initiate_immediate_request_on_cron($task)
144
-    {
145
-        $request_args = EE_Messages_Scheduler::get_request_params($task);
146
-        //set those request args in the request so it gets picked up
147
-        foreach ($request_args as $request_key => $request_value) {
148
-            EE_Registry::instance()->REQ->set($request_key, $request_value);
149
-        }
150
-        EED_Messages::instance()->run_cron();
151
-    }
152
-
153
-
154
-    /**
155
-     * Callback for scheduled AHEE__EE_Messages_Scheduler__generation wp cron event
156
-     */
157
-    public static function batch_generation()
158
-    {
159
-        /**
160
-         * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
161
-         */
162
-        if (! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
163
-            || ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
164
-        ) {
165
-            EE_Messages_Scheduler::initiate_immediate_request_on_cron('generate');
166
-        }
167
-    }
168
-
169
-
170
-    /**
171
-     * Callback for scheduled AHEE__EE_Messages_Scheduler__sending
172
-     */
173
-    public static function batch_sending()
174
-    {
175
-        /**
176
-         * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
177
-         */
178
-        if (! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
179
-            || ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
180
-        ) {
181
-            EE_Messages_Scheduler::initiate_immediate_request_on_cron('send');
182
-        }
183
-    }
184
-
185
-
186
-    /**
187
-     * This is the callback for the `AHEE__EE_Messages_Scheduler__cleanup` scheduled event action.
188
-     * This runs once a day and if cleanup is active (set via messages settings), it will (by default) delete permanently
189
-     * from the database messages that have a MSG_modified date older than 30 days.
190
-     */
191
-    public static function cleanup()
192
-    {
193
-        //first check if user has cleanup turned on or if we're in maintenance mode.  If in maintenance mode we'll wait
194
-        //until the next scheduled event.
195
-        if (! EE_Registry::instance()->CFG->messages->delete_threshold
196
-            || ! EE_Maintenance_Mode::instance()->models_can_query()
197
-        ) {
198
-            return;
199
-        }
200
-
201
-        /**
202
-         * This filter switch allows other code (such as the EE_Worker_Queue add-on) to replace this with its own handling
203
-         * of deleting messages.
204
-         */
205
-        if (apply_filters('FHEE__EE_Messages_Scheduler__cleanup__handle_cleanup_on_cron', true)) {
206
-            EEM_Message::instance()->delete_old_messages(EE_Registry::instance()->CFG->messages->delete_threshold);
207
-        }
208
-    }
15
+	/**
16
+	 * Number of seconds between batch sends/generates on the cron job.
17
+	 * Defaults to 5 minutes in seconds.  If you want to change this interval, you can use the native WordPress
18
+	 * `cron_schedules` filter and modify the existing custom `ee_message_cron` schedule interval added.
19
+	 *
20
+	 * @type int
21
+	 */
22
+	const message_cron_schedule = 300;
23
+
24
+	/**
25
+	 * Constructor
26
+	 */
27
+	public function __construct()
28
+	{
29
+		//register tasks (and make sure only registered once).
30
+		if (! has_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'))) {
31
+			add_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'), 10);
32
+		}
33
+
34
+		//register callbacks for scheduled events (but make sure they are set only once).
35
+		if (! has_action(
36
+			'AHEE__EE_Messages_Scheduler__generation',
37
+			array('EE_Messages_Scheduler', 'batch_generation')
38
+		)) {
39
+			add_action('AHEE__EE_Messages_Scheduler__generation', array('EE_Messages_Scheduler', 'batch_generation'));
40
+			add_action('AHEE__EE_Messages_Scheduler__sending', array('EE_Messages_Scheduler', 'batch_sending'));
41
+			add_action('AHEE__EE_Messages_Scheduler__cleanup', array('EE_Messages_Scheduler', 'cleanup'));
42
+		}
43
+
44
+		//add custom schedules
45
+		add_filter('cron_schedules', array($this, 'custom_schedules'));
46
+	}
47
+
48
+
49
+	/**
50
+	 * Add custom schedules for wp_cron
51
+	 *
52
+	 * @param $schedules
53
+	 */
54
+	public function custom_schedules($schedules)
55
+	{
56
+		$schedules['ee_message_cron'] = array(
57
+			'interval' => self::message_cron_schedule,
58
+			'display'  => __(
59
+				'This is the cron time interval for EE Message schedules (defaults to once every 5 minutes)',
60
+				'event_espresso'
61
+			),
62
+		);
63
+		return $schedules;
64
+	}
65
+
66
+
67
+	/**
68
+	 * Callback for FHEE__EEH_Activation__get_cron_tasks that is used to retrieve scheduled Cron events to add and
69
+	 * remove.
70
+	 *
71
+	 * @param array $tasks already existing scheduled tasks
72
+	 * @return array
73
+	 */
74
+	public function register_scheduled_tasks($tasks)
75
+	{
76
+		EE_Registry::instance()->load_helper('DTT_Helper');
77
+		$tasks['AHEE__EE_Messages_Scheduler__generation'] = 'ee_message_cron';
78
+		$tasks['AHEE__EE_Messages_Scheduler__sending']    = 'ee_message_cron';
79
+		$tasks['AHEE__EE_Messages_Scheduler__cleanup'] = array( EEH_DTT_Helper::tomorrow(), 'daily');
80
+		return $tasks;
81
+	}
82
+
83
+
84
+	/**
85
+	 * This initiates a non-blocking separate request to execute on a scheduled task.
86
+	 * Note: The EED_Messages module has the handlers for these requests.
87
+	 *
88
+	 * @param string $task The task the request is being generated for.
89
+	 */
90
+	public static function initiate_scheduled_non_blocking_request($task)
91
+	{
92
+		if (apply_filters(
93
+			'EE_Messages_Scheduler__initiate_scheduled_non_blocking_request__do_separate_request',
94
+			true
95
+		)) {
96
+			$request_url  = add_query_arg(
97
+				array_merge(
98
+					array('ee' => 'msg_cron_trigger'),
99
+					EE_Messages_Scheduler::get_request_params($task)
100
+				),
101
+				site_url()
102
+			);
103
+			$request_args = array(
104
+				'timeout'     => 300,
105
+				'blocking'    => (defined('DOING_CRON') && DOING_CRON) || (defined('DOING_AJAX') && DOING_AJAX) ? true : false,
106
+				'sslverify'   => false,
107
+				'redirection' => 10,
108
+			);
109
+			$response     = wp_remote_get($request_url, $request_args);
110
+			if (is_wp_error($response)) {
111
+				trigger_error($response->get_error_message());
112
+			}
113
+		} else {
114
+			EE_Messages_Scheduler::initiate_immediate_request_on_cron($task);
115
+		}
116
+	}
117
+
118
+
119
+	/**
120
+	 * This returns
121
+	 * the request params used for a scheduled message task request.
122
+	 *
123
+	 * @param string $task The task the request is for.
124
+	 * @return array
125
+	 */
126
+	public static function get_request_params($task)
127
+	{
128
+		//transient is used for flood control on msg_cron_trigger requests
129
+		$transient_key = 'ee_trans_' . uniqid($task);
130
+		set_transient($transient_key, 1, 5 * MINUTE_IN_SECONDS);
131
+		return array(
132
+			'type' => $task,
133
+			'key'  => $transient_key,
134
+		);
135
+	}
136
+
137
+
138
+	/**
139
+	 * This is used to execute an immediate call to the run_cron task performed by EED_Messages
140
+	 *
141
+	 * @param string $task The task the request is being generated for.
142
+	 */
143
+	public static function initiate_immediate_request_on_cron($task)
144
+	{
145
+		$request_args = EE_Messages_Scheduler::get_request_params($task);
146
+		//set those request args in the request so it gets picked up
147
+		foreach ($request_args as $request_key => $request_value) {
148
+			EE_Registry::instance()->REQ->set($request_key, $request_value);
149
+		}
150
+		EED_Messages::instance()->run_cron();
151
+	}
152
+
153
+
154
+	/**
155
+	 * Callback for scheduled AHEE__EE_Messages_Scheduler__generation wp cron event
156
+	 */
157
+	public static function batch_generation()
158
+	{
159
+		/**
160
+		 * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
161
+		 */
162
+		if (! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
163
+			|| ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
164
+		) {
165
+			EE_Messages_Scheduler::initiate_immediate_request_on_cron('generate');
166
+		}
167
+	}
168
+
169
+
170
+	/**
171
+	 * Callback for scheduled AHEE__EE_Messages_Scheduler__sending
172
+	 */
173
+	public static function batch_sending()
174
+	{
175
+		/**
176
+		 * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
177
+		 */
178
+		if (! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
179
+			|| ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
180
+		) {
181
+			EE_Messages_Scheduler::initiate_immediate_request_on_cron('send');
182
+		}
183
+	}
184
+
185
+
186
+	/**
187
+	 * This is the callback for the `AHEE__EE_Messages_Scheduler__cleanup` scheduled event action.
188
+	 * This runs once a day and if cleanup is active (set via messages settings), it will (by default) delete permanently
189
+	 * from the database messages that have a MSG_modified date older than 30 days.
190
+	 */
191
+	public static function cleanup()
192
+	{
193
+		//first check if user has cleanup turned on or if we're in maintenance mode.  If in maintenance mode we'll wait
194
+		//until the next scheduled event.
195
+		if (! EE_Registry::instance()->CFG->messages->delete_threshold
196
+			|| ! EE_Maintenance_Mode::instance()->models_can_query()
197
+		) {
198
+			return;
199
+		}
200
+
201
+		/**
202
+		 * This filter switch allows other code (such as the EE_Worker_Queue add-on) to replace this with its own handling
203
+		 * of deleting messages.
204
+		 */
205
+		if (apply_filters('FHEE__EE_Messages_Scheduler__cleanup__handle_cleanup_on_cron', true)) {
206
+			EEM_Message::instance()->delete_old_messages(EE_Registry::instance()->CFG->messages->delete_threshold);
207
+		}
208
+	}
209 209
 
210 210
 } //end EE_Messages_Scheduler
211 211
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -27,12 +27,12 @@  discard block
 block discarded – undo
27 27
     public function __construct()
28 28
     {
29 29
         //register tasks (and make sure only registered once).
30
-        if (! has_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'))) {
30
+        if ( ! has_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'))) {
31 31
             add_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'), 10);
32 32
         }
33 33
 
34 34
         //register callbacks for scheduled events (but make sure they are set only once).
35
-        if (! has_action(
35
+        if ( ! has_action(
36 36
             'AHEE__EE_Messages_Scheduler__generation',
37 37
             array('EE_Messages_Scheduler', 'batch_generation')
38 38
         )) {
@@ -76,7 +76,7 @@  discard block
 block discarded – undo
76 76
         EE_Registry::instance()->load_helper('DTT_Helper');
77 77
         $tasks['AHEE__EE_Messages_Scheduler__generation'] = 'ee_message_cron';
78 78
         $tasks['AHEE__EE_Messages_Scheduler__sending']    = 'ee_message_cron';
79
-        $tasks['AHEE__EE_Messages_Scheduler__cleanup'] = array( EEH_DTT_Helper::tomorrow(), 'daily');
79
+        $tasks['AHEE__EE_Messages_Scheduler__cleanup'] = array(EEH_DTT_Helper::tomorrow(), 'daily');
80 80
         return $tasks;
81 81
     }
82 82
 
@@ -93,7 +93,7 @@  discard block
 block discarded – undo
93 93
             'EE_Messages_Scheduler__initiate_scheduled_non_blocking_request__do_separate_request',
94 94
             true
95 95
         )) {
96
-            $request_url  = add_query_arg(
96
+            $request_url = add_query_arg(
97 97
                 array_merge(
98 98
                     array('ee' => 'msg_cron_trigger'),
99 99
                     EE_Messages_Scheduler::get_request_params($task)
@@ -106,7 +106,7 @@  discard block
 block discarded – undo
106 106
                 'sslverify'   => false,
107 107
                 'redirection' => 10,
108 108
             );
109
-            $response     = wp_remote_get($request_url, $request_args);
109
+            $response = wp_remote_get($request_url, $request_args);
110 110
             if (is_wp_error($response)) {
111 111
                 trigger_error($response->get_error_message());
112 112
             }
@@ -126,7 +126,7 @@  discard block
 block discarded – undo
126 126
     public static function get_request_params($task)
127 127
     {
128 128
         //transient is used for flood control on msg_cron_trigger requests
129
-        $transient_key = 'ee_trans_' . uniqid($task);
129
+        $transient_key = 'ee_trans_'.uniqid($task);
130 130
         set_transient($transient_key, 1, 5 * MINUTE_IN_SECONDS);
131 131
         return array(
132 132
             'type' => $task,
@@ -159,7 +159,7 @@  discard block
 block discarded – undo
159 159
         /**
160 160
          * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
161 161
          */
162
-        if (! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
162
+        if ( ! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
163 163
             || ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
164 164
         ) {
165 165
             EE_Messages_Scheduler::initiate_immediate_request_on_cron('generate');
@@ -175,7 +175,7 @@  discard block
 block discarded – undo
175 175
         /**
176 176
          * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
177 177
          */
178
-        if (! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
178
+        if ( ! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
179 179
             || ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
180 180
         ) {
181 181
             EE_Messages_Scheduler::initiate_immediate_request_on_cron('send');
@@ -192,7 +192,7 @@  discard block
 block discarded – undo
192 192
     {
193 193
         //first check if user has cleanup turned on or if we're in maintenance mode.  If in maintenance mode we'll wait
194 194
         //until the next scheduled event.
195
-        if (! EE_Registry::instance()->CFG->messages->delete_threshold
195
+        if ( ! EE_Registry::instance()->CFG->messages->delete_threshold
196 196
             || ! EE_Maintenance_Mode::instance()->models_can_query()
197 197
         ) {
198 198
             return;
Please login to merge, or discard this patch.
admin_pages/messages/Messages_Admin_Page.core.php 1 patch
Indentation   +3643 added lines, -3643 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('NO direct script access allowed');
2
+	exit('NO direct script access allowed');
3 3
 }
4 4
 
5 5
 /**
@@ -17,2213 +17,2213 @@  discard block
 block discarded – undo
17 17
 class Messages_Admin_Page extends EE_Admin_Page
18 18
 {
19 19
     
20
-    /**
21
-     * @type EE_Message_Resource_Manager $_message_resource_manager
22
-     */
23
-    protected $_message_resource_manager;
24
-    
25
-    /**
26
-     * @type string $_active_message_type_name
27
-     */
28
-    protected $_active_message_type_name = '';
29
-    
30
-    /**
31
-     * @type EE_messenger $_active_messenger
32
-     */
33
-    protected $_active_messenger;
34
-    protected $_activate_state;
35
-    protected $_activate_meta_box_type;
36
-    protected $_current_message_meta_box;
37
-    protected $_current_message_meta_box_object;
38
-    protected $_context_switcher;
39
-    protected $_shortcodes = array();
40
-    protected $_active_messengers = array();
41
-    protected $_active_message_types = array();
42
-    
43
-    /**
44
-     * @var EE_Message_Template_Group $_message_template_group
45
-     */
46
-    protected $_message_template_group;
47
-    protected $_m_mt_settings = array();
48
-    
49
-    
50
-    /**
51
-     * This is set via the _set_message_template_group method and holds whatever the template pack for the group is.
52
-     * IF there is no group then it gets automatically set to the Default template pack.
53
-     *
54
-     * @since 4.5.0
55
-     *
56
-     * @var EE_Messages_Template_Pack
57
-     */
58
-    protected $_template_pack;
59
-    
60
-    
61
-    /**
62
-     * This is set via the _set_message_template_group method and holds whatever the template pack variation for the
63
-     * group is.  If there is no group then it automatically gets set to default.
64
-     *
65
-     * @since 4.5.0
66
-     *
67
-     * @var string
68
-     */
69
-    protected $_variation;
70
-    
71
-    
72
-    /**
73
-     * @param bool $routing
74
-     */
75
-    public function __construct($routing = true)
76
-    {
77
-        //make sure messages autoloader is running
78
-        EED_Messages::set_autoloaders();
79
-        parent::__construct($routing);
80
-    }
81
-    
82
-    
83
-    protected function _init_page_props()
84
-    {
85
-        $this->page_slug        = EE_MSG_PG_SLUG;
86
-        $this->page_label       = __('Messages Settings', 'event_espresso');
87
-        $this->_admin_base_url  = EE_MSG_ADMIN_URL;
88
-        $this->_admin_base_path = EE_MSG_ADMIN;
89
-        
90
-        $this->_activate_state = isset($this->_req_data['activate_state']) ? (array)$this->_req_data['activate_state'] : array();
91
-        
92
-        $this->_active_messenger = isset($this->_req_data['messenger']) ? $this->_req_data['messenger'] : null;
93
-        $this->_load_message_resource_manager();
94
-    }
95
-    
96
-    
97
-    /**
98
-     * loads messenger objects into the $_active_messengers property (so we can access the needed methods)
99
-     *
100
-     *
101
-     * @throws EE_Error
102
-     */
103
-    protected function _load_message_resource_manager()
104
-    {
105
-        $this->_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
106
-    }
107
-    
108
-    
109
-    /**
110
-     * @deprecated 4.9.9.rc.014
111
-     * @return array
112
-     */
113
-    public function get_messengers_for_list_table()
114
-    {
115
-        EE_Error::doing_it_wrong(
116
-            __METHOD__,
117
-            __('This method is no longer in use.  There is no replacement for it. The method was used to generate a set of
20
+	/**
21
+	 * @type EE_Message_Resource_Manager $_message_resource_manager
22
+	 */
23
+	protected $_message_resource_manager;
24
+    
25
+	/**
26
+	 * @type string $_active_message_type_name
27
+	 */
28
+	protected $_active_message_type_name = '';
29
+    
30
+	/**
31
+	 * @type EE_messenger $_active_messenger
32
+	 */
33
+	protected $_active_messenger;
34
+	protected $_activate_state;
35
+	protected $_activate_meta_box_type;
36
+	protected $_current_message_meta_box;
37
+	protected $_current_message_meta_box_object;
38
+	protected $_context_switcher;
39
+	protected $_shortcodes = array();
40
+	protected $_active_messengers = array();
41
+	protected $_active_message_types = array();
42
+    
43
+	/**
44
+	 * @var EE_Message_Template_Group $_message_template_group
45
+	 */
46
+	protected $_message_template_group;
47
+	protected $_m_mt_settings = array();
48
+    
49
+    
50
+	/**
51
+	 * This is set via the _set_message_template_group method and holds whatever the template pack for the group is.
52
+	 * IF there is no group then it gets automatically set to the Default template pack.
53
+	 *
54
+	 * @since 4.5.0
55
+	 *
56
+	 * @var EE_Messages_Template_Pack
57
+	 */
58
+	protected $_template_pack;
59
+    
60
+    
61
+	/**
62
+	 * This is set via the _set_message_template_group method and holds whatever the template pack variation for the
63
+	 * group is.  If there is no group then it automatically gets set to default.
64
+	 *
65
+	 * @since 4.5.0
66
+	 *
67
+	 * @var string
68
+	 */
69
+	protected $_variation;
70
+    
71
+    
72
+	/**
73
+	 * @param bool $routing
74
+	 */
75
+	public function __construct($routing = true)
76
+	{
77
+		//make sure messages autoloader is running
78
+		EED_Messages::set_autoloaders();
79
+		parent::__construct($routing);
80
+	}
81
+    
82
+    
83
+	protected function _init_page_props()
84
+	{
85
+		$this->page_slug        = EE_MSG_PG_SLUG;
86
+		$this->page_label       = __('Messages Settings', 'event_espresso');
87
+		$this->_admin_base_url  = EE_MSG_ADMIN_URL;
88
+		$this->_admin_base_path = EE_MSG_ADMIN;
89
+        
90
+		$this->_activate_state = isset($this->_req_data['activate_state']) ? (array)$this->_req_data['activate_state'] : array();
91
+        
92
+		$this->_active_messenger = isset($this->_req_data['messenger']) ? $this->_req_data['messenger'] : null;
93
+		$this->_load_message_resource_manager();
94
+	}
95
+    
96
+    
97
+	/**
98
+	 * loads messenger objects into the $_active_messengers property (so we can access the needed methods)
99
+	 *
100
+	 *
101
+	 * @throws EE_Error
102
+	 */
103
+	protected function _load_message_resource_manager()
104
+	{
105
+		$this->_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
106
+	}
107
+    
108
+    
109
+	/**
110
+	 * @deprecated 4.9.9.rc.014
111
+	 * @return array
112
+	 */
113
+	public function get_messengers_for_list_table()
114
+	{
115
+		EE_Error::doing_it_wrong(
116
+			__METHOD__,
117
+			__('This method is no longer in use.  There is no replacement for it. The method was used to generate a set of
118 118
 			values for use in creating a messenger filter dropdown which is now generated differently via
119 119
 			 Messages_Admin_Page::get_messengers_select_input', 'event_espresso'),
120
-            '4.9.9.rc.014'
121
-        );
122
-        
123
-        $m_values          = array();
124
-        $active_messengers = EEM_Message::instance()->get_all(array('group_by' => 'MSG_messenger'));
125
-        //setup messengers for selects
126
-        $i = 1;
127
-        foreach ($active_messengers as $active_messenger) {
128
-            if ($active_messenger instanceof EE_Message) {
129
-                $m_values[$i]['id']   = $active_messenger->messenger();
130
-                $m_values[$i]['text'] = ucwords($active_messenger->messenger_label());
131
-                $i++;
132
-            }
133
-        }
134
-        
135
-        return $m_values;
136
-    }
137
-    
138
-    
139
-    /**
140
-     * @deprecated 4.9.9.rc.014
141
-     * @return array
142
-     */
143
-    public function get_message_types_for_list_table()
144
-    {
145
-        EE_Error::doing_it_wrong(
146
-            __METHOD__,
147
-            __('This method is no longer in use.  There is no replacement for it. The method was used to generate a set of
120
+			'4.9.9.rc.014'
121
+		);
122
+        
123
+		$m_values          = array();
124
+		$active_messengers = EEM_Message::instance()->get_all(array('group_by' => 'MSG_messenger'));
125
+		//setup messengers for selects
126
+		$i = 1;
127
+		foreach ($active_messengers as $active_messenger) {
128
+			if ($active_messenger instanceof EE_Message) {
129
+				$m_values[$i]['id']   = $active_messenger->messenger();
130
+				$m_values[$i]['text'] = ucwords($active_messenger->messenger_label());
131
+				$i++;
132
+			}
133
+		}
134
+        
135
+		return $m_values;
136
+	}
137
+    
138
+    
139
+	/**
140
+	 * @deprecated 4.9.9.rc.014
141
+	 * @return array
142
+	 */
143
+	public function get_message_types_for_list_table()
144
+	{
145
+		EE_Error::doing_it_wrong(
146
+			__METHOD__,
147
+			__('This method is no longer in use.  There is no replacement for it. The method was used to generate a set of
148 148
 			values for use in creating a message type filter dropdown which is now generated differently via
149 149
 			 Messages_Admin_Page::get_message_types_select_input', 'event_espresso'),
150
-            '4.9.9.rc.014'
151
-        );
152
-        
153
-        $mt_values       = array();
154
-        $active_messages = EEM_Message::instance()->get_all(array('group_by' => 'MSG_message_type'));
155
-        $i               = 1;
156
-        foreach ($active_messages as $active_message) {
157
-            if ($active_message instanceof EE_Message) {
158
-                $mt_values[$i]['id']   = $active_message->message_type();
159
-                $mt_values[$i]['text'] = ucwords($active_message->message_type_label());
160
-                $i++;
161
-            }
162
-        }
163
-        
164
-        return $mt_values;
165
-    }
166
-    
167
-    
168
-    /**
169
-     * @deprecated 4.9.9.rc.014
170
-     * @return array
171
-     */
172
-    public function get_contexts_for_message_types_for_list_table()
173
-    {
174
-        EE_Error::doing_it_wrong(
175
-            __METHOD__,
176
-            __('This method is no longer in use.  There is no replacement for it. The method was used to generate a set of
150
+			'4.9.9.rc.014'
151
+		);
152
+        
153
+		$mt_values       = array();
154
+		$active_messages = EEM_Message::instance()->get_all(array('group_by' => 'MSG_message_type'));
155
+		$i               = 1;
156
+		foreach ($active_messages as $active_message) {
157
+			if ($active_message instanceof EE_Message) {
158
+				$mt_values[$i]['id']   = $active_message->message_type();
159
+				$mt_values[$i]['text'] = ucwords($active_message->message_type_label());
160
+				$i++;
161
+			}
162
+		}
163
+        
164
+		return $mt_values;
165
+	}
166
+    
167
+    
168
+	/**
169
+	 * @deprecated 4.9.9.rc.014
170
+	 * @return array
171
+	 */
172
+	public function get_contexts_for_message_types_for_list_table()
173
+	{
174
+		EE_Error::doing_it_wrong(
175
+			__METHOD__,
176
+			__('This method is no longer in use.  There is no replacement for it. The method was used to generate a set of
177 177
 			values for use in creating a message type context filter dropdown which is now generated differently via
178 178
 			 Messages_Admin_Page::get_contexts_for_message_types_select_input', 'event_espresso'),
179
-            '4.9.9.rc.014'
180
-        );
181
-        
182
-        $contexts                = array();
183
-        $active_message_contexts = EEM_Message::instance()->get_all(array('group_by' => 'MSG_context'));
184
-        foreach ($active_message_contexts as $active_message) {
185
-            if ($active_message instanceof EE_Message) {
186
-                $message_type = $active_message->message_type_object();
187
-                if ($message_type instanceof EE_message_type) {
188
-                    $message_type_contexts = $message_type->get_contexts();
189
-                    foreach ($message_type_contexts as $context => $context_details) {
190
-                        $contexts[$context] = $context_details['label'];
191
-                    }
192
-                }
193
-            }
194
-        }
195
-        
196
-        return $contexts;
197
-    }
198
-    
199
-    
200
-    /**
201
-     * Generate select input with provided messenger options array.
202
-     *
203
-     * @param array $messenger_options Array of messengers indexed by messenger slug and values are the messenger
204
-     *                                 labels.
205
-     *
206
-     * @return string
207
-     */
208
-    public function get_messengers_select_input($messenger_options)
209
-    {
210
-        //if empty or just one value then just return an empty string
211
-        if (empty($messenger_options)
212
-            || ! is_array($messenger_options)
213
-            || count($messenger_options) === 1
214
-        ) {
215
-            return '';
216
-        }
217
-        //merge in default
218
-        $messenger_options = array_merge(
219
-            array('none_selected' => __('Show All Messengers', 'event_espresso')),
220
-            $messenger_options
221
-        );
222
-        $input             = new EE_Select_Input(
223
-            $messenger_options,
224
-            array(
225
-                'html_name'  => 'ee_messenger_filter_by',
226
-                'html_id'    => 'ee_messenger_filter_by',
227
-                'html_class' => 'wide',
228
-                'default'    => isset($this->_req_data['ee_messenger_filter_by'])
229
-                    ? sanitize_title($this->_req_data['ee_messenger_filter_by'])
230
-                    : 'none_selected'
231
-            )
232
-        );
233
-        
234
-        return $input->get_html_for_input();
235
-    }
236
-    
237
-    
238
-    /**
239
-     * Generate select input with provided message type options array.
240
-     *
241
-     * @param array $message_type_options Array of message types indexed by message type slug, and values are the
242
-     *                                    message type labels
243
-     *
244
-     * @return string
245
-     */
246
-    public function get_message_types_select_input($message_type_options)
247
-    {
248
-        //if empty or count of options is 1 then just return an empty string
249
-        if (empty($message_type_options)
250
-            || ! is_array($message_type_options)
251
-            || count($message_type_options) === 1
252
-        ) {
253
-            return '';
254
-        }
255
-        //merge in default
256
-        $message_type_options = array_merge(
257
-            array('none_selected' => __('Show All Message Types', 'event_espresso')),
258
-            $message_type_options
259
-        );
260
-        $input                = new EE_Select_Input(
261
-            $message_type_options,
262
-            array(
263
-                'html_name'  => 'ee_message_type_filter_by',
264
-                'html_id'    => 'ee_message_type_filter_by',
265
-                'html_class' => 'wide',
266
-                'default'    => isset($this->_req_data['ee_message_type_filter_by'])
267
-                    ? sanitize_title($this->_req_data['ee_message_type_filter_by'])
268
-                    : 'none_selected',
269
-            )
270
-        );
271
-        
272
-        return $input->get_html_for_input();
273
-    }
274
-    
275
-    
276
-    /**
277
-     * Generate select input with provide message type contexts array.
278
-     *
279
-     * @param array $context_options Array of message type contexts indexed by context slug, and values are the
280
-     *                               context label.
281
-     *
282
-     * @return string
283
-     */
284
-    public function get_contexts_for_message_types_select_input($context_options)
285
-    {
286
-        //if empty or count of options is one then just return empty string
287
-        if (empty($context_options)
288
-            || ! is_array($context_options)
289
-            || count($context_options) === 1
290
-        ) {
291
-            return '';
292
-        }
293
-        //merge in default
294
-        $context_options = array_merge(
295
-            array('none_selected' => __('Show all Contexts', 'event_espresso')),
296
-            $context_options
297
-        );
298
-        $input           = new EE_Select_Input(
299
-            $context_options,
300
-            array(
301
-                'html_name'  => 'ee_context_filter_by',
302
-                'html_id'    => 'ee_context_filter_by',
303
-                'html_class' => 'wide',
304
-                'default'    => isset($this->_req_data['ee_context_filter_by'])
305
-                    ? sanitize_title($this->_req_data['ee_context_filter_by'])
306
-                    : 'none_selected',
307
-            )
308
-        );
309
-        
310
-        return $input->get_html_for_input();
311
-    }
312
-    
313
-    
314
-    protected function _ajax_hooks()
315
-    {
316
-        add_action('wp_ajax_activate_messenger', array($this, 'activate_messenger_toggle'));
317
-        add_action('wp_ajax_activate_mt', array($this, 'activate_mt_toggle'));
318
-        add_action('wp_ajax_ee_msgs_save_settings', array($this, 'save_settings'));
319
-        add_action('wp_ajax_ee_msgs_update_mt_form', array($this, 'update_mt_form'));
320
-        add_action('wp_ajax_switch_template_pack', array($this, 'switch_template_pack'));
321
-    }
322
-    
323
-    
324
-    protected function _define_page_props()
325
-    {
326
-        $this->_admin_page_title = $this->page_label;
327
-        $this->_labels           = array(
328
-            'buttons'    => array(
329
-                'add'    => __('Add New Message Template', 'event_espresso'),
330
-                'edit'   => __('Edit Message Template', 'event_espresso'),
331
-                'delete' => __('Delete Message Template', 'event_espresso')
332
-            ),
333
-            'publishbox' => __('Update Actions', 'event_espresso')
334
-        );
335
-    }
336
-    
337
-    
338
-    /**
339
-     *        an array for storing key => value pairs of request actions and their corresponding methods
340
-     * @access protected
341
-     * @return void
342
-     */
343
-    protected function _set_page_routes()
344
-    {
345
-        $grp_id = ! empty($this->_req_data['GRP_ID']) && ! is_array($this->_req_data['GRP_ID'])
346
-            ? $this->_req_data['GRP_ID']
347
-            : 0;
348
-        $grp_id = empty($grp_id) && ! empty($this->_req_data['id'])
349
-            ? $this->_req_data['id']
350
-            : $grp_id;
351
-        $msg_id = ! empty($this->_req_data['MSG_ID']) && ! is_array($this->_req_data['MSG_ID'])
352
-            ? $this->_req_data['MSG_ID']
353
-            : 0;
354
-        
355
-        $this->_page_routes = array(
356
-            'default'                          => array(
357
-                'func'       => '_message_queue_list_table',
358
-                'capability' => 'ee_read_global_messages'
359
-            ),
360
-            'global_mtps'                      => array(
361
-                'func'       => '_ee_default_messages_overview_list_table',
362
-                'capability' => 'ee_read_global_messages'
363
-            ),
364
-            'custom_mtps'                      => array(
365
-                'func'       => '_custom_mtps_preview',
366
-                'capability' => 'ee_read_messages'
367
-            ),
368
-            'add_new_message_template'         => array(
369
-                'func'       => '_add_message_template',
370
-                'capability' => 'ee_edit_messages',
371
-                'noheader'   => true
372
-            ),
373
-            'edit_message_template'            => array(
374
-                'func'       => '_edit_message_template',
375
-                'capability' => 'ee_edit_message',
376
-                'obj_id'     => $grp_id
377
-            ),
378
-            'preview_message'                  => array(
379
-                'func'               => '_preview_message',
380
-                'capability'         => 'ee_read_message',
381
-                'obj_id'             => $grp_id,
382
-                'noheader'           => true,
383
-                'headers_sent_route' => 'display_preview_message'
384
-            ),
385
-            'display_preview_message'          => array(
386
-                'func'       => '_display_preview_message',
387
-                'capability' => 'ee_read_message',
388
-                'obj_id'     => $grp_id
389
-            ),
390
-            'insert_message_template'          => array(
391
-                'func'       => '_insert_or_update_message_template',
392
-                'capability' => 'ee_edit_messages',
393
-                'args'       => array('new_template' => true),
394
-                'noheader'   => true
395
-            ),
396
-            'update_message_template'          => array(
397
-                'func'       => '_insert_or_update_message_template',
398
-                'capability' => 'ee_edit_message',
399
-                'obj_id'     => $grp_id,
400
-                'args'       => array('new_template' => false),
401
-                'noheader'   => true
402
-            ),
403
-            'trash_message_template'           => array(
404
-                'func'       => '_trash_or_restore_message_template',
405
-                'capability' => 'ee_delete_message',
406
-                'obj_id'     => $grp_id,
407
-                'args'       => array('trash' => true, 'all' => true),
408
-                'noheader'   => true
409
-            ),
410
-            'trash_message_template_context'   => array(
411
-                'func'       => '_trash_or_restore_message_template',
412
-                'capability' => 'ee_delete_message',
413
-                'obj_id'     => $grp_id,
414
-                'args'       => array('trash' => true),
415
-                'noheader'   => true
416
-            ),
417
-            'restore_message_template'         => array(
418
-                'func'       => '_trash_or_restore_message_template',
419
-                'capability' => 'ee_delete_message',
420
-                'obj_id'     => $grp_id,
421
-                'args'       => array('trash' => false, 'all' => true),
422
-                'noheader'   => true
423
-            ),
424
-            'restore_message_template_context' => array(
425
-                'func'       => '_trash_or_restore_message_template',
426
-                'capability' => 'ee_delete_message',
427
-                'obj_id'     => $grp_id,
428
-                'args'       => array('trash' => false),
429
-                'noheader'   => true
430
-            ),
431
-            'delete_message_template'          => array(
432
-                'func'       => '_delete_message_template',
433
-                'capability' => 'ee_delete_message',
434
-                'obj_id'     => $grp_id,
435
-                'noheader'   => true
436
-            ),
437
-            'reset_to_default'                 => array(
438
-                'func'       => '_reset_to_default_template',
439
-                'capability' => 'ee_edit_message',
440
-                'obj_id'     => $grp_id,
441
-                'noheader'   => true
442
-            ),
443
-            'settings'                         => array(
444
-                'func'       => '_settings',
445
-                'capability' => 'manage_options'
446
-            ),
447
-            'update_global_settings'           => array(
448
-                'func'       => '_update_global_settings',
449
-                'capability' => 'manage_options',
450
-                'noheader'   => true
451
-            ),
452
-            'generate_now'                     => array(
453
-                'func'       => '_generate_now',
454
-                'capability' => 'ee_send_message',
455
-                'noheader'   => true
456
-            ),
457
-            'generate_and_send_now'            => array(
458
-                'func'       => '_generate_and_send_now',
459
-                'capability' => 'ee_send_message',
460
-                'noheader'   => true
461
-            ),
462
-            'queue_for_resending'              => array(
463
-                'func'       => '_queue_for_resending',
464
-                'capability' => 'ee_send_message',
465
-                'noheader'   => true
466
-            ),
467
-            'send_now'                         => array(
468
-                'func'       => '_send_now',
469
-                'capability' => 'ee_send_message',
470
-                'noheader'   => true
471
-            ),
472
-            'delete_ee_message'                => array(
473
-                'func'       => '_delete_ee_messages',
474
-                'capability' => 'ee_delete_message',
475
-                'noheader'   => true
476
-            ),
477
-            'delete_ee_messages'               => array(
478
-                'func'       => '_delete_ee_messages',
479
-                'capability' => 'ee_delete_messages',
480
-                'noheader'   => true,
481
-                'obj_id'     => $msg_id
482
-            )
483
-        );
484
-    }
485
-    
486
-    
487
-    protected function _set_page_config()
488
-    {
489
-        $this->_page_config = array(
490
-            'default'                  => array(
491
-                'nav'           => array(
492
-                    'label' => __('Message Activity', 'event_espresso'),
493
-                    'order' => 10
494
-                ),
495
-                'list_table'    => 'EE_Message_List_Table',
496
-                // 'qtips' => array( 'EE_Message_List_Table_Tips' ),
497
-                'require_nonce' => false
498
-            ),
499
-            'global_mtps'              => array(
500
-                'nav'           => array(
501
-                    'label' => __('Default Message Templates', 'event_espresso'),
502
-                    'order' => 20
503
-                ),
504
-                'list_table'    => 'Messages_Template_List_Table',
505
-                'help_tabs'     => array(
506
-                    'messages_overview_help_tab'                                => array(
507
-                        'title'    => __('Messages Overview', 'event_espresso'),
508
-                        'filename' => 'messages_overview'
509
-                    ),
510
-                    'messages_overview_messages_table_column_headings_help_tab' => array(
511
-                        'title'    => __('Messages Table Column Headings', 'event_espresso'),
512
-                        'filename' => 'messages_overview_table_column_headings'
513
-                    ),
514
-                    'messages_overview_messages_filters_help_tab'               => array(
515
-                        'title'    => __('Message Filters', 'event_espresso'),
516
-                        'filename' => 'messages_overview_filters'
517
-                    ),
518
-                    'messages_overview_messages_views_help_tab'                 => array(
519
-                        'title'    => __('Message Views', 'event_espresso'),
520
-                        'filename' => 'messages_overview_views'
521
-                    ),
522
-                    'message_overview_message_types_help_tab'                   => array(
523
-                        'title'    => __('Message Types', 'event_espresso'),
524
-                        'filename' => 'messages_overview_types'
525
-                    ),
526
-                    'messages_overview_messengers_help_tab'                     => array(
527
-                        'title'    => __('Messengers', 'event_espresso'),
528
-                        'filename' => 'messages_overview_messengers',
529
-                    ),
530
-                    'messages_overview_other_help_tab'                          => array(
531
-                        'title'    => __('Messages Other', 'event_espresso'),
532
-                        'filename' => 'messages_overview_other',
533
-                    ),
534
-                ),
535
-                'help_tour'     => array('Messages_Overview_Help_Tour'),
536
-                'require_nonce' => false
537
-            ),
538
-            'custom_mtps'              => array(
539
-                'nav'           => array(
540
-                    'label' => __('Custom Message Templates', 'event_espresso'),
541
-                    'order' => 30
542
-                ),
543
-                'help_tabs'     => array(),
544
-                'help_tour'     => array(),
545
-                'require_nonce' => false
546
-            ),
547
-            'add_new_message_template' => array(
548
-                'nav'           => array(
549
-                    'label'      => __('Add New Message Templates', 'event_espresso'),
550
-                    'order'      => 5,
551
-                    'persistent' => false
552
-                ),
553
-                'require_nonce' => false
554
-            ),
555
-            'edit_message_template'    => array(
556
-                'labels'        => array(
557
-                    'buttons'    => array(
558
-                        'reset' => __('Reset Templates'),
559
-                    ),
560
-                    'publishbox' => __('Update Actions', 'event_espresso')
561
-                ),
562
-                'nav'           => array(
563
-                    'label'      => __('Edit Message Templates', 'event_espresso'),
564
-                    'order'      => 5,
565
-                    'persistent' => false,
566
-                    'url'        => ''
567
-                ),
568
-                'metaboxes'     => array('_publish_post_box', '_register_edit_meta_boxes'),
569
-                'has_metaboxes' => true,
570
-                'help_tour'     => array('Message_Templates_Edit_Help_Tour'),
571
-                'help_tabs'     => array(
572
-                    'edit_message_template'       => array(
573
-                        'title'    => __('Message Template Editor', 'event_espresso'),
574
-                        'callback' => 'edit_message_template_help_tab'
575
-                    ),
576
-                    'message_templates_help_tab'  => array(
577
-                        'title'    => __('Message Templates', 'event_espresso'),
578
-                        'filename' => 'messages_templates'
579
-                    ),
580
-                    'message_template_shortcodes' => array(
581
-                        'title'    => __('Message Shortcodes', 'event_espresso'),
582
-                        'callback' => 'message_template_shortcodes_help_tab'
583
-                    ),
584
-                    'message_preview_help_tab'    => array(
585
-                        'title'    => __('Message Preview', 'event_espresso'),
586
-                        'filename' => 'messages_preview'
587
-                    ),
588
-                ),
589
-                'require_nonce' => false
590
-            ),
591
-            'display_preview_message'  => array(
592
-                'nav'           => array(
593
-                    'label'      => __('Message Preview', 'event_espresso'),
594
-                    'order'      => 5,
595
-                    'url'        => '',
596
-                    'persistent' => false
597
-                ),
598
-                'help_tabs'     => array(
599
-                    'preview_message' => array(
600
-                        'title'    => __('About Previews', 'event_espresso'),
601
-                        'callback' => 'preview_message_help_tab'
602
-                    )
603
-                ),
604
-                'require_nonce' => false
605
-            ),
606
-            'settings'                 => array(
607
-                'nav'           => array(
608
-                    'label' => __('Settings', 'event_espresso'),
609
-                    'order' => 40
610
-                ),
611
-                'metaboxes'     => array('_messages_settings_metaboxes'),
612
-                'help_tabs'     => array(
613
-                    'messages_settings_help_tab'               => array(
614
-                        'title'    => __('Messages Settings', 'event_espresso'),
615
-                        'filename' => 'messages_settings'
616
-                    ),
617
-                    'messages_settings_message_types_help_tab' => array(
618
-                        'title'    => __('Activating / Deactivating Message Types', 'event_espresso'),
619
-                        'filename' => 'messages_settings_message_types'
620
-                    ),
621
-                    'messages_settings_messengers_help_tab'    => array(
622
-                        'title'    => __('Activating / Deactivating Messengers', 'event_espresso'),
623
-                        'filename' => 'messages_settings_messengers'
624
-                    ),
625
-                ),
626
-                'help_tour'     => array('Messages_Settings_Help_Tour'),
627
-                'require_nonce' => false
628
-            )
629
-        );
630
-    }
631
-    
632
-    
633
-    protected function _add_screen_options()
634
-    {
635
-        //todo
636
-    }
637
-    
638
-    
639
-    protected function _add_screen_options_global_mtps()
640
-    {
641
-        /**
642
-         * Note: the reason for the value swap here on $this->_admin_page_title is because $this->_per_page_screen_options
643
-         * uses the $_admin_page_title property and we want different outputs in the different spots.
644
-         */
645
-        $page_title              = $this->_admin_page_title;
646
-        $this->_admin_page_title = __('Global Message Templates', 'event_espresso');
647
-        $this->_per_page_screen_option();
648
-        $this->_admin_page_title = $page_title;
649
-    }
650
-    
651
-    
652
-    protected function _add_screen_options_default()
653
-    {
654
-        $this->_admin_page_title = __('Message Activity', 'event_espresso');
655
-        $this->_per_page_screen_option();
656
-    }
657
-    
658
-    
659
-    //none of the below group are currently used for Messages
660
-    protected function _add_feature_pointers()
661
-    {
662
-    }
663
-    
664
-    public function admin_init()
665
-    {
666
-    }
667
-    
668
-    public function admin_notices()
669
-    {
670
-    }
671
-    
672
-    public function admin_footer_scripts()
673
-    {
674
-    }
675
-    
676
-    
677
-    public function messages_help_tab()
678
-    {
679
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
680
-    }
681
-    
682
-    
683
-    public function messengers_help_tab()
684
-    {
685
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
686
-    }
687
-    
688
-    
689
-    public function message_types_help_tab()
690
-    {
691
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
692
-    }
693
-    
694
-    
695
-    public function messages_overview_help_tab()
696
-    {
697
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
698
-    }
699
-    
700
-    
701
-    public function message_templates_help_tab()
702
-    {
703
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
704
-    }
705
-    
706
-    
707
-    public function edit_message_template_help_tab()
708
-    {
709
-        $args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="' . esc_attr__('Editor Title',
710
-                'event_espresso') . '" />';
711
-        $args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="' . esc_attr__('Context Switcher and Preview',
712
-                'event_espresso') . '" />';
713
-        $args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="' . esc_attr__('Message Template Form Fields',
714
-                'event_espresso') . '" />';
715
-        $args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="' . esc_attr__('Shortcodes Metabox',
716
-                'event_espresso') . '" />';
717
-        $args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="' . esc_attr__('Publish Metabox',
718
-                'event_espresso') . '" />';
719
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
720
-            $args);
721
-    }
722
-    
723
-    
724
-    public function message_template_shortcodes_help_tab()
725
-    {
726
-        $this->_set_shortcodes();
727
-        $args['shortcodes'] = $this->_shortcodes;
728
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
729
-            $args);
730
-    }
179
+			'4.9.9.rc.014'
180
+		);
181
+        
182
+		$contexts                = array();
183
+		$active_message_contexts = EEM_Message::instance()->get_all(array('group_by' => 'MSG_context'));
184
+		foreach ($active_message_contexts as $active_message) {
185
+			if ($active_message instanceof EE_Message) {
186
+				$message_type = $active_message->message_type_object();
187
+				if ($message_type instanceof EE_message_type) {
188
+					$message_type_contexts = $message_type->get_contexts();
189
+					foreach ($message_type_contexts as $context => $context_details) {
190
+						$contexts[$context] = $context_details['label'];
191
+					}
192
+				}
193
+			}
194
+		}
195
+        
196
+		return $contexts;
197
+	}
198
+    
199
+    
200
+	/**
201
+	 * Generate select input with provided messenger options array.
202
+	 *
203
+	 * @param array $messenger_options Array of messengers indexed by messenger slug and values are the messenger
204
+	 *                                 labels.
205
+	 *
206
+	 * @return string
207
+	 */
208
+	public function get_messengers_select_input($messenger_options)
209
+	{
210
+		//if empty or just one value then just return an empty string
211
+		if (empty($messenger_options)
212
+			|| ! is_array($messenger_options)
213
+			|| count($messenger_options) === 1
214
+		) {
215
+			return '';
216
+		}
217
+		//merge in default
218
+		$messenger_options = array_merge(
219
+			array('none_selected' => __('Show All Messengers', 'event_espresso')),
220
+			$messenger_options
221
+		);
222
+		$input             = new EE_Select_Input(
223
+			$messenger_options,
224
+			array(
225
+				'html_name'  => 'ee_messenger_filter_by',
226
+				'html_id'    => 'ee_messenger_filter_by',
227
+				'html_class' => 'wide',
228
+				'default'    => isset($this->_req_data['ee_messenger_filter_by'])
229
+					? sanitize_title($this->_req_data['ee_messenger_filter_by'])
230
+					: 'none_selected'
231
+			)
232
+		);
233
+        
234
+		return $input->get_html_for_input();
235
+	}
236
+    
237
+    
238
+	/**
239
+	 * Generate select input with provided message type options array.
240
+	 *
241
+	 * @param array $message_type_options Array of message types indexed by message type slug, and values are the
242
+	 *                                    message type labels
243
+	 *
244
+	 * @return string
245
+	 */
246
+	public function get_message_types_select_input($message_type_options)
247
+	{
248
+		//if empty or count of options is 1 then just return an empty string
249
+		if (empty($message_type_options)
250
+			|| ! is_array($message_type_options)
251
+			|| count($message_type_options) === 1
252
+		) {
253
+			return '';
254
+		}
255
+		//merge in default
256
+		$message_type_options = array_merge(
257
+			array('none_selected' => __('Show All Message Types', 'event_espresso')),
258
+			$message_type_options
259
+		);
260
+		$input                = new EE_Select_Input(
261
+			$message_type_options,
262
+			array(
263
+				'html_name'  => 'ee_message_type_filter_by',
264
+				'html_id'    => 'ee_message_type_filter_by',
265
+				'html_class' => 'wide',
266
+				'default'    => isset($this->_req_data['ee_message_type_filter_by'])
267
+					? sanitize_title($this->_req_data['ee_message_type_filter_by'])
268
+					: 'none_selected',
269
+			)
270
+		);
271
+        
272
+		return $input->get_html_for_input();
273
+	}
274
+    
275
+    
276
+	/**
277
+	 * Generate select input with provide message type contexts array.
278
+	 *
279
+	 * @param array $context_options Array of message type contexts indexed by context slug, and values are the
280
+	 *                               context label.
281
+	 *
282
+	 * @return string
283
+	 */
284
+	public function get_contexts_for_message_types_select_input($context_options)
285
+	{
286
+		//if empty or count of options is one then just return empty string
287
+		if (empty($context_options)
288
+			|| ! is_array($context_options)
289
+			|| count($context_options) === 1
290
+		) {
291
+			return '';
292
+		}
293
+		//merge in default
294
+		$context_options = array_merge(
295
+			array('none_selected' => __('Show all Contexts', 'event_espresso')),
296
+			$context_options
297
+		);
298
+		$input           = new EE_Select_Input(
299
+			$context_options,
300
+			array(
301
+				'html_name'  => 'ee_context_filter_by',
302
+				'html_id'    => 'ee_context_filter_by',
303
+				'html_class' => 'wide',
304
+				'default'    => isset($this->_req_data['ee_context_filter_by'])
305
+					? sanitize_title($this->_req_data['ee_context_filter_by'])
306
+					: 'none_selected',
307
+			)
308
+		);
309
+        
310
+		return $input->get_html_for_input();
311
+	}
312
+    
313
+    
314
+	protected function _ajax_hooks()
315
+	{
316
+		add_action('wp_ajax_activate_messenger', array($this, 'activate_messenger_toggle'));
317
+		add_action('wp_ajax_activate_mt', array($this, 'activate_mt_toggle'));
318
+		add_action('wp_ajax_ee_msgs_save_settings', array($this, 'save_settings'));
319
+		add_action('wp_ajax_ee_msgs_update_mt_form', array($this, 'update_mt_form'));
320
+		add_action('wp_ajax_switch_template_pack', array($this, 'switch_template_pack'));
321
+	}
322
+    
323
+    
324
+	protected function _define_page_props()
325
+	{
326
+		$this->_admin_page_title = $this->page_label;
327
+		$this->_labels           = array(
328
+			'buttons'    => array(
329
+				'add'    => __('Add New Message Template', 'event_espresso'),
330
+				'edit'   => __('Edit Message Template', 'event_espresso'),
331
+				'delete' => __('Delete Message Template', 'event_espresso')
332
+			),
333
+			'publishbox' => __('Update Actions', 'event_espresso')
334
+		);
335
+	}
336
+    
337
+    
338
+	/**
339
+	 *        an array for storing key => value pairs of request actions and their corresponding methods
340
+	 * @access protected
341
+	 * @return void
342
+	 */
343
+	protected function _set_page_routes()
344
+	{
345
+		$grp_id = ! empty($this->_req_data['GRP_ID']) && ! is_array($this->_req_data['GRP_ID'])
346
+			? $this->_req_data['GRP_ID']
347
+			: 0;
348
+		$grp_id = empty($grp_id) && ! empty($this->_req_data['id'])
349
+			? $this->_req_data['id']
350
+			: $grp_id;
351
+		$msg_id = ! empty($this->_req_data['MSG_ID']) && ! is_array($this->_req_data['MSG_ID'])
352
+			? $this->_req_data['MSG_ID']
353
+			: 0;
354
+        
355
+		$this->_page_routes = array(
356
+			'default'                          => array(
357
+				'func'       => '_message_queue_list_table',
358
+				'capability' => 'ee_read_global_messages'
359
+			),
360
+			'global_mtps'                      => array(
361
+				'func'       => '_ee_default_messages_overview_list_table',
362
+				'capability' => 'ee_read_global_messages'
363
+			),
364
+			'custom_mtps'                      => array(
365
+				'func'       => '_custom_mtps_preview',
366
+				'capability' => 'ee_read_messages'
367
+			),
368
+			'add_new_message_template'         => array(
369
+				'func'       => '_add_message_template',
370
+				'capability' => 'ee_edit_messages',
371
+				'noheader'   => true
372
+			),
373
+			'edit_message_template'            => array(
374
+				'func'       => '_edit_message_template',
375
+				'capability' => 'ee_edit_message',
376
+				'obj_id'     => $grp_id
377
+			),
378
+			'preview_message'                  => array(
379
+				'func'               => '_preview_message',
380
+				'capability'         => 'ee_read_message',
381
+				'obj_id'             => $grp_id,
382
+				'noheader'           => true,
383
+				'headers_sent_route' => 'display_preview_message'
384
+			),
385
+			'display_preview_message'          => array(
386
+				'func'       => '_display_preview_message',
387
+				'capability' => 'ee_read_message',
388
+				'obj_id'     => $grp_id
389
+			),
390
+			'insert_message_template'          => array(
391
+				'func'       => '_insert_or_update_message_template',
392
+				'capability' => 'ee_edit_messages',
393
+				'args'       => array('new_template' => true),
394
+				'noheader'   => true
395
+			),
396
+			'update_message_template'          => array(
397
+				'func'       => '_insert_or_update_message_template',
398
+				'capability' => 'ee_edit_message',
399
+				'obj_id'     => $grp_id,
400
+				'args'       => array('new_template' => false),
401
+				'noheader'   => true
402
+			),
403
+			'trash_message_template'           => array(
404
+				'func'       => '_trash_or_restore_message_template',
405
+				'capability' => 'ee_delete_message',
406
+				'obj_id'     => $grp_id,
407
+				'args'       => array('trash' => true, 'all' => true),
408
+				'noheader'   => true
409
+			),
410
+			'trash_message_template_context'   => array(
411
+				'func'       => '_trash_or_restore_message_template',
412
+				'capability' => 'ee_delete_message',
413
+				'obj_id'     => $grp_id,
414
+				'args'       => array('trash' => true),
415
+				'noheader'   => true
416
+			),
417
+			'restore_message_template'         => array(
418
+				'func'       => '_trash_or_restore_message_template',
419
+				'capability' => 'ee_delete_message',
420
+				'obj_id'     => $grp_id,
421
+				'args'       => array('trash' => false, 'all' => true),
422
+				'noheader'   => true
423
+			),
424
+			'restore_message_template_context' => array(
425
+				'func'       => '_trash_or_restore_message_template',
426
+				'capability' => 'ee_delete_message',
427
+				'obj_id'     => $grp_id,
428
+				'args'       => array('trash' => false),
429
+				'noheader'   => true
430
+			),
431
+			'delete_message_template'          => array(
432
+				'func'       => '_delete_message_template',
433
+				'capability' => 'ee_delete_message',
434
+				'obj_id'     => $grp_id,
435
+				'noheader'   => true
436
+			),
437
+			'reset_to_default'                 => array(
438
+				'func'       => '_reset_to_default_template',
439
+				'capability' => 'ee_edit_message',
440
+				'obj_id'     => $grp_id,
441
+				'noheader'   => true
442
+			),
443
+			'settings'                         => array(
444
+				'func'       => '_settings',
445
+				'capability' => 'manage_options'
446
+			),
447
+			'update_global_settings'           => array(
448
+				'func'       => '_update_global_settings',
449
+				'capability' => 'manage_options',
450
+				'noheader'   => true
451
+			),
452
+			'generate_now'                     => array(
453
+				'func'       => '_generate_now',
454
+				'capability' => 'ee_send_message',
455
+				'noheader'   => true
456
+			),
457
+			'generate_and_send_now'            => array(
458
+				'func'       => '_generate_and_send_now',
459
+				'capability' => 'ee_send_message',
460
+				'noheader'   => true
461
+			),
462
+			'queue_for_resending'              => array(
463
+				'func'       => '_queue_for_resending',
464
+				'capability' => 'ee_send_message',
465
+				'noheader'   => true
466
+			),
467
+			'send_now'                         => array(
468
+				'func'       => '_send_now',
469
+				'capability' => 'ee_send_message',
470
+				'noheader'   => true
471
+			),
472
+			'delete_ee_message'                => array(
473
+				'func'       => '_delete_ee_messages',
474
+				'capability' => 'ee_delete_message',
475
+				'noheader'   => true
476
+			),
477
+			'delete_ee_messages'               => array(
478
+				'func'       => '_delete_ee_messages',
479
+				'capability' => 'ee_delete_messages',
480
+				'noheader'   => true,
481
+				'obj_id'     => $msg_id
482
+			)
483
+		);
484
+	}
485
+    
486
+    
487
+	protected function _set_page_config()
488
+	{
489
+		$this->_page_config = array(
490
+			'default'                  => array(
491
+				'nav'           => array(
492
+					'label' => __('Message Activity', 'event_espresso'),
493
+					'order' => 10
494
+				),
495
+				'list_table'    => 'EE_Message_List_Table',
496
+				// 'qtips' => array( 'EE_Message_List_Table_Tips' ),
497
+				'require_nonce' => false
498
+			),
499
+			'global_mtps'              => array(
500
+				'nav'           => array(
501
+					'label' => __('Default Message Templates', 'event_espresso'),
502
+					'order' => 20
503
+				),
504
+				'list_table'    => 'Messages_Template_List_Table',
505
+				'help_tabs'     => array(
506
+					'messages_overview_help_tab'                                => array(
507
+						'title'    => __('Messages Overview', 'event_espresso'),
508
+						'filename' => 'messages_overview'
509
+					),
510
+					'messages_overview_messages_table_column_headings_help_tab' => array(
511
+						'title'    => __('Messages Table Column Headings', 'event_espresso'),
512
+						'filename' => 'messages_overview_table_column_headings'
513
+					),
514
+					'messages_overview_messages_filters_help_tab'               => array(
515
+						'title'    => __('Message Filters', 'event_espresso'),
516
+						'filename' => 'messages_overview_filters'
517
+					),
518
+					'messages_overview_messages_views_help_tab'                 => array(
519
+						'title'    => __('Message Views', 'event_espresso'),
520
+						'filename' => 'messages_overview_views'
521
+					),
522
+					'message_overview_message_types_help_tab'                   => array(
523
+						'title'    => __('Message Types', 'event_espresso'),
524
+						'filename' => 'messages_overview_types'
525
+					),
526
+					'messages_overview_messengers_help_tab'                     => array(
527
+						'title'    => __('Messengers', 'event_espresso'),
528
+						'filename' => 'messages_overview_messengers',
529
+					),
530
+					'messages_overview_other_help_tab'                          => array(
531
+						'title'    => __('Messages Other', 'event_espresso'),
532
+						'filename' => 'messages_overview_other',
533
+					),
534
+				),
535
+				'help_tour'     => array('Messages_Overview_Help_Tour'),
536
+				'require_nonce' => false
537
+			),
538
+			'custom_mtps'              => array(
539
+				'nav'           => array(
540
+					'label' => __('Custom Message Templates', 'event_espresso'),
541
+					'order' => 30
542
+				),
543
+				'help_tabs'     => array(),
544
+				'help_tour'     => array(),
545
+				'require_nonce' => false
546
+			),
547
+			'add_new_message_template' => array(
548
+				'nav'           => array(
549
+					'label'      => __('Add New Message Templates', 'event_espresso'),
550
+					'order'      => 5,
551
+					'persistent' => false
552
+				),
553
+				'require_nonce' => false
554
+			),
555
+			'edit_message_template'    => array(
556
+				'labels'        => array(
557
+					'buttons'    => array(
558
+						'reset' => __('Reset Templates'),
559
+					),
560
+					'publishbox' => __('Update Actions', 'event_espresso')
561
+				),
562
+				'nav'           => array(
563
+					'label'      => __('Edit Message Templates', 'event_espresso'),
564
+					'order'      => 5,
565
+					'persistent' => false,
566
+					'url'        => ''
567
+				),
568
+				'metaboxes'     => array('_publish_post_box', '_register_edit_meta_boxes'),
569
+				'has_metaboxes' => true,
570
+				'help_tour'     => array('Message_Templates_Edit_Help_Tour'),
571
+				'help_tabs'     => array(
572
+					'edit_message_template'       => array(
573
+						'title'    => __('Message Template Editor', 'event_espresso'),
574
+						'callback' => 'edit_message_template_help_tab'
575
+					),
576
+					'message_templates_help_tab'  => array(
577
+						'title'    => __('Message Templates', 'event_espresso'),
578
+						'filename' => 'messages_templates'
579
+					),
580
+					'message_template_shortcodes' => array(
581
+						'title'    => __('Message Shortcodes', 'event_espresso'),
582
+						'callback' => 'message_template_shortcodes_help_tab'
583
+					),
584
+					'message_preview_help_tab'    => array(
585
+						'title'    => __('Message Preview', 'event_espresso'),
586
+						'filename' => 'messages_preview'
587
+					),
588
+				),
589
+				'require_nonce' => false
590
+			),
591
+			'display_preview_message'  => array(
592
+				'nav'           => array(
593
+					'label'      => __('Message Preview', 'event_espresso'),
594
+					'order'      => 5,
595
+					'url'        => '',
596
+					'persistent' => false
597
+				),
598
+				'help_tabs'     => array(
599
+					'preview_message' => array(
600
+						'title'    => __('About Previews', 'event_espresso'),
601
+						'callback' => 'preview_message_help_tab'
602
+					)
603
+				),
604
+				'require_nonce' => false
605
+			),
606
+			'settings'                 => array(
607
+				'nav'           => array(
608
+					'label' => __('Settings', 'event_espresso'),
609
+					'order' => 40
610
+				),
611
+				'metaboxes'     => array('_messages_settings_metaboxes'),
612
+				'help_tabs'     => array(
613
+					'messages_settings_help_tab'               => array(
614
+						'title'    => __('Messages Settings', 'event_espresso'),
615
+						'filename' => 'messages_settings'
616
+					),
617
+					'messages_settings_message_types_help_tab' => array(
618
+						'title'    => __('Activating / Deactivating Message Types', 'event_espresso'),
619
+						'filename' => 'messages_settings_message_types'
620
+					),
621
+					'messages_settings_messengers_help_tab'    => array(
622
+						'title'    => __('Activating / Deactivating Messengers', 'event_espresso'),
623
+						'filename' => 'messages_settings_messengers'
624
+					),
625
+				),
626
+				'help_tour'     => array('Messages_Settings_Help_Tour'),
627
+				'require_nonce' => false
628
+			)
629
+		);
630
+	}
631
+    
632
+    
633
+	protected function _add_screen_options()
634
+	{
635
+		//todo
636
+	}
637
+    
638
+    
639
+	protected function _add_screen_options_global_mtps()
640
+	{
641
+		/**
642
+		 * Note: the reason for the value swap here on $this->_admin_page_title is because $this->_per_page_screen_options
643
+		 * uses the $_admin_page_title property and we want different outputs in the different spots.
644
+		 */
645
+		$page_title              = $this->_admin_page_title;
646
+		$this->_admin_page_title = __('Global Message Templates', 'event_espresso');
647
+		$this->_per_page_screen_option();
648
+		$this->_admin_page_title = $page_title;
649
+	}
650
+    
651
+    
652
+	protected function _add_screen_options_default()
653
+	{
654
+		$this->_admin_page_title = __('Message Activity', 'event_espresso');
655
+		$this->_per_page_screen_option();
656
+	}
657
+    
658
+    
659
+	//none of the below group are currently used for Messages
660
+	protected function _add_feature_pointers()
661
+	{
662
+	}
663
+    
664
+	public function admin_init()
665
+	{
666
+	}
667
+    
668
+	public function admin_notices()
669
+	{
670
+	}
671
+    
672
+	public function admin_footer_scripts()
673
+	{
674
+	}
675
+    
676
+    
677
+	public function messages_help_tab()
678
+	{
679
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
680
+	}
681
+    
682
+    
683
+	public function messengers_help_tab()
684
+	{
685
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
686
+	}
687
+    
688
+    
689
+	public function message_types_help_tab()
690
+	{
691
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
692
+	}
693
+    
694
+    
695
+	public function messages_overview_help_tab()
696
+	{
697
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
698
+	}
699
+    
700
+    
701
+	public function message_templates_help_tab()
702
+	{
703
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
704
+	}
705
+    
706
+    
707
+	public function edit_message_template_help_tab()
708
+	{
709
+		$args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="' . esc_attr__('Editor Title',
710
+				'event_espresso') . '" />';
711
+		$args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="' . esc_attr__('Context Switcher and Preview',
712
+				'event_espresso') . '" />';
713
+		$args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="' . esc_attr__('Message Template Form Fields',
714
+				'event_espresso') . '" />';
715
+		$args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="' . esc_attr__('Shortcodes Metabox',
716
+				'event_espresso') . '" />';
717
+		$args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="' . esc_attr__('Publish Metabox',
718
+				'event_espresso') . '" />';
719
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
720
+			$args);
721
+	}
722
+    
723
+    
724
+	public function message_template_shortcodes_help_tab()
725
+	{
726
+		$this->_set_shortcodes();
727
+		$args['shortcodes'] = $this->_shortcodes;
728
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
729
+			$args);
730
+	}
731 731
     
732 732
     
733
-    public function preview_message_help_tab()
734
-    {
735
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
736
-    }
733
+	public function preview_message_help_tab()
734
+	{
735
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
736
+	}
737 737
     
738
-    
739
-    public function settings_help_tab()
740
-    {
741
-        $args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png' . '" alt="' . esc_attr__('Active Email Tab',
742
-                'event_espresso') . '" />';
743
-        $args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png' . '" alt="' . esc_attr__('Inactive Email Tab',
744
-                'event_espresso') . '" />';
745
-        $args['img3'] = '<div class="switch"><input id="ee-on-off-toggle-on" class="ee-on-off-toggle ee-toggle-round-flat" type="checkbox" checked="checked"><label for="ee-on-off-toggle-on"></label>';
746
-        $args['img4'] = '<div class="switch"><input id="ee-on-off-toggle-on" class="ee-on-off-toggle ee-toggle-round-flat" type="checkbox"><label for="ee-on-off-toggle-on"></label>';
747
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
748
-    }
738
+    
739
+	public function settings_help_tab()
740
+	{
741
+		$args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png' . '" alt="' . esc_attr__('Active Email Tab',
742
+				'event_espresso') . '" />';
743
+		$args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png' . '" alt="' . esc_attr__('Inactive Email Tab',
744
+				'event_espresso') . '" />';
745
+		$args['img3'] = '<div class="switch"><input id="ee-on-off-toggle-on" class="ee-on-off-toggle ee-toggle-round-flat" type="checkbox" checked="checked"><label for="ee-on-off-toggle-on"></label>';
746
+		$args['img4'] = '<div class="switch"><input id="ee-on-off-toggle-on" class="ee-on-off-toggle ee-toggle-round-flat" type="checkbox"><label for="ee-on-off-toggle-on"></label>';
747
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
748
+	}
749 749
     
750 750
     
751
-    public function load_scripts_styles()
752
-    {
753
-        wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
754
-        wp_enqueue_style('espresso_ee_msg');
751
+	public function load_scripts_styles()
752
+	{
753
+		wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
754
+		wp_enqueue_style('espresso_ee_msg');
755 755
         
756
-        wp_register_script('ee-messages-settings', EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
757
-            array('jquery-ui-droppable', 'ee-serialize-full-array'), EVENT_ESPRESSO_VERSION, true);
758
-        wp_register_script('ee-msg-list-table-js', EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
759
-            array('ee-dialog'), EVENT_ESPRESSO_VERSION);
760
-    }
756
+		wp_register_script('ee-messages-settings', EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
757
+			array('jquery-ui-droppable', 'ee-serialize-full-array'), EVENT_ESPRESSO_VERSION, true);
758
+		wp_register_script('ee-msg-list-table-js', EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
759
+			array('ee-dialog'), EVENT_ESPRESSO_VERSION);
760
+	}
761 761
     
762 762
     
763
-    public function load_scripts_styles_default()
764
-    {
765
-        wp_enqueue_script('ee-msg-list-table-js');
766
-    }
763
+	public function load_scripts_styles_default()
764
+	{
765
+		wp_enqueue_script('ee-msg-list-table-js');
766
+	}
767 767
     
768 768
     
769
-    public function wp_editor_css($mce_css)
770
-    {
771
-        //if we're on the edit_message_template route
772
-        if ($this->_req_action == 'edit_message_template' && $this->_active_messenger instanceof EE_messenger) {
773
-            $message_type_name = $this->_active_message_type_name;
769
+	public function wp_editor_css($mce_css)
770
+	{
771
+		//if we're on the edit_message_template route
772
+		if ($this->_req_action == 'edit_message_template' && $this->_active_messenger instanceof EE_messenger) {
773
+			$message_type_name = $this->_active_message_type_name;
774 774
             
775
-            //we're going to REPLACE the existing mce css
776
-            //we need to get the css file location from the active messenger
777
-            $mce_css = $this->_active_messenger->get_variation($this->_template_pack, $message_type_name, true,
778
-                'wpeditor', $this->_variation);
779
-        }
775
+			//we're going to REPLACE the existing mce css
776
+			//we need to get the css file location from the active messenger
777
+			$mce_css = $this->_active_messenger->get_variation($this->_template_pack, $message_type_name, true,
778
+				'wpeditor', $this->_variation);
779
+		}
780 780
         
781
-        return $mce_css;
782
-    }
783
-    
784
-    
785
-    public function load_scripts_styles_edit_message_template()
786
-    {
787
-        
788
-        $this->_set_shortcodes();
781
+		return $mce_css;
782
+	}
783
+    
784
+    
785
+	public function load_scripts_styles_edit_message_template()
786
+	{
787
+        
788
+		$this->_set_shortcodes();
789 789
         
790
-        EE_Registry::$i18n_js_strings['confirm_default_reset']        = sprintf(
791
-            __('Are you sure you want to reset the %s %s message templates?  Remember continuing will reset the templates for all contexts in this messenger and message type group.',
792
-                'event_espresso'),
793
-            $this->_message_template_group->messenger_obj()->label['singular'],
794
-            $this->_message_template_group->message_type_obj()->label['singular']
795
-        );
796
-        EE_Registry::$i18n_js_strings['confirm_switch_template_pack'] = __('Switching the template pack for a messages template will reset the content for the template so the new layout is loaded.  Any custom content in the existing template will be lost. Are you sure you wish to do this?',
797
-            'event_espresso');
798
-        
799
-        wp_register_script('ee_msgs_edit_js', EE_MSG_ASSETS_URL . 'ee_message_editor.js', array('jquery'),
800
-            EVENT_ESPRESSO_VERSION);
801
-        
802
-        wp_enqueue_script('ee_admin_js');
803
-        wp_enqueue_script('ee_msgs_edit_js');
804
-        
805
-        //add in special css for tiny_mce
806
-        add_filter('mce_css', array($this, 'wp_editor_css'));
807
-    }
808
-    
809
-    
810
-    public function load_scripts_styles_display_preview_message()
811
-    {
812
-        
813
-        $this->_set_message_template_group();
814
-        
815
-        if (isset($this->_req_data['messenger'])) {
816
-            $this->_active_messenger = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
817
-        }
818
-        
819
-        $message_type_name = isset($this->_req_data['message_type']) ? $this->_req_data['message_type'] : '';
820
-        
821
-        
822
-        wp_enqueue_style('espresso_preview_css',
823
-            $this->_active_messenger->get_variation($this->_template_pack, $message_type_name, true, 'preview',
824
-                $this->_variation));
825
-    }
826
-    
827
-    
828
-    public function load_scripts_styles_settings()
829
-    {
830
-        wp_register_style('ee-message-settings', EE_MSG_ASSETS_URL . 'ee_message_settings.css', array(),
831
-            EVENT_ESPRESSO_VERSION);
832
-        wp_enqueue_style('ee-text-links');
833
-        wp_enqueue_style('ee-message-settings');
834
-        
835
-        wp_enqueue_script('ee-messages-settings');
836
-    }
837
-    
838
-    
839
-    /**
840
-     * set views array for List Table
841
-     */
842
-    public function _set_list_table_views_global_mtps()
843
-    {
844
-        $this->_views = array(
845
-            'in_use' => array(
846
-                'slug'        => 'in_use',
847
-                'label'       => __('In Use', 'event_espresso'),
848
-                'count'       => 0,
849
-                'bulk_action' => array(
850
-                    'trash_message_template' => __('Move to Trash', 'event_espresso')
851
-                )
852
-            )
853
-        );
854
-    }
855
-    
856
-    
857
-    /**
858
-     * set views array for message queue list table
859
-     */
860
-    public function _set_list_table_views_default()
861
-    {
862
-        EE_Registry::instance()->load_helper('Template');
863
-        
864
-        $common_bulk_actions = EE_Registry::instance()->CAP->current_user_can('ee_send_message',
865
-            'message_list_table_bulk_actions')
866
-            ? array(
867
-                'generate_now'          => __('Generate Now', 'event_espresso'),
868
-                'generate_and_send_now' => __('Generate and Send Now', 'event_espresso'),
869
-                'queue_for_resending'   => __('Queue for Resending', 'event_espresso'),
870
-                'send_now'              => __('Send Now', 'event_espresso')
871
-            )
872
-            : array();
873
-        
874
-        $delete_bulk_action = EE_Registry::instance()->CAP->current_user_can('ee_delete_messages',
875
-            'message_list_table_bulk_actions')
876
-            ? array('delete_ee_messages' => __('Delete Messages', 'event_espresso'))
877
-            : array();
878
-        
879
-        
880
-        $this->_views = array(
881
-            'all' => array(
882
-                'slug'        => 'all',
883
-                'label'       => __('All', 'event_espresso'),
884
-                'count'       => 0,
885
-                'bulk_action' => array_merge($common_bulk_actions, $delete_bulk_action)
886
-            )
887
-        );
888
-        
889
-        
890
-        foreach (EEM_Message::instance()->all_statuses() as $status) {
891
-            if ($status === EEM_Message::status_debug_only && ! EEM_Message::debug()) {
892
-                continue;
893
-            }
894
-            $status_bulk_actions = $common_bulk_actions;
895
-            //unset bulk actions not applying to status
896
-            if (! empty($status_bulk_actions)) {
897
-                switch ($status) {
898
-                    case EEM_Message::status_idle:
899
-                    case EEM_Message::status_resend:
900
-                        $status_bulk_actions['send_now'] = $common_bulk_actions['send_now'];
901
-                        break;
790
+		EE_Registry::$i18n_js_strings['confirm_default_reset']        = sprintf(
791
+			__('Are you sure you want to reset the %s %s message templates?  Remember continuing will reset the templates for all contexts in this messenger and message type group.',
792
+				'event_espresso'),
793
+			$this->_message_template_group->messenger_obj()->label['singular'],
794
+			$this->_message_template_group->message_type_obj()->label['singular']
795
+		);
796
+		EE_Registry::$i18n_js_strings['confirm_switch_template_pack'] = __('Switching the template pack for a messages template will reset the content for the template so the new layout is loaded.  Any custom content in the existing template will be lost. Are you sure you wish to do this?',
797
+			'event_espresso');
798
+        
799
+		wp_register_script('ee_msgs_edit_js', EE_MSG_ASSETS_URL . 'ee_message_editor.js', array('jquery'),
800
+			EVENT_ESPRESSO_VERSION);
801
+        
802
+		wp_enqueue_script('ee_admin_js');
803
+		wp_enqueue_script('ee_msgs_edit_js');
804
+        
805
+		//add in special css for tiny_mce
806
+		add_filter('mce_css', array($this, 'wp_editor_css'));
807
+	}
808
+    
809
+    
810
+	public function load_scripts_styles_display_preview_message()
811
+	{
812
+        
813
+		$this->_set_message_template_group();
814
+        
815
+		if (isset($this->_req_data['messenger'])) {
816
+			$this->_active_messenger = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
817
+		}
818
+        
819
+		$message_type_name = isset($this->_req_data['message_type']) ? $this->_req_data['message_type'] : '';
820
+        
821
+        
822
+		wp_enqueue_style('espresso_preview_css',
823
+			$this->_active_messenger->get_variation($this->_template_pack, $message_type_name, true, 'preview',
824
+				$this->_variation));
825
+	}
826
+    
827
+    
828
+	public function load_scripts_styles_settings()
829
+	{
830
+		wp_register_style('ee-message-settings', EE_MSG_ASSETS_URL . 'ee_message_settings.css', array(),
831
+			EVENT_ESPRESSO_VERSION);
832
+		wp_enqueue_style('ee-text-links');
833
+		wp_enqueue_style('ee-message-settings');
834
+        
835
+		wp_enqueue_script('ee-messages-settings');
836
+	}
837
+    
838
+    
839
+	/**
840
+	 * set views array for List Table
841
+	 */
842
+	public function _set_list_table_views_global_mtps()
843
+	{
844
+		$this->_views = array(
845
+			'in_use' => array(
846
+				'slug'        => 'in_use',
847
+				'label'       => __('In Use', 'event_espresso'),
848
+				'count'       => 0,
849
+				'bulk_action' => array(
850
+					'trash_message_template' => __('Move to Trash', 'event_espresso')
851
+				)
852
+			)
853
+		);
854
+	}
855
+    
856
+    
857
+	/**
858
+	 * set views array for message queue list table
859
+	 */
860
+	public function _set_list_table_views_default()
861
+	{
862
+		EE_Registry::instance()->load_helper('Template');
863
+        
864
+		$common_bulk_actions = EE_Registry::instance()->CAP->current_user_can('ee_send_message',
865
+			'message_list_table_bulk_actions')
866
+			? array(
867
+				'generate_now'          => __('Generate Now', 'event_espresso'),
868
+				'generate_and_send_now' => __('Generate and Send Now', 'event_espresso'),
869
+				'queue_for_resending'   => __('Queue for Resending', 'event_espresso'),
870
+				'send_now'              => __('Send Now', 'event_espresso')
871
+			)
872
+			: array();
873
+        
874
+		$delete_bulk_action = EE_Registry::instance()->CAP->current_user_can('ee_delete_messages',
875
+			'message_list_table_bulk_actions')
876
+			? array('delete_ee_messages' => __('Delete Messages', 'event_espresso'))
877
+			: array();
878
+        
879
+        
880
+		$this->_views = array(
881
+			'all' => array(
882
+				'slug'        => 'all',
883
+				'label'       => __('All', 'event_espresso'),
884
+				'count'       => 0,
885
+				'bulk_action' => array_merge($common_bulk_actions, $delete_bulk_action)
886
+			)
887
+		);
888
+        
889
+        
890
+		foreach (EEM_Message::instance()->all_statuses() as $status) {
891
+			if ($status === EEM_Message::status_debug_only && ! EEM_Message::debug()) {
892
+				continue;
893
+			}
894
+			$status_bulk_actions = $common_bulk_actions;
895
+			//unset bulk actions not applying to status
896
+			if (! empty($status_bulk_actions)) {
897
+				switch ($status) {
898
+					case EEM_Message::status_idle:
899
+					case EEM_Message::status_resend:
900
+						$status_bulk_actions['send_now'] = $common_bulk_actions['send_now'];
901
+						break;
902 902
                     
903
-                    case EEM_Message::status_failed:
904
-                    case EEM_Message::status_debug_only:
905
-                    case EEM_Message::status_messenger_executing:
906
-                        $status_bulk_actions = array();
907
-                        break;
903
+					case EEM_Message::status_failed:
904
+					case EEM_Message::status_debug_only:
905
+					case EEM_Message::status_messenger_executing:
906
+						$status_bulk_actions = array();
907
+						break;
908 908
                     
909
-                    case EEM_Message::status_incomplete:
910
-                        unset($status_bulk_actions['queue_for_resending'], $status_bulk_actions['send_now']);
911
-                        break;
909
+					case EEM_Message::status_incomplete:
910
+						unset($status_bulk_actions['queue_for_resending'], $status_bulk_actions['send_now']);
911
+						break;
912 912
                     
913
-                    case EEM_Message::status_retry:
914
-                    case EEM_Message::status_sent:
915
-                        unset($status_bulk_actions['generate_now'], $status_bulk_actions['generate_and_send_now']);
916
-                        break;
917
-                }
918
-            }
913
+					case EEM_Message::status_retry:
914
+					case EEM_Message::status_sent:
915
+						unset($status_bulk_actions['generate_now'], $status_bulk_actions['generate_and_send_now']);
916
+						break;
917
+				}
918
+			}
919 919
 
920
-            //skip adding messenger executing status to views because it will be included with the Failed view.
921
-            if ( $status === EEM_Message::status_messenger_executing ) {
922
-                continue;
923
-            }
920
+			//skip adding messenger executing status to views because it will be included with the Failed view.
921
+			if ( $status === EEM_Message::status_messenger_executing ) {
922
+				continue;
923
+			}
924 924
             
925
-            $this->_views[strtolower($status)] = array(
926
-                'slug'        => strtolower($status),
927
-                'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
928
-                'count'       => 0,
929
-                'bulk_action' => array_merge($status_bulk_actions, $delete_bulk_action)
930
-            );
931
-        }
932
-    }
933
-    
934
-    
935
-    protected function _ee_default_messages_overview_list_table()
936
-    {
937
-        $this->_admin_page_title = __('Default Message Templates', 'event_espresso');
938
-        $this->display_admin_list_table_page_with_no_sidebar();
939
-    }
940
-    
941
-    
942
-    protected function _message_queue_list_table()
943
-    {
944
-        $this->_search_btn_label                   = __('Message Activity', 'event_espresso');
945
-        $this->_template_args['per_column']        = 6;
946
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_message_legend_items());
947
-        $this->_template_args['before_list_table'] = '<h3>' . EEM_Message::instance()->get_pretty_label_for_results() . '</h3>';
948
-        $this->display_admin_list_table_page_with_no_sidebar();
949
-    }
950
-    
951
-    
952
-    protected function _message_legend_items()
953
-    {
954
-        
955
-        $action_css_classes = EEH_MSG_Template::get_message_action_icons();
956
-        $action_items       = array();
957
-        
958
-        foreach ($action_css_classes as $action_item => $action_details) {
959
-            if ($action_item === 'see_notifications_for') {
960
-                continue;
961
-            }
962
-            $action_items[$action_item] = array(
963
-                'class' => $action_details['css_class'],
964
-                'desc'  => $action_details['label']
965
-            );
966
-        }
967
-        
968
-        /** @type array $status_items status legend setup */
969
-        $status_items = array(
970
-            'sent_status'       => array(
971
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_sent,
972
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence')
973
-            ),
974
-            'idle_status'       => array(
975
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_idle,
976
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence')
977
-            ),
978
-            'failed_status'     => array(
979
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_failed,
980
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence')
981
-            ),
982
-            'messenger_executing_status' => array(
983
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_messenger_executing,
984
-                'desc' => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence')
985
-            ),
986
-            'resend_status'     => array(
987
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_resend,
988
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence')
989
-            ),
990
-            'incomplete_status' => array(
991
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_incomplete,
992
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence')
993
-            ),
994
-            'retry_status'      => array(
995
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_retry,
996
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence')
997
-            )
998
-        );
999
-        if (EEM_Message::debug()) {
1000
-            $status_items['debug_only_status'] = array(
1001
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_debug_only,
1002
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence')
1003
-            );
1004
-        }
1005
-        
1006
-        return array_merge($action_items, $status_items);
1007
-    }
1008
-    
1009
-    
1010
-    protected function _custom_mtps_preview()
1011
-    {
1012
-        $this->_admin_page_title              = __('Custom Message Templates (Preview)', 'event_espresso');
1013
-        $this->_template_args['preview_img']  = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png" alt="' . esc_attr__('Preview Custom Message Templates screenshot',
1014
-                'event_espresso') . '" />';
1015
-        $this->_template_args['preview_text'] = '<strong>' . __('Custom Message Templates is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Custom Message Templates feature, you are able to create custom message templates and assign them on a per-event basis.',
1016
-                'event_espresso') . '</strong>';
1017
-        $this->display_admin_caf_preview_page('custom_message_types', false);
1018
-    }
1019
-    
1020
-    
1021
-    /**
1022
-     * get_message_templates
1023
-     * This gets all the message templates for listing on the overview list.
1024
-     *
1025
-     * @access public
1026
-     *
1027
-     * @param int    $perpage the amount of templates groups to show per page
1028
-     * @param string $type    the current _view we're getting templates for
1029
-     * @param bool   $count   return count?
1030
-     * @param bool   $all     disregard any paging info (get all data);
1031
-     * @param bool   $global  whether to return just global (true) or custom templates (false)
1032
-     *
1033
-     * @return array
1034
-     */
1035
-    public function get_message_templates($perpage = 10, $type = 'in_use', $count = false, $all = false, $global = true)
1036
-    {
1037
-        
1038
-        $MTP = EEM_Message_Template_Group::instance();
1039
-        
1040
-        $this->_req_data['orderby'] = empty($this->_req_data['orderby']) ? 'GRP_ID' : $this->_req_data['orderby'];
1041
-        $orderby                    = $this->_req_data['orderby'];
1042
-        
1043
-        $order = (isset($this->_req_data['order']) && ! empty($this->_req_data['order'])) ? $this->_req_data['order'] : 'ASC';
1044
-        
1045
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged']) ? $this->_req_data['paged'] : 1;
1046
-        $per_page     = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage']) ? $this->_req_data['perpage'] : $perpage;
1047
-        
1048
-        $offset = ($current_page - 1) * $per_page;
1049
-        $limit  = $all ? null : array($offset, $per_page);
1050
-        
1051
-        
1052
-        //options will match what is in the _views array property
1053
-        switch ($type) {
925
+			$this->_views[strtolower($status)] = array(
926
+				'slug'        => strtolower($status),
927
+				'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
928
+				'count'       => 0,
929
+				'bulk_action' => array_merge($status_bulk_actions, $delete_bulk_action)
930
+			);
931
+		}
932
+	}
933
+    
934
+    
935
+	protected function _ee_default_messages_overview_list_table()
936
+	{
937
+		$this->_admin_page_title = __('Default Message Templates', 'event_espresso');
938
+		$this->display_admin_list_table_page_with_no_sidebar();
939
+	}
940
+    
941
+    
942
+	protected function _message_queue_list_table()
943
+	{
944
+		$this->_search_btn_label                   = __('Message Activity', 'event_espresso');
945
+		$this->_template_args['per_column']        = 6;
946
+		$this->_template_args['after_list_table']  = $this->_display_legend($this->_message_legend_items());
947
+		$this->_template_args['before_list_table'] = '<h3>' . EEM_Message::instance()->get_pretty_label_for_results() . '</h3>';
948
+		$this->display_admin_list_table_page_with_no_sidebar();
949
+	}
950
+    
951
+    
952
+	protected function _message_legend_items()
953
+	{
954
+        
955
+		$action_css_classes = EEH_MSG_Template::get_message_action_icons();
956
+		$action_items       = array();
957
+        
958
+		foreach ($action_css_classes as $action_item => $action_details) {
959
+			if ($action_item === 'see_notifications_for') {
960
+				continue;
961
+			}
962
+			$action_items[$action_item] = array(
963
+				'class' => $action_details['css_class'],
964
+				'desc'  => $action_details['label']
965
+			);
966
+		}
967
+        
968
+		/** @type array $status_items status legend setup */
969
+		$status_items = array(
970
+			'sent_status'       => array(
971
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_sent,
972
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence')
973
+			),
974
+			'idle_status'       => array(
975
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_idle,
976
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence')
977
+			),
978
+			'failed_status'     => array(
979
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_failed,
980
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence')
981
+			),
982
+			'messenger_executing_status' => array(
983
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_messenger_executing,
984
+				'desc' => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence')
985
+			),
986
+			'resend_status'     => array(
987
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_resend,
988
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence')
989
+			),
990
+			'incomplete_status' => array(
991
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_incomplete,
992
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence')
993
+			),
994
+			'retry_status'      => array(
995
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_retry,
996
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence')
997
+			)
998
+		);
999
+		if (EEM_Message::debug()) {
1000
+			$status_items['debug_only_status'] = array(
1001
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_debug_only,
1002
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence')
1003
+			);
1004
+		}
1005
+        
1006
+		return array_merge($action_items, $status_items);
1007
+	}
1008
+    
1009
+    
1010
+	protected function _custom_mtps_preview()
1011
+	{
1012
+		$this->_admin_page_title              = __('Custom Message Templates (Preview)', 'event_espresso');
1013
+		$this->_template_args['preview_img']  = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png" alt="' . esc_attr__('Preview Custom Message Templates screenshot',
1014
+				'event_espresso') . '" />';
1015
+		$this->_template_args['preview_text'] = '<strong>' . __('Custom Message Templates is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Custom Message Templates feature, you are able to create custom message templates and assign them on a per-event basis.',
1016
+				'event_espresso') . '</strong>';
1017
+		$this->display_admin_caf_preview_page('custom_message_types', false);
1018
+	}
1019
+    
1020
+    
1021
+	/**
1022
+	 * get_message_templates
1023
+	 * This gets all the message templates for listing on the overview list.
1024
+	 *
1025
+	 * @access public
1026
+	 *
1027
+	 * @param int    $perpage the amount of templates groups to show per page
1028
+	 * @param string $type    the current _view we're getting templates for
1029
+	 * @param bool   $count   return count?
1030
+	 * @param bool   $all     disregard any paging info (get all data);
1031
+	 * @param bool   $global  whether to return just global (true) or custom templates (false)
1032
+	 *
1033
+	 * @return array
1034
+	 */
1035
+	public function get_message_templates($perpage = 10, $type = 'in_use', $count = false, $all = false, $global = true)
1036
+	{
1037
+        
1038
+		$MTP = EEM_Message_Template_Group::instance();
1039
+        
1040
+		$this->_req_data['orderby'] = empty($this->_req_data['orderby']) ? 'GRP_ID' : $this->_req_data['orderby'];
1041
+		$orderby                    = $this->_req_data['orderby'];
1042
+        
1043
+		$order = (isset($this->_req_data['order']) && ! empty($this->_req_data['order'])) ? $this->_req_data['order'] : 'ASC';
1044
+        
1045
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged']) ? $this->_req_data['paged'] : 1;
1046
+		$per_page     = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage']) ? $this->_req_data['perpage'] : $perpage;
1047
+        
1048
+		$offset = ($current_page - 1) * $per_page;
1049
+		$limit  = $all ? null : array($offset, $per_page);
1050
+        
1051
+        
1052
+		//options will match what is in the _views array property
1053
+		switch ($type) {
1054 1054
             
1055
-            case 'in_use':
1056
-                $templates = $MTP->get_all_active_message_templates($orderby, $order, $limit, $count, $global, true);
1057
-                break;
1055
+			case 'in_use':
1056
+				$templates = $MTP->get_all_active_message_templates($orderby, $order, $limit, $count, $global, true);
1057
+				break;
1058 1058
             
1059
-            default:
1060
-                $templates = $MTP->get_all_trashed_grouped_message_templates($orderby, $order, $limit, $count, $global);
1059
+			default:
1060
+				$templates = $MTP->get_all_trashed_grouped_message_templates($orderby, $order, $limit, $count, $global);
1061 1061
             
1062
-        }
1063
-        
1064
-        return $templates;
1065
-    }
1066
-    
1067
-    
1068
-    /**
1069
-     * filters etc might need a list of installed message_types
1070
-     * @return array an array of message type objects
1071
-     */
1072
-    public function get_installed_message_types()
1073
-    {
1074
-        $installed_message_types = $this->_message_resource_manager->installed_message_types();
1075
-        $installed               = array();
1076
-        
1077
-        foreach ($installed_message_types as $message_type) {
1078
-            $installed[$message_type->name] = $message_type;
1079
-        }
1080
-        
1081
-        return $installed;
1082
-    }
1083
-    
1084
-    
1085
-    /**
1086
-     * _add_message_template
1087
-     *
1088
-     * This is used when creating a custom template. All Custom Templates start based off another template.
1089
-     *
1090
-     * @param string $message_type
1091
-     * @param string $messenger
1092
-     * @param string $GRP_ID
1093
-     *
1094
-     * @throws EE_error
1095
-     */
1096
-    protected function _add_message_template($message_type = '', $messenger = '', $GRP_ID = '')
1097
-    {
1098
-        //set values override any request data
1099
-        $message_type = ! empty($message_type) ? $message_type : '';
1100
-        $message_type = empty($message_type) && ! empty($this->_req_data['message_type']) ? $this->_req_data['message_type'] : $message_type;
1101
-        
1102
-        $messenger = ! empty($messenger) ? $messenger : '';
1103
-        $messenger = empty($messenger) && ! empty($this->_req_data['messenger']) ? $this->_req_data['messenger'] : $messenger;
1104
-        
1105
-        $GRP_ID = ! empty($GRP_ID) ? $GRP_ID : '';
1106
-        $GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : $GRP_ID;
1107
-        
1108
-        //we need messenger and message type.  They should be coming from the event editor. If not here then return error
1109
-        if (empty($message_type) || empty($messenger)) {
1110
-            throw new EE_error(__('Sorry, but we can\'t create new templates because we\'re missing the messenger or message type',
1111
-                'event_espresso'));
1112
-        }
1113
-        
1114
-        //we need the GRP_ID for the template being used as the base for the new template
1115
-        if (empty($GRP_ID)) {
1116
-            throw new EE_Error(__('In order to create a custom message template the GRP_ID of the template being used as a base is needed',
1117
-                'event_espresso'));
1118
-        }
1119
-        
1120
-        //let's just make sure the template gets generated!
1121
-        
1122
-        //we need to reassign some variables for what the insert is expecting
1123
-        $this->_req_data['MTP_messenger']    = $messenger;
1124
-        $this->_req_data['MTP_message_type'] = $message_type;
1125
-        $this->_req_data['GRP_ID']           = $GRP_ID;
1126
-        $this->_insert_or_update_message_template(true);
1127
-    }
1128
-    
1129
-    
1130
-    /**
1131
-     * public wrapper for the _add_message_template method
1132
-     *
1133
-     * @param string $message_type     message type slug
1134
-     * @param string $messenger        messenger slug
1135
-     * @param int    $GRP_ID           GRP_ID for the related message template group this new template will be based
1136
-     *                                 off of.
1137
-     */
1138
-    public function add_message_template($message_type, $messenger, $GRP_ID)
1139
-    {
1140
-        $this->_add_message_template($message_type, $messenger, $GRP_ID);
1141
-    }
1142
-    
1143
-    
1144
-    /**
1145
-     * _edit_message_template
1146
-     *
1147
-     * @access protected
1148
-     * @return void
1149
-     */
1150
-    protected function _edit_message_template()
1151
-    {
1152
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1153
-        $template_fields = '';
1154
-        $sidebar_fields  = '';
1155
-        //we filter the tinyMCE settings to remove the validation since message templates by their nature will not have valid html in the templates.
1156
-        add_filter('tiny_mce_before_init', array($this, 'filter_tinymce_init'), 10, 2);
1157
-        
1158
-        $GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
1159
-            ? absint($this->_req_data['id'])
1160
-            : false;
1161
-        
1162
-        $this->_set_shortcodes(); //this also sets the _message_template property.
1163
-        $message_template_group = $this->_message_template_group;
1164
-        $c_label                = $message_template_group->context_label();
1165
-        $c_config               = $message_template_group->contexts_config();
1166
-        
1167
-        reset($c_config);
1168
-        $context = isset($this->_req_data['context']) && ! empty($this->_req_data['context'])
1169
-            ? strtolower($this->_req_data['context'])
1170
-            : key($c_config);
1171
-        
1172
-        
1173
-        if (empty($GRP_ID)) {
1174
-            $action = 'insert_message_template';
1175
-            //$button_both = false;
1176
-            //$button_text = array( __( 'Save','event_espresso') );
1177
-            //$button_actions = array('something_different');
1178
-            //$referrer = false;
1179
-            $edit_message_template_form_url = add_query_arg(
1180
-                array('action' => $action, 'noheader' => true),
1181
-                EE_MSG_ADMIN_URL
1182
-            );
1183
-        } else {
1184
-            $action = 'update_message_template';
1185
-            //$button_both = true;
1186
-            //$button_text = array();
1187
-            //$button_actions = array();
1188
-            //$referrer = $this->_admin_base_url;
1189
-            $edit_message_template_form_url = add_query_arg(
1190
-                array('action' => $action, 'noheader' => true),
1191
-                EE_MSG_ADMIN_URL
1192
-            );
1193
-        }
1194
-        
1195
-        //set active messenger for this view
1196
-        $this->_active_messenger         = $this->_message_resource_manager->get_active_messenger(
1197
-            $message_template_group->messenger()
1198
-        );
1199
-        $this->_active_message_type_name = $message_template_group->message_type();
1200
-        
1201
-        
1202
-        //Do we have any validation errors?
1203
-        $validators = $this->_get_transient();
1204
-        $v_fields   = ! empty($validators) ? array_keys($validators) : array();
1205
-        
1206
-        
1207
-        //we need to assemble the title from Various details
1208
-        $context_label = sprintf(
1209
-            __('(%s %s)', 'event_espresso'),
1210
-            $c_config[$context]['label'],
1211
-            ucwords($c_label['label'])
1212
-        );
1213
-        
1214
-        $title = sprintf(
1215
-            __(' %s %s Template %s', 'event_espresso'),
1216
-            ucwords($message_template_group->messenger_obj()->label['singular']),
1217
-            ucwords($message_template_group->message_type_obj()->label['singular']),
1218
-            $context_label
1219
-        );
1220
-        
1221
-        $this->_template_args['GRP_ID']           = $GRP_ID;
1222
-        $this->_template_args['message_template'] = $message_template_group;
1223
-        $this->_template_args['is_extra_fields']  = false;
1224
-        
1225
-        
1226
-        //let's get EEH_MSG_Template so we can get template form fields
1227
-        $template_field_structure = EEH_MSG_Template::get_fields(
1228
-            $message_template_group->messenger(),
1229
-            $message_template_group->message_type()
1230
-        );
1231
-        
1232
-        if ( ! $template_field_structure) {
1233
-            $template_field_structure = false;
1234
-            $template_fields          = __('There was an error in assembling the fields for this display (you should see an error message)',
1235
-                'event_espresso');
1236
-        }
1237
-        
1238
-        
1239
-        $message_templates = $message_template_group->context_templates();
1240
-        
1241
-        
1242
-        //if we have the extra key.. then we need to remove the content index from the template_field_structure as it will get handled in the "extra" array.
1243
-        if (is_array($template_field_structure[$context]) && isset($template_field_structure[$context]['extra'])) {
1244
-            foreach ($template_field_structure[$context]['extra'] as $reference_field => $new_fields) {
1245
-                unset($template_field_structure[$context][$reference_field]);
1246
-            }
1247
-        }
1248
-        
1249
-        //let's loop through the template_field_structure and actually assemble the input fields!
1250
-        if ( ! empty($template_field_structure)) {
1251
-            foreach ($template_field_structure[$context] as $template_field => $field_setup_array) {
1252
-                //if this is an 'extra' template field then we need to remove any existing fields that are keyed up in the extra array and reset them.
1253
-                if ($template_field == 'extra') {
1254
-                    $this->_template_args['is_extra_fields'] = true;
1255
-                    foreach ($field_setup_array as $reference_field => $new_fields_array) {
1256
-                        $message_template = $message_templates[$context][$reference_field];
1257
-                        $content          = $message_template instanceof EE_Message_Template
1258
-                            ? $message_template->get('MTP_content')
1259
-                            : '';
1260
-                        foreach ($new_fields_array as $extra_field => $extra_array) {
1261
-                            //let's verify if we need this extra field via the shortcodes parameter.
1262
-                            $continue = false;
1263
-                            if (isset($extra_array['shortcodes_required'])) {
1264
-                                foreach ((array)$extra_array['shortcodes_required'] as $shortcode) {
1265
-                                    if ( ! array_key_exists($shortcode, $this->_shortcodes)) {
1266
-                                        $continue = true;
1267
-                                    }
1268
-                                }
1269
-                                if ($continue) {
1270
-                                    continue;
1271
-                                }
1272
-                            }
1062
+		}
1063
+        
1064
+		return $templates;
1065
+	}
1066
+    
1067
+    
1068
+	/**
1069
+	 * filters etc might need a list of installed message_types
1070
+	 * @return array an array of message type objects
1071
+	 */
1072
+	public function get_installed_message_types()
1073
+	{
1074
+		$installed_message_types = $this->_message_resource_manager->installed_message_types();
1075
+		$installed               = array();
1076
+        
1077
+		foreach ($installed_message_types as $message_type) {
1078
+			$installed[$message_type->name] = $message_type;
1079
+		}
1080
+        
1081
+		return $installed;
1082
+	}
1083
+    
1084
+    
1085
+	/**
1086
+	 * _add_message_template
1087
+	 *
1088
+	 * This is used when creating a custom template. All Custom Templates start based off another template.
1089
+	 *
1090
+	 * @param string $message_type
1091
+	 * @param string $messenger
1092
+	 * @param string $GRP_ID
1093
+	 *
1094
+	 * @throws EE_error
1095
+	 */
1096
+	protected function _add_message_template($message_type = '', $messenger = '', $GRP_ID = '')
1097
+	{
1098
+		//set values override any request data
1099
+		$message_type = ! empty($message_type) ? $message_type : '';
1100
+		$message_type = empty($message_type) && ! empty($this->_req_data['message_type']) ? $this->_req_data['message_type'] : $message_type;
1101
+        
1102
+		$messenger = ! empty($messenger) ? $messenger : '';
1103
+		$messenger = empty($messenger) && ! empty($this->_req_data['messenger']) ? $this->_req_data['messenger'] : $messenger;
1104
+        
1105
+		$GRP_ID = ! empty($GRP_ID) ? $GRP_ID : '';
1106
+		$GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : $GRP_ID;
1107
+        
1108
+		//we need messenger and message type.  They should be coming from the event editor. If not here then return error
1109
+		if (empty($message_type) || empty($messenger)) {
1110
+			throw new EE_error(__('Sorry, but we can\'t create new templates because we\'re missing the messenger or message type',
1111
+				'event_espresso'));
1112
+		}
1113
+        
1114
+		//we need the GRP_ID for the template being used as the base for the new template
1115
+		if (empty($GRP_ID)) {
1116
+			throw new EE_Error(__('In order to create a custom message template the GRP_ID of the template being used as a base is needed',
1117
+				'event_espresso'));
1118
+		}
1119
+        
1120
+		//let's just make sure the template gets generated!
1121
+        
1122
+		//we need to reassign some variables for what the insert is expecting
1123
+		$this->_req_data['MTP_messenger']    = $messenger;
1124
+		$this->_req_data['MTP_message_type'] = $message_type;
1125
+		$this->_req_data['GRP_ID']           = $GRP_ID;
1126
+		$this->_insert_or_update_message_template(true);
1127
+	}
1128
+    
1129
+    
1130
+	/**
1131
+	 * public wrapper for the _add_message_template method
1132
+	 *
1133
+	 * @param string $message_type     message type slug
1134
+	 * @param string $messenger        messenger slug
1135
+	 * @param int    $GRP_ID           GRP_ID for the related message template group this new template will be based
1136
+	 *                                 off of.
1137
+	 */
1138
+	public function add_message_template($message_type, $messenger, $GRP_ID)
1139
+	{
1140
+		$this->_add_message_template($message_type, $messenger, $GRP_ID);
1141
+	}
1142
+    
1143
+    
1144
+	/**
1145
+	 * _edit_message_template
1146
+	 *
1147
+	 * @access protected
1148
+	 * @return void
1149
+	 */
1150
+	protected function _edit_message_template()
1151
+	{
1152
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1153
+		$template_fields = '';
1154
+		$sidebar_fields  = '';
1155
+		//we filter the tinyMCE settings to remove the validation since message templates by their nature will not have valid html in the templates.
1156
+		add_filter('tiny_mce_before_init', array($this, 'filter_tinymce_init'), 10, 2);
1157
+        
1158
+		$GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
1159
+			? absint($this->_req_data['id'])
1160
+			: false;
1161
+        
1162
+		$this->_set_shortcodes(); //this also sets the _message_template property.
1163
+		$message_template_group = $this->_message_template_group;
1164
+		$c_label                = $message_template_group->context_label();
1165
+		$c_config               = $message_template_group->contexts_config();
1166
+        
1167
+		reset($c_config);
1168
+		$context = isset($this->_req_data['context']) && ! empty($this->_req_data['context'])
1169
+			? strtolower($this->_req_data['context'])
1170
+			: key($c_config);
1171
+        
1172
+        
1173
+		if (empty($GRP_ID)) {
1174
+			$action = 'insert_message_template';
1175
+			//$button_both = false;
1176
+			//$button_text = array( __( 'Save','event_espresso') );
1177
+			//$button_actions = array('something_different');
1178
+			//$referrer = false;
1179
+			$edit_message_template_form_url = add_query_arg(
1180
+				array('action' => $action, 'noheader' => true),
1181
+				EE_MSG_ADMIN_URL
1182
+			);
1183
+		} else {
1184
+			$action = 'update_message_template';
1185
+			//$button_both = true;
1186
+			//$button_text = array();
1187
+			//$button_actions = array();
1188
+			//$referrer = $this->_admin_base_url;
1189
+			$edit_message_template_form_url = add_query_arg(
1190
+				array('action' => $action, 'noheader' => true),
1191
+				EE_MSG_ADMIN_URL
1192
+			);
1193
+		}
1194
+        
1195
+		//set active messenger for this view
1196
+		$this->_active_messenger         = $this->_message_resource_manager->get_active_messenger(
1197
+			$message_template_group->messenger()
1198
+		);
1199
+		$this->_active_message_type_name = $message_template_group->message_type();
1200
+        
1201
+        
1202
+		//Do we have any validation errors?
1203
+		$validators = $this->_get_transient();
1204
+		$v_fields   = ! empty($validators) ? array_keys($validators) : array();
1205
+        
1206
+        
1207
+		//we need to assemble the title from Various details
1208
+		$context_label = sprintf(
1209
+			__('(%s %s)', 'event_espresso'),
1210
+			$c_config[$context]['label'],
1211
+			ucwords($c_label['label'])
1212
+		);
1213
+        
1214
+		$title = sprintf(
1215
+			__(' %s %s Template %s', 'event_espresso'),
1216
+			ucwords($message_template_group->messenger_obj()->label['singular']),
1217
+			ucwords($message_template_group->message_type_obj()->label['singular']),
1218
+			$context_label
1219
+		);
1220
+        
1221
+		$this->_template_args['GRP_ID']           = $GRP_ID;
1222
+		$this->_template_args['message_template'] = $message_template_group;
1223
+		$this->_template_args['is_extra_fields']  = false;
1224
+        
1225
+        
1226
+		//let's get EEH_MSG_Template so we can get template form fields
1227
+		$template_field_structure = EEH_MSG_Template::get_fields(
1228
+			$message_template_group->messenger(),
1229
+			$message_template_group->message_type()
1230
+		);
1231
+        
1232
+		if ( ! $template_field_structure) {
1233
+			$template_field_structure = false;
1234
+			$template_fields          = __('There was an error in assembling the fields for this display (you should see an error message)',
1235
+				'event_espresso');
1236
+		}
1237
+        
1238
+        
1239
+		$message_templates = $message_template_group->context_templates();
1240
+        
1241
+        
1242
+		//if we have the extra key.. then we need to remove the content index from the template_field_structure as it will get handled in the "extra" array.
1243
+		if (is_array($template_field_structure[$context]) && isset($template_field_structure[$context]['extra'])) {
1244
+			foreach ($template_field_structure[$context]['extra'] as $reference_field => $new_fields) {
1245
+				unset($template_field_structure[$context][$reference_field]);
1246
+			}
1247
+		}
1248
+        
1249
+		//let's loop through the template_field_structure and actually assemble the input fields!
1250
+		if ( ! empty($template_field_structure)) {
1251
+			foreach ($template_field_structure[$context] as $template_field => $field_setup_array) {
1252
+				//if this is an 'extra' template field then we need to remove any existing fields that are keyed up in the extra array and reset them.
1253
+				if ($template_field == 'extra') {
1254
+					$this->_template_args['is_extra_fields'] = true;
1255
+					foreach ($field_setup_array as $reference_field => $new_fields_array) {
1256
+						$message_template = $message_templates[$context][$reference_field];
1257
+						$content          = $message_template instanceof EE_Message_Template
1258
+							? $message_template->get('MTP_content')
1259
+							: '';
1260
+						foreach ($new_fields_array as $extra_field => $extra_array) {
1261
+							//let's verify if we need this extra field via the shortcodes parameter.
1262
+							$continue = false;
1263
+							if (isset($extra_array['shortcodes_required'])) {
1264
+								foreach ((array)$extra_array['shortcodes_required'] as $shortcode) {
1265
+									if ( ! array_key_exists($shortcode, $this->_shortcodes)) {
1266
+										$continue = true;
1267
+									}
1268
+								}
1269
+								if ($continue) {
1270
+									continue;
1271
+								}
1272
+							}
1273 1273
                             
1274
-                            $field_id                                = $reference_field . '-' . $extra_field . '-content';
1275
-                            $template_form_fields[$field_id]         = $extra_array;
1276
-                            $template_form_fields[$field_id]['name'] = 'MTP_template_fields[' . $reference_field . '][content][' . $extra_field . ']';
1277
-                            $css_class                               = isset($extra_array['css_class']) ? $extra_array['css_class'] : '';
1274
+							$field_id                                = $reference_field . '-' . $extra_field . '-content';
1275
+							$template_form_fields[$field_id]         = $extra_array;
1276
+							$template_form_fields[$field_id]['name'] = 'MTP_template_fields[' . $reference_field . '][content][' . $extra_field . ']';
1277
+							$css_class                               = isset($extra_array['css_class']) ? $extra_array['css_class'] : '';
1278 1278
                             
1279
-                            $template_form_fields[$field_id]['css_class'] = ! empty($v_fields)
1280
-                                                                            && in_array($extra_field, $v_fields)
1281
-                                                                            &&
1282
-                                                                            (
1283
-                                                                                is_array($validators[$extra_field])
1284
-                                                                                && isset($validators[$extra_field]['msg'])
1285
-                                                                            )
1286
-                                ? 'validate-error ' . $css_class
1287
-                                : $css_class;
1279
+							$template_form_fields[$field_id]['css_class'] = ! empty($v_fields)
1280
+																			&& in_array($extra_field, $v_fields)
1281
+																			&&
1282
+																			(
1283
+																				is_array($validators[$extra_field])
1284
+																				&& isset($validators[$extra_field]['msg'])
1285
+																			)
1286
+								? 'validate-error ' . $css_class
1287
+								: $css_class;
1288 1288
                             
1289
-                            $template_form_fields[$field_id]['value'] = ! empty($message_templates) && isset($content[$extra_field])
1290
-                                ? stripslashes(html_entity_decode($content[$extra_field], ENT_QUOTES, "UTF-8"))
1291
-                                : '';
1289
+							$template_form_fields[$field_id]['value'] = ! empty($message_templates) && isset($content[$extra_field])
1290
+								? stripslashes(html_entity_decode($content[$extra_field], ENT_QUOTES, "UTF-8"))
1291
+								: '';
1292 1292
                             
1293
-                            //do we have a validation error?  if we do then let's use that value instead
1294
-                            $template_form_fields[$field_id]['value'] = isset($validators[$extra_field]) ? $validators[$extra_field]['value'] : $template_form_fields[$field_id]['value'];
1293
+							//do we have a validation error?  if we do then let's use that value instead
1294
+							$template_form_fields[$field_id]['value'] = isset($validators[$extra_field]) ? $validators[$extra_field]['value'] : $template_form_fields[$field_id]['value'];
1295 1295
                             
1296 1296
                             
1297
-                            $template_form_fields[$field_id]['db-col'] = 'MTP_content';
1297
+							$template_form_fields[$field_id]['db-col'] = 'MTP_content';
1298 1298
                             
1299
-                            //shortcode selector
1300
-                            $field_name_to_use                                 = $extra_field == 'main' ? 'content' : $extra_field;
1301
-                            $template_form_fields[$field_id]['append_content'] = $this->_get_shortcode_selector(
1302
-                                $field_name_to_use,
1303
-                                $field_id
1304
-                            );
1299
+							//shortcode selector
1300
+							$field_name_to_use                                 = $extra_field == 'main' ? 'content' : $extra_field;
1301
+							$template_form_fields[$field_id]['append_content'] = $this->_get_shortcode_selector(
1302
+								$field_name_to_use,
1303
+								$field_id
1304
+							);
1305 1305
                             
1306
-                            if (isset($extra_array['input']) && $extra_array['input'] == 'wp_editor') {
1307
-                                //we want to decode the entities
1308
-                                $template_form_fields[$field_id]['value'] = stripslashes(
1309
-                                    html_entity_decode($template_form_fields[$field_id]['value'], ENT_QUOTES, "UTF-8")
1310
-                                );
1306
+							if (isset($extra_array['input']) && $extra_array['input'] == 'wp_editor') {
1307
+								//we want to decode the entities
1308
+								$template_form_fields[$field_id]['value'] = stripslashes(
1309
+									html_entity_decode($template_form_fields[$field_id]['value'], ENT_QUOTES, "UTF-8")
1310
+								);
1311 1311
                                 
1312
-                            }/**/
1313
-                        }
1314
-                        $templatefield_MTP_id          = $reference_field . '-MTP_ID';
1315
-                        $templatefield_templatename_id = $reference_field . '-name';
1312
+							}/**/
1313
+						}
1314
+						$templatefield_MTP_id          = $reference_field . '-MTP_ID';
1315
+						$templatefield_templatename_id = $reference_field . '-name';
1316 1316
                         
1317
-                        $template_form_fields[$templatefield_MTP_id] = array(
1318
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1319
-                            'label'      => null,
1320
-                            'input'      => 'hidden',
1321
-                            'type'       => 'int',
1322
-                            'required'   => false,
1323
-                            'validation' => false,
1324
-                            'value'      => ! empty($message_templates) ? $message_template->ID() : '',
1325
-                            'css_class'  => '',
1326
-                            'format'     => '%d',
1327
-                            'db-col'     => 'MTP_ID'
1328
-                        );
1317
+						$template_form_fields[$templatefield_MTP_id] = array(
1318
+							'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1319
+							'label'      => null,
1320
+							'input'      => 'hidden',
1321
+							'type'       => 'int',
1322
+							'required'   => false,
1323
+							'validation' => false,
1324
+							'value'      => ! empty($message_templates) ? $message_template->ID() : '',
1325
+							'css_class'  => '',
1326
+							'format'     => '%d',
1327
+							'db-col'     => 'MTP_ID'
1328
+						);
1329 1329
                         
1330
-                        $template_form_fields[$templatefield_templatename_id] = array(
1331
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1332
-                            'label'      => null,
1333
-                            'input'      => 'hidden',
1334
-                            'type'       => 'string',
1335
-                            'required'   => false,
1336
-                            'validation' => true,
1337
-                            'value'      => $reference_field,
1338
-                            'css_class'  => '',
1339
-                            'format'     => '%s',
1340
-                            'db-col'     => 'MTP_template_field'
1341
-                        );
1342
-                    }
1343
-                    continue; //skip the next stuff, we got the necessary fields here for this dataset.
1344
-                } else {
1345
-                    $field_id                                 = $template_field . '-content';
1346
-                    $template_form_fields[$field_id]          = $field_setup_array;
1347
-                    $template_form_fields[$field_id]['name']  = 'MTP_template_fields[' . $template_field . '][content]';
1348
-                    $message_template                         = isset($message_templates[$context][$template_field])
1349
-                        ? $message_templates[$context][$template_field]
1350
-                        : null;
1351
-                    $template_form_fields[$field_id]['value'] = ! empty($message_templates)
1352
-                                                                && is_array($message_templates[$context])
1353
-                                                                && $message_template instanceof EE_Message_Template
1354
-                        ? $message_template->get('MTP_content')
1355
-                        : '';
1330
+						$template_form_fields[$templatefield_templatename_id] = array(
1331
+							'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1332
+							'label'      => null,
1333
+							'input'      => 'hidden',
1334
+							'type'       => 'string',
1335
+							'required'   => false,
1336
+							'validation' => true,
1337
+							'value'      => $reference_field,
1338
+							'css_class'  => '',
1339
+							'format'     => '%s',
1340
+							'db-col'     => 'MTP_template_field'
1341
+						);
1342
+					}
1343
+					continue; //skip the next stuff, we got the necessary fields here for this dataset.
1344
+				} else {
1345
+					$field_id                                 = $template_field . '-content';
1346
+					$template_form_fields[$field_id]          = $field_setup_array;
1347
+					$template_form_fields[$field_id]['name']  = 'MTP_template_fields[' . $template_field . '][content]';
1348
+					$message_template                         = isset($message_templates[$context][$template_field])
1349
+						? $message_templates[$context][$template_field]
1350
+						: null;
1351
+					$template_form_fields[$field_id]['value'] = ! empty($message_templates)
1352
+																&& is_array($message_templates[$context])
1353
+																&& $message_template instanceof EE_Message_Template
1354
+						? $message_template->get('MTP_content')
1355
+						: '';
1356 1356
                     
1357
-                    //do we have a validator error for this field?  if we do then we'll use that value instead
1358
-                    $template_form_fields[$field_id]['value'] = isset($validators[$template_field])
1359
-                        ? $validators[$template_field]['value']
1360
-                        : $template_form_fields[$field_id]['value'];
1357
+					//do we have a validator error for this field?  if we do then we'll use that value instead
1358
+					$template_form_fields[$field_id]['value'] = isset($validators[$template_field])
1359
+						? $validators[$template_field]['value']
1360
+						: $template_form_fields[$field_id]['value'];
1361 1361
                     
1362 1362
                     
1363
-                    $template_form_fields[$field_id]['db-col']    = 'MTP_content';
1364
-                    $css_class                                    = isset($field_setup_array['css_class']) ? $field_setup_array['css_class'] : '';
1365
-                    $template_form_fields[$field_id]['css_class'] = ! empty($v_fields)
1366
-                                                                    && in_array($template_field, $v_fields)
1367
-                                                                    && isset($validators[$template_field]['msg'])
1368
-                        ? 'validate-error ' . $css_class
1369
-                        : $css_class;
1363
+					$template_form_fields[$field_id]['db-col']    = 'MTP_content';
1364
+					$css_class                                    = isset($field_setup_array['css_class']) ? $field_setup_array['css_class'] : '';
1365
+					$template_form_fields[$field_id]['css_class'] = ! empty($v_fields)
1366
+																	&& in_array($template_field, $v_fields)
1367
+																	&& isset($validators[$template_field]['msg'])
1368
+						? 'validate-error ' . $css_class
1369
+						: $css_class;
1370 1370
                     
1371
-                    //shortcode selector
1372
-                    $template_form_fields[$field_id]['append_content'] = $this->_get_shortcode_selector(
1373
-                        $template_field, $field_id
1374
-                    );
1375
-                }
1371
+					//shortcode selector
1372
+					$template_form_fields[$field_id]['append_content'] = $this->_get_shortcode_selector(
1373
+						$template_field, $field_id
1374
+					);
1375
+				}
1376 1376
                 
1377
-                //k took care of content field(s) now let's take care of others.
1377
+				//k took care of content field(s) now let's take care of others.
1378 1378
                 
1379
-                $templatefield_MTP_id                = $template_field . '-MTP_ID';
1380
-                $templatefield_field_templatename_id = $template_field . '-name';
1379
+				$templatefield_MTP_id                = $template_field . '-MTP_ID';
1380
+				$templatefield_field_templatename_id = $template_field . '-name';
1381 1381
                 
1382
-                //foreach template field there are actually two form fields created
1383
-                $template_form_fields[$templatefield_MTP_id] = array(
1384
-                    'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1385
-                    'label'      => null,
1386
-                    'input'      => 'hidden',
1387
-                    'type'       => 'int',
1388
-                    'required'   => false,
1389
-                    'validation' => true,
1390
-                    'value'      => $message_template instanceof EE_Message_Template ? $message_template->ID() : '',
1391
-                    'css_class'  => '',
1392
-                    'format'     => '%d',
1393
-                    'db-col'     => 'MTP_ID'
1394
-                );
1382
+				//foreach template field there are actually two form fields created
1383
+				$template_form_fields[$templatefield_MTP_id] = array(
1384
+					'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1385
+					'label'      => null,
1386
+					'input'      => 'hidden',
1387
+					'type'       => 'int',
1388
+					'required'   => false,
1389
+					'validation' => true,
1390
+					'value'      => $message_template instanceof EE_Message_Template ? $message_template->ID() : '',
1391
+					'css_class'  => '',
1392
+					'format'     => '%d',
1393
+					'db-col'     => 'MTP_ID'
1394
+				);
1395 1395
                 
1396
-                $template_form_fields[$templatefield_field_templatename_id] = array(
1397
-                    'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1398
-                    'label'      => null,
1399
-                    'input'      => 'hidden',
1400
-                    'type'       => 'string',
1401
-                    'required'   => false,
1402
-                    'validation' => true,
1403
-                    'value'      => $template_field,
1404
-                    'css_class'  => '',
1405
-                    'format'     => '%s',
1406
-                    'db-col'     => 'MTP_template_field'
1407
-                );
1396
+				$template_form_fields[$templatefield_field_templatename_id] = array(
1397
+					'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1398
+					'label'      => null,
1399
+					'input'      => 'hidden',
1400
+					'type'       => 'string',
1401
+					'required'   => false,
1402
+					'validation' => true,
1403
+					'value'      => $template_field,
1404
+					'css_class'  => '',
1405
+					'format'     => '%s',
1406
+					'db-col'     => 'MTP_template_field'
1407
+				);
1408 1408
                 
1409
-            }
1409
+			}
1410 1410
             
1411
-            //add other fields
1412
-            $template_form_fields['ee-msg-current-context'] = array(
1413
-                'name'       => 'MTP_context',
1414
-                'label'      => null,
1415
-                'input'      => 'hidden',
1416
-                'type'       => 'string',
1417
-                'required'   => false,
1418
-                'validation' => true,
1419
-                'value'      => $context,
1420
-                'css_class'  => '',
1421
-                'format'     => '%s',
1422
-                'db-col'     => 'MTP_context'
1423
-            );
1411
+			//add other fields
1412
+			$template_form_fields['ee-msg-current-context'] = array(
1413
+				'name'       => 'MTP_context',
1414
+				'label'      => null,
1415
+				'input'      => 'hidden',
1416
+				'type'       => 'string',
1417
+				'required'   => false,
1418
+				'validation' => true,
1419
+				'value'      => $context,
1420
+				'css_class'  => '',
1421
+				'format'     => '%s',
1422
+				'db-col'     => 'MTP_context'
1423
+			);
1424 1424
             
1425
-            $template_form_fields['ee-msg-grp-id'] = array(
1426
-                'name'       => 'GRP_ID',
1427
-                'label'      => null,
1428
-                'input'      => 'hidden',
1429
-                'type'       => 'int',
1430
-                'required'   => false,
1431
-                'validation' => true,
1432
-                'value'      => $GRP_ID,
1433
-                'css_class'  => '',
1434
-                'format'     => '%d',
1435
-                'db-col'     => 'GRP_ID'
1436
-            );
1425
+			$template_form_fields['ee-msg-grp-id'] = array(
1426
+				'name'       => 'GRP_ID',
1427
+				'label'      => null,
1428
+				'input'      => 'hidden',
1429
+				'type'       => 'int',
1430
+				'required'   => false,
1431
+				'validation' => true,
1432
+				'value'      => $GRP_ID,
1433
+				'css_class'  => '',
1434
+				'format'     => '%d',
1435
+				'db-col'     => 'GRP_ID'
1436
+			);
1437 1437
             
1438
-            $template_form_fields['ee-msg-messenger'] = array(
1439
-                'name'       => 'MTP_messenger',
1440
-                'label'      => null,
1441
-                'input'      => 'hidden',
1442
-                'type'       => 'string',
1443
-                'required'   => false,
1444
-                'validation' => true,
1445
-                'value'      => $message_template_group->messenger(),
1446
-                'css_class'  => '',
1447
-                'format'     => '%s',
1448
-                'db-col'     => 'MTP_messenger'
1449
-            );
1438
+			$template_form_fields['ee-msg-messenger'] = array(
1439
+				'name'       => 'MTP_messenger',
1440
+				'label'      => null,
1441
+				'input'      => 'hidden',
1442
+				'type'       => 'string',
1443
+				'required'   => false,
1444
+				'validation' => true,
1445
+				'value'      => $message_template_group->messenger(),
1446
+				'css_class'  => '',
1447
+				'format'     => '%s',
1448
+				'db-col'     => 'MTP_messenger'
1449
+			);
1450 1450
             
1451
-            $template_form_fields['ee-msg-message-type'] = array(
1452
-                'name'       => 'MTP_message_type',
1453
-                'label'      => null,
1454
-                'input'      => 'hidden',
1455
-                'type'       => 'string',
1456
-                'required'   => false,
1457
-                'validation' => true,
1458
-                'value'      => $message_template_group->message_type(),
1459
-                'css_class'  => '',
1460
-                'format'     => '%s',
1461
-                'db-col'     => 'MTP_message_type'
1462
-            );
1451
+			$template_form_fields['ee-msg-message-type'] = array(
1452
+				'name'       => 'MTP_message_type',
1453
+				'label'      => null,
1454
+				'input'      => 'hidden',
1455
+				'type'       => 'string',
1456
+				'required'   => false,
1457
+				'validation' => true,
1458
+				'value'      => $message_template_group->message_type(),
1459
+				'css_class'  => '',
1460
+				'format'     => '%s',
1461
+				'db-col'     => 'MTP_message_type'
1462
+			);
1463 1463
             
1464
-            $sidebar_form_fields['ee-msg-is-global'] = array(
1465
-                'name'       => 'MTP_is_global',
1466
-                'label'      => __('Global Template', 'event_espresso'),
1467
-                'input'      => 'hidden',
1468
-                'type'       => 'int',
1469
-                'required'   => false,
1470
-                'validation' => true,
1471
-                'value'      => $message_template_group->get('MTP_is_global'),
1472
-                'css_class'  => '',
1473
-                'format'     => '%d',
1474
-                'db-col'     => 'MTP_is_global'
1475
-            );
1464
+			$sidebar_form_fields['ee-msg-is-global'] = array(
1465
+				'name'       => 'MTP_is_global',
1466
+				'label'      => __('Global Template', 'event_espresso'),
1467
+				'input'      => 'hidden',
1468
+				'type'       => 'int',
1469
+				'required'   => false,
1470
+				'validation' => true,
1471
+				'value'      => $message_template_group->get('MTP_is_global'),
1472
+				'css_class'  => '',
1473
+				'format'     => '%d',
1474
+				'db-col'     => 'MTP_is_global'
1475
+			);
1476 1476
             
1477
-            $sidebar_form_fields['ee-msg-is-override'] = array(
1478
-                'name'       => 'MTP_is_override',
1479
-                'label'      => __('Override all custom', 'event_espresso'),
1480
-                'input'      => $message_template_group->is_global() ? 'checkbox' : 'hidden',
1481
-                'type'       => 'int',
1482
-                'required'   => false,
1483
-                'validation' => true,
1484
-                'value'      => $message_template_group->get('MTP_is_override'),
1485
-                'css_class'  => '',
1486
-                'format'     => '%d',
1487
-                'db-col'     => 'MTP_is_override'
1488
-            );
1477
+			$sidebar_form_fields['ee-msg-is-override'] = array(
1478
+				'name'       => 'MTP_is_override',
1479
+				'label'      => __('Override all custom', 'event_espresso'),
1480
+				'input'      => $message_template_group->is_global() ? 'checkbox' : 'hidden',
1481
+				'type'       => 'int',
1482
+				'required'   => false,
1483
+				'validation' => true,
1484
+				'value'      => $message_template_group->get('MTP_is_override'),
1485
+				'css_class'  => '',
1486
+				'format'     => '%d',
1487
+				'db-col'     => 'MTP_is_override'
1488
+			);
1489 1489
             
1490
-            $sidebar_form_fields['ee-msg-is-active'] = array(
1491
-                'name'       => 'MTP_is_active',
1492
-                'label'      => __('Active Template', 'event_espresso'),
1493
-                'input'      => 'hidden',
1494
-                'type'       => 'int',
1495
-                'required'   => false,
1496
-                'validation' => true,
1497
-                'value'      => $message_template_group->is_active(),
1498
-                'css_class'  => '',
1499
-                'format'     => '%d',
1500
-                'db-col'     => 'MTP_is_active'
1501
-            );
1490
+			$sidebar_form_fields['ee-msg-is-active'] = array(
1491
+				'name'       => 'MTP_is_active',
1492
+				'label'      => __('Active Template', 'event_espresso'),
1493
+				'input'      => 'hidden',
1494
+				'type'       => 'int',
1495
+				'required'   => false,
1496
+				'validation' => true,
1497
+				'value'      => $message_template_group->is_active(),
1498
+				'css_class'  => '',
1499
+				'format'     => '%d',
1500
+				'db-col'     => 'MTP_is_active'
1501
+			);
1502 1502
             
1503
-            $sidebar_form_fields['ee-msg-deleted'] = array(
1504
-                'name'       => 'MTP_deleted',
1505
-                'label'      => null,
1506
-                'input'      => 'hidden',
1507
-                'type'       => 'int',
1508
-                'required'   => false,
1509
-                'validation' => true,
1510
-                'value'      => $message_template_group->get('MTP_deleted'),
1511
-                'css_class'  => '',
1512
-                'format'     => '%d',
1513
-                'db-col'     => 'MTP_deleted'
1514
-            );
1515
-            $sidebar_form_fields['ee-msg-author']  = array(
1516
-                'name'       => 'MTP_user_id',
1517
-                'label'      => __('Author', 'event_espresso'),
1518
-                'input'      => 'hidden',
1519
-                'type'       => 'int',
1520
-                'required'   => false,
1521
-                'validation' => false,
1522
-                'value'      => $message_template_group->user(),
1523
-                'format'     => '%d',
1524
-                'db-col'     => 'MTP_user_id'
1525
-            );
1503
+			$sidebar_form_fields['ee-msg-deleted'] = array(
1504
+				'name'       => 'MTP_deleted',
1505
+				'label'      => null,
1506
+				'input'      => 'hidden',
1507
+				'type'       => 'int',
1508
+				'required'   => false,
1509
+				'validation' => true,
1510
+				'value'      => $message_template_group->get('MTP_deleted'),
1511
+				'css_class'  => '',
1512
+				'format'     => '%d',
1513
+				'db-col'     => 'MTP_deleted'
1514
+			);
1515
+			$sidebar_form_fields['ee-msg-author']  = array(
1516
+				'name'       => 'MTP_user_id',
1517
+				'label'      => __('Author', 'event_espresso'),
1518
+				'input'      => 'hidden',
1519
+				'type'       => 'int',
1520
+				'required'   => false,
1521
+				'validation' => false,
1522
+				'value'      => $message_template_group->user(),
1523
+				'format'     => '%d',
1524
+				'db-col'     => 'MTP_user_id'
1525
+			);
1526 1526
             
1527
-            $sidebar_form_fields['ee-msg-route'] = array(
1528
-                'name'  => 'action',
1529
-                'input' => 'hidden',
1530
-                'type'  => 'string',
1531
-                'value' => $action
1532
-            );
1527
+			$sidebar_form_fields['ee-msg-route'] = array(
1528
+				'name'  => 'action',
1529
+				'input' => 'hidden',
1530
+				'type'  => 'string',
1531
+				'value' => $action
1532
+			);
1533 1533
             
1534
-            $sidebar_form_fields['ee-msg-id']        = array(
1535
-                'name'  => 'id',
1536
-                'input' => 'hidden',
1537
-                'type'  => 'int',
1538
-                'value' => $GRP_ID
1539
-            );
1540
-            $sidebar_form_fields['ee-msg-evt-nonce'] = array(
1541
-                'name'  => $action . '_nonce',
1542
-                'input' => 'hidden',
1543
-                'type'  => 'string',
1544
-                'value' => wp_create_nonce($action . '_nonce')
1545
-            );
1534
+			$sidebar_form_fields['ee-msg-id']        = array(
1535
+				'name'  => 'id',
1536
+				'input' => 'hidden',
1537
+				'type'  => 'int',
1538
+				'value' => $GRP_ID
1539
+			);
1540
+			$sidebar_form_fields['ee-msg-evt-nonce'] = array(
1541
+				'name'  => $action . '_nonce',
1542
+				'input' => 'hidden',
1543
+				'type'  => 'string',
1544
+				'value' => wp_create_nonce($action . '_nonce')
1545
+			);
1546 1546
             
1547
-            if (isset($this->_req_data['template_switch']) && $this->_req_data['template_switch']) {
1548
-                $sidebar_form_fields['ee-msg-template-switch'] = array(
1549
-                    'name'  => 'template_switch',
1550
-                    'input' => 'hidden',
1551
-                    'type'  => 'int',
1552
-                    'value' => 1
1553
-                );
1554
-            }
1547
+			if (isset($this->_req_data['template_switch']) && $this->_req_data['template_switch']) {
1548
+				$sidebar_form_fields['ee-msg-template-switch'] = array(
1549
+					'name'  => 'template_switch',
1550
+					'input' => 'hidden',
1551
+					'type'  => 'int',
1552
+					'value' => 1
1553
+				);
1554
+			}
1555 1555
             
1556 1556
             
1557
-            $template_fields = $this->_generate_admin_form_fields($template_form_fields);
1558
-            $sidebar_fields  = $this->_generate_admin_form_fields($sidebar_form_fields);
1557
+			$template_fields = $this->_generate_admin_form_fields($template_form_fields);
1558
+			$sidebar_fields  = $this->_generate_admin_form_fields($sidebar_form_fields);
1559 1559
             
1560 1560
             
1561
-        } //end if ( !empty($template_field_structure) )
1561
+		} //end if ( !empty($template_field_structure) )
1562 1562
         
1563
-        //set extra content for publish box
1564
-        $this->_template_args['publish_box_extra_content'] = $sidebar_fields;
1565
-        $this->_set_publish_post_box_vars(
1566
-            'id',
1567
-            $GRP_ID,
1568
-            false,
1569
-            add_query_arg(
1570
-                array('action' => 'global_mtps'),
1571
-                $this->_admin_base_url
1572
-            )
1573
-        );
1574
-        
1575
-        //add preview button
1576
-        $preview_url    = parent::add_query_args_and_nonce(
1577
-            array(
1578
-                'message_type' => $message_template_group->message_type(),
1579
-                'messenger'    => $message_template_group->messenger(),
1580
-                'context'      => $context,
1581
-                'GRP_ID'       => $GRP_ID,
1582
-                'action'       => 'preview_message'
1583
-            ),
1584
-            $this->_admin_base_url
1585
-        );
1586
-        $preview_button = '<a href="' . $preview_url . '" class="button-secondary messages-preview-button">' . __('Preview',
1587
-                'event_espresso') . '</a>';
1588
-        
1589
-        
1590
-        //setup context switcher
1591
-        $context_switcher_args = array(
1592
-            'page'    => 'espresso_messages',
1593
-            'action'  => 'edit_message_template',
1594
-            'id'      => $GRP_ID,
1595
-            'context' => $context,
1596
-            'extra'   => $preview_button
1597
-        );
1598
-        $this->_set_context_switcher($message_template_group, $context_switcher_args);
1599
-        
1600
-        
1601
-        //main box
1602
-        $this->_template_args['template_fields']                         = $template_fields;
1603
-        $this->_template_args['sidebar_box_id']                          = 'details';
1604
-        $this->_template_args['action']                                  = $action;
1605
-        $this->_template_args['context']                                 = $context;
1606
-        $this->_template_args['edit_message_template_form_url']          = $edit_message_template_form_url;
1607
-        $this->_template_args['learn_more_about_message_templates_link'] = $this->_learn_more_about_message_templates_link();
1608
-        
1609
-        
1610
-        $this->_template_args['before_admin_page_content'] = $this->add_context_switcher();
1611
-        $this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1612
-        $this->_template_args['after_admin_page_content'] = $this->_add_form_element_after();
1613
-        
1614
-        $this->_template_path = $this->_template_args['GRP_ID']
1615
-            ? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1616
-            : EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1617
-        
1618
-        //send along EE_Message_Template_Group object for further template use.
1619
-        $this->_template_args['MTP'] = $message_template_group;
1620
-        
1621
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
1622
-            $this->_template_args, true);
1623
-        
1624
-        
1625
-        //finally, let's set the admin_page title
1626
-        $this->_admin_page_title = sprintf(__('Editing %s', 'event_espresso'), $title);
1627
-        
1628
-        
1629
-        //we need to take care of setting the shortcodes property for use elsewhere.
1630
-        $this->_set_shortcodes();
1631
-        
1632
-        
1633
-        //final template wrapper
1634
-        $this->display_admin_page_with_sidebar();
1635
-    }
1636
-    
1637
-    
1638
-    public function filter_tinymce_init($mceInit, $editor_id)
1639
-    {
1640
-        return $mceInit;
1641
-    }
1642
-    
1643
-    
1644
-    public function add_context_switcher()
1645
-    {
1646
-        return $this->_context_switcher;
1647
-    }
1648
-    
1649
-    public function _add_form_element_before()
1650
-    {
1651
-        return '<form method="post" action="' . $this->_template_args["edit_message_template_form_url"] . '" id="ee-msg-edit-frm">';
1652
-    }
1653
-    
1654
-    public function _add_form_element_after()
1655
-    {
1656
-        return '</form>';
1657
-    }
1658
-    
1659
-    
1660
-    /**
1661
-     * This executes switching the template pack for a message template.
1662
-     *
1663
-     * @since 4.5.0
1664
-     *
1665
-     */
1666
-    public function switch_template_pack()
1667
-    {
1668
-        $GRP_ID        = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
1669
-        $template_pack = ! empty($this->_req_data['template_pack']) ? $this->_req_data['template_pack'] : '';
1670
-        
1671
-        //verify we have needed values.
1672
-        if (empty($GRP_ID) || empty($template_pack)) {
1673
-            $this->_template_args['error'] = true;
1674
-            EE_Error::add_error(__('The required date for switching templates is not available.', 'event_espresso'),
1675
-                __FILE__, __FUNCTION__, __LINE__);
1676
-        } else {
1677
-            //get template, set the new template_pack and then reset to default
1678
-            /** @type EE_Message_Template_Group $message_template_group */
1679
-            $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
1563
+		//set extra content for publish box
1564
+		$this->_template_args['publish_box_extra_content'] = $sidebar_fields;
1565
+		$this->_set_publish_post_box_vars(
1566
+			'id',
1567
+			$GRP_ID,
1568
+			false,
1569
+			add_query_arg(
1570
+				array('action' => 'global_mtps'),
1571
+				$this->_admin_base_url
1572
+			)
1573
+		);
1574
+        
1575
+		//add preview button
1576
+		$preview_url    = parent::add_query_args_and_nonce(
1577
+			array(
1578
+				'message_type' => $message_template_group->message_type(),
1579
+				'messenger'    => $message_template_group->messenger(),
1580
+				'context'      => $context,
1581
+				'GRP_ID'       => $GRP_ID,
1582
+				'action'       => 'preview_message'
1583
+			),
1584
+			$this->_admin_base_url
1585
+		);
1586
+		$preview_button = '<a href="' . $preview_url . '" class="button-secondary messages-preview-button">' . __('Preview',
1587
+				'event_espresso') . '</a>';
1588
+        
1589
+        
1590
+		//setup context switcher
1591
+		$context_switcher_args = array(
1592
+			'page'    => 'espresso_messages',
1593
+			'action'  => 'edit_message_template',
1594
+			'id'      => $GRP_ID,
1595
+			'context' => $context,
1596
+			'extra'   => $preview_button
1597
+		);
1598
+		$this->_set_context_switcher($message_template_group, $context_switcher_args);
1599
+        
1600
+        
1601
+		//main box
1602
+		$this->_template_args['template_fields']                         = $template_fields;
1603
+		$this->_template_args['sidebar_box_id']                          = 'details';
1604
+		$this->_template_args['action']                                  = $action;
1605
+		$this->_template_args['context']                                 = $context;
1606
+		$this->_template_args['edit_message_template_form_url']          = $edit_message_template_form_url;
1607
+		$this->_template_args['learn_more_about_message_templates_link'] = $this->_learn_more_about_message_templates_link();
1608
+        
1609
+        
1610
+		$this->_template_args['before_admin_page_content'] = $this->add_context_switcher();
1611
+		$this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1612
+		$this->_template_args['after_admin_page_content'] = $this->_add_form_element_after();
1613
+        
1614
+		$this->_template_path = $this->_template_args['GRP_ID']
1615
+			? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1616
+			: EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1617
+        
1618
+		//send along EE_Message_Template_Group object for further template use.
1619
+		$this->_template_args['MTP'] = $message_template_group;
1620
+        
1621
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
1622
+			$this->_template_args, true);
1623
+        
1624
+        
1625
+		//finally, let's set the admin_page title
1626
+		$this->_admin_page_title = sprintf(__('Editing %s', 'event_espresso'), $title);
1627
+        
1628
+        
1629
+		//we need to take care of setting the shortcodes property for use elsewhere.
1630
+		$this->_set_shortcodes();
1631
+        
1632
+        
1633
+		//final template wrapper
1634
+		$this->display_admin_page_with_sidebar();
1635
+	}
1636
+    
1637
+    
1638
+	public function filter_tinymce_init($mceInit, $editor_id)
1639
+	{
1640
+		return $mceInit;
1641
+	}
1642
+    
1643
+    
1644
+	public function add_context_switcher()
1645
+	{
1646
+		return $this->_context_switcher;
1647
+	}
1648
+    
1649
+	public function _add_form_element_before()
1650
+	{
1651
+		return '<form method="post" action="' . $this->_template_args["edit_message_template_form_url"] . '" id="ee-msg-edit-frm">';
1652
+	}
1653
+    
1654
+	public function _add_form_element_after()
1655
+	{
1656
+		return '</form>';
1657
+	}
1658
+    
1659
+    
1660
+	/**
1661
+	 * This executes switching the template pack for a message template.
1662
+	 *
1663
+	 * @since 4.5.0
1664
+	 *
1665
+	 */
1666
+	public function switch_template_pack()
1667
+	{
1668
+		$GRP_ID        = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
1669
+		$template_pack = ! empty($this->_req_data['template_pack']) ? $this->_req_data['template_pack'] : '';
1670
+        
1671
+		//verify we have needed values.
1672
+		if (empty($GRP_ID) || empty($template_pack)) {
1673
+			$this->_template_args['error'] = true;
1674
+			EE_Error::add_error(__('The required date for switching templates is not available.', 'event_espresso'),
1675
+				__FILE__, __FUNCTION__, __LINE__);
1676
+		} else {
1677
+			//get template, set the new template_pack and then reset to default
1678
+			/** @type EE_Message_Template_Group $message_template_group */
1679
+			$message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
1680 1680
             
1681
-            $message_template_group->set_template_pack_name($template_pack);
1682
-            $this->_req_data['msgr'] = $message_template_group->messenger();
1683
-            $this->_req_data['mt']   = $message_template_group->message_type();
1681
+			$message_template_group->set_template_pack_name($template_pack);
1682
+			$this->_req_data['msgr'] = $message_template_group->messenger();
1683
+			$this->_req_data['mt']   = $message_template_group->message_type();
1684 1684
             
1685
-            $query_args = $this->_reset_to_default_template();
1685
+			$query_args = $this->_reset_to_default_template();
1686 1686
             
1687
-            if (empty($query_args['id'])) {
1688
-                EE_Error::add_error(
1689
-                    __(
1690
-                        'Something went wrong with switching the template pack. Please try again or contact EE support',
1691
-                        'event_espresso'
1692
-                    ),
1693
-                    __FILE__, __FUNCTION__, __LINE__
1694
-                );
1695
-                $this->_template_args['error'] = true;
1696
-            } else {
1697
-                $template_label       = $message_template_group->get_template_pack()->label;
1698
-                $template_pack_labels = $message_template_group->messenger_obj()->get_supports_labels();
1699
-                EE_Error::add_success(
1700
-                    sprintf(
1701
-                        __(
1702
-                            'This message template has been successfully switched to use the %1$s %2$s.  Please wait while the page reloads with your new template.',
1703
-                            'event_espresso'
1704
-                        ),
1705
-                        $template_label,
1706
-                        $template_pack_labels->template_pack
1707
-                    )
1708
-                );
1709
-                //generate the redirect url for js.
1710
-                $url                                          = self::add_query_args_and_nonce($query_args,
1711
-                    $this->_admin_base_url);
1712
-                $this->_template_args['data']['redirect_url'] = $url;
1713
-                $this->_template_args['success']              = true;
1714
-            }
1687
+			if (empty($query_args['id'])) {
1688
+				EE_Error::add_error(
1689
+					__(
1690
+						'Something went wrong with switching the template pack. Please try again or contact EE support',
1691
+						'event_espresso'
1692
+					),
1693
+					__FILE__, __FUNCTION__, __LINE__
1694
+				);
1695
+				$this->_template_args['error'] = true;
1696
+			} else {
1697
+				$template_label       = $message_template_group->get_template_pack()->label;
1698
+				$template_pack_labels = $message_template_group->messenger_obj()->get_supports_labels();
1699
+				EE_Error::add_success(
1700
+					sprintf(
1701
+						__(
1702
+							'This message template has been successfully switched to use the %1$s %2$s.  Please wait while the page reloads with your new template.',
1703
+							'event_espresso'
1704
+						),
1705
+						$template_label,
1706
+						$template_pack_labels->template_pack
1707
+					)
1708
+				);
1709
+				//generate the redirect url for js.
1710
+				$url                                          = self::add_query_args_and_nonce($query_args,
1711
+					$this->_admin_base_url);
1712
+				$this->_template_args['data']['redirect_url'] = $url;
1713
+				$this->_template_args['success']              = true;
1714
+			}
1715 1715
             
1716
-            $this->_return_json();
1716
+			$this->_return_json();
1717 1717
             
1718
-        }
1719
-    }
1720
-    
1721
-    
1722
-    /**
1723
-     * This handles resetting the template for the given messenger/message_type so that users can start from scratch if
1724
-     * they want.
1725
-     *
1726
-     * @access protected
1727
-     * @return array|null
1728
-     */
1729
-    protected function _reset_to_default_template()
1730
-    {
1731
-        
1732
-        $templates = array();
1733
-        $GRP_ID    = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
1734
-        //we need to make sure we've got the info we need.
1735
-        if ( ! isset($this->_req_data['msgr'], $this->_req_data['mt'], $this->_req_data['GRP_ID'])) {
1736
-            EE_Error::add_error(
1737
-                __(
1738
-                    'In order to reset the template to its default we require the messenger, message type, and message template GRP_ID to know what is being reset.  At least one of these is missing.',
1739
-                    'event_espresso'
1740
-                ),
1741
-                __FILE__, __FUNCTION__, __LINE__
1742
-            );
1743
-        }
1744
-        
1745
-        // all templates will be reset to whatever the defaults are
1746
-        // for the global template matching the messenger and message type.
1747
-        $success = ! empty($GRP_ID) ? true : false;
1748
-        
1749
-        if ($success) {
1718
+		}
1719
+	}
1720
+    
1721
+    
1722
+	/**
1723
+	 * This handles resetting the template for the given messenger/message_type so that users can start from scratch if
1724
+	 * they want.
1725
+	 *
1726
+	 * @access protected
1727
+	 * @return array|null
1728
+	 */
1729
+	protected function _reset_to_default_template()
1730
+	{
1731
+        
1732
+		$templates = array();
1733
+		$GRP_ID    = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
1734
+		//we need to make sure we've got the info we need.
1735
+		if ( ! isset($this->_req_data['msgr'], $this->_req_data['mt'], $this->_req_data['GRP_ID'])) {
1736
+			EE_Error::add_error(
1737
+				__(
1738
+					'In order to reset the template to its default we require the messenger, message type, and message template GRP_ID to know what is being reset.  At least one of these is missing.',
1739
+					'event_espresso'
1740
+				),
1741
+				__FILE__, __FUNCTION__, __LINE__
1742
+			);
1743
+		}
1744
+        
1745
+		// all templates will be reset to whatever the defaults are
1746
+		// for the global template matching the messenger and message type.
1747
+		$success = ! empty($GRP_ID) ? true : false;
1748
+        
1749
+		if ($success) {
1750 1750
             
1751
-            //let's first determine if the incoming template is a global template,
1752
-            // if it isn't then we need to get the global template matching messenger and message type.
1753
-            //$MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID( $GRP_ID );
1751
+			//let's first determine if the incoming template is a global template,
1752
+			// if it isn't then we need to get the global template matching messenger and message type.
1753
+			//$MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID( $GRP_ID );
1754 1754
             
1755 1755
             
1756
-            //note this is ONLY deleting the template fields (Message Template rows) NOT the message template group.
1757
-            $success = $this->_delete_mtp_permanently($GRP_ID, false);
1756
+			//note this is ONLY deleting the template fields (Message Template rows) NOT the message template group.
1757
+			$success = $this->_delete_mtp_permanently($GRP_ID, false);
1758 1758
             
1759
-            if ($success) {
1760
-                // if successfully deleted, lets generate the new ones.
1761
-                // Note. We set GLOBAL to true, because resets on ANY template
1762
-                // will use the related global template defaults for regeneration.
1763
-                // This means that if a custom template is reset it resets to whatever the related global template is.
1764
-                // HOWEVER, we DO keep the template pack and template variation set
1765
-                // for the current custom template when resetting.
1766
-                $templates = $this->_generate_new_templates(
1767
-                    $this->_req_data['msgr'],
1768
-                    $this->_req_data['mt'],
1769
-                    $GRP_ID,
1770
-                    true
1771
-                );
1772
-            }
1759
+			if ($success) {
1760
+				// if successfully deleted, lets generate the new ones.
1761
+				// Note. We set GLOBAL to true, because resets on ANY template
1762
+				// will use the related global template defaults for regeneration.
1763
+				// This means that if a custom template is reset it resets to whatever the related global template is.
1764
+				// HOWEVER, we DO keep the template pack and template variation set
1765
+				// for the current custom template when resetting.
1766
+				$templates = $this->_generate_new_templates(
1767
+					$this->_req_data['msgr'],
1768
+					$this->_req_data['mt'],
1769
+					$GRP_ID,
1770
+					true
1771
+				);
1772
+			}
1773 1773
             
1774
-        }
1775
-        
1776
-        //any error messages?
1777
-        if ( ! $success) {
1778
-            EE_Error::add_error(
1779
-                __('Something went wrong with deleting existing templates. Unable to reset to default',
1780
-                    'event_espresso'),
1781
-                __FILE__, __FUNCTION__, __LINE__
1782
-            );
1783
-        }
1784
-        
1785
-        //all good, let's add a success message!
1786
-        if ($success && ! empty($templates)) {
1787
-            $templates = $templates[0]; //the info for the template we generated is the first element in the returned array.
1788
-            EE_Error::overwrite_success();
1789
-            EE_Error::add_success(__('Templates have been reset to defaults.', 'event_espresso'));
1790
-        }
1791
-        
1792
-        
1793
-        $query_args = array(
1794
-            'id'      => isset($templates['GRP_ID']) ? $templates['GRP_ID'] : null,
1795
-            'context' => isset($templates['MTP_context']) ? $templates['MTP_context'] : null,
1796
-            'action'  => isset($templates['GRP_ID']) ? 'edit_message_template' : 'global_mtps'
1797
-        );
1798
-        
1799
-        //if called via ajax then we return query args otherwise redirect
1800
-        if (defined('DOING_AJAX') && DOING_AJAX) {
1801
-            return $query_args;
1802
-        } else {
1803
-            $this->_redirect_after_action(false, '', '', $query_args, true);
1774
+		}
1775
+        
1776
+		//any error messages?
1777
+		if ( ! $success) {
1778
+			EE_Error::add_error(
1779
+				__('Something went wrong with deleting existing templates. Unable to reset to default',
1780
+					'event_espresso'),
1781
+				__FILE__, __FUNCTION__, __LINE__
1782
+			);
1783
+		}
1784
+        
1785
+		//all good, let's add a success message!
1786
+		if ($success && ! empty($templates)) {
1787
+			$templates = $templates[0]; //the info for the template we generated is the first element in the returned array.
1788
+			EE_Error::overwrite_success();
1789
+			EE_Error::add_success(__('Templates have been reset to defaults.', 'event_espresso'));
1790
+		}
1791
+        
1792
+        
1793
+		$query_args = array(
1794
+			'id'      => isset($templates['GRP_ID']) ? $templates['GRP_ID'] : null,
1795
+			'context' => isset($templates['MTP_context']) ? $templates['MTP_context'] : null,
1796
+			'action'  => isset($templates['GRP_ID']) ? 'edit_message_template' : 'global_mtps'
1797
+		);
1798
+        
1799
+		//if called via ajax then we return query args otherwise redirect
1800
+		if (defined('DOING_AJAX') && DOING_AJAX) {
1801
+			return $query_args;
1802
+		} else {
1803
+			$this->_redirect_after_action(false, '', '', $query_args, true);
1804 1804
             
1805
-            return null;
1806
-        }
1807
-    }
1808
-    
1809
-    
1810
-    /**
1811
-     * Retrieve and set the message preview for display.
1812
-     *
1813
-     * @param bool $send if TRUE then we are doing an actual TEST send with the results of the preview.
1814
-     *
1815
-     * @return string
1816
-     */
1817
-    public function _preview_message($send = false)
1818
-    {
1819
-        //first make sure we've got the necessary parameters
1820
-        if (
1821
-        ! isset(
1822
-            $this->_req_data['message_type'],
1823
-            $this->_req_data['messenger'],
1824
-            $this->_req_data['messenger'],
1825
-            $this->_req_data['GRP_ID']
1826
-        )
1827
-        ) {
1828
-            EE_Error::add_error(
1829
-                __('Missing necessary parameters for displaying preview', 'event_espresso'),
1830
-                __FILE__, __FUNCTION__, __LINE__
1831
-            );
1832
-        }
1833
-        
1834
-        EE_Registry::instance()->REQ->set('GRP_ID', $this->_req_data['GRP_ID']);
1835
-        
1836
-        
1837
-        //get the preview!
1838
-        $preview = EED_Messages::preview_message($this->_req_data['message_type'], $this->_req_data['context'],
1839
-            $this->_req_data['messenger'], $send);
1840
-        
1841
-        if ($send) {
1842
-            return $preview;
1843
-        }
1844
-        
1845
-        //let's add a button to go back to the edit view
1846
-        $query_args             = array(
1847
-            'id'      => $this->_req_data['GRP_ID'],
1848
-            'context' => $this->_req_data['context'],
1849
-            'action'  => 'edit_message_template'
1850
-        );
1851
-        $go_back_url            = parent::add_query_args_and_nonce($query_args, $this->_admin_base_url);
1852
-        $preview_button         = '<a href="' . $go_back_url . '" class="button-secondary messages-preview-go-back-button">' . __('Go Back to Edit',
1853
-                'event_espresso') . '</a>';
1854
-        $message_types          = $this->get_installed_message_types();
1855
-        $active_messenger       = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
1856
-        $active_messenger_label = $active_messenger instanceof EE_messenger
1857
-            ? ucwords($active_messenger->label['singular'])
1858
-            : esc_html__('Unknown Messenger', 'event_espresso');
1859
-        //let's provide a helpful title for context
1860
-        $preview_title = sprintf(
1861
-            __('Viewing Preview for %s %s Message Template', 'event_espresso'),
1862
-            $active_messenger_label,
1863
-            ucwords($message_types[$this->_req_data['message_type']]->label['singular'])
1864
-        );
1865
-        //setup display of preview.
1866
-        $this->_admin_page_title                    = $preview_title;
1867
-        $this->_template_args['admin_page_content'] = $preview_button . '<br />' . stripslashes($preview);
1868
-        $this->_template_args['data']['force_json'] = true;
1869
-        
1870
-        return '';
1871
-    }
1872
-    
1873
-    
1874
-    /**
1875
-     * The initial _preview_message is on a no headers route.  It will optionally call this if necessary otherwise it
1876
-     * gets called automatically.
1877
-     *
1878
-     * @since 4.5.0
1879
-     *
1880
-     * @return string
1881
-     */
1882
-    protected function _display_preview_message()
1883
-    {
1884
-        $this->display_admin_page_with_no_sidebar();
1885
-    }
1886
-    
1887
-    
1888
-    /**
1889
-     * registers metaboxes that should show up on the "edit_message_template" page
1890
-     *
1891
-     * @access protected
1892
-     * @return void
1893
-     */
1894
-    protected function _register_edit_meta_boxes()
1895
-    {
1896
-        add_meta_box('mtp_valid_shortcodes', __('Valid Shortcodes', 'event_espresso'),
1897
-            array($this, 'shortcode_meta_box'), $this->_current_screen->id, 'side', 'default');
1898
-        add_meta_box('mtp_extra_actions', __('Extra Actions', 'event_espresso'), array($this, 'extra_actions_meta_box'),
1899
-            $this->_current_screen->id, 'side', 'high');
1900
-        add_meta_box('mtp_templates', __('Template Styles', 'event_espresso'), array($this, 'template_pack_meta_box'),
1901
-            $this->_current_screen->id, 'side', 'high');
1902
-    }
1903
-    
1904
-    
1905
-    /**
1906
-     * metabox content for all template pack and variation selection.
1907
-     *
1908
-     * @since 4.5.0
1909
-     *
1910
-     * @return string
1911
-     */
1912
-    public function template_pack_meta_box()
1913
-    {
1914
-        $this->_set_message_template_group();
1915
-        
1916
-        $tp_collection = EEH_MSG_Template::get_template_pack_collection();
1917
-        
1918
-        $tp_select_values = array();
1919
-        
1920
-        foreach ($tp_collection as $tp) {
1921
-            //only include template packs that support this messenger and message type!
1922
-            $supports = $tp->get_supports();
1923
-            if (
1924
-                ! isset($supports[$this->_message_template_group->messenger()])
1925
-                || ! in_array(
1926
-                    $this->_message_template_group->message_type(),
1927
-                    $supports[$this->_message_template_group->messenger()]
1928
-                )
1929
-            ) {
1930
-                //not supported
1931
-                continue;
1932
-            }
1805
+			return null;
1806
+		}
1807
+	}
1808
+    
1809
+    
1810
+	/**
1811
+	 * Retrieve and set the message preview for display.
1812
+	 *
1813
+	 * @param bool $send if TRUE then we are doing an actual TEST send with the results of the preview.
1814
+	 *
1815
+	 * @return string
1816
+	 */
1817
+	public function _preview_message($send = false)
1818
+	{
1819
+		//first make sure we've got the necessary parameters
1820
+		if (
1821
+		! isset(
1822
+			$this->_req_data['message_type'],
1823
+			$this->_req_data['messenger'],
1824
+			$this->_req_data['messenger'],
1825
+			$this->_req_data['GRP_ID']
1826
+		)
1827
+		) {
1828
+			EE_Error::add_error(
1829
+				__('Missing necessary parameters for displaying preview', 'event_espresso'),
1830
+				__FILE__, __FUNCTION__, __LINE__
1831
+			);
1832
+		}
1833
+        
1834
+		EE_Registry::instance()->REQ->set('GRP_ID', $this->_req_data['GRP_ID']);
1835
+        
1836
+        
1837
+		//get the preview!
1838
+		$preview = EED_Messages::preview_message($this->_req_data['message_type'], $this->_req_data['context'],
1839
+			$this->_req_data['messenger'], $send);
1840
+        
1841
+		if ($send) {
1842
+			return $preview;
1843
+		}
1844
+        
1845
+		//let's add a button to go back to the edit view
1846
+		$query_args             = array(
1847
+			'id'      => $this->_req_data['GRP_ID'],
1848
+			'context' => $this->_req_data['context'],
1849
+			'action'  => 'edit_message_template'
1850
+		);
1851
+		$go_back_url            = parent::add_query_args_and_nonce($query_args, $this->_admin_base_url);
1852
+		$preview_button         = '<a href="' . $go_back_url . '" class="button-secondary messages-preview-go-back-button">' . __('Go Back to Edit',
1853
+				'event_espresso') . '</a>';
1854
+		$message_types          = $this->get_installed_message_types();
1855
+		$active_messenger       = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
1856
+		$active_messenger_label = $active_messenger instanceof EE_messenger
1857
+			? ucwords($active_messenger->label['singular'])
1858
+			: esc_html__('Unknown Messenger', 'event_espresso');
1859
+		//let's provide a helpful title for context
1860
+		$preview_title = sprintf(
1861
+			__('Viewing Preview for %s %s Message Template', 'event_espresso'),
1862
+			$active_messenger_label,
1863
+			ucwords($message_types[$this->_req_data['message_type']]->label['singular'])
1864
+		);
1865
+		//setup display of preview.
1866
+		$this->_admin_page_title                    = $preview_title;
1867
+		$this->_template_args['admin_page_content'] = $preview_button . '<br />' . stripslashes($preview);
1868
+		$this->_template_args['data']['force_json'] = true;
1869
+        
1870
+		return '';
1871
+	}
1872
+    
1873
+    
1874
+	/**
1875
+	 * The initial _preview_message is on a no headers route.  It will optionally call this if necessary otherwise it
1876
+	 * gets called automatically.
1877
+	 *
1878
+	 * @since 4.5.0
1879
+	 *
1880
+	 * @return string
1881
+	 */
1882
+	protected function _display_preview_message()
1883
+	{
1884
+		$this->display_admin_page_with_no_sidebar();
1885
+	}
1886
+    
1887
+    
1888
+	/**
1889
+	 * registers metaboxes that should show up on the "edit_message_template" page
1890
+	 *
1891
+	 * @access protected
1892
+	 * @return void
1893
+	 */
1894
+	protected function _register_edit_meta_boxes()
1895
+	{
1896
+		add_meta_box('mtp_valid_shortcodes', __('Valid Shortcodes', 'event_espresso'),
1897
+			array($this, 'shortcode_meta_box'), $this->_current_screen->id, 'side', 'default');
1898
+		add_meta_box('mtp_extra_actions', __('Extra Actions', 'event_espresso'), array($this, 'extra_actions_meta_box'),
1899
+			$this->_current_screen->id, 'side', 'high');
1900
+		add_meta_box('mtp_templates', __('Template Styles', 'event_espresso'), array($this, 'template_pack_meta_box'),
1901
+			$this->_current_screen->id, 'side', 'high');
1902
+	}
1903
+    
1904
+    
1905
+	/**
1906
+	 * metabox content for all template pack and variation selection.
1907
+	 *
1908
+	 * @since 4.5.0
1909
+	 *
1910
+	 * @return string
1911
+	 */
1912
+	public function template_pack_meta_box()
1913
+	{
1914
+		$this->_set_message_template_group();
1915
+        
1916
+		$tp_collection = EEH_MSG_Template::get_template_pack_collection();
1917
+        
1918
+		$tp_select_values = array();
1919
+        
1920
+		foreach ($tp_collection as $tp) {
1921
+			//only include template packs that support this messenger and message type!
1922
+			$supports = $tp->get_supports();
1923
+			if (
1924
+				! isset($supports[$this->_message_template_group->messenger()])
1925
+				|| ! in_array(
1926
+					$this->_message_template_group->message_type(),
1927
+					$supports[$this->_message_template_group->messenger()]
1928
+				)
1929
+			) {
1930
+				//not supported
1931
+				continue;
1932
+			}
1933 1933
             
1934
-            $tp_select_values[] = array(
1935
-                'text' => $tp->label,
1936
-                'id'   => $tp->dbref
1937
-            );
1938
-        }
1939
-        
1940
-        //if empty $tp_select_values then we make sure default is set because EVERY message type should be supported by the default template pack.  This still allows for the odd template pack to override.
1941
-        if (empty($tp_select_values)) {
1942
-            $tp_select_values[] = array(
1943
-                'text' => __('Default', 'event_espresso'),
1944
-                'id'   => 'default'
1945
-            );
1946
-        }
1947
-        
1948
-        //setup variation select values for the currently selected template.
1949
-        $variations               = $this->_message_template_group->get_template_pack()->get_variations(
1950
-            $this->_message_template_group->messenger(),
1951
-            $this->_message_template_group->message_type()
1952
-        );
1953
-        $variations_select_values = array();
1954
-        foreach ($variations as $variation => $label) {
1955
-            $variations_select_values[] = array(
1956
-                'text' => $label,
1957
-                'id'   => $variation
1958
-            );
1959
-        }
1960
-        
1961
-        $template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
1962
-        
1963
-        $template_args['template_packs_selector']        = EEH_Form_Fields::select_input(
1964
-            'MTP_template_pack',
1965
-            $tp_select_values,
1966
-            $this->_message_template_group->get_template_pack_name()
1967
-        );
1968
-        $template_args['variations_selector']            = EEH_Form_Fields::select_input(
1969
-            'MTP_template_variation',
1970
-            $variations_select_values,
1971
-            $this->_message_template_group->get_template_pack_variation()
1972
-        );
1973
-        $template_args['template_pack_label']            = $template_pack_labels->template_pack;
1974
-        $template_args['template_variation_label']       = $template_pack_labels->template_variation;
1975
-        $template_args['template_pack_description']      = $template_pack_labels->template_pack_description;
1976
-        $template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
1977
-        
1978
-        $template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
1979
-        
1980
-        EEH_Template::display_template($template, $template_args);
1981
-    }
1982
-    
1983
-    
1984
-    /**
1985
-     * This meta box holds any extra actions related to Message Templates
1986
-     * For now, this includes Resetting templates to defaults and sending a test email.
1987
-     *
1988
-     * @access  public
1989
-     * @return void
1990
-     * @throws \EE_Error
1991
-     */
1992
-    public function extra_actions_meta_box()
1993
-    {
1994
-        $template_form_fields = array();
1995
-        
1996
-        $extra_args = array(
1997
-            'msgr'   => $this->_message_template_group->messenger(),
1998
-            'mt'     => $this->_message_template_group->message_type(),
1999
-            'GRP_ID' => $this->_message_template_group->GRP_ID()
2000
-        );
2001
-        //first we need to see if there are any fields
2002
-        $fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2003
-        
2004
-        if ( ! empty($fields)) {
2005
-            //yup there be fields
2006
-            foreach ($fields as $field => $config) {
2007
-                $field_id = $this->_message_template_group->messenger() . '_' . $field;
2008
-                $existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2009
-                $default  = isset($config['default']) ? $config['default'] : '';
2010
-                $default  = isset($config['value']) ? $config['value'] : $default;
1934
+			$tp_select_values[] = array(
1935
+				'text' => $tp->label,
1936
+				'id'   => $tp->dbref
1937
+			);
1938
+		}
1939
+        
1940
+		//if empty $tp_select_values then we make sure default is set because EVERY message type should be supported by the default template pack.  This still allows for the odd template pack to override.
1941
+		if (empty($tp_select_values)) {
1942
+			$tp_select_values[] = array(
1943
+				'text' => __('Default', 'event_espresso'),
1944
+				'id'   => 'default'
1945
+			);
1946
+		}
1947
+        
1948
+		//setup variation select values for the currently selected template.
1949
+		$variations               = $this->_message_template_group->get_template_pack()->get_variations(
1950
+			$this->_message_template_group->messenger(),
1951
+			$this->_message_template_group->message_type()
1952
+		);
1953
+		$variations_select_values = array();
1954
+		foreach ($variations as $variation => $label) {
1955
+			$variations_select_values[] = array(
1956
+				'text' => $label,
1957
+				'id'   => $variation
1958
+			);
1959
+		}
1960
+        
1961
+		$template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
1962
+        
1963
+		$template_args['template_packs_selector']        = EEH_Form_Fields::select_input(
1964
+			'MTP_template_pack',
1965
+			$tp_select_values,
1966
+			$this->_message_template_group->get_template_pack_name()
1967
+		);
1968
+		$template_args['variations_selector']            = EEH_Form_Fields::select_input(
1969
+			'MTP_template_variation',
1970
+			$variations_select_values,
1971
+			$this->_message_template_group->get_template_pack_variation()
1972
+		);
1973
+		$template_args['template_pack_label']            = $template_pack_labels->template_pack;
1974
+		$template_args['template_variation_label']       = $template_pack_labels->template_variation;
1975
+		$template_args['template_pack_description']      = $template_pack_labels->template_pack_description;
1976
+		$template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
1977
+        
1978
+		$template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
1979
+        
1980
+		EEH_Template::display_template($template, $template_args);
1981
+	}
1982
+    
1983
+    
1984
+	/**
1985
+	 * This meta box holds any extra actions related to Message Templates
1986
+	 * For now, this includes Resetting templates to defaults and sending a test email.
1987
+	 *
1988
+	 * @access  public
1989
+	 * @return void
1990
+	 * @throws \EE_Error
1991
+	 */
1992
+	public function extra_actions_meta_box()
1993
+	{
1994
+		$template_form_fields = array();
1995
+        
1996
+		$extra_args = array(
1997
+			'msgr'   => $this->_message_template_group->messenger(),
1998
+			'mt'     => $this->_message_template_group->message_type(),
1999
+			'GRP_ID' => $this->_message_template_group->GRP_ID()
2000
+		);
2001
+		//first we need to see if there are any fields
2002
+		$fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2003
+        
2004
+		if ( ! empty($fields)) {
2005
+			//yup there be fields
2006
+			foreach ($fields as $field => $config) {
2007
+				$field_id = $this->_message_template_group->messenger() . '_' . $field;
2008
+				$existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2009
+				$default  = isset($config['default']) ? $config['default'] : '';
2010
+				$default  = isset($config['value']) ? $config['value'] : $default;
2011 2011
                 
2012
-                // if type is hidden and the value is empty
2013
-                // something may have gone wrong so let's correct with the defaults
2014
-                $fix              = $config['input'] === 'hidden' && isset($existing[$field]) && empty($existing[$field])
2015
-                    ? $default
2016
-                    : '';
2017
-                $existing[$field] = isset($existing[$field]) && empty($fix)
2018
-                    ? $existing[$field]
2019
-                    : $fix;
2012
+				// if type is hidden and the value is empty
2013
+				// something may have gone wrong so let's correct with the defaults
2014
+				$fix              = $config['input'] === 'hidden' && isset($existing[$field]) && empty($existing[$field])
2015
+					? $default
2016
+					: '';
2017
+				$existing[$field] = isset($existing[$field]) && empty($fix)
2018
+					? $existing[$field]
2019
+					: $fix;
2020 2020
                 
2021
-                $template_form_fields[$field_id] = array(
2022
-                    'name'       => 'test_settings_fld[' . $field . ']',
2023
-                    'label'      => $config['label'],
2024
-                    'input'      => $config['input'],
2025
-                    'type'       => $config['type'],
2026
-                    'required'   => $config['required'],
2027
-                    'validation' => $config['validation'],
2028
-                    'value'      => isset($existing[$field]) ? $existing[$field] : $default,
2029
-                    'css_class'  => $config['css_class'],
2030
-                    'options'    => isset($config['options']) ? $config['options'] : array(),
2031
-                    'default'    => $default,
2032
-                    'format'     => $config['format']
2033
-                );
2034
-            }
2035
-        }
2036
-        
2037
-        $test_settings_fields = ! empty($template_form_fields)
2038
-            ? $this->_generate_admin_form_fields($template_form_fields, 'string', 'ee_tst_settings_flds')
2039
-            : '';
2040
-        
2041
-        $test_settings_html = '';
2042
-        //print out $test_settings_fields
2043
-        if ( ! empty($test_settings_fields)) {
2044
-            echo $test_settings_fields;
2045
-            $test_settings_html = '<input type="submit" class="button-primary mtp-test-button alignright" ';
2046
-            $test_settings_html .= 'name="test_button" value="';
2047
-            $test_settings_html .= __('Test Send', 'event_espresso');
2048
-            $test_settings_html .= '" /><div style="clear:both"></div>';
2049
-        }
2050
-        
2051
-        //and button
2052
-        $test_settings_html .= '<p>' . __('Need to reset this message type and start over?', 'event_espresso') . '</p>';
2053
-        $test_settings_html .= '<div class="publishing-action alignright resetbutton">';
2054
-        $test_settings_html .= $this->get_action_link_or_button(
2055
-            'reset_to_default',
2056
-            'reset',
2057
-            $extra_args,
2058
-            'button-primary reset-default-button'
2059
-        );
2060
-        $test_settings_html .= '</div><div style="clear:both"></div>';
2061
-        echo $test_settings_html;
2062
-    }
2063
-    
2064
-    
2065
-    /**
2066
-     * This returns the shortcode selector skeleton for a given context and field.
2067
-     *
2068
-     * @since 4.9.rc.000
2069
-     *
2070
-     * @param string $field           The name of the field retrieving shortcodes for.
2071
-     * @param string $linked_input_id The css id of the input that the shortcodes get added to.
2072
-     *
2073
-     * @return string
2074
-     */
2075
-    protected function _get_shortcode_selector($field, $linked_input_id)
2076
-    {
2077
-        $template_args = array(
2078
-            'shortcodes'      => $this->_get_shortcodes(array($field), true),
2079
-            'fieldname'       => $field,
2080
-            'linked_input_id' => $linked_input_id
2081
-        );
2082
-        
2083
-        return EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2084
-            $template_args, true);
2085
-    }
2086
-    
2087
-    
2088
-    /**
2089
-     * This just takes care of returning the meta box content for shortcodes (only used on the edit message template
2090
-     * page)
2091
-     *
2092
-     * @access public
2093
-     * @return void
2094
-     */
2095
-    public function shortcode_meta_box()
2096
-    {
2097
-        $shortcodes = $this->_get_shortcodes(array(), false); //just make sure shortcodes property is set
2098
-        //$messenger = $this->_message_template_group->messenger_obj();
2099
-        //now let's set the content depending on the status of the shortcodes array
2100
-        if (empty($shortcodes)) {
2101
-            $content = '<p>' . __('There are no valid shortcodes available', 'event_espresso') . '</p>';
2102
-            echo $content;
2103
-        } else {
2104
-            //$alt = 0;
2105
-            ?>
2021
+				$template_form_fields[$field_id] = array(
2022
+					'name'       => 'test_settings_fld[' . $field . ']',
2023
+					'label'      => $config['label'],
2024
+					'input'      => $config['input'],
2025
+					'type'       => $config['type'],
2026
+					'required'   => $config['required'],
2027
+					'validation' => $config['validation'],
2028
+					'value'      => isset($existing[$field]) ? $existing[$field] : $default,
2029
+					'css_class'  => $config['css_class'],
2030
+					'options'    => isset($config['options']) ? $config['options'] : array(),
2031
+					'default'    => $default,
2032
+					'format'     => $config['format']
2033
+				);
2034
+			}
2035
+		}
2036
+        
2037
+		$test_settings_fields = ! empty($template_form_fields)
2038
+			? $this->_generate_admin_form_fields($template_form_fields, 'string', 'ee_tst_settings_flds')
2039
+			: '';
2040
+        
2041
+		$test_settings_html = '';
2042
+		//print out $test_settings_fields
2043
+		if ( ! empty($test_settings_fields)) {
2044
+			echo $test_settings_fields;
2045
+			$test_settings_html = '<input type="submit" class="button-primary mtp-test-button alignright" ';
2046
+			$test_settings_html .= 'name="test_button" value="';
2047
+			$test_settings_html .= __('Test Send', 'event_espresso');
2048
+			$test_settings_html .= '" /><div style="clear:both"></div>';
2049
+		}
2050
+        
2051
+		//and button
2052
+		$test_settings_html .= '<p>' . __('Need to reset this message type and start over?', 'event_espresso') . '</p>';
2053
+		$test_settings_html .= '<div class="publishing-action alignright resetbutton">';
2054
+		$test_settings_html .= $this->get_action_link_or_button(
2055
+			'reset_to_default',
2056
+			'reset',
2057
+			$extra_args,
2058
+			'button-primary reset-default-button'
2059
+		);
2060
+		$test_settings_html .= '</div><div style="clear:both"></div>';
2061
+		echo $test_settings_html;
2062
+	}
2063
+    
2064
+    
2065
+	/**
2066
+	 * This returns the shortcode selector skeleton for a given context and field.
2067
+	 *
2068
+	 * @since 4.9.rc.000
2069
+	 *
2070
+	 * @param string $field           The name of the field retrieving shortcodes for.
2071
+	 * @param string $linked_input_id The css id of the input that the shortcodes get added to.
2072
+	 *
2073
+	 * @return string
2074
+	 */
2075
+	protected function _get_shortcode_selector($field, $linked_input_id)
2076
+	{
2077
+		$template_args = array(
2078
+			'shortcodes'      => $this->_get_shortcodes(array($field), true),
2079
+			'fieldname'       => $field,
2080
+			'linked_input_id' => $linked_input_id
2081
+		);
2082
+        
2083
+		return EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2084
+			$template_args, true);
2085
+	}
2086
+    
2087
+    
2088
+	/**
2089
+	 * This just takes care of returning the meta box content for shortcodes (only used on the edit message template
2090
+	 * page)
2091
+	 *
2092
+	 * @access public
2093
+	 * @return void
2094
+	 */
2095
+	public function shortcode_meta_box()
2096
+	{
2097
+		$shortcodes = $this->_get_shortcodes(array(), false); //just make sure shortcodes property is set
2098
+		//$messenger = $this->_message_template_group->messenger_obj();
2099
+		//now let's set the content depending on the status of the shortcodes array
2100
+		if (empty($shortcodes)) {
2101
+			$content = '<p>' . __('There are no valid shortcodes available', 'event_espresso') . '</p>';
2102
+			echo $content;
2103
+		} else {
2104
+			//$alt = 0;
2105
+			?>
2106 2106
             <div
2107 2107
                 style="float:right; margin-top:10px"><?php echo $this->_get_help_tab_link('message_template_shortcodes'); ?></div>
2108 2108
             <p class="small-text"><?php printf(__('You can view the shortcodes usable in your template by clicking the %s icon next to each field.',
2109
-                    'event_espresso'), '<span class="dashicons dashicons-menu"></span>'); ?></p>
2109
+					'event_espresso'), '<span class="dashicons dashicons-menu"></span>'); ?></p>
2110 2110
             <?php
2111
-        }
2112
-        
2113
-        
2114
-    }
2115
-    
2116
-    
2117
-    /**
2118
-     * used to set the $_shortcodes property for when its needed elsewhere.
2119
-     *
2120
-     * @access protected
2121
-     * @return void
2122
-     */
2123
-    protected function _set_shortcodes()
2124
-    {
2125
-        
2126
-        //no need to run this if the property is already set
2127
-        if ( ! empty($this->_shortcodes)) {
2128
-            return;
2129
-        }
2130
-        
2131
-        $this->_shortcodes = $this->_get_shortcodes();
2132
-    }
2133
-    
2134
-    
2135
-    /**
2136
-     * get's all shortcodes for a given template group. (typically used by _set_shortcodes to set the $_shortcodes
2137
-     * property)
2138
-     *
2139
-     * @access  protected
2140
-     *
2141
-     * @param  array   $fields include an array of specific field names that you want to be used to get the shortcodes
2142
-     *                         for. Defaults to all (for the given context)
2143
-     * @param  boolean $merged Whether to merge all the shortcodes into one list of unique shortcodes
2144
-     *
2145
-     * @return array          Shortcodes indexed by fieldname and the an array of shortcode/label pairs OR if merged is
2146
-     *                        true just an array of shortcode/label pairs.
2147
-     */
2148
-    protected function _get_shortcodes($fields = array(), $merged = true)
2149
-    {
2150
-        $this->_set_message_template_group();
2151
-        
2152
-        //we need the messenger and message template to retrieve the valid shortcodes array.
2153
-        $GRP_ID  = isset($this->_req_data['id']) && ! empty($this->_req_data['id']) ? absint($this->_req_data['id']) : false;
2154
-        $context = isset($this->_req_data['context']) ? $this->_req_data['context'] : key($this->_message_template_group->contexts_config());
2155
-        
2156
-        return ! empty($GRP_ID) ? $this->_message_template_group->get_shortcodes($context, $fields, $merged) : array();
2157
-    }
2158
-    
2159
-    
2160
-    /**
2161
-     * This sets the _message_template property (containing the called message_template object)
2162
-     *
2163
-     * @access protected
2164
-     * @return  void
2165
-     */
2166
-    protected function _set_message_template_group()
2167
-    {
2168
-        
2169
-        if ( ! empty($this->_message_template_group)) {
2170
-            return;
2171
-        } //get out if this is already set.
2172
-        
2173
-        $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? absint($this->_req_data['GRP_ID']) : false;
2174
-        $GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['id']) ? $this->_req_data['id'] : $GRP_ID;
2175
-        
2176
-        //let's get the message templates
2177
-        $MTP = EEM_Message_Template_Group::instance();
2178
-        
2179
-        if (empty($GRP_ID)) {
2180
-            $this->_message_template_group = $MTP->create_default_object();
2181
-        } else {
2182
-            $this->_message_template_group = $MTP->get_one_by_ID($GRP_ID);
2183
-        }
2184
-        
2185
-        $this->_template_pack = $this->_message_template_group->get_template_pack();
2186
-        $this->_variation     = $this->_message_template_group->get_template_pack_variation();
2187
-        
2188
-    }
2189
-    
2190
-    
2191
-    /**
2192
-     * sets up a context switcher for edit forms
2193
-     *
2194
-     * @access  protected
2195
-     *
2196
-     * @param  EE_Message_Template_Group $template_group_object the template group object being displayed on the form
2197
-     * @param array                      $args                  various things the context switcher needs.
2198
-     *
2199
-     */
2200
-    protected function _set_context_switcher(EE_Message_Template_Group $template_group_object, $args)
2201
-    {
2202
-        $context_details = $template_group_object->contexts_config();
2203
-        $context_label   = $template_group_object->context_label();
2204
-        ob_start();
2205
-        ?>
2111
+		}
2112
+        
2113
+        
2114
+	}
2115
+    
2116
+    
2117
+	/**
2118
+	 * used to set the $_shortcodes property for when its needed elsewhere.
2119
+	 *
2120
+	 * @access protected
2121
+	 * @return void
2122
+	 */
2123
+	protected function _set_shortcodes()
2124
+	{
2125
+        
2126
+		//no need to run this if the property is already set
2127
+		if ( ! empty($this->_shortcodes)) {
2128
+			return;
2129
+		}
2130
+        
2131
+		$this->_shortcodes = $this->_get_shortcodes();
2132
+	}
2133
+    
2134
+    
2135
+	/**
2136
+	 * get's all shortcodes for a given template group. (typically used by _set_shortcodes to set the $_shortcodes
2137
+	 * property)
2138
+	 *
2139
+	 * @access  protected
2140
+	 *
2141
+	 * @param  array   $fields include an array of specific field names that you want to be used to get the shortcodes
2142
+	 *                         for. Defaults to all (for the given context)
2143
+	 * @param  boolean $merged Whether to merge all the shortcodes into one list of unique shortcodes
2144
+	 *
2145
+	 * @return array          Shortcodes indexed by fieldname and the an array of shortcode/label pairs OR if merged is
2146
+	 *                        true just an array of shortcode/label pairs.
2147
+	 */
2148
+	protected function _get_shortcodes($fields = array(), $merged = true)
2149
+	{
2150
+		$this->_set_message_template_group();
2151
+        
2152
+		//we need the messenger and message template to retrieve the valid shortcodes array.
2153
+		$GRP_ID  = isset($this->_req_data['id']) && ! empty($this->_req_data['id']) ? absint($this->_req_data['id']) : false;
2154
+		$context = isset($this->_req_data['context']) ? $this->_req_data['context'] : key($this->_message_template_group->contexts_config());
2155
+        
2156
+		return ! empty($GRP_ID) ? $this->_message_template_group->get_shortcodes($context, $fields, $merged) : array();
2157
+	}
2158
+    
2159
+    
2160
+	/**
2161
+	 * This sets the _message_template property (containing the called message_template object)
2162
+	 *
2163
+	 * @access protected
2164
+	 * @return  void
2165
+	 */
2166
+	protected function _set_message_template_group()
2167
+	{
2168
+        
2169
+		if ( ! empty($this->_message_template_group)) {
2170
+			return;
2171
+		} //get out if this is already set.
2172
+        
2173
+		$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? absint($this->_req_data['GRP_ID']) : false;
2174
+		$GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['id']) ? $this->_req_data['id'] : $GRP_ID;
2175
+        
2176
+		//let's get the message templates
2177
+		$MTP = EEM_Message_Template_Group::instance();
2178
+        
2179
+		if (empty($GRP_ID)) {
2180
+			$this->_message_template_group = $MTP->create_default_object();
2181
+		} else {
2182
+			$this->_message_template_group = $MTP->get_one_by_ID($GRP_ID);
2183
+		}
2184
+        
2185
+		$this->_template_pack = $this->_message_template_group->get_template_pack();
2186
+		$this->_variation     = $this->_message_template_group->get_template_pack_variation();
2187
+        
2188
+	}
2189
+    
2190
+    
2191
+	/**
2192
+	 * sets up a context switcher for edit forms
2193
+	 *
2194
+	 * @access  protected
2195
+	 *
2196
+	 * @param  EE_Message_Template_Group $template_group_object the template group object being displayed on the form
2197
+	 * @param array                      $args                  various things the context switcher needs.
2198
+	 *
2199
+	 */
2200
+	protected function _set_context_switcher(EE_Message_Template_Group $template_group_object, $args)
2201
+	{
2202
+		$context_details = $template_group_object->contexts_config();
2203
+		$context_label   = $template_group_object->context_label();
2204
+		ob_start();
2205
+		?>
2206 2206
         <div class="ee-msg-switcher-container">
2207 2207
             <form method="get" action="<?php echo EE_MSG_ADMIN_URL; ?>" id="ee-msg-context-switcher-frm">
2208 2208
                 <?php
2209
-                foreach ($args as $name => $value) {
2210
-                    if ($name == 'context' || empty($value) || $name == 'extra') {
2211
-                        continue;
2212
-                    }
2213
-                    ?>
2209
+				foreach ($args as $name => $value) {
2210
+					if ($name == 'context' || empty($value) || $name == 'extra') {
2211
+						continue;
2212
+					}
2213
+					?>
2214 2214
                     <input type="hidden" name="<?php echo $name; ?>" value="<?php echo $value; ?>"/>
2215 2215
                     <?php
2216
-                }
2217
-                //setup nonce_url
2218
-                wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2219
-                ?>
2216
+				}
2217
+				//setup nonce_url
2218
+				wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2219
+				?>
2220 2220
                 <select name="context">
2221 2221
                     <?php
2222
-                    $context_templates = $template_group_object->context_templates();
2223
-                    if (is_array($context_templates)) :
2224
-                        foreach ($context_templates as $context => $template_fields) :
2225
-                            $checked = ($context == $args['context']) ? 'selected="selected"' : '';
2226
-                            ?>
2222
+					$context_templates = $template_group_object->context_templates();
2223
+					if (is_array($context_templates)) :
2224
+						foreach ($context_templates as $context => $template_fields) :
2225
+							$checked = ($context == $args['context']) ? 'selected="selected"' : '';
2226
+							?>
2227 2227
                             <option value="<?php echo $context; ?>" <?php echo $checked; ?>>
2228 2228
                                 <?php echo $context_details[$context]['label']; ?>
2229 2229
                             </option>
@@ -2236,1584 +2236,1584 @@  discard block
 block discarded – undo
2236 2236
             <?php echo $args['extra']; ?>
2237 2237
         </div> <!-- end .ee-msg-switcher-container -->
2238 2238
         <?php
2239
-        $output = ob_get_contents();
2240
-        ob_clean();
2241
-        $this->_context_switcher = $output;
2242
-    }
2243
-    
2244
-    
2245
-    /**
2246
-     * utility for sanitizing new values coming in.
2247
-     * Note: this is only used when updating a context.
2248
-     *
2249
-     * @access protected
2250
-     *
2251
-     * @param int $index This helps us know which template field to select from the request array.
2252
-     *
2253
-     * @return array
2254
-     */
2255
-    protected function _set_message_template_column_values($index)
2256
-    {
2257
-        if (is_array($this->_req_data['MTP_template_fields'][$index]['content'])) {
2258
-            foreach ($this->_req_data['MTP_template_fields'][$index]['content'] as $field => $value) {
2259
-                $this->_req_data['MTP_template_fields'][$index]['content'][$field] = $value;
2260
-            }
2261
-        } /*else {
2239
+		$output = ob_get_contents();
2240
+		ob_clean();
2241
+		$this->_context_switcher = $output;
2242
+	}
2243
+    
2244
+    
2245
+	/**
2246
+	 * utility for sanitizing new values coming in.
2247
+	 * Note: this is only used when updating a context.
2248
+	 *
2249
+	 * @access protected
2250
+	 *
2251
+	 * @param int $index This helps us know which template field to select from the request array.
2252
+	 *
2253
+	 * @return array
2254
+	 */
2255
+	protected function _set_message_template_column_values($index)
2256
+	{
2257
+		if (is_array($this->_req_data['MTP_template_fields'][$index]['content'])) {
2258
+			foreach ($this->_req_data['MTP_template_fields'][$index]['content'] as $field => $value) {
2259
+				$this->_req_data['MTP_template_fields'][$index]['content'][$field] = $value;
2260
+			}
2261
+		} /*else {
2262 2262
 			$this->_req_data['MTP_template_fields'][$index]['content'] = $this->_req_data['MTP_template_fields'][$index]['content'];
2263 2263
 		}*/
2264 2264
         
2265 2265
         
2266
-        $set_column_values = array(
2267
-            'MTP_ID'             => absint($this->_req_data['MTP_template_fields'][$index]['MTP_ID']),
2268
-            'GRP_ID'             => absint($this->_req_data['GRP_ID']),
2269
-            'MTP_user_id'        => absint($this->_req_data['MTP_user_id']),
2270
-            'MTP_messenger'      => strtolower($this->_req_data['MTP_messenger']),
2271
-            'MTP_message_type'   => strtolower($this->_req_data['MTP_message_type']),
2272
-            'MTP_template_field' => strtolower($this->_req_data['MTP_template_fields'][$index]['name']),
2273
-            'MTP_context'        => strtolower($this->_req_data['MTP_context']),
2274
-            'MTP_content'        => $this->_req_data['MTP_template_fields'][$index]['content'],
2275
-            'MTP_is_global'      => isset($this->_req_data['MTP_is_global'])
2276
-                ? absint($this->_req_data['MTP_is_global'])
2277
-                : 0,
2278
-            'MTP_is_override'    => isset($this->_req_data['MTP_is_override'])
2279
-                ? absint($this->_req_data['MTP_is_override'])
2280
-                : 0,
2281
-            'MTP_deleted'        => absint($this->_req_data['MTP_deleted']),
2282
-            'MTP_is_active'      => absint($this->_req_data['MTP_is_active'])
2283
-        );
2284
-        
2285
-        
2286
-        return $set_column_values;
2287
-    }
2288
-    
2289
-    
2290
-    protected function _insert_or_update_message_template($new = false)
2291
-    {
2292
-        
2293
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2294
-        $success  = 0;
2295
-        $override = false;
2296
-        
2297
-        //setup notices description
2298
-        $messenger_slug = ! empty($this->_req_data['MTP_messenger']) ? $this->_req_data['MTP_messenger'] : '';
2299
-        
2300
-        //need the message type and messenger objects to be able to use the labels for the notices
2301
-        $messenger_object = $this->_message_resource_manager->get_messenger($messenger_slug);
2302
-        $messenger_label  = $messenger_object instanceof EE_messenger ? ucwords($messenger_object->label['singular']) : '';
2303
-        
2304
-        $message_type_slug   = ! empty($this->_req_data['MTP_message_type']) ? $this->_req_data['MTP_message_type'] : '';
2305
-        $message_type_object = $this->_message_resource_manager->get_message_type($message_type_slug);
2306
-        
2307
-        $message_type_label = $message_type_object instanceof EE_message_type
2308
-            ? ucwords($message_type_object->label['singular'])
2309
-            : '';
2310
-        
2311
-        $context_slug = ! empty($this->_req_data['MTP_context'])
2312
-            ? $this->_req_data['MTP_context']
2313
-            : '';
2314
-        $context      = ucwords(str_replace('_', ' ', $context_slug));
2315
-        
2316
-        $item_desc = $messenger_label && $message_type_label ? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' ' : '';
2317
-        $item_desc .= 'Message Template';
2318
-        $query_args  = array();
2319
-        $edit_array  = array();
2320
-        $action_desc = '';
2321
-        
2322
-        //if this is "new" then we need to generate the default contexts for the selected messenger/message_type for user to edit.
2323
-        if ($new) {
2324
-            $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2325
-            if ($edit_array = $this->_generate_new_templates($messenger_slug, $message_type_slug, $GRP_ID)) {
2326
-                if (empty($edit_array)) {
2327
-                    $success = 0;
2328
-                } else {
2329
-                    $success    = 1;
2330
-                    $edit_array = $edit_array[0];
2331
-                    $query_args = array(
2332
-                        'id'      => $edit_array['GRP_ID'],
2333
-                        'context' => $edit_array['MTP_context'],
2334
-                        'action'  => 'edit_message_template'
2335
-                    );
2336
-                }
2337
-            }
2338
-            $action_desc = 'created';
2339
-        } else {
2340
-            $MTPG = EEM_Message_Template_Group::instance();
2341
-            $MTP  = EEM_Message_Template::instance();
2266
+		$set_column_values = array(
2267
+			'MTP_ID'             => absint($this->_req_data['MTP_template_fields'][$index]['MTP_ID']),
2268
+			'GRP_ID'             => absint($this->_req_data['GRP_ID']),
2269
+			'MTP_user_id'        => absint($this->_req_data['MTP_user_id']),
2270
+			'MTP_messenger'      => strtolower($this->_req_data['MTP_messenger']),
2271
+			'MTP_message_type'   => strtolower($this->_req_data['MTP_message_type']),
2272
+			'MTP_template_field' => strtolower($this->_req_data['MTP_template_fields'][$index]['name']),
2273
+			'MTP_context'        => strtolower($this->_req_data['MTP_context']),
2274
+			'MTP_content'        => $this->_req_data['MTP_template_fields'][$index]['content'],
2275
+			'MTP_is_global'      => isset($this->_req_data['MTP_is_global'])
2276
+				? absint($this->_req_data['MTP_is_global'])
2277
+				: 0,
2278
+			'MTP_is_override'    => isset($this->_req_data['MTP_is_override'])
2279
+				? absint($this->_req_data['MTP_is_override'])
2280
+				: 0,
2281
+			'MTP_deleted'        => absint($this->_req_data['MTP_deleted']),
2282
+			'MTP_is_active'      => absint($this->_req_data['MTP_is_active'])
2283
+		);
2284
+        
2285
+        
2286
+		return $set_column_values;
2287
+	}
2288
+    
2289
+    
2290
+	protected function _insert_or_update_message_template($new = false)
2291
+	{
2292
+        
2293
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2294
+		$success  = 0;
2295
+		$override = false;
2296
+        
2297
+		//setup notices description
2298
+		$messenger_slug = ! empty($this->_req_data['MTP_messenger']) ? $this->_req_data['MTP_messenger'] : '';
2299
+        
2300
+		//need the message type and messenger objects to be able to use the labels for the notices
2301
+		$messenger_object = $this->_message_resource_manager->get_messenger($messenger_slug);
2302
+		$messenger_label  = $messenger_object instanceof EE_messenger ? ucwords($messenger_object->label['singular']) : '';
2303
+        
2304
+		$message_type_slug   = ! empty($this->_req_data['MTP_message_type']) ? $this->_req_data['MTP_message_type'] : '';
2305
+		$message_type_object = $this->_message_resource_manager->get_message_type($message_type_slug);
2306
+        
2307
+		$message_type_label = $message_type_object instanceof EE_message_type
2308
+			? ucwords($message_type_object->label['singular'])
2309
+			: '';
2310
+        
2311
+		$context_slug = ! empty($this->_req_data['MTP_context'])
2312
+			? $this->_req_data['MTP_context']
2313
+			: '';
2314
+		$context      = ucwords(str_replace('_', ' ', $context_slug));
2315
+        
2316
+		$item_desc = $messenger_label && $message_type_label ? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' ' : '';
2317
+		$item_desc .= 'Message Template';
2318
+		$query_args  = array();
2319
+		$edit_array  = array();
2320
+		$action_desc = '';
2321
+        
2322
+		//if this is "new" then we need to generate the default contexts for the selected messenger/message_type for user to edit.
2323
+		if ($new) {
2324
+			$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2325
+			if ($edit_array = $this->_generate_new_templates($messenger_slug, $message_type_slug, $GRP_ID)) {
2326
+				if (empty($edit_array)) {
2327
+					$success = 0;
2328
+				} else {
2329
+					$success    = 1;
2330
+					$edit_array = $edit_array[0];
2331
+					$query_args = array(
2332
+						'id'      => $edit_array['GRP_ID'],
2333
+						'context' => $edit_array['MTP_context'],
2334
+						'action'  => 'edit_message_template'
2335
+					);
2336
+				}
2337
+			}
2338
+			$action_desc = 'created';
2339
+		} else {
2340
+			$MTPG = EEM_Message_Template_Group::instance();
2341
+			$MTP  = EEM_Message_Template::instance();
2342 2342
             
2343 2343
             
2344
-            //run update for each template field in displayed context
2345
-            if ( ! isset($this->_req_data['MTP_template_fields']) && empty($this->_req_data['MTP_template_fields'])) {
2346
-                EE_Error::add_error(
2347
-                    __('There was a problem saving the template fields from the form because I didn\'t receive any actual template field data.',
2348
-                        'event_espresso'),
2349
-                    __FILE__, __FUNCTION__, __LINE__
2350
-                );
2351
-                $success = 0;
2344
+			//run update for each template field in displayed context
2345
+			if ( ! isset($this->_req_data['MTP_template_fields']) && empty($this->_req_data['MTP_template_fields'])) {
2346
+				EE_Error::add_error(
2347
+					__('There was a problem saving the template fields from the form because I didn\'t receive any actual template field data.',
2348
+						'event_espresso'),
2349
+					__FILE__, __FUNCTION__, __LINE__
2350
+				);
2351
+				$success = 0;
2352 2352
                 
2353
-            } else {
2354
-                //first validate all fields!
2355
-                $validates = $MTPG->validate($this->_req_data['MTP_template_fields'], $context_slug, $messenger_slug,
2356
-                    $message_type_slug);
2353
+			} else {
2354
+				//first validate all fields!
2355
+				$validates = $MTPG->validate($this->_req_data['MTP_template_fields'], $context_slug, $messenger_slug,
2356
+					$message_type_slug);
2357 2357
                 
2358
-                //if $validate returned error messages (i.e. is_array()) then we need to process them and setup an appropriate response. HMM, dang this isn't correct, $validates will ALWAYS be an array.  WE need to make sure there is no actual error messages in validates.
2359
-                if (is_array($validates) && ! empty($validates)) {
2360
-                    //add the transient so when the form loads we know which fields to highlight
2361
-                    $this->_add_transient('edit_message_template', $validates);
2358
+				//if $validate returned error messages (i.e. is_array()) then we need to process them and setup an appropriate response. HMM, dang this isn't correct, $validates will ALWAYS be an array.  WE need to make sure there is no actual error messages in validates.
2359
+				if (is_array($validates) && ! empty($validates)) {
2360
+					//add the transient so when the form loads we know which fields to highlight
2361
+					$this->_add_transient('edit_message_template', $validates);
2362 2362
                     
2363
-                    $success = 0;
2363
+					$success = 0;
2364 2364
                     
2365
-                    //setup notices
2366
-                    foreach ($validates as $field => $error) {
2367
-                        if (isset($error['msg'])) {
2368
-                            EE_Error::add_error($error['msg'], __FILE__, __FUNCTION__, __LINE__);
2369
-                        }
2370
-                    }
2365
+					//setup notices
2366
+					foreach ($validates as $field => $error) {
2367
+						if (isset($error['msg'])) {
2368
+							EE_Error::add_error($error['msg'], __FILE__, __FUNCTION__, __LINE__);
2369
+						}
2370
+					}
2371 2371
                     
2372
-                } else {
2373
-                    $set_column_values = array();
2374
-                    foreach ($this->_req_data['MTP_template_fields'] as $template_field => $content) {
2375
-                        $set_column_values = $this->_set_message_template_column_values($template_field);
2372
+				} else {
2373
+					$set_column_values = array();
2374
+					foreach ($this->_req_data['MTP_template_fields'] as $template_field => $content) {
2375
+						$set_column_values = $this->_set_message_template_column_values($template_field);
2376 2376
                         
2377
-                        $where_cols_n_values = array(
2378
-                            'MTP_ID' => $this->_req_data['MTP_template_fields'][$template_field]['MTP_ID']
2379
-                        );
2377
+						$where_cols_n_values = array(
2378
+							'MTP_ID' => $this->_req_data['MTP_template_fields'][$template_field]['MTP_ID']
2379
+						);
2380 2380
                         
2381
-                        $message_template_fields = array(
2382
-                            'GRP_ID'             => $set_column_values['GRP_ID'],
2383
-                            'MTP_template_field' => $set_column_values['MTP_template_field'],
2384
-                            'MTP_context'        => $set_column_values['MTP_context'],
2385
-                            'MTP_content'        => $set_column_values['MTP_content']
2386
-                        );
2387
-                        if ($updated = $MTP->update($message_template_fields, array($where_cols_n_values))) {
2388
-                            if ($updated === false) {
2389
-                                EE_Error::add_error(
2390
-                                    sprintf(
2391
-                                        __('%s field was NOT updated for some reason', 'event_espresso'),
2392
-                                        $template_field
2393
-                                    ),
2394
-                                    __FILE__, __FUNCTION__, __LINE__
2395
-                                );
2396
-                            } else {
2397
-                                $success = 1;
2398
-                            }
2399
-                        }
2400
-                        $action_desc = 'updated';
2401
-                    }
2381
+						$message_template_fields = array(
2382
+							'GRP_ID'             => $set_column_values['GRP_ID'],
2383
+							'MTP_template_field' => $set_column_values['MTP_template_field'],
2384
+							'MTP_context'        => $set_column_values['MTP_context'],
2385
+							'MTP_content'        => $set_column_values['MTP_content']
2386
+						);
2387
+						if ($updated = $MTP->update($message_template_fields, array($where_cols_n_values))) {
2388
+							if ($updated === false) {
2389
+								EE_Error::add_error(
2390
+									sprintf(
2391
+										__('%s field was NOT updated for some reason', 'event_espresso'),
2392
+										$template_field
2393
+									),
2394
+									__FILE__, __FUNCTION__, __LINE__
2395
+								);
2396
+							} else {
2397
+								$success = 1;
2398
+							}
2399
+						}
2400
+						$action_desc = 'updated';
2401
+					}
2402 2402
                     
2403
-                    //we can use the last set_column_values for the MTPG update (because its the same for all of these specific MTPs)
2404
-                    $mtpg_fields = array(
2405
-                        'MTP_user_id'      => $set_column_values['MTP_user_id'],
2406
-                        'MTP_messenger'    => $set_column_values['MTP_messenger'],
2407
-                        'MTP_message_type' => $set_column_values['MTP_message_type'],
2408
-                        'MTP_is_global'    => $set_column_values['MTP_is_global'],
2409
-                        'MTP_is_override'  => $set_column_values['MTP_is_override'],
2410
-                        'MTP_deleted'      => $set_column_values['MTP_deleted'],
2411
-                        'MTP_is_active'    => $set_column_values['MTP_is_active'],
2412
-                        'MTP_name'         => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_name'])
2413
-                            ? $this->_req_data['ee_msg_non_global_fields']['MTP_name']
2414
-                            : '',
2415
-                        'MTP_description'  => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_description'])
2416
-                            ? $this->_req_data['ee_msg_non_global_fields']['MTP_description']
2417
-                            : ''
2418
-                    );
2403
+					//we can use the last set_column_values for the MTPG update (because its the same for all of these specific MTPs)
2404
+					$mtpg_fields = array(
2405
+						'MTP_user_id'      => $set_column_values['MTP_user_id'],
2406
+						'MTP_messenger'    => $set_column_values['MTP_messenger'],
2407
+						'MTP_message_type' => $set_column_values['MTP_message_type'],
2408
+						'MTP_is_global'    => $set_column_values['MTP_is_global'],
2409
+						'MTP_is_override'  => $set_column_values['MTP_is_override'],
2410
+						'MTP_deleted'      => $set_column_values['MTP_deleted'],
2411
+						'MTP_is_active'    => $set_column_values['MTP_is_active'],
2412
+						'MTP_name'         => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_name'])
2413
+							? $this->_req_data['ee_msg_non_global_fields']['MTP_name']
2414
+							: '',
2415
+						'MTP_description'  => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_description'])
2416
+							? $this->_req_data['ee_msg_non_global_fields']['MTP_description']
2417
+							: ''
2418
+					);
2419 2419
                     
2420
-                    $mtpg_where = array('GRP_ID' => $set_column_values['GRP_ID']);
2421
-                    $updated    = $MTPG->update($mtpg_fields, array($mtpg_where));
2420
+					$mtpg_where = array('GRP_ID' => $set_column_values['GRP_ID']);
2421
+					$updated    = $MTPG->update($mtpg_fields, array($mtpg_where));
2422 2422
                     
2423
-                    if ($updated === false) {
2424
-                        EE_Error::add_error(
2425
-                            sprintf(
2426
-                                __('The Message Template Group (%d) was NOT updated for some reason', 'event_espresso'),
2427
-                                $set_column_values['GRP_ID']
2428
-                            ),
2429
-                            __FILE__, __FUNCTION__, __LINE__
2430
-                        );
2431
-                    } else {
2432
-                        //k now we need to ensure the template_pack and template_variation fields are set.
2433
-                        $template_pack = ! empty($this->_req_data['MTP_template_pack'])
2434
-                            ? $this->_req_data['MTP_template_pack']
2435
-                            : 'default';
2423
+					if ($updated === false) {
2424
+						EE_Error::add_error(
2425
+							sprintf(
2426
+								__('The Message Template Group (%d) was NOT updated for some reason', 'event_espresso'),
2427
+								$set_column_values['GRP_ID']
2428
+							),
2429
+							__FILE__, __FUNCTION__, __LINE__
2430
+						);
2431
+					} else {
2432
+						//k now we need to ensure the template_pack and template_variation fields are set.
2433
+						$template_pack = ! empty($this->_req_data['MTP_template_pack'])
2434
+							? $this->_req_data['MTP_template_pack']
2435
+							: 'default';
2436 2436
                         
2437
-                        $template_variation = ! empty($this->_req_data['MTP_template_variation'])
2438
-                            ? $this->_req_data['MTP_template_variation']
2439
-                            : 'default';
2437
+						$template_variation = ! empty($this->_req_data['MTP_template_variation'])
2438
+							? $this->_req_data['MTP_template_variation']
2439
+							: 'default';
2440 2440
                         
2441
-                        $mtpg_obj = $MTPG->get_one_by_ID($set_column_values['GRP_ID']);
2442
-                        if ($mtpg_obj instanceof EE_Message_Template_Group) {
2443
-                            $mtpg_obj->set_template_pack_name($template_pack);
2444
-                            $mtpg_obj->set_template_pack_variation($template_variation);
2445
-                        }
2446
-                        $success = 1;
2447
-                    }
2448
-                }
2449
-            }
2441
+						$mtpg_obj = $MTPG->get_one_by_ID($set_column_values['GRP_ID']);
2442
+						if ($mtpg_obj instanceof EE_Message_Template_Group) {
2443
+							$mtpg_obj->set_template_pack_name($template_pack);
2444
+							$mtpg_obj->set_template_pack_variation($template_variation);
2445
+						}
2446
+						$success = 1;
2447
+					}
2448
+				}
2449
+			}
2450 2450
             
2451
-        }
2452
-        
2453
-        //we return things differently if doing ajax
2454
-        if (defined('DOING_AJAX') && DOING_AJAX) {
2455
-            $this->_template_args['success'] = $success;
2456
-            $this->_template_args['error']   = ! $success ? true : false;
2457
-            $this->_template_args['content'] = '';
2458
-            $this->_template_args['data']    = array(
2459
-                'grpID'        => $edit_array['GRP_ID'],
2460
-                'templateName' => $edit_array['template_name']
2461
-            );
2462
-            if ($success) {
2463
-                EE_Error::overwrite_success();
2464
-                EE_Error::add_success(__('The new template has been created and automatically selected for this event.  You can edit the new template by clicking the edit button.  Note before this template is assigned to this event, the event must be saved.',
2465
-                    'event_espresso'));
2466
-            }
2451
+		}
2452
+        
2453
+		//we return things differently if doing ajax
2454
+		if (defined('DOING_AJAX') && DOING_AJAX) {
2455
+			$this->_template_args['success'] = $success;
2456
+			$this->_template_args['error']   = ! $success ? true : false;
2457
+			$this->_template_args['content'] = '';
2458
+			$this->_template_args['data']    = array(
2459
+				'grpID'        => $edit_array['GRP_ID'],
2460
+				'templateName' => $edit_array['template_name']
2461
+			);
2462
+			if ($success) {
2463
+				EE_Error::overwrite_success();
2464
+				EE_Error::add_success(__('The new template has been created and automatically selected for this event.  You can edit the new template by clicking the edit button.  Note before this template is assigned to this event, the event must be saved.',
2465
+					'event_espresso'));
2466
+			}
2467 2467
             
2468
-            $this->_return_json();
2469
-        }
2470
-        
2471
-        
2472
-        //was a test send triggered?
2473
-        if (isset($this->_req_data['test_button'])) {
2474
-            EE_Error::overwrite_success();
2475
-            $this->_do_test_send($context_slug, $messenger_slug, $message_type_slug);
2476
-            $override = true;
2477
-        }
2478
-        
2479
-        if (empty($query_args)) {
2480
-            $query_args = array(
2481
-                'id'      => $this->_req_data['GRP_ID'],
2482
-                'context' => $context_slug,
2483
-                'action'  => 'edit_message_template'
2484
-            );
2485
-        }
2486
-        
2487
-        $this->_redirect_after_action($success, $item_desc, $action_desc, $query_args, $override);
2488
-    }
2489
-    
2490
-    
2491
-    /**
2492
-     * processes a test send request to do an actual messenger delivery test for the given message template being tested
2493
-     *
2494
-     * @param  string $context      what context being tested
2495
-     * @param  string $messenger    messenger being tested
2496
-     * @param  string $message_type message type being tested
2497
-     *
2498
-     */
2499
-    protected function _do_test_send($context, $messenger, $message_type)
2500
-    {
2501
-        //set things up for preview
2502
-        $this->_req_data['messenger']    = $messenger;
2503
-        $this->_req_data['message_type'] = $message_type;
2504
-        $this->_req_data['context']      = $context;
2505
-        $this->_req_data['GRP_ID']       = isset($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : '';
2506
-        $active_messenger                = $this->_message_resource_manager->get_active_messenger($messenger);
2507
-        
2508
-        //let's save any existing fields that might be required by the messenger
2509
-        if (
2510
-            isset($this->_req_data['test_settings_fld'])
2511
-            && $active_messenger instanceof EE_messenger
2512
-            && apply_filters(
2513
-                'FHEE__Messages_Admin_Page__do_test_send__set_existing_test_settings',
2514
-                true,
2515
-                $this->_req_data['test_settings_fld'],
2516
-                $active_messenger
2517
-            )
2518
-        ) {
2519
-            $active_messenger->set_existing_test_settings($this->_req_data['test_settings_fld']);
2520
-        }
2521
-        
2522
-        $success = $this->_preview_message(true);
2523
-        
2524
-        if ($success) {
2525
-            EE_Error::add_success(__('Test message sent', 'event_espresso'));
2526
-        } else {
2527
-            EE_Error::add_error(__('The test message was not sent', 'event_espresso'), __FILE__, __FUNCTION__,
2528
-                __LINE__);
2529
-        }
2530
-    }
2531
-    
2532
-    
2533
-    /**
2534
-     * _generate_new_templates
2535
-     * This will handle the messenger, message_type selection when "adding a new custom template" for an event and will
2536
-     * automatically create the defaults for the event.  The user would then be redirected to edit the default context
2537
-     * for the event.
2538
-     *
2539
-     *
2540
-     * @param  string $messenger     the messenger we are generating templates for
2541
-     * @param array   $message_types array of message types that the templates are generated for.
2542
-     * @param int     $GRP_ID        If this is a custom template being generated then a GRP_ID needs to be included to
2543
-     *                               indicate the message_template_group being used as the base.
2544
-     *
2545
-     * @param bool    $global
2546
-     *
2547
-     * @return array|bool array of data required for the redirect to the correct edit page or bool if
2548
-     *                               encountering problems.
2549
-     * @throws \EE_Error
2550
-     */
2551
-    protected function _generate_new_templates($messenger, $message_types, $GRP_ID = 0, $global = false)
2552
-    {
2553
-        
2554
-        //if no $message_types are given then that's okay... this may be a messenger that just adds shortcodes, so we just don't generate any templates.
2555
-        if (empty($message_types)) {
2556
-            return true;
2557
-        }
2558
-        
2559
-        return EEH_MSG_Template::generate_new_templates($messenger, $message_types, $GRP_ID, $global);
2560
-    }
2561
-    
2562
-    
2563
-    /**
2564
-     * [_trash_or_restore_message_template]
2565
-     *
2566
-     * @param  boolean $trash whether to move an item to trash/restore (TRUE) or restore it (FALSE)
2567
-     * @param boolean  $all   whether this is going to trash/restore all contexts within a template group (TRUE) OR just
2568
-     *                        an individual context (FALSE).
2569
-     *
2570
-     * @return void
2571
-     */
2572
-    protected function _trash_or_restore_message_template($trash = true, $all = false)
2573
-    {
2574
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2575
-        $MTP = EEM_Message_Template_Group::instance();
2576
-        
2577
-        $success = 1;
2578
-        
2579
-        //incoming GRP_IDs
2580
-        if ($all) {
2581
-            //Checkboxes
2582
-            if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
2583
-                //if array has more than one element then success message should be plural.
2584
-                //todo: what about nonce?
2585
-                $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
2468
+			$this->_return_json();
2469
+		}
2470
+        
2471
+        
2472
+		//was a test send triggered?
2473
+		if (isset($this->_req_data['test_button'])) {
2474
+			EE_Error::overwrite_success();
2475
+			$this->_do_test_send($context_slug, $messenger_slug, $message_type_slug);
2476
+			$override = true;
2477
+		}
2478
+        
2479
+		if (empty($query_args)) {
2480
+			$query_args = array(
2481
+				'id'      => $this->_req_data['GRP_ID'],
2482
+				'context' => $context_slug,
2483
+				'action'  => 'edit_message_template'
2484
+			);
2485
+		}
2486
+        
2487
+		$this->_redirect_after_action($success, $item_desc, $action_desc, $query_args, $override);
2488
+	}
2489
+    
2490
+    
2491
+	/**
2492
+	 * processes a test send request to do an actual messenger delivery test for the given message template being tested
2493
+	 *
2494
+	 * @param  string $context      what context being tested
2495
+	 * @param  string $messenger    messenger being tested
2496
+	 * @param  string $message_type message type being tested
2497
+	 *
2498
+	 */
2499
+	protected function _do_test_send($context, $messenger, $message_type)
2500
+	{
2501
+		//set things up for preview
2502
+		$this->_req_data['messenger']    = $messenger;
2503
+		$this->_req_data['message_type'] = $message_type;
2504
+		$this->_req_data['context']      = $context;
2505
+		$this->_req_data['GRP_ID']       = isset($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : '';
2506
+		$active_messenger                = $this->_message_resource_manager->get_active_messenger($messenger);
2507
+        
2508
+		//let's save any existing fields that might be required by the messenger
2509
+		if (
2510
+			isset($this->_req_data['test_settings_fld'])
2511
+			&& $active_messenger instanceof EE_messenger
2512
+			&& apply_filters(
2513
+				'FHEE__Messages_Admin_Page__do_test_send__set_existing_test_settings',
2514
+				true,
2515
+				$this->_req_data['test_settings_fld'],
2516
+				$active_messenger
2517
+			)
2518
+		) {
2519
+			$active_messenger->set_existing_test_settings($this->_req_data['test_settings_fld']);
2520
+		}
2521
+        
2522
+		$success = $this->_preview_message(true);
2523
+        
2524
+		if ($success) {
2525
+			EE_Error::add_success(__('Test message sent', 'event_espresso'));
2526
+		} else {
2527
+			EE_Error::add_error(__('The test message was not sent', 'event_espresso'), __FILE__, __FUNCTION__,
2528
+				__LINE__);
2529
+		}
2530
+	}
2531
+    
2532
+    
2533
+	/**
2534
+	 * _generate_new_templates
2535
+	 * This will handle the messenger, message_type selection when "adding a new custom template" for an event and will
2536
+	 * automatically create the defaults for the event.  The user would then be redirected to edit the default context
2537
+	 * for the event.
2538
+	 *
2539
+	 *
2540
+	 * @param  string $messenger     the messenger we are generating templates for
2541
+	 * @param array   $message_types array of message types that the templates are generated for.
2542
+	 * @param int     $GRP_ID        If this is a custom template being generated then a GRP_ID needs to be included to
2543
+	 *                               indicate the message_template_group being used as the base.
2544
+	 *
2545
+	 * @param bool    $global
2546
+	 *
2547
+	 * @return array|bool array of data required for the redirect to the correct edit page or bool if
2548
+	 *                               encountering problems.
2549
+	 * @throws \EE_Error
2550
+	 */
2551
+	protected function _generate_new_templates($messenger, $message_types, $GRP_ID = 0, $global = false)
2552
+	{
2553
+        
2554
+		//if no $message_types are given then that's okay... this may be a messenger that just adds shortcodes, so we just don't generate any templates.
2555
+		if (empty($message_types)) {
2556
+			return true;
2557
+		}
2558
+        
2559
+		return EEH_MSG_Template::generate_new_templates($messenger, $message_types, $GRP_ID, $global);
2560
+	}
2561
+    
2562
+    
2563
+	/**
2564
+	 * [_trash_or_restore_message_template]
2565
+	 *
2566
+	 * @param  boolean $trash whether to move an item to trash/restore (TRUE) or restore it (FALSE)
2567
+	 * @param boolean  $all   whether this is going to trash/restore all contexts within a template group (TRUE) OR just
2568
+	 *                        an individual context (FALSE).
2569
+	 *
2570
+	 * @return void
2571
+	 */
2572
+	protected function _trash_or_restore_message_template($trash = true, $all = false)
2573
+	{
2574
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2575
+		$MTP = EEM_Message_Template_Group::instance();
2576
+        
2577
+		$success = 1;
2578
+        
2579
+		//incoming GRP_IDs
2580
+		if ($all) {
2581
+			//Checkboxes
2582
+			if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
2583
+				//if array has more than one element then success message should be plural.
2584
+				//todo: what about nonce?
2585
+				$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
2586 2586
                 
2587
-                //cycle through checkboxes
2588
-                while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
2589
-                    $trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
2590
-                    if ( ! $trashed_or_restored) {
2591
-                        $success = 0;
2592
-                    }
2593
-                }
2594
-            } else {
2595
-                //grab single GRP_ID and handle
2596
-                $GRP_ID = isset($this->_req_data['id']) ? absint($this->_req_data['id']) : 0;
2597
-                if ( ! empty($GRP_ID)) {
2598
-                    $trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
2599
-                    if ( ! $trashed_or_restored) {
2600
-                        $success = 0;
2601
-                    }
2602
-                } else {
2603
-                    $success = 0;
2604
-                }
2605
-            }
2587
+				//cycle through checkboxes
2588
+				while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
2589
+					$trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
2590
+					if ( ! $trashed_or_restored) {
2591
+						$success = 0;
2592
+					}
2593
+				}
2594
+			} else {
2595
+				//grab single GRP_ID and handle
2596
+				$GRP_ID = isset($this->_req_data['id']) ? absint($this->_req_data['id']) : 0;
2597
+				if ( ! empty($GRP_ID)) {
2598
+					$trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
2599
+					if ( ! $trashed_or_restored) {
2600
+						$success = 0;
2601
+					}
2602
+				} else {
2603
+					$success = 0;
2604
+				}
2605
+			}
2606 2606
             
2607
-        }
2607
+		}
2608 2608
         
2609
-        $action_desc = $trash ? __('moved to the trash', 'event_espresso') : __('restored', 'event_espresso');
2609
+		$action_desc = $trash ? __('moved to the trash', 'event_espresso') : __('restored', 'event_espresso');
2610 2610
         
2611
-        $action_desc = ! empty($this->_req_data['template_switch']) ? __('switched') : $action_desc;
2611
+		$action_desc = ! empty($this->_req_data['template_switch']) ? __('switched') : $action_desc;
2612 2612
         
2613
-        $item_desc = $all ? _n('Message Template Group', 'Message Template Groups', $success,
2614
-            'event_espresso') : _n('Message Template Context', 'Message Template Contexts', $success, 'event_espresso');
2613
+		$item_desc = $all ? _n('Message Template Group', 'Message Template Groups', $success,
2614
+			'event_espresso') : _n('Message Template Context', 'Message Template Contexts', $success, 'event_espresso');
2615 2615
         
2616
-        $item_desc = ! empty($this->_req_data['template_switch']) ? _n('template', 'templates', $success,
2617
-            'event_espresso') : $item_desc;
2616
+		$item_desc = ! empty($this->_req_data['template_switch']) ? _n('template', 'templates', $success,
2617
+			'event_espresso') : $item_desc;
2618 2618
         
2619
-        $this->_redirect_after_action($success, $item_desc, $action_desc, array());
2619
+		$this->_redirect_after_action($success, $item_desc, $action_desc, array());
2620 2620
         
2621
-    }
2621
+	}
2622 2622
     
2623 2623
     
2624
-    /**
2625
-     * [_delete_message_template]
2626
-     * NOTE: this handles not only the deletion of the groups but also all the templates belonging to that group.
2627
-     * @return void
2628
-     */
2629
-    protected function _delete_message_template()
2630
-    {
2631
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2624
+	/**
2625
+	 * [_delete_message_template]
2626
+	 * NOTE: this handles not only the deletion of the groups but also all the templates belonging to that group.
2627
+	 * @return void
2628
+	 */
2629
+	protected function _delete_message_template()
2630
+	{
2631
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2632 2632
         
2633
-        //checkboxes
2634
-        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
2635
-            //if array has more than one element then success message should be plural
2636
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
2633
+		//checkboxes
2634
+		if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
2635
+			//if array has more than one element then success message should be plural
2636
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
2637 2637
             
2638
-            //cycle through bulk action checkboxes
2639
-            while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
2640
-                $success = $this->_delete_mtp_permanently($GRP_ID);
2641
-            }
2642
-        } else {
2643
-            //grab single grp_id and delete
2644
-            $GRP_ID  = absint($this->_req_data['id']);
2645
-            $success = $this->_delete_mtp_permanently($GRP_ID);
2646
-        }
2647
-        
2648
-        $this->_redirect_after_action($success, 'Message Templates', 'deleted', array());
2649
-        
2650
-    }
2651
-    
2652
-    
2653
-    /**
2654
-     * helper for permanently deleting a mtP group and all related message_templates
2655
-     *
2656
-     * @param  int  $GRP_ID        The group being deleted
2657
-     * @param  bool $include_group whether to delete the Message Template Group as well.
2658
-     *
2659
-     * @return bool        boolean to indicate the success of the deletes or not.
2660
-     */
2661
-    private function _delete_mtp_permanently($GRP_ID, $include_group = true)
2662
-    {
2663
-        $success = 1;
2664
-        $MTPG    = EEM_Message_Template_Group::instance();
2665
-        //first let's GET this group
2666
-        $MTG = $MTPG->get_one_by_ID($GRP_ID);
2667
-        //then delete permanently all the related Message Templates
2668
-        $deleted = $MTG->delete_related_permanently('Message_Template');
2669
-        
2670
-        if ($deleted === 0) {
2671
-            $success = 0;
2672
-        }
2673
-        
2674
-        //now delete permanently this particular group
2675
-        
2676
-        if ($include_group && ! $MTG->delete_permanently()) {
2677
-            $success = 0;
2678
-        }
2679
-        
2680
-        return $success;
2681
-    }
2682
-    
2683
-    
2684
-    /**
2685
-     *    _learn_more_about_message_templates_link
2686
-     * @access protected
2687
-     * @return string
2688
-     */
2689
-    protected function _learn_more_about_message_templates_link()
2690
-    {
2691
-        return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >' . __('learn more about how message templates works',
2692
-            'event_espresso') . '</a>';
2693
-    }
2694
-    
2695
-    
2696
-    /**
2697
-     * Used for setting up messenger/message type activation.  This loads up the initial view.  The rest is handled by
2698
-     * ajax and other routes.
2699
-     * @return void
2700
-     */
2701
-    protected function _settings()
2702
-    {
2703
-        
2704
-        
2705
-        $this->_set_m_mt_settings();
2706
-        
2707
-        $selected_messenger = isset($this->_req_data['selected_messenger']) ? $this->_req_data['selected_messenger'] : 'email';
2708
-        
2709
-        //let's setup the messenger tabs
2710
-        $this->_template_args['admin_page_header']         = EEH_Tabbed_Content::tab_text_links($this->_m_mt_settings['messenger_tabs'],
2711
-            'messenger_links', '|', $selected_messenger);
2712
-        $this->_template_args['before_admin_page_content'] = '<div class="ui-widget ui-helper-clearfix">';
2713
-        $this->_template_args['after_admin_page_content']  = '</div><!-- end .ui-widget -->';
2714
-        
2715
-        $this->display_admin_page_with_sidebar();
2716
-        
2717
-    }
2718
-    
2719
-    
2720
-    /**
2721
-     * This sets the $_m_mt_settings property for when needed (used on the Messages settings page)
2722
-     *
2723
-     * @access protected
2724
-     * @return void
2725
-     */
2726
-    protected function _set_m_mt_settings()
2727
-    {
2728
-        //first if this is already set then lets get out no need to regenerate data.
2729
-        if ( ! empty($this->_m_mt_settings)) {
2730
-            return;
2731
-        }
2732
-        
2733
-        //$selected_messenger = isset( $this->_req_data['selected_messenger'] ) ? $this->_req_data['selected_messenger'] : 'email';
2734
-        
2735
-        //get all installed messengers and message_types
2736
-        /** @type EE_messenger[] $messengers */
2737
-        $messengers = $this->_message_resource_manager->installed_messengers();
2738
-        /** @type EE_message_type[] $message_types */
2739
-        $message_types = $this->_message_resource_manager->installed_message_types();
2740
-        
2741
-        
2742
-        //assemble the array for the _tab_text_links helper
2743
-        
2744
-        foreach ($messengers as $messenger) {
2745
-            $this->_m_mt_settings['messenger_tabs'][$messenger->name] = array(
2746
-                'label' => ucwords($messenger->label['singular']),
2747
-                'class' => $this->_message_resource_manager->is_messenger_active($messenger->name) ? 'messenger-active' : '',
2748
-                'href'  => $messenger->name,
2749
-                'title' => __('Modify this Messenger', 'event_espresso'),
2750
-                'slug'  => $messenger->name,
2751
-                'obj'   => $messenger
2752
-            );
2638
+			//cycle through bulk action checkboxes
2639
+			while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
2640
+				$success = $this->_delete_mtp_permanently($GRP_ID);
2641
+			}
2642
+		} else {
2643
+			//grab single grp_id and delete
2644
+			$GRP_ID  = absint($this->_req_data['id']);
2645
+			$success = $this->_delete_mtp_permanently($GRP_ID);
2646
+		}
2647
+        
2648
+		$this->_redirect_after_action($success, 'Message Templates', 'deleted', array());
2649
+        
2650
+	}
2651
+    
2652
+    
2653
+	/**
2654
+	 * helper for permanently deleting a mtP group and all related message_templates
2655
+	 *
2656
+	 * @param  int  $GRP_ID        The group being deleted
2657
+	 * @param  bool $include_group whether to delete the Message Template Group as well.
2658
+	 *
2659
+	 * @return bool        boolean to indicate the success of the deletes or not.
2660
+	 */
2661
+	private function _delete_mtp_permanently($GRP_ID, $include_group = true)
2662
+	{
2663
+		$success = 1;
2664
+		$MTPG    = EEM_Message_Template_Group::instance();
2665
+		//first let's GET this group
2666
+		$MTG = $MTPG->get_one_by_ID($GRP_ID);
2667
+		//then delete permanently all the related Message Templates
2668
+		$deleted = $MTG->delete_related_permanently('Message_Template');
2669
+        
2670
+		if ($deleted === 0) {
2671
+			$success = 0;
2672
+		}
2673
+        
2674
+		//now delete permanently this particular group
2675
+        
2676
+		if ($include_group && ! $MTG->delete_permanently()) {
2677
+			$success = 0;
2678
+		}
2679
+        
2680
+		return $success;
2681
+	}
2682
+    
2683
+    
2684
+	/**
2685
+	 *    _learn_more_about_message_templates_link
2686
+	 * @access protected
2687
+	 * @return string
2688
+	 */
2689
+	protected function _learn_more_about_message_templates_link()
2690
+	{
2691
+		return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >' . __('learn more about how message templates works',
2692
+			'event_espresso') . '</a>';
2693
+	}
2694
+    
2695
+    
2696
+	/**
2697
+	 * Used for setting up messenger/message type activation.  This loads up the initial view.  The rest is handled by
2698
+	 * ajax and other routes.
2699
+	 * @return void
2700
+	 */
2701
+	protected function _settings()
2702
+	{
2703
+        
2704
+        
2705
+		$this->_set_m_mt_settings();
2706
+        
2707
+		$selected_messenger = isset($this->_req_data['selected_messenger']) ? $this->_req_data['selected_messenger'] : 'email';
2708
+        
2709
+		//let's setup the messenger tabs
2710
+		$this->_template_args['admin_page_header']         = EEH_Tabbed_Content::tab_text_links($this->_m_mt_settings['messenger_tabs'],
2711
+			'messenger_links', '|', $selected_messenger);
2712
+		$this->_template_args['before_admin_page_content'] = '<div class="ui-widget ui-helper-clearfix">';
2713
+		$this->_template_args['after_admin_page_content']  = '</div><!-- end .ui-widget -->';
2714
+        
2715
+		$this->display_admin_page_with_sidebar();
2716
+        
2717
+	}
2718
+    
2719
+    
2720
+	/**
2721
+	 * This sets the $_m_mt_settings property for when needed (used on the Messages settings page)
2722
+	 *
2723
+	 * @access protected
2724
+	 * @return void
2725
+	 */
2726
+	protected function _set_m_mt_settings()
2727
+	{
2728
+		//first if this is already set then lets get out no need to regenerate data.
2729
+		if ( ! empty($this->_m_mt_settings)) {
2730
+			return;
2731
+		}
2732
+        
2733
+		//$selected_messenger = isset( $this->_req_data['selected_messenger'] ) ? $this->_req_data['selected_messenger'] : 'email';
2734
+        
2735
+		//get all installed messengers and message_types
2736
+		/** @type EE_messenger[] $messengers */
2737
+		$messengers = $this->_message_resource_manager->installed_messengers();
2738
+		/** @type EE_message_type[] $message_types */
2739
+		$message_types = $this->_message_resource_manager->installed_message_types();
2740
+        
2741
+        
2742
+		//assemble the array for the _tab_text_links helper
2743
+        
2744
+		foreach ($messengers as $messenger) {
2745
+			$this->_m_mt_settings['messenger_tabs'][$messenger->name] = array(
2746
+				'label' => ucwords($messenger->label['singular']),
2747
+				'class' => $this->_message_resource_manager->is_messenger_active($messenger->name) ? 'messenger-active' : '',
2748
+				'href'  => $messenger->name,
2749
+				'title' => __('Modify this Messenger', 'event_espresso'),
2750
+				'slug'  => $messenger->name,
2751
+				'obj'   => $messenger
2752
+			);
2753 2753
             
2754 2754
             
2755
-            $message_types_for_messenger = $messenger->get_valid_message_types();
2755
+			$message_types_for_messenger = $messenger->get_valid_message_types();
2756 2756
             
2757
-            foreach ($message_types as $message_type) {
2758
-                //first we need to verify that this message type is valid with this messenger. Cause if it isn't then it shouldn't show in either the inactive OR active metabox.
2759
-                if ( ! in_array($message_type->name, $message_types_for_messenger)) {
2760
-                    continue;
2761
-                }
2757
+			foreach ($message_types as $message_type) {
2758
+				//first we need to verify that this message type is valid with this messenger. Cause if it isn't then it shouldn't show in either the inactive OR active metabox.
2759
+				if ( ! in_array($message_type->name, $message_types_for_messenger)) {
2760
+					continue;
2761
+				}
2762 2762
                 
2763
-                $a_or_i = $this->_message_resource_manager->is_message_type_active_for_messenger($messenger->name,
2764
-                    $message_type->name) ? 'active' : 'inactive';
2763
+				$a_or_i = $this->_message_resource_manager->is_message_type_active_for_messenger($messenger->name,
2764
+					$message_type->name) ? 'active' : 'inactive';
2765 2765
                 
2766
-                $this->_m_mt_settings['message_type_tabs'][$messenger->name][$a_or_i][$message_type->name] = array(
2767
-                    'label'    => ucwords($message_type->label['singular']),
2768
-                    'class'    => 'message-type-' . $a_or_i,
2769
-                    'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
2770
-                    'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
2771
-                    'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
2772
-                    'title'    => $a_or_i == 'active'
2773
-                        ? __('Drag this message type to the Inactive window to deactivate', 'event_espresso')
2774
-                        : __('Drag this message type to the messenger to activate', 'event_espresso'),
2775
-                    'content'  => $a_or_i == 'active'
2776
-                        ? $this->_message_type_settings_content($message_type, $messenger, true)
2777
-                        : $this->_message_type_settings_content($message_type, $messenger),
2778
-                    'slug'     => $message_type->name,
2779
-                    'active'   => $a_or_i == 'active' ? true : false,
2780
-                    'obj'      => $message_type
2781
-                );
2782
-            }
2783
-        }
2784
-    }
2785
-    
2786
-    
2787
-    /**
2788
-     * This just prepares the content for the message type settings
2789
-     *
2790
-     * @param  object  $message_type The message type object
2791
-     * @param  object  $messenger    The messenger object
2792
-     * @param  boolean $active       Whether the message type is active or not
2793
-     *
2794
-     * @return string                html output for the content
2795
-     */
2796
-    protected function _message_type_settings_content($message_type, $messenger, $active = false)
2797
-    {
2798
-        //get message type fields
2799
-        $fields                                         = $message_type->get_admin_settings_fields();
2800
-        $settings_template_args['template_form_fields'] = '';
2801
-        
2802
-        if ( ! empty($fields) && $active) {
2766
+				$this->_m_mt_settings['message_type_tabs'][$messenger->name][$a_or_i][$message_type->name] = array(
2767
+					'label'    => ucwords($message_type->label['singular']),
2768
+					'class'    => 'message-type-' . $a_or_i,
2769
+					'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
2770
+					'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
2771
+					'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
2772
+					'title'    => $a_or_i == 'active'
2773
+						? __('Drag this message type to the Inactive window to deactivate', 'event_espresso')
2774
+						: __('Drag this message type to the messenger to activate', 'event_espresso'),
2775
+					'content'  => $a_or_i == 'active'
2776
+						? $this->_message_type_settings_content($message_type, $messenger, true)
2777
+						: $this->_message_type_settings_content($message_type, $messenger),
2778
+					'slug'     => $message_type->name,
2779
+					'active'   => $a_or_i == 'active' ? true : false,
2780
+					'obj'      => $message_type
2781
+				);
2782
+			}
2783
+		}
2784
+	}
2785
+    
2786
+    
2787
+	/**
2788
+	 * This just prepares the content for the message type settings
2789
+	 *
2790
+	 * @param  object  $message_type The message type object
2791
+	 * @param  object  $messenger    The messenger object
2792
+	 * @param  boolean $active       Whether the message type is active or not
2793
+	 *
2794
+	 * @return string                html output for the content
2795
+	 */
2796
+	protected function _message_type_settings_content($message_type, $messenger, $active = false)
2797
+	{
2798
+		//get message type fields
2799
+		$fields                                         = $message_type->get_admin_settings_fields();
2800
+		$settings_template_args['template_form_fields'] = '';
2801
+        
2802
+		if ( ! empty($fields) && $active) {
2803 2803
             
2804
-            $existing_settings = $message_type->get_existing_admin_settings($messenger->name);
2804
+			$existing_settings = $message_type->get_existing_admin_settings($messenger->name);
2805 2805
             
2806
-            foreach ($fields as $fldname => $fldprops) {
2807
-                $field_id                       = $messenger->name . '-' . $message_type->name . '-' . $fldname;
2808
-                $template_form_field[$field_id] = array(
2809
-                    'name'       => 'message_type_settings[' . $fldname . ']',
2810
-                    'label'      => $fldprops['label'],
2811
-                    'input'      => $fldprops['field_type'],
2812
-                    'type'       => $fldprops['value_type'],
2813
-                    'required'   => $fldprops['required'],
2814
-                    'validation' => $fldprops['validation'],
2815
-                    'value'      => isset($existing_settings[$fldname]) ? $existing_settings[$fldname] : $fldprops['default'],
2816
-                    'options'    => isset($fldprops['options']) ? $fldprops['options'] : array(),
2817
-                    'default'    => isset($existing_settings[$fldname]) ? $existing_settings[$fldname] : $fldprops['default'],
2818
-                    'css_class'  => 'no-drag',
2819
-                    'format'     => $fldprops['format']
2820
-                );
2821
-            }
2806
+			foreach ($fields as $fldname => $fldprops) {
2807
+				$field_id                       = $messenger->name . '-' . $message_type->name . '-' . $fldname;
2808
+				$template_form_field[$field_id] = array(
2809
+					'name'       => 'message_type_settings[' . $fldname . ']',
2810
+					'label'      => $fldprops['label'],
2811
+					'input'      => $fldprops['field_type'],
2812
+					'type'       => $fldprops['value_type'],
2813
+					'required'   => $fldprops['required'],
2814
+					'validation' => $fldprops['validation'],
2815
+					'value'      => isset($existing_settings[$fldname]) ? $existing_settings[$fldname] : $fldprops['default'],
2816
+					'options'    => isset($fldprops['options']) ? $fldprops['options'] : array(),
2817
+					'default'    => isset($existing_settings[$fldname]) ? $existing_settings[$fldname] : $fldprops['default'],
2818
+					'css_class'  => 'no-drag',
2819
+					'format'     => $fldprops['format']
2820
+				);
2821
+			}
2822 2822
             
2823 2823
             
2824
-            $settings_template_args['template_form_fields'] = ! empty($template_form_field) ? $this->_generate_admin_form_fields($template_form_field,
2825
-                'string', 'ee_mt_activate_form') : '';
2826
-        }
2827
-        
2828
-        $settings_template_args['description'] = $message_type->description;
2829
-        //we also need some hidden fields
2830
-        $settings_template_args['hidden_fields'] = array(
2831
-            'message_type_settings[messenger]'    => array(
2832
-                'type'  => 'hidden',
2833
-                'value' => $messenger->name
2834
-            ),
2835
-            'message_type_settings[message_type]' => array(
2836
-                'type'  => 'hidden',
2837
-                'value' => $message_type->name
2838
-            ),
2839
-            'type'                                => array(
2840
-                'type'  => 'hidden',
2841
-                'value' => 'message_type'
2842
-            )
2843
-        );
2844
-        
2845
-        $settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields($settings_template_args['hidden_fields'],
2846
-            'array');
2847
-        $settings_template_args['show_form']     = empty($settings_template_args['template_form_fields']) ? ' hidden' : '';
2848
-        
2849
-        
2850
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
2851
-        $content  = EEH_Template::display_template($template, $settings_template_args, true);
2852
-        
2853
-        return $content;
2854
-    }
2855
-    
2856
-    
2857
-    /**
2858
-     * Generate all the metaboxes for the message types and register them for the messages settings page.
2859
-     *
2860
-     * @access protected
2861
-     * @return void
2862
-     */
2863
-    protected function _messages_settings_metaboxes()
2864
-    {
2865
-        $this->_set_m_mt_settings();
2866
-        $m_boxes         = $mt_boxes = array();
2867
-        $m_template_args = $mt_template_args = array();
2868
-        
2869
-        $selected_messenger = isset($this->_req_data['selected_messenger']) ? $this->_req_data['selected_messenger'] : 'email';
2870
-        
2871
-        if (isset($this->_m_mt_settings['messenger_tabs'])) {
2872
-            foreach ($this->_m_mt_settings['messenger_tabs'] as $messenger => $tab_array) {
2873
-                $hide_on_message  = $this->_message_resource_manager->is_messenger_active($messenger) ? '' : 'hidden';
2874
-                $hide_off_message = $this->_message_resource_manager->is_messenger_active($messenger) ? 'hidden' : '';
2875
-                //messenger meta boxes
2876
-                $active                                 = $selected_messenger == $messenger ? true : false;
2877
-                $active_mt_tabs                         = isset($this->_m_mt_settings['message_type_tabs'][$messenger]['active'])
2878
-                    ? $this->_m_mt_settings['message_type_tabs'][$messenger]['active']
2879
-                    : '';
2880
-                $m_boxes[$messenger . '_a_box']         = sprintf(
2881
-                    __('%s Settings', 'event_espresso'),
2882
-                    $tab_array['label']
2883
-                );
2884
-                $m_template_args[$messenger . '_a_box'] = array(
2885
-                    'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
2886
-                    'inactive_message_types' => isset($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
2887
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
2888
-                        : '',
2889
-                    'content'                => $this->_get_messenger_box_content($tab_array['obj']),
2890
-                    'hidden'                 => $active ? '' : ' hidden',
2891
-                    'hide_on_message'        => $hide_on_message,
2892
-                    'messenger'              => $messenger,
2893
-                    'active'                 => $active
2894
-                );
2895
-                // message type meta boxes
2896
-                // (which is really just the inactive container for each messenger
2897
-                // showing inactive message types for that messenger)
2898
-                $mt_boxes[$messenger . '_i_box']         = __('Inactive Message Types', 'event_espresso');
2899
-                $mt_template_args[$messenger . '_i_box'] = array(
2900
-                    'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
2901
-                    'inactive_message_types' => isset($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
2902
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
2903
-                        : '',
2904
-                    'hidden'                 => $active ? '' : ' hidden',
2905
-                    'hide_on_message'        => $hide_on_message,
2906
-                    'hide_off_message'       => $hide_off_message,
2907
-                    'messenger'              => $messenger,
2908
-                    'active'                 => $active
2909
-                );
2910
-            }
2911
-        }
2912
-        
2913
-        
2914
-        //register messenger metaboxes
2915
-        $m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
2916
-        foreach ($m_boxes as $box => $label) {
2917
-            $callback_args = array('template_path' => $m_template_path, 'template_args' => $m_template_args[$box]);
2918
-            $msgr          = str_replace('_a_box', '', $box);
2919
-            add_meta_box(
2920
-                'espresso_' . $msgr . '_settings',
2921
-                $label,
2922
-                function ($post, $metabox) {
2923
-                    echo EEH_Template::display_template($metabox["args"]["template_path"],
2924
-                        $metabox["args"]["template_args"], true);
2925
-                },
2926
-                $this->_current_screen->id,
2927
-                'normal',
2928
-                'high',
2929
-                $callback_args
2930
-            );
2931
-        }
2932
-        
2933
-        //register message type metaboxes
2934
-        $mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
2935
-        foreach ($mt_boxes as $box => $label) {
2936
-            $callback_args = array(
2937
-                'template_path' => $mt_template_path,
2938
-                'template_args' => $mt_template_args[$box]
2939
-            );
2940
-            $mt            = str_replace('_i_box', '', $box);
2941
-            add_meta_box(
2942
-                'espresso_' . $mt . '_inactive_mts',
2943
-                $label,
2944
-                function ($post, $metabox) {
2945
-                    echo EEH_Template::display_template($metabox["args"]["template_path"],
2946
-                        $metabox["args"]["template_args"], true);
2947
-                },
2948
-                $this->_current_screen->id,
2949
-                'side',
2950
-                'high',
2951
-                $callback_args
2952
-            );
2953
-        }
2954
-        
2955
-        //register metabox for global messages settings but only when on the main site.  On single site installs this will
2956
-        //always result in the metabox showing, on multisite installs the metabox will only show on the main site.
2957
-        if (is_main_site()) {
2958
-            add_meta_box(
2959
-                'espresso_global_message_settings',
2960
-                __('Global Message Settings', 'event_espresso'),
2961
-                array($this, 'global_messages_settings_metabox_content'),
2962
-                $this->_current_screen->id,
2963
-                'normal',
2964
-                'low',
2965
-                array()
2966
-            );
2967
-        }
2968
-        
2969
-    }
2970
-    
2971
-    
2972
-    /**
2973
-     *  This generates the content for the global messages settings metabox.
2974
-     * @return string
2975
-     */
2976
-    public function global_messages_settings_metabox_content()
2977
-    {
2978
-        $form = $this->_generate_global_settings_form();
2979
-        echo $form->form_open(
2980
-                $this->add_query_args_and_nonce(array('action' => 'update_global_settings'), EE_MSG_ADMIN_URL),
2981
-                'POST'
2982
-            )
2983
-             . $form->get_html()
2984
-             . $form->form_close();
2985
-    }
2986
-    
2987
-    
2988
-    /**
2989
-     * This generates and returns the form object for the global messages settings.
2990
-     * @return EE_Form_Section_Proper
2991
-     */
2992
-    protected function _generate_global_settings_form()
2993
-    {
2994
-        EE_Registry::instance()->load_helper('HTML');
2995
-        /** @var EE_Network_Core_Config $network_config */
2996
-        $network_config = EE_Registry::instance()->NET_CFG->core;
2997
-        
2998
-        return new EE_Form_Section_Proper(
2999
-            array(
3000
-                'name'            => 'global_messages_settings',
3001
-                'html_id'         => 'global_messages_settings',
3002
-                'html_class'      => 'form-table',
3003
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
3004
-                'subsections'     => apply_filters(
3005
-                    'FHEE__Messages_Admin_Page__global_messages_settings_metabox_content__form_subsections',
3006
-                    array(
3007
-                        'do_messages_on_same_request' => new EE_Select_Input(
3008
-                            array(
3009
-                                true  => esc_html__("On the same request", "event_espresso"),
3010
-                                false => esc_html__("On a separate request", "event_espresso")
3011
-                            ),
3012
-                            array(
3013
-                                'default'         => $network_config->do_messages_on_same_request,
3014
-                                'html_label_text' => esc_html__('Generate and send all messages:', 'event_espresso'),
3015
-                                'html_help_text'  => esc_html__('By default the messages system uses a more efficient means of processing messages on separate requests and utilizes the wp-cron scheduling system.  This makes things execute faster for people registering for your events.  However, if the wp-cron system is disabled on your site and there is no alternative in place, then you can change this so messages are always executed on the same request.',
3016
-                                    'event_espresso'),
3017
-                            )
3018
-                        ),
3019
-                        'delete_threshold' => new EE_Select_Input(
3020
-                            array(
3021
-                                0 => esc_html__('Forever', 'event_espresso'),
3022
-                                3 => esc_html__('3 Months', 'event_espresso'),
3023
-                                6 => esc_html__('6 Months', 'event_espresso'),
3024
-                                9 => esc_html__('9 Months', 'event_espresso'),
3025
-                                12 => esc_html__('12 Months', 'event_espresso'),
3026
-                                24 => esc_html__('24 Months', 'event_espresso'),
3027
-                                36 => esc_html__('36 Months', 'event_espresso')
3028
-                            ),
3029
-                            array(
3030
-                                'default' => EE_Registry::instance()->CFG->messages->delete_threshold,
3031
-                                'html_label_text' => esc_html__('Cleanup of old messages:', 'event_espresso'),
3032
-                                'html_help_text' => esc_html__('You can control how long a record of processed messages is kept 
2824
+			$settings_template_args['template_form_fields'] = ! empty($template_form_field) ? $this->_generate_admin_form_fields($template_form_field,
2825
+				'string', 'ee_mt_activate_form') : '';
2826
+		}
2827
+        
2828
+		$settings_template_args['description'] = $message_type->description;
2829
+		//we also need some hidden fields
2830
+		$settings_template_args['hidden_fields'] = array(
2831
+			'message_type_settings[messenger]'    => array(
2832
+				'type'  => 'hidden',
2833
+				'value' => $messenger->name
2834
+			),
2835
+			'message_type_settings[message_type]' => array(
2836
+				'type'  => 'hidden',
2837
+				'value' => $message_type->name
2838
+			),
2839
+			'type'                                => array(
2840
+				'type'  => 'hidden',
2841
+				'value' => 'message_type'
2842
+			)
2843
+		);
2844
+        
2845
+		$settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields($settings_template_args['hidden_fields'],
2846
+			'array');
2847
+		$settings_template_args['show_form']     = empty($settings_template_args['template_form_fields']) ? ' hidden' : '';
2848
+        
2849
+        
2850
+		$template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
2851
+		$content  = EEH_Template::display_template($template, $settings_template_args, true);
2852
+        
2853
+		return $content;
2854
+	}
2855
+    
2856
+    
2857
+	/**
2858
+	 * Generate all the metaboxes for the message types and register them for the messages settings page.
2859
+	 *
2860
+	 * @access protected
2861
+	 * @return void
2862
+	 */
2863
+	protected function _messages_settings_metaboxes()
2864
+	{
2865
+		$this->_set_m_mt_settings();
2866
+		$m_boxes         = $mt_boxes = array();
2867
+		$m_template_args = $mt_template_args = array();
2868
+        
2869
+		$selected_messenger = isset($this->_req_data['selected_messenger']) ? $this->_req_data['selected_messenger'] : 'email';
2870
+        
2871
+		if (isset($this->_m_mt_settings['messenger_tabs'])) {
2872
+			foreach ($this->_m_mt_settings['messenger_tabs'] as $messenger => $tab_array) {
2873
+				$hide_on_message  = $this->_message_resource_manager->is_messenger_active($messenger) ? '' : 'hidden';
2874
+				$hide_off_message = $this->_message_resource_manager->is_messenger_active($messenger) ? 'hidden' : '';
2875
+				//messenger meta boxes
2876
+				$active                                 = $selected_messenger == $messenger ? true : false;
2877
+				$active_mt_tabs                         = isset($this->_m_mt_settings['message_type_tabs'][$messenger]['active'])
2878
+					? $this->_m_mt_settings['message_type_tabs'][$messenger]['active']
2879
+					: '';
2880
+				$m_boxes[$messenger . '_a_box']         = sprintf(
2881
+					__('%s Settings', 'event_espresso'),
2882
+					$tab_array['label']
2883
+				);
2884
+				$m_template_args[$messenger . '_a_box'] = array(
2885
+					'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
2886
+					'inactive_message_types' => isset($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
2887
+						? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
2888
+						: '',
2889
+					'content'                => $this->_get_messenger_box_content($tab_array['obj']),
2890
+					'hidden'                 => $active ? '' : ' hidden',
2891
+					'hide_on_message'        => $hide_on_message,
2892
+					'messenger'              => $messenger,
2893
+					'active'                 => $active
2894
+				);
2895
+				// message type meta boxes
2896
+				// (which is really just the inactive container for each messenger
2897
+				// showing inactive message types for that messenger)
2898
+				$mt_boxes[$messenger . '_i_box']         = __('Inactive Message Types', 'event_espresso');
2899
+				$mt_template_args[$messenger . '_i_box'] = array(
2900
+					'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
2901
+					'inactive_message_types' => isset($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
2902
+						? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
2903
+						: '',
2904
+					'hidden'                 => $active ? '' : ' hidden',
2905
+					'hide_on_message'        => $hide_on_message,
2906
+					'hide_off_message'       => $hide_off_message,
2907
+					'messenger'              => $messenger,
2908
+					'active'                 => $active
2909
+				);
2910
+			}
2911
+		}
2912
+        
2913
+        
2914
+		//register messenger metaboxes
2915
+		$m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
2916
+		foreach ($m_boxes as $box => $label) {
2917
+			$callback_args = array('template_path' => $m_template_path, 'template_args' => $m_template_args[$box]);
2918
+			$msgr          = str_replace('_a_box', '', $box);
2919
+			add_meta_box(
2920
+				'espresso_' . $msgr . '_settings',
2921
+				$label,
2922
+				function ($post, $metabox) {
2923
+					echo EEH_Template::display_template($metabox["args"]["template_path"],
2924
+						$metabox["args"]["template_args"], true);
2925
+				},
2926
+				$this->_current_screen->id,
2927
+				'normal',
2928
+				'high',
2929
+				$callback_args
2930
+			);
2931
+		}
2932
+        
2933
+		//register message type metaboxes
2934
+		$mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
2935
+		foreach ($mt_boxes as $box => $label) {
2936
+			$callback_args = array(
2937
+				'template_path' => $mt_template_path,
2938
+				'template_args' => $mt_template_args[$box]
2939
+			);
2940
+			$mt            = str_replace('_i_box', '', $box);
2941
+			add_meta_box(
2942
+				'espresso_' . $mt . '_inactive_mts',
2943
+				$label,
2944
+				function ($post, $metabox) {
2945
+					echo EEH_Template::display_template($metabox["args"]["template_path"],
2946
+						$metabox["args"]["template_args"], true);
2947
+				},
2948
+				$this->_current_screen->id,
2949
+				'side',
2950
+				'high',
2951
+				$callback_args
2952
+			);
2953
+		}
2954
+        
2955
+		//register metabox for global messages settings but only when on the main site.  On single site installs this will
2956
+		//always result in the metabox showing, on multisite installs the metabox will only show on the main site.
2957
+		if (is_main_site()) {
2958
+			add_meta_box(
2959
+				'espresso_global_message_settings',
2960
+				__('Global Message Settings', 'event_espresso'),
2961
+				array($this, 'global_messages_settings_metabox_content'),
2962
+				$this->_current_screen->id,
2963
+				'normal',
2964
+				'low',
2965
+				array()
2966
+			);
2967
+		}
2968
+        
2969
+	}
2970
+    
2971
+    
2972
+	/**
2973
+	 *  This generates the content for the global messages settings metabox.
2974
+	 * @return string
2975
+	 */
2976
+	public function global_messages_settings_metabox_content()
2977
+	{
2978
+		$form = $this->_generate_global_settings_form();
2979
+		echo $form->form_open(
2980
+				$this->add_query_args_and_nonce(array('action' => 'update_global_settings'), EE_MSG_ADMIN_URL),
2981
+				'POST'
2982
+			)
2983
+			 . $form->get_html()
2984
+			 . $form->form_close();
2985
+	}
2986
+    
2987
+    
2988
+	/**
2989
+	 * This generates and returns the form object for the global messages settings.
2990
+	 * @return EE_Form_Section_Proper
2991
+	 */
2992
+	protected function _generate_global_settings_form()
2993
+	{
2994
+		EE_Registry::instance()->load_helper('HTML');
2995
+		/** @var EE_Network_Core_Config $network_config */
2996
+		$network_config = EE_Registry::instance()->NET_CFG->core;
2997
+        
2998
+		return new EE_Form_Section_Proper(
2999
+			array(
3000
+				'name'            => 'global_messages_settings',
3001
+				'html_id'         => 'global_messages_settings',
3002
+				'html_class'      => 'form-table',
3003
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
3004
+				'subsections'     => apply_filters(
3005
+					'FHEE__Messages_Admin_Page__global_messages_settings_metabox_content__form_subsections',
3006
+					array(
3007
+						'do_messages_on_same_request' => new EE_Select_Input(
3008
+							array(
3009
+								true  => esc_html__("On the same request", "event_espresso"),
3010
+								false => esc_html__("On a separate request", "event_espresso")
3011
+							),
3012
+							array(
3013
+								'default'         => $network_config->do_messages_on_same_request,
3014
+								'html_label_text' => esc_html__('Generate and send all messages:', 'event_espresso'),
3015
+								'html_help_text'  => esc_html__('By default the messages system uses a more efficient means of processing messages on separate requests and utilizes the wp-cron scheduling system.  This makes things execute faster for people registering for your events.  However, if the wp-cron system is disabled on your site and there is no alternative in place, then you can change this so messages are always executed on the same request.',
3016
+									'event_espresso'),
3017
+							)
3018
+						),
3019
+						'delete_threshold' => new EE_Select_Input(
3020
+							array(
3021
+								0 => esc_html__('Forever', 'event_espresso'),
3022
+								3 => esc_html__('3 Months', 'event_espresso'),
3023
+								6 => esc_html__('6 Months', 'event_espresso'),
3024
+								9 => esc_html__('9 Months', 'event_espresso'),
3025
+								12 => esc_html__('12 Months', 'event_espresso'),
3026
+								24 => esc_html__('24 Months', 'event_espresso'),
3027
+								36 => esc_html__('36 Months', 'event_espresso')
3028
+							),
3029
+							array(
3030
+								'default' => EE_Registry::instance()->CFG->messages->delete_threshold,
3031
+								'html_label_text' => esc_html__('Cleanup of old messages:', 'event_espresso'),
3032
+								'html_help_text' => esc_html__('You can control how long a record of processed messages is kept 
3033 3033
                                                     via this option.', 'event_espresso'),
3034
-                            )
3035
-                        ),
3036
-                        'update_settings'             => new EE_Submit_Input(
3037
-                            array(
3038
-                                'default'         => esc_html__('Update', 'event_espresso'),
3039
-                                'html_label_text' => '&nbsp'
3040
-                            )
3041
-                        )
3042
-                    )
3043
-                )
3044
-            )
3045
-        );
3046
-    }
3047
-    
3048
-    
3049
-    /**
3050
-     * This handles updating the global settings set on the admin page.
3051
-     * @throws \EE_Error
3052
-     */
3053
-    protected function _update_global_settings()
3054
-    {
3055
-        /** @var EE_Network_Core_Config $network_config */
3056
-        $network_config = EE_Registry::instance()->NET_CFG->core;
3057
-        $messages_config = EE_Registry::instance()->CFG->messages;
3058
-        $form           = $this->_generate_global_settings_form();
3059
-        if ($form->was_submitted()) {
3060
-            $form->receive_form_submission();
3061
-            if ($form->is_valid()) {
3062
-                $valid_data = $form->valid_data();
3063
-                foreach ($valid_data as $property => $value) {
3064
-                    $setter = 'set_' . $property;
3065
-                    if (method_exists($network_config, $setter)) {
3066
-                        $network_config->{$setter}($value);
3067
-                    } else if (
3068
-                        property_exists($network_config, $property)
3069
-                        && $network_config->{$property} !== $value
3070
-                    ) {
3071
-                        $network_config->{$property} = $value;
3072
-                    } else if (
3073
-                        property_exists($messages_config, $property)
3074
-                        && $messages_config->{$property} !== $value
3075
-                    ) {
3076
-                        $messages_config->{$property} = $value;
3077
-                    }
3078
-                }
3079
-                //only update if the form submission was valid!
3080
-                EE_Registry::instance()->NET_CFG->update_config(true, false);
3081
-                EE_Registry::instance()->CFG->update_espresso_config();
3082
-                EE_Error::overwrite_success();
3083
-                EE_Error::add_success(__('Global message settings were updated', 'event_espresso'));
3084
-            }
3085
-        }
3086
-        $this->_redirect_after_action(0, '', '', array('action' => 'settings'), true);
3087
-    }
3088
-    
3089
-    
3090
-    /**
3091
-     * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3092
-     *
3093
-     * @param  array $tab_array This is an array of message type tab details used to generate the tabs
3094
-     *
3095
-     * @return string            html formatted tabs
3096
-     */
3097
-    protected function _get_mt_tabs($tab_array)
3098
-    {
3099
-        $tab_array = (array)$tab_array;
3100
-        $template  = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3101
-        $tabs      = '';
3102
-        
3103
-        foreach ($tab_array as $tab) {
3104
-            $tabs .= EEH_Template::display_template($template, $tab, true);
3105
-        }
3106
-        
3107
-        return $tabs;
3108
-    }
3109
-    
3110
-    
3111
-    /**
3112
-     * This prepares the content of the messenger meta box admin settings
3113
-     *
3114
-     * @param  EE_messenger $messenger The messenger we're setting up content for
3115
-     *
3116
-     * @return string            html formatted content
3117
-     */
3118
-    protected function _get_messenger_box_content(EE_messenger $messenger)
3119
-    {
3120
-        
3121
-        $fields                                         = $messenger->get_admin_settings_fields();
3122
-        $settings_template_args['template_form_fields'] = '';
3123
-        
3124
-        //is $messenger active?
3125
-        $settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3126
-        
3127
-        
3128
-        if ( ! empty($fields)) {
3034
+							)
3035
+						),
3036
+						'update_settings'             => new EE_Submit_Input(
3037
+							array(
3038
+								'default'         => esc_html__('Update', 'event_espresso'),
3039
+								'html_label_text' => '&nbsp'
3040
+							)
3041
+						)
3042
+					)
3043
+				)
3044
+			)
3045
+		);
3046
+	}
3047
+    
3048
+    
3049
+	/**
3050
+	 * This handles updating the global settings set on the admin page.
3051
+	 * @throws \EE_Error
3052
+	 */
3053
+	protected function _update_global_settings()
3054
+	{
3055
+		/** @var EE_Network_Core_Config $network_config */
3056
+		$network_config = EE_Registry::instance()->NET_CFG->core;
3057
+		$messages_config = EE_Registry::instance()->CFG->messages;
3058
+		$form           = $this->_generate_global_settings_form();
3059
+		if ($form->was_submitted()) {
3060
+			$form->receive_form_submission();
3061
+			if ($form->is_valid()) {
3062
+				$valid_data = $form->valid_data();
3063
+				foreach ($valid_data as $property => $value) {
3064
+					$setter = 'set_' . $property;
3065
+					if (method_exists($network_config, $setter)) {
3066
+						$network_config->{$setter}($value);
3067
+					} else if (
3068
+						property_exists($network_config, $property)
3069
+						&& $network_config->{$property} !== $value
3070
+					) {
3071
+						$network_config->{$property} = $value;
3072
+					} else if (
3073
+						property_exists($messages_config, $property)
3074
+						&& $messages_config->{$property} !== $value
3075
+					) {
3076
+						$messages_config->{$property} = $value;
3077
+					}
3078
+				}
3079
+				//only update if the form submission was valid!
3080
+				EE_Registry::instance()->NET_CFG->update_config(true, false);
3081
+				EE_Registry::instance()->CFG->update_espresso_config();
3082
+				EE_Error::overwrite_success();
3083
+				EE_Error::add_success(__('Global message settings were updated', 'event_espresso'));
3084
+			}
3085
+		}
3086
+		$this->_redirect_after_action(0, '', '', array('action' => 'settings'), true);
3087
+	}
3088
+    
3089
+    
3090
+	/**
3091
+	 * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3092
+	 *
3093
+	 * @param  array $tab_array This is an array of message type tab details used to generate the tabs
3094
+	 *
3095
+	 * @return string            html formatted tabs
3096
+	 */
3097
+	protected function _get_mt_tabs($tab_array)
3098
+	{
3099
+		$tab_array = (array)$tab_array;
3100
+		$template  = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3101
+		$tabs      = '';
3102
+        
3103
+		foreach ($tab_array as $tab) {
3104
+			$tabs .= EEH_Template::display_template($template, $tab, true);
3105
+		}
3106
+        
3107
+		return $tabs;
3108
+	}
3109
+    
3110
+    
3111
+	/**
3112
+	 * This prepares the content of the messenger meta box admin settings
3113
+	 *
3114
+	 * @param  EE_messenger $messenger The messenger we're setting up content for
3115
+	 *
3116
+	 * @return string            html formatted content
3117
+	 */
3118
+	protected function _get_messenger_box_content(EE_messenger $messenger)
3119
+	{
3120
+        
3121
+		$fields                                         = $messenger->get_admin_settings_fields();
3122
+		$settings_template_args['template_form_fields'] = '';
3123
+        
3124
+		//is $messenger active?
3125
+		$settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3126
+        
3127
+        
3128
+		if ( ! empty($fields)) {
3129 3129
             
3130
-            $existing_settings = $messenger->get_existing_admin_settings();
3130
+			$existing_settings = $messenger->get_existing_admin_settings();
3131 3131
             
3132
-            foreach ($fields as $fldname => $fldprops) {
3133
-                $field_id                       = $messenger->name . '-' . $fldname;
3134
-                $template_form_field[$field_id] = array(
3135
-                    'name'       => 'messenger_settings[' . $field_id . ']',
3136
-                    'label'      => $fldprops['label'],
3137
-                    'input'      => $fldprops['field_type'],
3138
-                    'type'       => $fldprops['value_type'],
3139
-                    'required'   => $fldprops['required'],
3140
-                    'validation' => $fldprops['validation'],
3141
-                    'value'      => isset($existing_settings[$field_id])
3142
-                        ? $existing_settings[$field_id]
3143
-                        : $fldprops['default'],
3144
-                    'css_class'  => '',
3145
-                    'format'     => $fldprops['format']
3146
-                );
3147
-            }
3132
+			foreach ($fields as $fldname => $fldprops) {
3133
+				$field_id                       = $messenger->name . '-' . $fldname;
3134
+				$template_form_field[$field_id] = array(
3135
+					'name'       => 'messenger_settings[' . $field_id . ']',
3136
+					'label'      => $fldprops['label'],
3137
+					'input'      => $fldprops['field_type'],
3138
+					'type'       => $fldprops['value_type'],
3139
+					'required'   => $fldprops['required'],
3140
+					'validation' => $fldprops['validation'],
3141
+					'value'      => isset($existing_settings[$field_id])
3142
+						? $existing_settings[$field_id]
3143
+						: $fldprops['default'],
3144
+					'css_class'  => '',
3145
+					'format'     => $fldprops['format']
3146
+				);
3147
+			}
3148 3148
             
3149 3149
             
3150
-            $settings_template_args['template_form_fields'] = ! empty($template_form_field)
3151
-                ? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3152
-                : '';
3153
-        }
3154
-        
3155
-        //we also need some hidden fields
3156
-        $settings_template_args['hidden_fields'] = array(
3157
-            'messenger_settings[messenger]' => array(
3158
-                'type'  => 'hidden',
3159
-                'value' => $messenger->name
3160
-            ),
3161
-            'type'                          => array(
3162
-                'type'  => 'hidden',
3163
-                'value' => 'messenger'
3164
-            )
3165
-        );
3166
-        
3167
-        //make sure any active message types that are existing are included in the hidden fields
3168
-        if (isset($this->_m_mt_settings['message_type_tabs'][$messenger->name]['active'])) {
3169
-            foreach ($this->_m_mt_settings['message_type_tabs'][$messenger->name]['active'] as $mt => $values) {
3170
-                $settings_template_args['hidden_fields']['messenger_settings[message_types][' . $mt . ']'] = array(
3171
-                    'type'  => 'hidden',
3172
-                    'value' => $mt
3173
-                );
3174
-            }
3175
-        }
3176
-        $settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3177
-            $settings_template_args['hidden_fields'],
3178
-            'array'
3179
-        );
3180
-        $active                                  = $this->_message_resource_manager->is_messenger_active($messenger->name);
3181
-        
3182
-        $settings_template_args['messenger']           = $messenger->name;
3183
-        $settings_template_args['description']         = $messenger->description;
3184
-        $settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3185
-        
3186
-        
3187
-        $settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active($messenger->name)
3188
-            ? $settings_template_args['show_hide_edit_form']
3189
-            : ' hidden';
3190
-        
3191
-        $settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3192
-            ? ' hidden'
3193
-            : $settings_template_args['show_hide_edit_form'];
3194
-        
3195
-        
3196
-        $settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3197
-        $settings_template_args['nonce']         = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3198
-        $settings_template_args['on_off_status'] = $active ? true : false;
3199
-        $template                                = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3200
-        $content                                 = EEH_Template::display_template($template, $settings_template_args,
3201
-            true);
3202
-        
3203
-        return $content;
3204
-    }
3205
-    
3206
-    
3207
-    /**
3208
-     * used by ajax on the messages settings page to activate|deactivate the messenger
3209
-     */
3210
-    public function activate_messenger_toggle()
3211
-    {
3212
-        $success = true;
3213
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
3214
-        //let's check that we have required data
3215
-        if ( ! isset($this->_req_data['messenger'])) {
3216
-            EE_Error::add_error(
3217
-                __('Messenger name needed to toggle activation. None given', 'event_espresso'),
3218
-                __FILE__,
3219
-                __FUNCTION__,
3220
-                __LINE__
3221
-            );
3222
-            $success = false;
3223
-        }
3224
-        
3225
-        //do a nonce check here since we're not arriving via a normal route
3226
-        $nonce     = isset($this->_req_data['activate_nonce']) ? sanitize_text_field($this->_req_data['activate_nonce']) : '';
3227
-        $nonce_ref = 'activate_' . $this->_req_data['messenger'] . '_toggle_nonce';
3228
-        
3229
-        $this->_verify_nonce($nonce, $nonce_ref);
3230
-        
3231
-        
3232
-        if ( ! isset($this->_req_data['status'])) {
3233
-            EE_Error::add_error(
3234
-                __(
3235
-                    'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3236
-                    'event_espresso'
3237
-                ),
3238
-                __FILE__,
3239
-                __FUNCTION__,
3240
-                __LINE__
3241
-            );
3242
-            $success = false;
3243
-        }
3244
-        
3245
-        //do check to verify we have a valid status.
3246
-        $status = $this->_req_data['status'];
3247
-        
3248
-        if ($status != 'off' && $status != 'on') {
3249
-            EE_Error::add_error(
3250
-                sprintf(
3251
-                    __('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
3252
-                    $this->_req_data['status']
3253
-                ),
3254
-                __FILE__,
3255
-                __FUNCTION__,
3256
-                __LINE__
3257
-            );
3258
-            $success = false;
3259
-        }
3260
-        
3261
-        if ($success) {
3262
-            //made it here?  Stop dawdling then!!
3263
-            $success = $status == 'off'
3264
-                ? $this->_deactivate_messenger($this->_req_data['messenger'])
3265
-                : $this->_activate_messenger($this->_req_data['messenger']);
3266
-        }
3267
-        
3268
-        $this->_template_args['success'] = $success;
3269
-        
3270
-        //no special instructions so let's just do the json return (which should automatically do all the special stuff).
3271
-        $this->_return_json();
3272
-        
3273
-    }
3274
-    
3275
-    
3276
-    /**
3277
-     * used by ajax from the messages settings page to activate|deactivate a message type
3278
-     *
3279
-     */
3280
-    public function activate_mt_toggle()
3281
-    {
3282
-        $success = true;
3283
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
3284
-        
3285
-        //let's make sure we have the necessary data
3286
-        if ( ! isset($this->_req_data['message_type'])) {
3287
-            EE_Error::add_error(
3288
-                __('Message Type name needed to toggle activation. None given', 'event_espresso'),
3289
-                __FILE__, __FUNCTION__, __LINE__
3290
-            );
3291
-            $success = false;
3292
-        }
3293
-        
3294
-        if ( ! isset($this->_req_data['messenger'])) {
3295
-            EE_Error::add_error(
3296
-                __('Messenger name needed to toggle activation. None given', 'event_espresso'),
3297
-                __FILE__, __FUNCTION__, __LINE__
3298
-            );
3299
-            $success = false;
3300
-        }
3301
-        
3302
-        if ( ! isset($this->_req_data['status'])) {
3303
-            EE_Error::add_error(
3304
-                __('Messenger status needed to know whether activation or deactivation is happening. No status is given',
3305
-                    'event_espresso'),
3306
-                __FILE__, __FUNCTION__, __LINE__
3307
-            );
3308
-            $success = false;
3309
-        }
3310
-        
3311
-        
3312
-        //do check to verify we have a valid status.
3313
-        $status = $this->_req_data['status'];
3314
-        
3315
-        if ($status != 'activate' && $status != 'deactivate') {
3316
-            EE_Error::add_error(
3317
-                sprintf(
3318
-                    __('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
3319
-                    $this->_req_data['status']
3320
-                ),
3321
-                __FILE__, __FUNCTION__, __LINE__
3322
-            );
3323
-            $success = false;
3324
-        }
3325
-        
3326
-        
3327
-        //do a nonce check here since we're not arriving via a normal route
3328
-        $nonce     = isset($this->_req_data['mt_nonce']) ? sanitize_text_field($this->_req_data['mt_nonce']) : '';
3329
-        $nonce_ref = $this->_req_data['message_type'] . '_nonce';
3330
-        
3331
-        $this->_verify_nonce($nonce, $nonce_ref);
3332
-        
3333
-        if ($success) {
3334
-            //made it here? um, what are you waiting for then?
3335
-            $success = $status == 'deactivate'
3336
-                ? $this->_deactivate_message_type_for_messenger($this->_req_data['messenger'],
3337
-                    $this->_req_data['message_type'])
3338
-                : $this->_activate_message_type_for_messenger($this->_req_data['messenger'],
3339
-                    $this->_req_data['message_type']);
3340
-        }
3341
-        
3342
-        $this->_template_args['success'] = $success;
3343
-        $this->_return_json();
3344
-    }
3345
-    
3346
-    
3347
-    /**
3348
-     * Takes care of processing activating a messenger and preparing the appropriate response.
3349
-     *
3350
-     * @param string $messenger_name The name of the messenger being activated
3351
-     *
3352
-     * @return bool
3353
-     */
3354
-    protected function _activate_messenger($messenger_name)
3355
-    {
3356
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
3357
-        $active_messenger          = $this->_message_resource_manager->get_messenger($messenger_name);
3358
-        $message_types_to_activate = $active_messenger instanceof EE_Messenger ? $active_messenger->get_default_message_types() : array();
3359
-        
3360
-        //ensure is active
3361
-        $this->_message_resource_manager->activate_messenger($messenger_name, $message_types_to_activate);
3362
-        
3363
-        //set response_data for reload
3364
-        foreach ($message_types_to_activate as $message_type_name) {
3365
-            /** @var EE_message_type $message_type */
3366
-            $message_type = $this->_message_resource_manager->get_message_type($message_type_name);
3367
-            if ($this->_message_resource_manager->is_message_type_active_for_messenger($messenger_name,
3368
-                    $message_type_name)
3369
-                && $message_type instanceof EE_message_type
3370
-            ) {
3371
-                $this->_template_args['data']['active_mts'][] = $message_type_name;
3372
-                if ($message_type->get_admin_settings_fields()) {
3373
-                    $this->_template_args['data']['mt_reload'][] = $message_type_name;
3374
-                }
3375
-            }
3376
-        }
3377
-        
3378
-        //add success message for activating messenger
3379
-        return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
3380
-        
3381
-    }
3382
-    
3383
-    
3384
-    /**
3385
-     * Takes care of processing deactivating a messenger and preparing the appropriate response.
3386
-     *
3387
-     * @param string $messenger_name The name of the messenger being activated
3388
-     *
3389
-     * @return bool
3390
-     */
3391
-    protected function _deactivate_messenger($messenger_name)
3392
-    {
3393
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
3394
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
3395
-        $this->_message_resource_manager->deactivate_messenger($messenger_name);
3396
-        
3397
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
3398
-    }
3399
-    
3400
-    
3401
-    /**
3402
-     * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
3403
-     *
3404
-     * @param string $messenger_name    The name of the messenger the message type is being activated for.
3405
-     * @param string $message_type_name The name of the message type being activated for the messenger
3406
-     *
3407
-     * @return bool
3408
-     */
3409
-    protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
3410
-    {
3411
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
3412
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
3413
-        /** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
3414
-        $message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
3415
-        
3416
-        //ensure is active
3417
-        $this->_message_resource_manager->activate_messenger($messenger_name, $message_type_name);
3418
-        
3419
-        //set response for load
3420
-        if ($this->_message_resource_manager->is_message_type_active_for_messenger($messenger_name,
3421
-            $message_type_name)
3422
-        ) {
3423
-            $this->_template_args['data']['active_mts'][] = $message_type_name;
3424
-            if ($message_type_to_activate->get_admin_settings_fields()) {
3425
-                $this->_template_args['data']['mt_reload'][] = $message_type_name;
3426
-            }
3427
-        }
3428
-        
3429
-        return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger,
3430
-            $message_type_to_activate);
3431
-    }
3432
-    
3433
-    
3434
-    /**
3435
-     * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
3436
-     *
3437
-     * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
3438
-     * @param string $message_type_name The name of the message type being deactivated for the messenger
3439
-     *
3440
-     * @return bool
3441
-     */
3442
-    protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
3443
-    {
3444
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
3445
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
3446
-        /** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
3447
-        $message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
3448
-        $this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
3449
-        
3450
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger,
3451
-            $message_type_to_deactivate);
3452
-    }
3453
-    
3454
-    
3455
-    /**
3456
-     * This just initializes the defaults for activating messenger and message type responses.
3457
-     */
3458
-    protected function _prep_default_response_for_messenger_or_message_type_toggle()
3459
-    {
3460
-        $this->_template_args['data']['active_mts'] = array();
3461
-        $this->_template_args['data']['mt_reload']  = array();
3462
-    }
3463
-    
3464
-    
3465
-    /**
3466
-     * Setup appropriate response for activating a messenger and/or message types
3467
-     *
3468
-     * @param EE_messenger         $messenger
3469
-     * @param EE_message_type|null $message_type
3470
-     *
3471
-     * @return bool
3472
-     * @throws EE_Error
3473
-     */
3474
-    protected function _setup_response_message_for_activating_messenger_with_message_types(
3475
-        $messenger,
3476
-        EE_Message_Type $message_type = null
3477
-    ) {
3478
-        //if $messenger isn't a valid messenger object then get out.
3479
-        if ( ! $messenger instanceof EE_Messenger) {
3480
-            EE_Error::add_error(
3481
-                __('The messenger being activated is not a valid messenger', 'event_espresso'),
3482
-                __FILE__,
3483
-                __FUNCTION__,
3484
-                __LINE__
3485
-            );
3150
+			$settings_template_args['template_form_fields'] = ! empty($template_form_field)
3151
+				? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3152
+				: '';
3153
+		}
3154
+        
3155
+		//we also need some hidden fields
3156
+		$settings_template_args['hidden_fields'] = array(
3157
+			'messenger_settings[messenger]' => array(
3158
+				'type'  => 'hidden',
3159
+				'value' => $messenger->name
3160
+			),
3161
+			'type'                          => array(
3162
+				'type'  => 'hidden',
3163
+				'value' => 'messenger'
3164
+			)
3165
+		);
3166
+        
3167
+		//make sure any active message types that are existing are included in the hidden fields
3168
+		if (isset($this->_m_mt_settings['message_type_tabs'][$messenger->name]['active'])) {
3169
+			foreach ($this->_m_mt_settings['message_type_tabs'][$messenger->name]['active'] as $mt => $values) {
3170
+				$settings_template_args['hidden_fields']['messenger_settings[message_types][' . $mt . ']'] = array(
3171
+					'type'  => 'hidden',
3172
+					'value' => $mt
3173
+				);
3174
+			}
3175
+		}
3176
+		$settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3177
+			$settings_template_args['hidden_fields'],
3178
+			'array'
3179
+		);
3180
+		$active                                  = $this->_message_resource_manager->is_messenger_active($messenger->name);
3181
+        
3182
+		$settings_template_args['messenger']           = $messenger->name;
3183
+		$settings_template_args['description']         = $messenger->description;
3184
+		$settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3185
+        
3186
+        
3187
+		$settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active($messenger->name)
3188
+			? $settings_template_args['show_hide_edit_form']
3189
+			: ' hidden';
3190
+        
3191
+		$settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3192
+			? ' hidden'
3193
+			: $settings_template_args['show_hide_edit_form'];
3194
+        
3195
+        
3196
+		$settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3197
+		$settings_template_args['nonce']         = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3198
+		$settings_template_args['on_off_status'] = $active ? true : false;
3199
+		$template                                = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3200
+		$content                                 = EEH_Template::display_template($template, $settings_template_args,
3201
+			true);
3202
+        
3203
+		return $content;
3204
+	}
3205
+    
3206
+    
3207
+	/**
3208
+	 * used by ajax on the messages settings page to activate|deactivate the messenger
3209
+	 */
3210
+	public function activate_messenger_toggle()
3211
+	{
3212
+		$success = true;
3213
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
3214
+		//let's check that we have required data
3215
+		if ( ! isset($this->_req_data['messenger'])) {
3216
+			EE_Error::add_error(
3217
+				__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3218
+				__FILE__,
3219
+				__FUNCTION__,
3220
+				__LINE__
3221
+			);
3222
+			$success = false;
3223
+		}
3224
+        
3225
+		//do a nonce check here since we're not arriving via a normal route
3226
+		$nonce     = isset($this->_req_data['activate_nonce']) ? sanitize_text_field($this->_req_data['activate_nonce']) : '';
3227
+		$nonce_ref = 'activate_' . $this->_req_data['messenger'] . '_toggle_nonce';
3228
+        
3229
+		$this->_verify_nonce($nonce, $nonce_ref);
3230
+        
3231
+        
3232
+		if ( ! isset($this->_req_data['status'])) {
3233
+			EE_Error::add_error(
3234
+				__(
3235
+					'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3236
+					'event_espresso'
3237
+				),
3238
+				__FILE__,
3239
+				__FUNCTION__,
3240
+				__LINE__
3241
+			);
3242
+			$success = false;
3243
+		}
3244
+        
3245
+		//do check to verify we have a valid status.
3246
+		$status = $this->_req_data['status'];
3247
+        
3248
+		if ($status != 'off' && $status != 'on') {
3249
+			EE_Error::add_error(
3250
+				sprintf(
3251
+					__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
3252
+					$this->_req_data['status']
3253
+				),
3254
+				__FILE__,
3255
+				__FUNCTION__,
3256
+				__LINE__
3257
+			);
3258
+			$success = false;
3259
+		}
3260
+        
3261
+		if ($success) {
3262
+			//made it here?  Stop dawdling then!!
3263
+			$success = $status == 'off'
3264
+				? $this->_deactivate_messenger($this->_req_data['messenger'])
3265
+				: $this->_activate_messenger($this->_req_data['messenger']);
3266
+		}
3267
+        
3268
+		$this->_template_args['success'] = $success;
3269
+        
3270
+		//no special instructions so let's just do the json return (which should automatically do all the special stuff).
3271
+		$this->_return_json();
3272
+        
3273
+	}
3274
+    
3275
+    
3276
+	/**
3277
+	 * used by ajax from the messages settings page to activate|deactivate a message type
3278
+	 *
3279
+	 */
3280
+	public function activate_mt_toggle()
3281
+	{
3282
+		$success = true;
3283
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
3284
+        
3285
+		//let's make sure we have the necessary data
3286
+		if ( ! isset($this->_req_data['message_type'])) {
3287
+			EE_Error::add_error(
3288
+				__('Message Type name needed to toggle activation. None given', 'event_espresso'),
3289
+				__FILE__, __FUNCTION__, __LINE__
3290
+			);
3291
+			$success = false;
3292
+		}
3293
+        
3294
+		if ( ! isset($this->_req_data['messenger'])) {
3295
+			EE_Error::add_error(
3296
+				__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3297
+				__FILE__, __FUNCTION__, __LINE__
3298
+			);
3299
+			$success = false;
3300
+		}
3301
+        
3302
+		if ( ! isset($this->_req_data['status'])) {
3303
+			EE_Error::add_error(
3304
+				__('Messenger status needed to know whether activation or deactivation is happening. No status is given',
3305
+					'event_espresso'),
3306
+				__FILE__, __FUNCTION__, __LINE__
3307
+			);
3308
+			$success = false;
3309
+		}
3310
+        
3311
+        
3312
+		//do check to verify we have a valid status.
3313
+		$status = $this->_req_data['status'];
3314
+        
3315
+		if ($status != 'activate' && $status != 'deactivate') {
3316
+			EE_Error::add_error(
3317
+				sprintf(
3318
+					__('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
3319
+					$this->_req_data['status']
3320
+				),
3321
+				__FILE__, __FUNCTION__, __LINE__
3322
+			);
3323
+			$success = false;
3324
+		}
3325
+        
3326
+        
3327
+		//do a nonce check here since we're not arriving via a normal route
3328
+		$nonce     = isset($this->_req_data['mt_nonce']) ? sanitize_text_field($this->_req_data['mt_nonce']) : '';
3329
+		$nonce_ref = $this->_req_data['message_type'] . '_nonce';
3330
+        
3331
+		$this->_verify_nonce($nonce, $nonce_ref);
3332
+        
3333
+		if ($success) {
3334
+			//made it here? um, what are you waiting for then?
3335
+			$success = $status == 'deactivate'
3336
+				? $this->_deactivate_message_type_for_messenger($this->_req_data['messenger'],
3337
+					$this->_req_data['message_type'])
3338
+				: $this->_activate_message_type_for_messenger($this->_req_data['messenger'],
3339
+					$this->_req_data['message_type']);
3340
+		}
3341
+        
3342
+		$this->_template_args['success'] = $success;
3343
+		$this->_return_json();
3344
+	}
3345
+    
3346
+    
3347
+	/**
3348
+	 * Takes care of processing activating a messenger and preparing the appropriate response.
3349
+	 *
3350
+	 * @param string $messenger_name The name of the messenger being activated
3351
+	 *
3352
+	 * @return bool
3353
+	 */
3354
+	protected function _activate_messenger($messenger_name)
3355
+	{
3356
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
3357
+		$active_messenger          = $this->_message_resource_manager->get_messenger($messenger_name);
3358
+		$message_types_to_activate = $active_messenger instanceof EE_Messenger ? $active_messenger->get_default_message_types() : array();
3359
+        
3360
+		//ensure is active
3361
+		$this->_message_resource_manager->activate_messenger($messenger_name, $message_types_to_activate);
3362
+        
3363
+		//set response_data for reload
3364
+		foreach ($message_types_to_activate as $message_type_name) {
3365
+			/** @var EE_message_type $message_type */
3366
+			$message_type = $this->_message_resource_manager->get_message_type($message_type_name);
3367
+			if ($this->_message_resource_manager->is_message_type_active_for_messenger($messenger_name,
3368
+					$message_type_name)
3369
+				&& $message_type instanceof EE_message_type
3370
+			) {
3371
+				$this->_template_args['data']['active_mts'][] = $message_type_name;
3372
+				if ($message_type->get_admin_settings_fields()) {
3373
+					$this->_template_args['data']['mt_reload'][] = $message_type_name;
3374
+				}
3375
+			}
3376
+		}
3377
+        
3378
+		//add success message for activating messenger
3379
+		return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
3380
+        
3381
+	}
3382
+    
3383
+    
3384
+	/**
3385
+	 * Takes care of processing deactivating a messenger and preparing the appropriate response.
3386
+	 *
3387
+	 * @param string $messenger_name The name of the messenger being activated
3388
+	 *
3389
+	 * @return bool
3390
+	 */
3391
+	protected function _deactivate_messenger($messenger_name)
3392
+	{
3393
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
3394
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
3395
+		$this->_message_resource_manager->deactivate_messenger($messenger_name);
3396
+        
3397
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
3398
+	}
3399
+    
3400
+    
3401
+	/**
3402
+	 * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
3403
+	 *
3404
+	 * @param string $messenger_name    The name of the messenger the message type is being activated for.
3405
+	 * @param string $message_type_name The name of the message type being activated for the messenger
3406
+	 *
3407
+	 * @return bool
3408
+	 */
3409
+	protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
3410
+	{
3411
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
3412
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
3413
+		/** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
3414
+		$message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
3415
+        
3416
+		//ensure is active
3417
+		$this->_message_resource_manager->activate_messenger($messenger_name, $message_type_name);
3418
+        
3419
+		//set response for load
3420
+		if ($this->_message_resource_manager->is_message_type_active_for_messenger($messenger_name,
3421
+			$message_type_name)
3422
+		) {
3423
+			$this->_template_args['data']['active_mts'][] = $message_type_name;
3424
+			if ($message_type_to_activate->get_admin_settings_fields()) {
3425
+				$this->_template_args['data']['mt_reload'][] = $message_type_name;
3426
+			}
3427
+		}
3428
+        
3429
+		return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger,
3430
+			$message_type_to_activate);
3431
+	}
3432
+    
3433
+    
3434
+	/**
3435
+	 * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
3436
+	 *
3437
+	 * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
3438
+	 * @param string $message_type_name The name of the message type being deactivated for the messenger
3439
+	 *
3440
+	 * @return bool
3441
+	 */
3442
+	protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
3443
+	{
3444
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
3445
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
3446
+		/** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
3447
+		$message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
3448
+		$this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
3449
+        
3450
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger,
3451
+			$message_type_to_deactivate);
3452
+	}
3453
+    
3454
+    
3455
+	/**
3456
+	 * This just initializes the defaults for activating messenger and message type responses.
3457
+	 */
3458
+	protected function _prep_default_response_for_messenger_or_message_type_toggle()
3459
+	{
3460
+		$this->_template_args['data']['active_mts'] = array();
3461
+		$this->_template_args['data']['mt_reload']  = array();
3462
+	}
3463
+    
3464
+    
3465
+	/**
3466
+	 * Setup appropriate response for activating a messenger and/or message types
3467
+	 *
3468
+	 * @param EE_messenger         $messenger
3469
+	 * @param EE_message_type|null $message_type
3470
+	 *
3471
+	 * @return bool
3472
+	 * @throws EE_Error
3473
+	 */
3474
+	protected function _setup_response_message_for_activating_messenger_with_message_types(
3475
+		$messenger,
3476
+		EE_Message_Type $message_type = null
3477
+	) {
3478
+		//if $messenger isn't a valid messenger object then get out.
3479
+		if ( ! $messenger instanceof EE_Messenger) {
3480
+			EE_Error::add_error(
3481
+				__('The messenger being activated is not a valid messenger', 'event_espresso'),
3482
+				__FILE__,
3483
+				__FUNCTION__,
3484
+				__LINE__
3485
+			);
3486 3486
             
3487
-            return false;
3488
-        }
3489
-        //activated
3490
-        if ($this->_template_args['data']['active_mts']) {
3491
-            EE_Error::overwrite_success();
3492
-            //activated a message type with the messenger
3493
-            if ($message_type instanceof EE_message_type) {
3494
-                EE_Error::add_success(
3495
-                    sprintf(
3496
-                        __('%s message type has been successfully activated with the %s messenger', 'event_espresso'),
3497
-                        ucwords($message_type->label['singular']),
3498
-                        ucwords($messenger->label['singular'])
3499
-                    )
3500
-                );
3487
+			return false;
3488
+		}
3489
+		//activated
3490
+		if ($this->_template_args['data']['active_mts']) {
3491
+			EE_Error::overwrite_success();
3492
+			//activated a message type with the messenger
3493
+			if ($message_type instanceof EE_message_type) {
3494
+				EE_Error::add_success(
3495
+					sprintf(
3496
+						__('%s message type has been successfully activated with the %s messenger', 'event_espresso'),
3497
+						ucwords($message_type->label['singular']),
3498
+						ucwords($messenger->label['singular'])
3499
+					)
3500
+				);
3501 3501
                 
3502
-                //if message type was invoice then let's make sure we activate the invoice payment method.
3503
-                if ($message_type->name == 'invoice') {
3504
-                    EE_Registry::instance()->load_lib('Payment_Method_Manager');
3505
-                    $pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
3506
-                    if ($pm instanceof EE_Payment_Method) {
3507
-                        EE_Error::add_attention(__('Activating the invoice message type also automatically activates the invoice payment method.  If you do not wish the invoice payment method to be active, or to change its settings, visit the payment method admin page.',
3508
-                            'event_espresso'));
3509
-                    }
3510
-                }
3511
-                //just toggles the entire messenger
3512
-            } else {
3513
-                EE_Error::add_success(
3514
-                    sprintf(
3515
-                        __('%s messenger has been successfully activated', 'event_espresso'),
3516
-                        ucwords($messenger->label['singular'])
3517
-                    )
3518
-                );
3519
-            }
3502
+				//if message type was invoice then let's make sure we activate the invoice payment method.
3503
+				if ($message_type->name == 'invoice') {
3504
+					EE_Registry::instance()->load_lib('Payment_Method_Manager');
3505
+					$pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
3506
+					if ($pm instanceof EE_Payment_Method) {
3507
+						EE_Error::add_attention(__('Activating the invoice message type also automatically activates the invoice payment method.  If you do not wish the invoice payment method to be active, or to change its settings, visit the payment method admin page.',
3508
+							'event_espresso'));
3509
+					}
3510
+				}
3511
+				//just toggles the entire messenger
3512
+			} else {
3513
+				EE_Error::add_success(
3514
+					sprintf(
3515
+						__('%s messenger has been successfully activated', 'event_espresso'),
3516
+						ucwords($messenger->label['singular'])
3517
+					)
3518
+				);
3519
+			}
3520 3520
             
3521
-            return true;
3521
+			return true;
3522 3522
             
3523
-            //possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
3524
-            //message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
3525
-            //in which case we just give a success message for the messenger being successfully activated.
3526
-        } else {
3527
-            if ( ! $messenger->get_default_message_types()) {
3528
-                //messenger doesn't have any default message types so still a success.
3529
-                EE_Error::add_success(
3530
-                    sprintf(
3531
-                        __('%s messenger was successfully activated.', 'event_espresso'),
3532
-                        ucwords($messenger->label['singular'])
3533
-                    )
3534
-                );
3523
+			//possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
3524
+			//message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
3525
+			//in which case we just give a success message for the messenger being successfully activated.
3526
+		} else {
3527
+			if ( ! $messenger->get_default_message_types()) {
3528
+				//messenger doesn't have any default message types so still a success.
3529
+				EE_Error::add_success(
3530
+					sprintf(
3531
+						__('%s messenger was successfully activated.', 'event_espresso'),
3532
+						ucwords($messenger->label['singular'])
3533
+					)
3534
+				);
3535 3535
                 
3536
-                return true;
3537
-            } else {
3538
-                EE_Error::add_error(
3539
-                    $message_type instanceof EE_message_type
3540
-                        ? sprintf(
3541
-                        __('%s message type was not successfully activated with the %s messenger', 'event_espresso'),
3542
-                        ucwords($message_type->label['singular']),
3543
-                        ucwords($messenger->label['singular'])
3544
-                    )
3545
-                        : sprintf(
3546
-                        __('%s messenger was not successfully activated', 'event_espresso'),
3547
-                        ucwords($messenger->label['singular'])
3548
-                    ),
3549
-                    __FILE__,
3550
-                    __FUNCTION__,
3551
-                    __LINE__
3552
-                );
3536
+				return true;
3537
+			} else {
3538
+				EE_Error::add_error(
3539
+					$message_type instanceof EE_message_type
3540
+						? sprintf(
3541
+						__('%s message type was not successfully activated with the %s messenger', 'event_espresso'),
3542
+						ucwords($message_type->label['singular']),
3543
+						ucwords($messenger->label['singular'])
3544
+					)
3545
+						: sprintf(
3546
+						__('%s messenger was not successfully activated', 'event_espresso'),
3547
+						ucwords($messenger->label['singular'])
3548
+					),
3549
+					__FILE__,
3550
+					__FUNCTION__,
3551
+					__LINE__
3552
+				);
3553 3553
                 
3554
-                return false;
3555
-            }
3556
-        }
3557
-    }
3558
-    
3559
-    
3560
-    /**
3561
-     * This sets up the appropriate response for deactivating a messenger and/or message type.
3562
-     *
3563
-     * @param EE_messenger         $messenger
3564
-     * @param EE_message_type|null $message_type
3565
-     *
3566
-     * @return bool
3567
-     */
3568
-    protected function _setup_response_message_for_deactivating_messenger_with_message_types(
3569
-        $messenger,
3570
-        EE_message_type $message_type = null
3571
-    ) {
3572
-        EE_Error::overwrite_success();
3573
-        
3574
-        //if $messenger isn't a valid messenger object then get out.
3575
-        if ( ! $messenger instanceof EE_Messenger) {
3576
-            EE_Error::add_error(
3577
-                __('The messenger being deactivated is not a valid messenger', 'event_espresso'),
3578
-                __FILE__,
3579
-                __FUNCTION__,
3580
-                __LINE__
3581
-            );
3554
+				return false;
3555
+			}
3556
+		}
3557
+	}
3558
+    
3559
+    
3560
+	/**
3561
+	 * This sets up the appropriate response for deactivating a messenger and/or message type.
3562
+	 *
3563
+	 * @param EE_messenger         $messenger
3564
+	 * @param EE_message_type|null $message_type
3565
+	 *
3566
+	 * @return bool
3567
+	 */
3568
+	protected function _setup_response_message_for_deactivating_messenger_with_message_types(
3569
+		$messenger,
3570
+		EE_message_type $message_type = null
3571
+	) {
3572
+		EE_Error::overwrite_success();
3573
+        
3574
+		//if $messenger isn't a valid messenger object then get out.
3575
+		if ( ! $messenger instanceof EE_Messenger) {
3576
+			EE_Error::add_error(
3577
+				__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
3578
+				__FILE__,
3579
+				__FUNCTION__,
3580
+				__LINE__
3581
+			);
3582 3582
             
3583
-            return false;
3584
-        }
3585
-        
3586
-        if ($message_type instanceof EE_message_type) {
3587
-            $message_type_name = $message_type->name;
3588
-            EE_Error::add_success(
3589
-                sprintf(
3590
-                    __('%s message type has been successfully deactivated for the %s messenger.', 'event_espresso'),
3591
-                    ucwords($message_type->label['singular']),
3592
-                    ucwords($messenger->label['singular'])
3593
-                )
3594
-            );
3595
-        } else {
3596
-            $message_type_name = '';
3597
-            EE_Error::add_success(
3598
-                sprintf(
3599
-                    __('%s messenger has been successfully deactivated.', 'event_espresso'),
3600
-                    ucwords($messenger->label['singular'])
3601
-                )
3602
-            );
3603
-        }
3604
-        
3605
-        //if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
3606
-        if ($messenger->name == 'html' || $message_type_name == 'invoice') {
3607
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
3608
-            $count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
3609
-            if ($count_updated > 0) {
3610
-                $msg = $message_type_name == 'invoice'
3611
-                    ? __('Deactivating the invoice message type also automatically deactivates the invoice payment method. In order for invoices to be generated the invoice message type must be active. If you completed this action by mistake, simply reactivate the invoice message type and then visit the payment methods admin page to reactivate the invoice payment method.',
3612
-                        'event_espresso')
3613
-                    : __('Deactivating the html messenger also automatically deactivates the invoice payment method.  In order for invoices to be generated the html messenger must be be active.  If you completed this action by mistake, simply reactivate the html messenger, then visit the payment methods admin page to reactivate the invoice payment method.',
3614
-                        'event_espresso');
3615
-                EE_Error::add_attention($msg);
3616
-            }
3617
-        }
3618
-        
3619
-        return true;
3620
-    }
3621
-    
3622
-    
3623
-    /**
3624
-     * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
3625
-     */
3626
-    public function update_mt_form()
3627
-    {
3628
-        if ( ! isset($this->_req_data['messenger']) || ! isset($this->_req_data['message_type'])) {
3629
-            EE_Error::add_error(__('Require message type or messenger to send an updated form'), __FILE__, __FUNCTION__,
3630
-                __LINE__);
3631
-            $this->_return_json();
3632
-        }
3633
-        
3634
-        $message_types = $this->get_installed_message_types();
3635
-        
3636
-        $message_type = $message_types[$this->_req_data['message_type']];
3637
-        $messenger    = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
3638
-        
3639
-        $content                         = $this->_message_type_settings_content($message_type, $messenger, true);
3640
-        $this->_template_args['success'] = true;
3641
-        $this->_template_args['content'] = $content;
3642
-        $this->_return_json();
3643
-    }
3644
-    
3645
-    
3646
-    /**
3647
-     * this handles saving the settings for a messenger or message type
3648
-     *
3649
-     */
3650
-    public function save_settings()
3651
-    {
3652
-        if ( ! isset($this->_req_data['type'])) {
3653
-            EE_Error::add_error(__('Cannot save settings because type is unknown (messenger settings or messsage type settings?)',
3654
-                'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
3655
-            $this->_template_args['error'] = true;
3656
-            $this->_return_json();
3657
-        }
3658
-        
3659
-        
3660
-        if ($this->_req_data['type'] == 'messenger') {
3661
-            $settings  = $this->_req_data['messenger_settings']; //this should be an array.
3662
-            $messenger = $settings['messenger'];
3663
-            //let's setup the settings data
3664
-            foreach ($settings as $key => $value) {
3665
-                switch ($key) {
3666
-                    case 'messenger' :
3667
-                        unset($settings['messenger']);
3668
-                        break;
3669
-                    case 'message_types' :
3670
-                        unset($settings['message_types']);
3671
-                        break;
3672
-                    default :
3673
-                        $settings[$key] = $value;
3674
-                        break;
3675
-                }
3676
-            }
3677
-            $this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
3678
-        } else if ($this->_req_data['type'] == 'message_type') {
3679
-            $settings     = $this->_req_data['message_type_settings'];
3680
-            $messenger    = $settings['messenger'];
3681
-            $message_type = $settings['message_type'];
3583
+			return false;
3584
+		}
3585
+        
3586
+		if ($message_type instanceof EE_message_type) {
3587
+			$message_type_name = $message_type->name;
3588
+			EE_Error::add_success(
3589
+				sprintf(
3590
+					__('%s message type has been successfully deactivated for the %s messenger.', 'event_espresso'),
3591
+					ucwords($message_type->label['singular']),
3592
+					ucwords($messenger->label['singular'])
3593
+				)
3594
+			);
3595
+		} else {
3596
+			$message_type_name = '';
3597
+			EE_Error::add_success(
3598
+				sprintf(
3599
+					__('%s messenger has been successfully deactivated.', 'event_espresso'),
3600
+					ucwords($messenger->label['singular'])
3601
+				)
3602
+			);
3603
+		}
3604
+        
3605
+		//if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
3606
+		if ($messenger->name == 'html' || $message_type_name == 'invoice') {
3607
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
3608
+			$count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
3609
+			if ($count_updated > 0) {
3610
+				$msg = $message_type_name == 'invoice'
3611
+					? __('Deactivating the invoice message type also automatically deactivates the invoice payment method. In order for invoices to be generated the invoice message type must be active. If you completed this action by mistake, simply reactivate the invoice message type and then visit the payment methods admin page to reactivate the invoice payment method.',
3612
+						'event_espresso')
3613
+					: __('Deactivating the html messenger also automatically deactivates the invoice payment method.  In order for invoices to be generated the html messenger must be be active.  If you completed this action by mistake, simply reactivate the html messenger, then visit the payment methods admin page to reactivate the invoice payment method.',
3614
+						'event_espresso');
3615
+				EE_Error::add_attention($msg);
3616
+			}
3617
+		}
3618
+        
3619
+		return true;
3620
+	}
3621
+    
3622
+    
3623
+	/**
3624
+	 * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
3625
+	 */
3626
+	public function update_mt_form()
3627
+	{
3628
+		if ( ! isset($this->_req_data['messenger']) || ! isset($this->_req_data['message_type'])) {
3629
+			EE_Error::add_error(__('Require message type or messenger to send an updated form'), __FILE__, __FUNCTION__,
3630
+				__LINE__);
3631
+			$this->_return_json();
3632
+		}
3633
+        
3634
+		$message_types = $this->get_installed_message_types();
3635
+        
3636
+		$message_type = $message_types[$this->_req_data['message_type']];
3637
+		$messenger    = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
3638
+        
3639
+		$content                         = $this->_message_type_settings_content($message_type, $messenger, true);
3640
+		$this->_template_args['success'] = true;
3641
+		$this->_template_args['content'] = $content;
3642
+		$this->_return_json();
3643
+	}
3644
+    
3645
+    
3646
+	/**
3647
+	 * this handles saving the settings for a messenger or message type
3648
+	 *
3649
+	 */
3650
+	public function save_settings()
3651
+	{
3652
+		if ( ! isset($this->_req_data['type'])) {
3653
+			EE_Error::add_error(__('Cannot save settings because type is unknown (messenger settings or messsage type settings?)',
3654
+				'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
3655
+			$this->_template_args['error'] = true;
3656
+			$this->_return_json();
3657
+		}
3658
+        
3659
+        
3660
+		if ($this->_req_data['type'] == 'messenger') {
3661
+			$settings  = $this->_req_data['messenger_settings']; //this should be an array.
3662
+			$messenger = $settings['messenger'];
3663
+			//let's setup the settings data
3664
+			foreach ($settings as $key => $value) {
3665
+				switch ($key) {
3666
+					case 'messenger' :
3667
+						unset($settings['messenger']);
3668
+						break;
3669
+					case 'message_types' :
3670
+						unset($settings['message_types']);
3671
+						break;
3672
+					default :
3673
+						$settings[$key] = $value;
3674
+						break;
3675
+				}
3676
+			}
3677
+			$this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
3678
+		} else if ($this->_req_data['type'] == 'message_type') {
3679
+			$settings     = $this->_req_data['message_type_settings'];
3680
+			$messenger    = $settings['messenger'];
3681
+			$message_type = $settings['message_type'];
3682 3682
             
3683
-            foreach ($settings as $key => $value) {
3684
-                switch ($key) {
3685
-                    case 'messenger' :
3686
-                        unset($settings['messenger']);
3687
-                        break;
3688
-                    case 'message_type' :
3689
-                        unset($settings['message_type']);
3690
-                        break;
3691
-                    default :
3692
-                        $settings[$key] = $value;
3693
-                        break;
3694
-                }
3695
-            }
3683
+			foreach ($settings as $key => $value) {
3684
+				switch ($key) {
3685
+					case 'messenger' :
3686
+						unset($settings['messenger']);
3687
+						break;
3688
+					case 'message_type' :
3689
+						unset($settings['message_type']);
3690
+						break;
3691
+					default :
3692
+						$settings[$key] = $value;
3693
+						break;
3694
+				}
3695
+			}
3696 3696
             
3697
-            $this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
3698
-        }
3699
-        
3700
-        //okay we should have the data all setup.  Now we just update!
3701
-        $success = $this->_message_resource_manager->update_active_messengers_option();
3702
-        
3703
-        if ($success) {
3704
-            EE_Error::add_success(__('Settings updated', 'event_espresso'));
3705
-        } else {
3706
-            EE_Error::add_error(__('Settings did not get updated', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
3707
-        }
3708
-        
3709
-        $this->_template_args['success'] = $success;
3710
-        $this->_return_json();
3711
-    }
3712
-    
3713
-    
3714
-    
3715
-    
3716
-    /**  EE MESSAGE PROCESSING ACTIONS **/
3717
-    
3718
-    
3719
-    /**
3720
-     * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
3721
-     * However, this does not send immediately, it just queues for sending.
3722
-     *
3723
-     * @since 4.9.0
3724
-     */
3725
-    protected function _generate_now()
3726
-    {
3727
-        $msg_ids = $this->_get_msg_ids_from_request();
3728
-        EED_Messages::generate_now($msg_ids);
3729
-        $this->_redirect_after_action(false, '', '', array(), true);
3730
-    }
3731
-    
3732
-    
3733
-    /**
3734
-     * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
3735
-     * are EEM_Message::status_resend or EEM_Message::status_idle
3736
-     *
3737
-     * @since 4.9.0
3738
-     *
3739
-     */
3740
-    protected function _generate_and_send_now()
3741
-    {
3742
-        $this->_generate_now();
3743
-        $this->_send_now();
3744
-        $this->_redirect_after_action(false, '', '', array(), true);
3745
-    }
3746
-    
3747
-    
3748
-    /**
3749
-     * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
3750
-     *
3751
-     * @since 4.9.0
3752
-     */
3753
-    protected function _queue_for_resending()
3754
-    {
3755
-        $msg_ids = $this->_get_msg_ids_from_request();
3756
-        EED_Messages::queue_for_resending($msg_ids);
3757
-        $this->_redirect_after_action(false, '', '', array(), true);
3758
-    }
3759
-    
3760
-    
3761
-    /**
3762
-     *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
3763
-     *
3764
-     * @since 4.9.0
3765
-     */
3766
-    protected function _send_now()
3767
-    {
3768
-        $msg_ids = $this->_get_msg_ids_from_request();
3769
-        EED_Messages::send_now($msg_ids);
3770
-        $this->_redirect_after_action(false, '', '', array(), true);
3771
-    }
3772
-    
3773
-    
3774
-    /**
3775
-     * Deletes EE_messages for IDs in the request.
3776
-     *
3777
-     * @since 4.9.0
3778
-     */
3779
-    protected function _delete_ee_messages()
3780
-    {
3781
-        $msg_ids       = $this->_get_msg_ids_from_request();
3782
-        $deleted_count = 0;
3783
-        foreach ($msg_ids as $msg_id) {
3784
-            if (EEM_Message::instance()->delete_by_ID($msg_id)) {
3785
-                $deleted_count++;
3786
-            }
3787
-        }
3788
-        if ($deleted_count) {
3789
-            $this->_redirect_after_action(
3790
-                true,
3791
-                _n('message', 'messages', $deleted_count, 'event_espresso'),
3792
-                __('deleted', 'event_espresso')
3793
-            );
3794
-        } else {
3795
-            EE_Error::add_error(
3796
-                _n('The message was not deleted.', 'The messages were not deleted', count($msg_ids), 'event_espresso'),
3797
-                __FILE__, __FUNCTION__, __LINE__
3798
-            );
3799
-            $this->_redirect_after_action(false, '', '', array(), true);
3800
-        }
3801
-    }
3802
-    
3803
-    
3804
-    /**
3805
-     *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
3806
-     * @since 4.9.0
3807
-     * @return array
3808
-     */
3809
-    protected function _get_msg_ids_from_request()
3810
-    {
3811
-        if ( ! isset($this->_req_data['MSG_ID'])) {
3812
-            return array();
3813
-        }
3814
-        
3815
-        return is_array($this->_req_data['MSG_ID']) ? array_keys($this->_req_data['MSG_ID']) : array($this->_req_data['MSG_ID']);
3816
-    }
3697
+			$this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
3698
+		}
3699
+        
3700
+		//okay we should have the data all setup.  Now we just update!
3701
+		$success = $this->_message_resource_manager->update_active_messengers_option();
3702
+        
3703
+		if ($success) {
3704
+			EE_Error::add_success(__('Settings updated', 'event_espresso'));
3705
+		} else {
3706
+			EE_Error::add_error(__('Settings did not get updated', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
3707
+		}
3708
+        
3709
+		$this->_template_args['success'] = $success;
3710
+		$this->_return_json();
3711
+	}
3712
+    
3713
+    
3714
+    
3715
+    
3716
+	/**  EE MESSAGE PROCESSING ACTIONS **/
3717
+    
3718
+    
3719
+	/**
3720
+	 * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
3721
+	 * However, this does not send immediately, it just queues for sending.
3722
+	 *
3723
+	 * @since 4.9.0
3724
+	 */
3725
+	protected function _generate_now()
3726
+	{
3727
+		$msg_ids = $this->_get_msg_ids_from_request();
3728
+		EED_Messages::generate_now($msg_ids);
3729
+		$this->_redirect_after_action(false, '', '', array(), true);
3730
+	}
3731
+    
3732
+    
3733
+	/**
3734
+	 * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
3735
+	 * are EEM_Message::status_resend or EEM_Message::status_idle
3736
+	 *
3737
+	 * @since 4.9.0
3738
+	 *
3739
+	 */
3740
+	protected function _generate_and_send_now()
3741
+	{
3742
+		$this->_generate_now();
3743
+		$this->_send_now();
3744
+		$this->_redirect_after_action(false, '', '', array(), true);
3745
+	}
3746
+    
3747
+    
3748
+	/**
3749
+	 * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
3750
+	 *
3751
+	 * @since 4.9.0
3752
+	 */
3753
+	protected function _queue_for_resending()
3754
+	{
3755
+		$msg_ids = $this->_get_msg_ids_from_request();
3756
+		EED_Messages::queue_for_resending($msg_ids);
3757
+		$this->_redirect_after_action(false, '', '', array(), true);
3758
+	}
3759
+    
3760
+    
3761
+	/**
3762
+	 *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
3763
+	 *
3764
+	 * @since 4.9.0
3765
+	 */
3766
+	protected function _send_now()
3767
+	{
3768
+		$msg_ids = $this->_get_msg_ids_from_request();
3769
+		EED_Messages::send_now($msg_ids);
3770
+		$this->_redirect_after_action(false, '', '', array(), true);
3771
+	}
3772
+    
3773
+    
3774
+	/**
3775
+	 * Deletes EE_messages for IDs in the request.
3776
+	 *
3777
+	 * @since 4.9.0
3778
+	 */
3779
+	protected function _delete_ee_messages()
3780
+	{
3781
+		$msg_ids       = $this->_get_msg_ids_from_request();
3782
+		$deleted_count = 0;
3783
+		foreach ($msg_ids as $msg_id) {
3784
+			if (EEM_Message::instance()->delete_by_ID($msg_id)) {
3785
+				$deleted_count++;
3786
+			}
3787
+		}
3788
+		if ($deleted_count) {
3789
+			$this->_redirect_after_action(
3790
+				true,
3791
+				_n('message', 'messages', $deleted_count, 'event_espresso'),
3792
+				__('deleted', 'event_espresso')
3793
+			);
3794
+		} else {
3795
+			EE_Error::add_error(
3796
+				_n('The message was not deleted.', 'The messages were not deleted', count($msg_ids), 'event_espresso'),
3797
+				__FILE__, __FUNCTION__, __LINE__
3798
+			);
3799
+			$this->_redirect_after_action(false, '', '', array(), true);
3800
+		}
3801
+	}
3802
+    
3803
+    
3804
+	/**
3805
+	 *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
3806
+	 * @since 4.9.0
3807
+	 * @return array
3808
+	 */
3809
+	protected function _get_msg_ids_from_request()
3810
+	{
3811
+		if ( ! isset($this->_req_data['MSG_ID'])) {
3812
+			return array();
3813
+		}
3814
+        
3815
+		return is_array($this->_req_data['MSG_ID']) ? array_keys($this->_req_data['MSG_ID']) : array($this->_req_data['MSG_ID']);
3816
+	}
3817 3817
     
3818 3818
     
3819 3819
 }
Please login to merge, or discard this patch.
core/helpers/EEH_DTT_Helper.helper.php 2 patches
Indentation   +916 added lines, -916 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 if (! defined('EVENT_ESPRESSO_VERSION')) {
3
-    exit('NO direct script access allowed');
3
+	exit('NO direct script access allowed');
4 4
 }
5 5
 
6 6
 /**
@@ -26,233 +26,233 @@  discard block
 block discarded – undo
26 26
 {
27 27
 
28 28
 
29
-    /**
30
-     * return the timezone set for the WP install
31
-     *
32
-     * @return string valid timezone string for PHP DateTimeZone() class
33
-     */
34
-    public static function get_timezone()
35
-    {
36
-        return EEH_DTT_Helper::get_valid_timezone_string();
37
-    }
38
-
39
-
40
-    /**
41
-     * get_valid_timezone_string
42
-     *    ensures that a valid timezone string is returned
43
-     *
44
-     * @access protected
45
-     * @param string $timezone_string
46
-     * @return string
47
-     * @throws \EE_Error
48
-     */
49
-    public static function get_valid_timezone_string($timezone_string = '')
50
-    {
51
-        // if passed a value, then use that, else get WP option
52
-        $timezone_string = ! empty($timezone_string) ? $timezone_string : get_option('timezone_string');
53
-        // value from above exists, use that, else get timezone string from gmt_offset
54
-        $timezone_string = ! empty($timezone_string) ? $timezone_string : EEH_DTT_Helper::get_timezone_string_from_gmt_offset();
55
-        EEH_DTT_Helper::validate_timezone($timezone_string);
56
-        return $timezone_string;
57
-    }
58
-
59
-
60
-    /**
61
-     * This only purpose for this static method is to validate that the incoming timezone is a valid php timezone.
62
-     *
63
-     * @static
64
-     * @access public
65
-     * @param  string $timezone_string Timezone string to check
66
-     * @param bool    $throw_error
67
-     * @return bool
68
-     * @throws \EE_Error
69
-     */
70
-    public static function validate_timezone($timezone_string, $throw_error = true)
71
-    {
72
-        // easiest way to test a timezone string is just see if it throws an error when you try to create a DateTimeZone object with it
73
-        try {
74
-            new DateTimeZone($timezone_string);
75
-        } catch (Exception $e) {
76
-            // sometimes we take exception to exceptions
77
-            if (! $throw_error) {
78
-                return false;
79
-            }
80
-            throw new EE_Error(
81
-                sprintf(
82
-                    __('The timezone given (%1$s), is invalid, please check with %2$sthis list%3$s for what valid timezones can be used',
83
-                        'event_espresso'),
84
-                    $timezone_string,
85
-                    '<a href="http://www.php.net/manual/en/timezones.php">',
86
-                    '</a>'
87
-                )
88
-            );
89
-        }
90
-        return true;
91
-    }
92
-
93
-
94
-    /**
95
-     * _create_timezone_object_from_timezone_name
96
-     *
97
-     * @access protected
98
-     * @param string $gmt_offset
99
-     * @return string
100
-     */
101
-    public static function get_timezone_string_from_gmt_offset($gmt_offset = '')
102
-    {
103
-        $timezone_string = 'UTC';
104
-        $gmt_offset      = ! empty($gmt_offset) ? $gmt_offset : get_option('gmt_offset');
105
-        if ($gmt_offset !== '') {
106
-            // convert GMT offset to seconds
107
-            $gmt_offset = $gmt_offset * HOUR_IN_SECONDS;
108
-            // account for WP offsets that aren't valid UTC
109
-            $gmt_offset = EEH_DTT_Helper::adjust_invalid_gmt_offsets($gmt_offset);
110
-            // although we don't know the TZ abbreviation, we know the UTC offset
111
-            $timezone_string = timezone_name_from_abbr(null, $gmt_offset);
112
-        }
113
-        // better have a valid timezone string by now, but if not, sigh... loop thru  the timezone_abbreviations_list()...
114
-        $timezone_string = $timezone_string !== false
115
-            ? $timezone_string
116
-            : EEH_DTT_Helper::get_timezone_string_from_abbreviations_list($gmt_offset);
117
-        return $timezone_string;
118
-    }
119
-
120
-    /**
121
-     * Gets the site's GMT offset based on either the timezone string
122
-     * (in which case teh gmt offset will vary depending on the location's
123
-     * observance of daylight savings time) or the gmt_offset wp option
124
-     *
125
-     * @return int seconds offset
126
-     */
127
-    public static function get_site_timezone_gmt_offset()
128
-    {
129
-        $timezone_string = get_option('timezone_string');
130
-        if ($timezone_string) {
131
-            try {
132
-                $timezone = new DateTimeZone($timezone_string);
133
-                return $timezone->getOffset(new DateTime()); //in WordPress DateTime defaults to UTC
134
-            } catch (Exception $e) {
135
-            }
136
-        }
137
-        $offset = get_option('gmt_offset');
138
-        return (int)($offset * HOUR_IN_SECONDS);
139
-    }
140
-
141
-
142
-    /**
143
-     * _create_timezone_object_from_timezone_name
144
-     *
145
-     * @access public
146
-     * @param int $gmt_offset
147
-     * @return int
148
-     */
149
-    public static function adjust_invalid_gmt_offsets($gmt_offset = 0)
150
-    {
151
-        //make sure $gmt_offset is int
152
-        $gmt_offset = (int)$gmt_offset;
153
-        switch ($gmt_offset) {
154
-
155
-            //			case -30600 :
156
-            //				$gmt_offset = -28800;
157
-            //				break;
158
-
159
-            case -27000 :
160
-                $gmt_offset = -25200;
161
-                break;
162
-
163
-            case -23400 :
164
-                $gmt_offset = -21600;
165
-                break;
166
-
167
-            case -19800 :
168
-                $gmt_offset = -18000;
169
-                break;
170
-
171
-            case -9000 :
172
-                $gmt_offset = -7200;
173
-                break;
174
-
175
-            case -5400 :
176
-                $gmt_offset = -3600;
177
-                break;
178
-
179
-            case -1800 :
180
-                $gmt_offset = 0;
181
-                break;
182
-
183
-            case 1800 :
184
-                $gmt_offset = 3600;
185
-                break;
186
-
187
-            case 49500 :
188
-                $gmt_offset = 50400;
189
-                break;
190
-
191
-        }
192
-        return $gmt_offset;
193
-    }
194
-
195
-
196
-    /**
197
-     * get_timezone_string_from_abbreviations_list
198
-     *
199
-     * @access public
200
-     * @param int $gmt_offset
201
-     * @return string
202
-     * @throws \EE_Error
203
-     */
204
-    public static function get_timezone_string_from_abbreviations_list($gmt_offset = 0)
205
-    {
206
-        $abbreviations = timezone_abbreviations_list();
207
-        foreach ($abbreviations as $abbreviation) {
208
-            foreach ($abbreviation as $city) {
209
-                if ($city['offset'] === $gmt_offset && $city['dst'] === false) {
210
-                    // check if the timezone is valid but don't throw any errors if it isn't
211
-                    if (EEH_DTT_Helper::validate_timezone($city['timezone_id'], false)) {
212
-                        return $city['timezone_id'];
213
-                    }
214
-                }
215
-            }
216
-        }
217
-        throw new EE_Error(
218
-            sprintf(
219
-                __('The provided GMT offset (%1$s), is invalid, please check with %2$sthis list%3$s for what valid timezones can be used',
220
-                    'event_espresso'),
221
-                $gmt_offset,
222
-                '<a href="http://www.php.net/manual/en/timezones.php">',
223
-                '</a>'
224
-            )
225
-        );
226
-    }
227
-
228
-
229
-    /**
230
-     * @access public
231
-     * @param string $timezone_string
232
-     */
233
-    public static function timezone_select_input($timezone_string = '')
234
-    {
235
-        // get WP date time format
236
-        $datetime_format = get_option('date_format') . ' ' . get_option('time_format');
237
-        // if passed a value, then use that, else get WP option
238
-        $timezone_string = ! empty($timezone_string) ? $timezone_string : get_option('timezone_string');
239
-        // check if the timezone is valid but don't throw any errors if it isn't
240
-        $timezone_string = EEH_DTT_Helper::validate_timezone($timezone_string, false);
241
-        $gmt_offset      = get_option('gmt_offset');
242
-
243
-        $check_zone_info = true;
244
-        if (empty($timezone_string)) {
245
-            // Create a UTC+- zone if no timezone string exists
246
-            $check_zone_info = false;
247
-            if ($gmt_offset > 0) {
248
-                $timezone_string = 'UTC+' . $gmt_offset;
249
-            } elseif ($gmt_offset < 0) {
250
-                $timezone_string = 'UTC' . $gmt_offset;
251
-            } else {
252
-                $timezone_string = 'UTC';
253
-            }
254
-        }
255
-        ?>
29
+	/**
30
+	 * return the timezone set for the WP install
31
+	 *
32
+	 * @return string valid timezone string for PHP DateTimeZone() class
33
+	 */
34
+	public static function get_timezone()
35
+	{
36
+		return EEH_DTT_Helper::get_valid_timezone_string();
37
+	}
38
+
39
+
40
+	/**
41
+	 * get_valid_timezone_string
42
+	 *    ensures that a valid timezone string is returned
43
+	 *
44
+	 * @access protected
45
+	 * @param string $timezone_string
46
+	 * @return string
47
+	 * @throws \EE_Error
48
+	 */
49
+	public static function get_valid_timezone_string($timezone_string = '')
50
+	{
51
+		// if passed a value, then use that, else get WP option
52
+		$timezone_string = ! empty($timezone_string) ? $timezone_string : get_option('timezone_string');
53
+		// value from above exists, use that, else get timezone string from gmt_offset
54
+		$timezone_string = ! empty($timezone_string) ? $timezone_string : EEH_DTT_Helper::get_timezone_string_from_gmt_offset();
55
+		EEH_DTT_Helper::validate_timezone($timezone_string);
56
+		return $timezone_string;
57
+	}
58
+
59
+
60
+	/**
61
+	 * This only purpose for this static method is to validate that the incoming timezone is a valid php timezone.
62
+	 *
63
+	 * @static
64
+	 * @access public
65
+	 * @param  string $timezone_string Timezone string to check
66
+	 * @param bool    $throw_error
67
+	 * @return bool
68
+	 * @throws \EE_Error
69
+	 */
70
+	public static function validate_timezone($timezone_string, $throw_error = true)
71
+	{
72
+		// easiest way to test a timezone string is just see if it throws an error when you try to create a DateTimeZone object with it
73
+		try {
74
+			new DateTimeZone($timezone_string);
75
+		} catch (Exception $e) {
76
+			// sometimes we take exception to exceptions
77
+			if (! $throw_error) {
78
+				return false;
79
+			}
80
+			throw new EE_Error(
81
+				sprintf(
82
+					__('The timezone given (%1$s), is invalid, please check with %2$sthis list%3$s for what valid timezones can be used',
83
+						'event_espresso'),
84
+					$timezone_string,
85
+					'<a href="http://www.php.net/manual/en/timezones.php">',
86
+					'</a>'
87
+				)
88
+			);
89
+		}
90
+		return true;
91
+	}
92
+
93
+
94
+	/**
95
+	 * _create_timezone_object_from_timezone_name
96
+	 *
97
+	 * @access protected
98
+	 * @param string $gmt_offset
99
+	 * @return string
100
+	 */
101
+	public static function get_timezone_string_from_gmt_offset($gmt_offset = '')
102
+	{
103
+		$timezone_string = 'UTC';
104
+		$gmt_offset      = ! empty($gmt_offset) ? $gmt_offset : get_option('gmt_offset');
105
+		if ($gmt_offset !== '') {
106
+			// convert GMT offset to seconds
107
+			$gmt_offset = $gmt_offset * HOUR_IN_SECONDS;
108
+			// account for WP offsets that aren't valid UTC
109
+			$gmt_offset = EEH_DTT_Helper::adjust_invalid_gmt_offsets($gmt_offset);
110
+			// although we don't know the TZ abbreviation, we know the UTC offset
111
+			$timezone_string = timezone_name_from_abbr(null, $gmt_offset);
112
+		}
113
+		// better have a valid timezone string by now, but if not, sigh... loop thru  the timezone_abbreviations_list()...
114
+		$timezone_string = $timezone_string !== false
115
+			? $timezone_string
116
+			: EEH_DTT_Helper::get_timezone_string_from_abbreviations_list($gmt_offset);
117
+		return $timezone_string;
118
+	}
119
+
120
+	/**
121
+	 * Gets the site's GMT offset based on either the timezone string
122
+	 * (in which case teh gmt offset will vary depending on the location's
123
+	 * observance of daylight savings time) or the gmt_offset wp option
124
+	 *
125
+	 * @return int seconds offset
126
+	 */
127
+	public static function get_site_timezone_gmt_offset()
128
+	{
129
+		$timezone_string = get_option('timezone_string');
130
+		if ($timezone_string) {
131
+			try {
132
+				$timezone = new DateTimeZone($timezone_string);
133
+				return $timezone->getOffset(new DateTime()); //in WordPress DateTime defaults to UTC
134
+			} catch (Exception $e) {
135
+			}
136
+		}
137
+		$offset = get_option('gmt_offset');
138
+		return (int)($offset * HOUR_IN_SECONDS);
139
+	}
140
+
141
+
142
+	/**
143
+	 * _create_timezone_object_from_timezone_name
144
+	 *
145
+	 * @access public
146
+	 * @param int $gmt_offset
147
+	 * @return int
148
+	 */
149
+	public static function adjust_invalid_gmt_offsets($gmt_offset = 0)
150
+	{
151
+		//make sure $gmt_offset is int
152
+		$gmt_offset = (int)$gmt_offset;
153
+		switch ($gmt_offset) {
154
+
155
+			//			case -30600 :
156
+			//				$gmt_offset = -28800;
157
+			//				break;
158
+
159
+			case -27000 :
160
+				$gmt_offset = -25200;
161
+				break;
162
+
163
+			case -23400 :
164
+				$gmt_offset = -21600;
165
+				break;
166
+
167
+			case -19800 :
168
+				$gmt_offset = -18000;
169
+				break;
170
+
171
+			case -9000 :
172
+				$gmt_offset = -7200;
173
+				break;
174
+
175
+			case -5400 :
176
+				$gmt_offset = -3600;
177
+				break;
178
+
179
+			case -1800 :
180
+				$gmt_offset = 0;
181
+				break;
182
+
183
+			case 1800 :
184
+				$gmt_offset = 3600;
185
+				break;
186
+
187
+			case 49500 :
188
+				$gmt_offset = 50400;
189
+				break;
190
+
191
+		}
192
+		return $gmt_offset;
193
+	}
194
+
195
+
196
+	/**
197
+	 * get_timezone_string_from_abbreviations_list
198
+	 *
199
+	 * @access public
200
+	 * @param int $gmt_offset
201
+	 * @return string
202
+	 * @throws \EE_Error
203
+	 */
204
+	public static function get_timezone_string_from_abbreviations_list($gmt_offset = 0)
205
+	{
206
+		$abbreviations = timezone_abbreviations_list();
207
+		foreach ($abbreviations as $abbreviation) {
208
+			foreach ($abbreviation as $city) {
209
+				if ($city['offset'] === $gmt_offset && $city['dst'] === false) {
210
+					// check if the timezone is valid but don't throw any errors if it isn't
211
+					if (EEH_DTT_Helper::validate_timezone($city['timezone_id'], false)) {
212
+						return $city['timezone_id'];
213
+					}
214
+				}
215
+			}
216
+		}
217
+		throw new EE_Error(
218
+			sprintf(
219
+				__('The provided GMT offset (%1$s), is invalid, please check with %2$sthis list%3$s for what valid timezones can be used',
220
+					'event_espresso'),
221
+				$gmt_offset,
222
+				'<a href="http://www.php.net/manual/en/timezones.php">',
223
+				'</a>'
224
+			)
225
+		);
226
+	}
227
+
228
+
229
+	/**
230
+	 * @access public
231
+	 * @param string $timezone_string
232
+	 */
233
+	public static function timezone_select_input($timezone_string = '')
234
+	{
235
+		// get WP date time format
236
+		$datetime_format = get_option('date_format') . ' ' . get_option('time_format');
237
+		// if passed a value, then use that, else get WP option
238
+		$timezone_string = ! empty($timezone_string) ? $timezone_string : get_option('timezone_string');
239
+		// check if the timezone is valid but don't throw any errors if it isn't
240
+		$timezone_string = EEH_DTT_Helper::validate_timezone($timezone_string, false);
241
+		$gmt_offset      = get_option('gmt_offset');
242
+
243
+		$check_zone_info = true;
244
+		if (empty($timezone_string)) {
245
+			// Create a UTC+- zone if no timezone string exists
246
+			$check_zone_info = false;
247
+			if ($gmt_offset > 0) {
248
+				$timezone_string = 'UTC+' . $gmt_offset;
249
+			} elseif ($gmt_offset < 0) {
250
+				$timezone_string = 'UTC' . $gmt_offset;
251
+			} else {
252
+				$timezone_string = 'UTC';
253
+			}
254
+		}
255
+		?>
256 256
 
257 257
         <p>
258 258
             <label for="timezone_string"><?php _e('timezone'); ?></label>
@@ -265,13 +265,13 @@  discard block
 block discarded – undo
265 265
 
266 266
         <p>
267 267
         <span><?php
268
-            printf(
269
-                __('%1$sUTC%2$s time is %3$s'),
270
-                '<abbr title="Coordinated Universal Time">',
271
-                '</abbr>',
272
-                '<code>' . date_i18n($datetime_format, false, true) . '</code>'
273
-            );
274
-            ?></span>
268
+			printf(
269
+				__('%1$sUTC%2$s time is %3$s'),
270
+				'<abbr title="Coordinated Universal Time">',
271
+				'</abbr>',
272
+				'<code>' . date_i18n($datetime_format, false, true) . '</code>'
273
+			);
274
+			?></span>
275 275
         <?php if (! empty($timezone_string) || ! empty($gmt_offset)) : ?>
276 276
         <br/><span><?php printf(__('Local time is %1$s'), '<code>' . date_i18n($datetime_format) . '</code>'); ?></span>
277 277
     <?php endif; ?>
@@ -280,693 +280,693 @@  discard block
 block discarded – undo
280 280
         <br/>
281 281
         <span>
282 282
 					<?php
283
-                    // Set TZ so localtime works.
284
-                    date_default_timezone_set($timezone_string);
285
-                    $now = localtime(time(), true);
286
-                    if ($now['tm_isdst']) {
287
-                        _e('This timezone is currently in daylight saving time.');
288
-                    } else {
289
-                        _e('This timezone is currently in standard time.');
290
-                    }
291
-                    ?>
283
+					// Set TZ so localtime works.
284
+					date_default_timezone_set($timezone_string);
285
+					$now = localtime(time(), true);
286
+					if ($now['tm_isdst']) {
287
+						_e('This timezone is currently in daylight saving time.');
288
+					} else {
289
+						_e('This timezone is currently in standard time.');
290
+					}
291
+					?>
292 292
             <br/>
293 293
             <?php
294
-            if (function_exists('timezone_transitions_get')) {
295
-                $found                   = false;
296
-                $date_time_zone_selected = new DateTimeZone($timezone_string);
297
-                $tz_offset               = timezone_offset_get($date_time_zone_selected, date_create());
298
-                $right_now               = time();
299
-                $tr['isdst']             = false;
300
-                foreach (timezone_transitions_get($date_time_zone_selected) as $tr) {
301
-                    if ($tr['ts'] > $right_now) {
302
-                        $found = true;
303
-                        break;
304
-                    }
305
-                }
306
-
307
-                if ($found) {
308
-                    $message = $tr['isdst'] ?
309
-                        __(' Daylight saving time begins on: %s.') :
310
-                        __(' Standard time begins  on: %s.');
311
-                    // Add the difference between the current offset and the new offset to ts to get the correct transition time from date_i18n().
312
-                    printf($message,
313
-                        '<code >' . date_i18n($datetime_format, $tr['ts'] + ($tz_offset - $tr['offset'])) . '</code >');
314
-                } else {
315
-                    _e('This timezone does not observe daylight saving time.');
316
-                }
317
-            }
318
-            // Set back to UTC.
319
-            date_default_timezone_set('UTC');
320
-            ?>
294
+			if (function_exists('timezone_transitions_get')) {
295
+				$found                   = false;
296
+				$date_time_zone_selected = new DateTimeZone($timezone_string);
297
+				$tz_offset               = timezone_offset_get($date_time_zone_selected, date_create());
298
+				$right_now               = time();
299
+				$tr['isdst']             = false;
300
+				foreach (timezone_transitions_get($date_time_zone_selected) as $tr) {
301
+					if ($tr['ts'] > $right_now) {
302
+						$found = true;
303
+						break;
304
+					}
305
+				}
306
+
307
+				if ($found) {
308
+					$message = $tr['isdst'] ?
309
+						__(' Daylight saving time begins on: %s.') :
310
+						__(' Standard time begins  on: %s.');
311
+					// Add the difference between the current offset and the new offset to ts to get the correct transition time from date_i18n().
312
+					printf($message,
313
+						'<code >' . date_i18n($datetime_format, $tr['ts'] + ($tz_offset - $tr['offset'])) . '</code >');
314
+				} else {
315
+					_e('This timezone does not observe daylight saving time.');
316
+				}
317
+			}
318
+			// Set back to UTC.
319
+			date_default_timezone_set('UTC');
320
+			?>
321 321
 				</span></p>
322 322
         <?php
323
-    endif;
324
-    }
325
-
326
-
327
-    /**
328
-     * This method will take an incoming unix timestamp and add the offset to it for the given timezone_string.
329
-     * If no unix timestamp is given then time() is used.  If no timezone is given then the set timezone string for
330
-     * the site is used.
331
-     * This is used typically when using a Unix timestamp any core WP functions that expect their specially
332
-     * computed timestamp (i.e. date_i18n() )
333
-     *
334
-     * @param int    $unix_timestamp                  if 0, then time() will be used.
335
-     * @param string $timezone_string                 timezone_string. If empty, then the current set timezone for the
336
-     *                                                site will be used.
337
-     * @return int      $unix_timestamp with the offset applied for the given timezone.
338
-     */
339
-    public static function get_timestamp_with_offset($unix_timestamp = 0, $timezone_string = '')
340
-    {
341
-        $unix_timestamp  = $unix_timestamp === 0 ? time() : (int)$unix_timestamp;
342
-        $timezone_string = self::get_valid_timezone_string($timezone_string);
343
-        $TimeZone        = new DateTimeZone($timezone_string);
344
-
345
-        $DateTime = new DateTime('@' . $unix_timestamp, $TimeZone);
346
-        $offset   = timezone_offset_get($TimeZone, $DateTime);
347
-        return (int)$DateTime->format('U') + (int)$offset;
348
-    }
349
-
350
-
351
-    /**
352
-     *    _set_date_time_field
353
-     *    modifies EE_Base_Class EE_Datetime_Field objects
354
-     *
355
-     * @param  EE_Base_Class $obj                 EE_Base_Class object
356
-     * @param    DateTime    $DateTime            PHP DateTime object
357
-     * @param  string        $datetime_field_name the datetime fieldname to be manipulated
358
-     * @return    EE_Base_Class
359
-     */
360
-    protected static function _set_date_time_field(EE_Base_Class $obj, DateTime $DateTime, $datetime_field_name)
361
-    {
362
-        // grab current datetime format
363
-        $current_format = $obj->get_format();
364
-        // set new full timestamp format
365
-        $obj->set_date_format(EE_Datetime_Field::mysql_date_format);
366
-        $obj->set_time_format(EE_Datetime_Field::mysql_time_format);
367
-        // set the new date value using a full timestamp format so that no data is lost
368
-        $obj->set($datetime_field_name, $DateTime->format(EE_Datetime_Field::mysql_timestamp_format));
369
-        // reset datetime formats
370
-        $obj->set_date_format($current_format[0]);
371
-        $obj->set_time_format($current_format[1]);
372
-        return $obj;
373
-    }
374
-
375
-
376
-    /**
377
-     *    date_time_add
378
-     *    helper for doing simple datetime calculations on a given datetime from EE_Base_Class
379
-     *    and modifying it IN the EE_Base_Class so you don't have to do anything else.
380
-     *
381
-     * @param  EE_Base_Class $obj                 EE_Base_Class object
382
-     * @param  string        $datetime_field_name name of the EE_Datetime_Filed datatype db column to be manipulated
383
-     * @param  string        $period              what you are adding. The options are (years, months, days, hours,
384
-     *                                            minutes, seconds) defaults to years
385
-     * @param  integer       $value               what you want to increment the time by
386
-     * @return EE_Base_Class           return the EE_Base_Class object so right away you can do something with it
387
-     *                                 (chaining)
388
-     */
389
-    public static function date_time_add(EE_Base_Class $obj, $datetime_field_name, $period = 'years', $value = 1)
390
-    {
391
-        //get the raw UTC date.
392
-        $DateTime = $obj->get_DateTime_object($datetime_field_name);
393
-        $DateTime = EEH_DTT_Helper::calc_date($DateTime, $period, $value);
394
-        return EEH_DTT_Helper::_set_date_time_field($obj, $DateTime, $datetime_field_name);
395
-    }
396
-
397
-
398
-    /**
399
-     *    date_time_subtract
400
-     *    same as date_time_add except subtracting value instead of adding.
401
-     *
402
-     * @param \EE_Base_Class $obj
403
-     * @param  string        $datetime_field_name name of the EE_Datetime_Filed datatype db column to be manipulated
404
-     * @param string         $period
405
-     * @param int            $value
406
-     * @return \EE_Base_Class
407
-     */
408
-    public static function date_time_subtract(EE_Base_Class $obj, $datetime_field_name, $period = 'years', $value = 1)
409
-    {
410
-        //get the raw UTC date
411
-        $DateTime = $obj->get_DateTime_object($datetime_field_name);
412
-        $DateTime = EEH_DTT_Helper::calc_date($DateTime, $period, $value, '-');
413
-        return EEH_DTT_Helper::_set_date_time_field($obj, $DateTime, $datetime_field_name);
414
-    }
415
-
416
-
417
-    /**
418
-     * Simply takes an incoming DateTime object and does calculations on it based on the incoming parameters
419
-     *
420
-     * @param  DateTime $DateTime DateTime object
421
-     * @param  string   $period   a value to indicate what interval is being used in the calculation. The options are
422
-     *                            'years', 'months', 'days', 'hours', 'minutes', 'seconds'. Defaults to years.
423
-     * @param  integer  $value    What you want to increment the date by
424
-     * @param  string   $operand  What operand you wish to use for the calculation
425
-     * @return \DateTime return whatever type came in.
426
-     * @throws \EE_Error
427
-     */
428
-    protected static function _modify_datetime_object(DateTime $DateTime, $period = 'years', $value = 1, $operand = '+')
429
-    {
430
-        if (! $DateTime instanceof DateTime) {
431
-            throw new EE_Error(
432
-                sprintf(
433
-                    __('Expected a PHP DateTime object, but instead received %1$s', 'event_espresso'),
434
-                    print_r($DateTime, true)
435
-                )
436
-            );
437
-        }
438
-        switch ($period) {
439
-            case 'years' :
440
-                $value = 'P' . $value . 'Y';
441
-                break;
442
-            case 'months' :
443
-                $value = 'P' . $value . 'M';
444
-                break;
445
-            case 'weeks' :
446
-                $value = 'P' . $value . 'W';
447
-                break;
448
-            case 'days' :
449
-                $value = 'P' . $value . 'D';
450
-                break;
451
-            case 'hours' :
452
-                $value = 'PT' . $value . 'H';
453
-                break;
454
-            case 'minutes' :
455
-                $value = 'PT' . $value . 'M';
456
-                break;
457
-            case 'seconds' :
458
-                $value = 'PT' . $value . 'S';
459
-                break;
460
-        }
461
-        switch ($operand) {
462
-            case '+':
463
-                $DateTime->add(new DateInterval($value));
464
-                break;
465
-            case '-':
466
-                $DateTime->sub(new DateInterval($value));
467
-                break;
468
-        }
469
-        return $DateTime;
470
-    }
471
-
472
-
473
-    /**
474
-     * Simply takes an incoming Unix timestamp and does calculations on it based on the incoming parameters
475
-     *
476
-     * @param  int     $timestamp Unix timestamp
477
-     * @param  string  $period    a value to indicate what interval is being used in the calculation. The options are
478
-     *                            'years', 'months', 'days', 'hours', 'minutes', 'seconds'. Defaults to years.
479
-     * @param  integer $value     What you want to increment the date by
480
-     * @param  string  $operand   What operand you wish to use for the calculation
481
-     * @return \DateTime return whatever type came in.
482
-     * @throws \EE_Error
483
-     */
484
-    protected static function _modify_timestamp($timestamp, $period = 'years', $value = 1, $operand = '+')
485
-    {
486
-        if (! preg_match(EE_Datetime_Field::unix_timestamp_regex, $timestamp)) {
487
-            throw new EE_Error(
488
-                sprintf(
489
-                    __('Expected a Unix timestamp, but instead received %1$s', 'event_espresso'),
490
-                    print_r($timestamp, true)
491
-                )
492
-            );
493
-        }
494
-        switch ($period) {
495
-            case 'years' :
496
-                $value = YEAR_IN_SECONDS * $value;
497
-                break;
498
-            case 'months' :
499
-                $value = YEAR_IN_SECONDS / 12 * $value;
500
-                break;
501
-            case 'weeks' :
502
-                $value = WEEK_IN_SECONDS * $value;
503
-                break;
504
-            case 'days' :
505
-                $value = DAY_IN_SECONDS * $value;
506
-                break;
507
-            case 'hours' :
508
-                $value = HOUR_IN_SECONDS * $value;
509
-                break;
510
-            case 'minutes' :
511
-                $value = MINUTE_IN_SECONDS * $value;
512
-                break;
513
-        }
514
-        switch ($operand) {
515
-            case '+':
516
-                $timestamp += $value;
517
-                break;
518
-            case '-':
519
-                $timestamp -= $value;
520
-                break;
521
-        }
522
-        return $timestamp;
523
-    }
524
-
525
-
526
-    /**
527
-     * Simply takes an incoming UTC timestamp or DateTime object and does calculations on it based on the incoming
528
-     * parameters and returns the new timestamp or DateTime.
529
-     *
530
-     * @param  int | DateTime $DateTime_or_timestamp DateTime object or Unix timestamp
531
-     * @param  string         $period                a value to indicate what interval is being used in the
532
-     *                                               calculation. The options are 'years', 'months', 'days', 'hours',
533
-     *                                               'minutes', 'seconds'. Defaults to years.
534
-     * @param  integer        $value                 What you want to increment the date by
535
-     * @param  string         $operand               What operand you wish to use for the calculation
536
-     * @return mixed string|DateTime          return whatever type came in.
537
-     */
538
-    public static function calc_date($DateTime_or_timestamp, $period = 'years', $value = 1, $operand = '+')
539
-    {
540
-        if ($DateTime_or_timestamp instanceof DateTime) {
541
-            return EEH_DTT_Helper::_modify_datetime_object($DateTime_or_timestamp, $period, $value, $operand);
542
-        } else if (preg_match(EE_Datetime_Field::unix_timestamp_regex, $DateTime_or_timestamp)) {
543
-            return EEH_DTT_Helper::_modify_timestamp($DateTime_or_timestamp, $period, $value, $operand);
544
-        } else {
545
-            //error
546
-            return $DateTime_or_timestamp;
547
-        }
548
-    }
549
-
550
-
551
-    /**
552
-     * The purpose of this helper method is to receive an incoming format string in php date/time format
553
-     * and spit out the js and moment.js equivalent formats.
554
-     * Note, if no format string is given, then it is assumed the user wants what is set for WP.
555
-     * Note, js date and time formats are those used by the jquery-ui datepicker and the jquery-ui date-
556
-     * time picker.
557
-     *
558
-     * @see http://stackoverflow.com/posts/16725290/ for the code inspiration.
559
-     * @param null $date_format_string
560
-     * @param null $time_format_string
561
-     * @return array
562
-     *                array(
563
-     *                'js' => array (
564
-     *                'date' => //date format
565
-     *                'time' => //time format
566
-     *                ),
567
-     *                'moment' => //date and time format.
568
-     *                )
569
-     */
570
-    public static function convert_php_to_js_and_moment_date_formats(
571
-        $date_format_string = null,
572
-        $time_format_string = null
573
-    ) {
574
-        if ($date_format_string === null) {
575
-            $date_format_string = get_option('date_format');
576
-        }
577
-
578
-        if ($time_format_string === null) {
579
-            $time_format_string = get_option('time_format');
580
-        }
581
-
582
-        $date_format = self::_php_to_js_moment_converter($date_format_string);
583
-        $time_format = self::_php_to_js_moment_converter($time_format_string);
584
-
585
-        return array(
586
-            'js'     => array(
587
-                'date' => $date_format['js'],
588
-                'time' => $time_format['js'],
589
-            ),
590
-            'moment' => $date_format['moment'] . ' ' . $time_format['moment'],
591
-        );
592
-    }
593
-
594
-
595
-    /**
596
-     * This converts incoming format string into js and moment variations.
597
-     *
598
-     * @param string $format_string incoming php format string
599
-     * @return array js and moment formats.
600
-     */
601
-    protected static function _php_to_js_moment_converter($format_string)
602
-    {
603
-        /**
604
-         * This is a map of symbols for formats.
605
-         * The index is the php symbol, the equivalent values are in the array.
606
-         *
607
-         * @var array
608
-         */
609
-        $symbols_map      = array(
610
-            // Day
611
-            //01
612
-            'd' => array(
613
-                'js'     => 'dd',
614
-                'moment' => 'DD',
615
-            ),
616
-            //Mon
617
-            'D' => array(
618
-                'js'     => 'D',
619
-                'moment' => 'ddd',
620
-            ),
621
-            //1,2,...31
622
-            'j' => array(
623
-                'js'     => 'd',
624
-                'moment' => 'D',
625
-            ),
626
-            //Monday
627
-            'l' => array(
628
-                'js'     => 'DD',
629
-                'moment' => 'dddd',
630
-            ),
631
-            //ISO numeric representation of the day of the week (1-6)
632
-            'N' => array(
633
-                'js'     => '',
634
-                'moment' => 'E',
635
-            ),
636
-            //st,nd.rd
637
-            'S' => array(
638
-                'js'     => '',
639
-                'moment' => 'o',
640
-            ),
641
-            //numeric representation of day of week (0-6)
642
-            'w' => array(
643
-                'js'     => '',
644
-                'moment' => 'd',
645
-            ),
646
-            //day of year starting from 0 (0-365)
647
-            'z' => array(
648
-                'js'     => 'o',
649
-                'moment' => 'DDD' //note moment does not start with 0 so will need to modify by subtracting 1
650
-            ),
651
-            // Week
652
-            //ISO-8601 week number of year (weeks starting on monday)
653
-            'W' => array(
654
-                'js'     => '',
655
-                'moment' => 'w',
656
-            ),
657
-            // Month
658
-            // January...December
659
-            'F' => array(
660
-                'js'     => 'MM',
661
-                'moment' => 'MMMM',
662
-            ),
663
-            //01...12
664
-            'm' => array(
665
-                'js'     => 'mm',
666
-                'moment' => 'MM',
667
-            ),
668
-            //Jan...Dec
669
-            'M' => array(
670
-                'js'     => 'M',
671
-                'moment' => 'MMM',
672
-            ),
673
-            //1-12
674
-            'n' => array(
675
-                'js'     => 'm',
676
-                'moment' => 'M',
677
-            ),
678
-            //number of days in given month
679
-            't' => array(
680
-                'js'     => '',
681
-                'moment' => '',
682
-            ),
683
-            // Year
684
-            //whether leap year or not 1/0
685
-            'L' => array(
686
-                'js'     => '',
687
-                'moment' => '',
688
-            ),
689
-            //ISO-8601 year number
690
-            'o' => array(
691
-                'js'     => '',
692
-                'moment' => 'GGGG',
693
-            ),
694
-            //1999...2003
695
-            'Y' => array(
696
-                'js'     => 'yy',
697
-                'moment' => 'YYYY',
698
-            ),
699
-            //99...03
700
-            'y' => array(
701
-                'js'     => 'y',
702
-                'moment' => 'YY',
703
-            ),
704
-            // Time
705
-            // am/pm
706
-            'a' => array(
707
-                'js'     => 'tt',
708
-                'moment' => 'a',
709
-            ),
710
-            // AM/PM
711
-            'A' => array(
712
-                'js'     => 'TT',
713
-                'moment' => 'A',
714
-            ),
715
-            // Swatch Internet Time?!?
716
-            'B' => array(
717
-                'js'     => '',
718
-                'moment' => '',
719
-            ),
720
-            //1...12
721
-            'g' => array(
722
-                'js'     => 'h',
723
-                'moment' => 'h',
724
-            ),
725
-            //0...23
726
-            'G' => array(
727
-                'js'     => 'H',
728
-                'moment' => 'H',
729
-            ),
730
-            //01...12
731
-            'h' => array(
732
-                'js'     => 'hh',
733
-                'moment' => 'hh',
734
-            ),
735
-            //00...23
736
-            'H' => array(
737
-                'js'     => 'HH',
738
-                'moment' => 'HH',
739
-            ),
740
-            //00..59
741
-            'i' => array(
742
-                'js'     => 'mm',
743
-                'moment' => 'mm',
744
-            ),
745
-            //seconds... 00...59
746
-            's' => array(
747
-                'js'     => 'ss',
748
-                'moment' => 'ss',
749
-            ),
750
-            //microseconds
751
-            'u' => array(
752
-                'js'     => '',
753
-                'moment' => '',
754
-            ),
755
-        );
756
-        $jquery_ui_format = "";
757
-        $moment_format    = "";
758
-        $escaping         = false;
759
-        for ($i = 0; $i < strlen($format_string); $i++) {
760
-            $char = $format_string[$i];
761
-            if ($char === '\\') { // PHP date format escaping character
762
-                $i++;
763
-                if ($escaping) {
764
-                    $jquery_ui_format .= $format_string[$i];
765
-                    $moment_format .= $format_string[$i];
766
-                } else {
767
-                    $jquery_ui_format .= '\'' . $format_string[$i];
768
-                    $moment_format .= $format_string[$i];
769
-                }
770
-                $escaping = true;
771
-            } else {
772
-                if ($escaping) {
773
-                    $jquery_ui_format .= "'";
774
-                    $moment_format .= "'";
775
-                    $escaping = false;
776
-                }
777
-                if (isset($symbols_map[$char])) {
778
-                    $jquery_ui_format .= $symbols_map[$char]['js'];
779
-                    $moment_format .= $symbols_map[$char]['moment'];
780
-                } else {
781
-                    $jquery_ui_format .= $char;
782
-                    $moment_format .= $char;
783
-                }
784
-            }
785
-        }
786
-        return array('js' => $jquery_ui_format, 'moment' => $moment_format);
787
-    }
788
-
789
-
790
-    /**
791
-     * This takes an incoming format string and validates it to ensure it will work fine with PHP.
792
-     *
793
-     * @param string $format_string   Incoming format string for php date().
794
-     * @return mixed bool|array  If all is okay then TRUE is returned.  Otherwise an array of validation
795
-     *                                errors is returned.  So for client code calling, check for is_array() to
796
-     *                                indicate failed validations.
797
-     */
798
-    public static function validate_format_string($format_string)
799
-    {
800
-        $error_msg = array();
801
-        //time format checks
802
-        switch (true) {
803
-            case   strpos($format_string, 'h') !== false  :
804
-            case   strpos($format_string, 'g') !== false :
805
-                /**
806
-                 * if the time string has a lowercase 'h' which == 12 hour time format and there
807
-                 * is not any ante meridiem format ('a' or 'A').  Then throw an error because its
808
-                 * too ambiguous and PHP won't be able to figure out whether 1 = 1pm or 1am.
809
-                 */
810
-                if (strpos(strtoupper($format_string), 'A') === false) {
811
-                    $error_msg[] = __('There is a  time format for 12 hour time but no  "a" or "A" to indicate am/pm.  Without this distinction, PHP is unable to determine if a "1" for the hour value equals "1pm" or "1am".',
812
-                        'event_espresso');
813
-                }
814
-                break;
815
-
816
-        }
817
-
818
-        return empty($error_msg) ? true : $error_msg;
819
-    }
820
-
821
-
822
-    /**
823
-     *     If the the first date starts at midnight on one day, and the next date ends at midnight on the
824
-     *     very next day then this method will return true.
825
-     *    If $date_1 = 2015-12-15 00:00:00 and $date_2 = 2015-12-16 00:00:00 then this function will return true.
826
-     *    If $date_1 = 2015-12-15 03:00:00 and $date_2 = 2015-12_16 03:00:00 then this function will return false.
827
-     *    If $date_1 = 2015-12-15 00:00:00 and $date_2 = 2015-12-15 00:00:00 then this function will return true.
828
-     *
829
-     * @param mixed $date_1
830
-     * @param mixed $date_2
831
-     * @return bool
832
-     */
833
-    public static function dates_represent_one_24_hour_date($date_1, $date_2)
834
-    {
835
-
836
-        if (
837
-            (! $date_1 instanceof DateTime || ! $date_2 instanceof DateTime) ||
838
-            ($date_1->format(EE_Datetime_Field::mysql_time_format) != '00:00:00' || $date_2->format(EE_Datetime_Field::mysql_time_format) != '00:00:00')
839
-        ) {
840
-            return false;
841
-        }
842
-        return $date_2->format('U') - $date_1->format('U') == 86400 ? true : false;
843
-    }
844
-
845
-
846
-    /**
847
-     * This returns the appropriate query interval string that can be used in sql queries involving mysql Date
848
-     * Functions.
849
-     *
850
-     * @param string $timezone_string    A timezone string in a valid format to instantiate a DateTimeZone object.
851
-     * @param string $field_for_interval The Database field that is the interval is applied to in the query.
852
-     * @return string
853
-     */
854
-    public static function get_sql_query_interval_for_offset($timezone_string, $field_for_interval)
855
-    {
856
-        try {
857
-            /** need to account for timezone offset on the selects */
858
-            $DateTimeZone = new DateTimeZone($timezone_string);
859
-        } catch (Exception $e) {
860
-            $DateTimeZone = null;
861
-        }
862
-
863
-        /**
864
-         * Note get_option( 'gmt_offset') returns a value in hours, whereas DateTimeZone::getOffset returns values in seconds.
865
-         * Hence we do the calc for DateTimeZone::getOffset.
866
-         */
867
-        $offset         = $DateTimeZone instanceof DateTimeZone ? ($DateTimeZone->getOffset(new DateTime('now'))) / HOUR_IN_SECONDS : get_option('gmt_offset');
868
-        $query_interval = $offset < 0
869
-            ? 'DATE_SUB(' . $field_for_interval . ', INTERVAL ' . $offset * -1 . ' HOUR)'
870
-            : 'DATE_ADD(' . $field_for_interval . ', INTERVAL ' . $offset . ' HOUR)';
871
-        return $query_interval;
872
-    }
873
-
874
-    /**
875
-     * Retrieves the site's default timezone and returns it formatted so it's ready for display
876
-     * to users. If you want to customize how its displayed feel free to fetch the 'timezone_string'
877
-     * and 'gmt_offset' WordPress options directly; or use the filter
878
-     * FHEE__EEH_DTT_Helper__get_timezone_string_for_display
879
-     * (although note that we remove any HTML that may be added)
880
-     *
881
-     * @return string
882
-     */
883
-    public static function get_timezone_string_for_display()
884
-    {
885
-        $pretty_timezone = apply_filters('FHEE__EEH_DTT_Helper__get_timezone_string_for_display', '');
886
-        if (! empty($pretty_timezone)) {
887
-            return esc_html($pretty_timezone);
888
-        }
889
-        $timezone_string = get_option('timezone_string');
890
-        if ($timezone_string) {
891
-            static $mo_loaded = false;
892
-            // Load translations for continents and cities just like wp_timezone_choice does
893
-            if (! $mo_loaded) {
894
-                $locale = get_locale();
895
-                $mofile = WP_LANG_DIR . '/continents-cities-' . $locale . '.mo';
896
-                load_textdomain('continents-cities', $mofile);
897
-                $mo_loaded = true;
898
-            }
899
-            //well that was easy.
900
-            $parts = explode('/', $timezone_string);
901
-            //remove the continent
902
-            unset($parts[0]);
903
-            $t_parts = array();
904
-            foreach ($parts as $part) {
905
-                $t_parts[] = translate(str_replace('_', ' ', $part), 'continents-cities');
906
-            }
907
-            return implode(' - ', $t_parts);
908
-        }
909
-        //they haven't set the timezone string, so let's return a string like "UTC+1"
910
-        $gmt_offset = get_option('gmt_offset');
911
-        if (intval($gmt_offset) >= 0) {
912
-            $prefix = '+';
913
-        } else {
914
-            $prefix = '';
915
-        }
916
-        $parts = explode('.', (string)$gmt_offset);
917
-        if (count($parts) === 1) {
918
-            $parts[1] = '00';
919
-        } else {
920
-            //convert the part after the decimal, eg "5" (from x.5) or "25" (from x.25)
921
-            //to minutes, eg 30 or 15, respectively
922
-            $hour_fraction = (float)('0.' . $parts[1]);
923
-            $parts[1]      = (string)$hour_fraction * 60;
924
-        }
925
-        return sprintf(__('UTC%1$s', 'event_espresso'), $prefix . implode(':', $parts));
926
-    }
927
-
928
-
929
-
930
-    /**
931
-     * So PHP does this awesome thing where if you are trying to get a timestamp
932
-     * for a month using a string like "February" or "February 2017",
933
-     * and you don't specify a day as part of your string,
934
-     * then PHP will use whatever the current day of the month is.
935
-     * IF the current day of the month happens to be the 30th or 31st,
936
-     * then PHP gets really confused by a date like February 30,
937
-     * so instead of saying
938
-     *      "Hey February only has 28 days (this year)...
939
-     *      ...you must have meant the last day of the month!"
940
-     * PHP does the next most logical thing, and bumps the date up to March 2nd,
941
-     * because someone requesting February 30th obviously meant March 1st!
942
-     * The way around this is to always set the day to the first,
943
-     * so that the month will stay on the month you wanted.
944
-     * this method will add that "1" into your date regardless of the format.
945
-     *
946
-     * @param string $month
947
-     * @return string
948
-     */
949
-    public static function first_of_month_timestamp($month = '')
950
-    {
951
-        $month = (string)$month;
952
-        $year = '';
953
-        // check if the incoming string has a year in it or not
954
-       if (preg_match('/\b\d{4}\b/', $month, $matches)) {
955
-           $year = $matches[0];
956
-           // ten remove that from the month string as well as any spaces
957
-           $month = trim(str_replace($year, '', $month));
958
-           // add a space before the year
959
-           $year = " {$year}";
960
-        }
961
-        // return timestamp for something like "February 1 2017"
962
-        return strtotime("{$month} 1{$year}");
963
-    }
323
+	endif;
324
+	}
325
+
326
+
327
+	/**
328
+	 * This method will take an incoming unix timestamp and add the offset to it for the given timezone_string.
329
+	 * If no unix timestamp is given then time() is used.  If no timezone is given then the set timezone string for
330
+	 * the site is used.
331
+	 * This is used typically when using a Unix timestamp any core WP functions that expect their specially
332
+	 * computed timestamp (i.e. date_i18n() )
333
+	 *
334
+	 * @param int    $unix_timestamp                  if 0, then time() will be used.
335
+	 * @param string $timezone_string                 timezone_string. If empty, then the current set timezone for the
336
+	 *                                                site will be used.
337
+	 * @return int      $unix_timestamp with the offset applied for the given timezone.
338
+	 */
339
+	public static function get_timestamp_with_offset($unix_timestamp = 0, $timezone_string = '')
340
+	{
341
+		$unix_timestamp  = $unix_timestamp === 0 ? time() : (int)$unix_timestamp;
342
+		$timezone_string = self::get_valid_timezone_string($timezone_string);
343
+		$TimeZone        = new DateTimeZone($timezone_string);
344
+
345
+		$DateTime = new DateTime('@' . $unix_timestamp, $TimeZone);
346
+		$offset   = timezone_offset_get($TimeZone, $DateTime);
347
+		return (int)$DateTime->format('U') + (int)$offset;
348
+	}
349
+
350
+
351
+	/**
352
+	 *    _set_date_time_field
353
+	 *    modifies EE_Base_Class EE_Datetime_Field objects
354
+	 *
355
+	 * @param  EE_Base_Class $obj                 EE_Base_Class object
356
+	 * @param    DateTime    $DateTime            PHP DateTime object
357
+	 * @param  string        $datetime_field_name the datetime fieldname to be manipulated
358
+	 * @return    EE_Base_Class
359
+	 */
360
+	protected static function _set_date_time_field(EE_Base_Class $obj, DateTime $DateTime, $datetime_field_name)
361
+	{
362
+		// grab current datetime format
363
+		$current_format = $obj->get_format();
364
+		// set new full timestamp format
365
+		$obj->set_date_format(EE_Datetime_Field::mysql_date_format);
366
+		$obj->set_time_format(EE_Datetime_Field::mysql_time_format);
367
+		// set the new date value using a full timestamp format so that no data is lost
368
+		$obj->set($datetime_field_name, $DateTime->format(EE_Datetime_Field::mysql_timestamp_format));
369
+		// reset datetime formats
370
+		$obj->set_date_format($current_format[0]);
371
+		$obj->set_time_format($current_format[1]);
372
+		return $obj;
373
+	}
374
+
375
+
376
+	/**
377
+	 *    date_time_add
378
+	 *    helper for doing simple datetime calculations on a given datetime from EE_Base_Class
379
+	 *    and modifying it IN the EE_Base_Class so you don't have to do anything else.
380
+	 *
381
+	 * @param  EE_Base_Class $obj                 EE_Base_Class object
382
+	 * @param  string        $datetime_field_name name of the EE_Datetime_Filed datatype db column to be manipulated
383
+	 * @param  string        $period              what you are adding. The options are (years, months, days, hours,
384
+	 *                                            minutes, seconds) defaults to years
385
+	 * @param  integer       $value               what you want to increment the time by
386
+	 * @return EE_Base_Class           return the EE_Base_Class object so right away you can do something with it
387
+	 *                                 (chaining)
388
+	 */
389
+	public static function date_time_add(EE_Base_Class $obj, $datetime_field_name, $period = 'years', $value = 1)
390
+	{
391
+		//get the raw UTC date.
392
+		$DateTime = $obj->get_DateTime_object($datetime_field_name);
393
+		$DateTime = EEH_DTT_Helper::calc_date($DateTime, $period, $value);
394
+		return EEH_DTT_Helper::_set_date_time_field($obj, $DateTime, $datetime_field_name);
395
+	}
396
+
397
+
398
+	/**
399
+	 *    date_time_subtract
400
+	 *    same as date_time_add except subtracting value instead of adding.
401
+	 *
402
+	 * @param \EE_Base_Class $obj
403
+	 * @param  string        $datetime_field_name name of the EE_Datetime_Filed datatype db column to be manipulated
404
+	 * @param string         $period
405
+	 * @param int            $value
406
+	 * @return \EE_Base_Class
407
+	 */
408
+	public static function date_time_subtract(EE_Base_Class $obj, $datetime_field_name, $period = 'years', $value = 1)
409
+	{
410
+		//get the raw UTC date
411
+		$DateTime = $obj->get_DateTime_object($datetime_field_name);
412
+		$DateTime = EEH_DTT_Helper::calc_date($DateTime, $period, $value, '-');
413
+		return EEH_DTT_Helper::_set_date_time_field($obj, $DateTime, $datetime_field_name);
414
+	}
415
+
416
+
417
+	/**
418
+	 * Simply takes an incoming DateTime object and does calculations on it based on the incoming parameters
419
+	 *
420
+	 * @param  DateTime $DateTime DateTime object
421
+	 * @param  string   $period   a value to indicate what interval is being used in the calculation. The options are
422
+	 *                            'years', 'months', 'days', 'hours', 'minutes', 'seconds'. Defaults to years.
423
+	 * @param  integer  $value    What you want to increment the date by
424
+	 * @param  string   $operand  What operand you wish to use for the calculation
425
+	 * @return \DateTime return whatever type came in.
426
+	 * @throws \EE_Error
427
+	 */
428
+	protected static function _modify_datetime_object(DateTime $DateTime, $period = 'years', $value = 1, $operand = '+')
429
+	{
430
+		if (! $DateTime instanceof DateTime) {
431
+			throw new EE_Error(
432
+				sprintf(
433
+					__('Expected a PHP DateTime object, but instead received %1$s', 'event_espresso'),
434
+					print_r($DateTime, true)
435
+				)
436
+			);
437
+		}
438
+		switch ($period) {
439
+			case 'years' :
440
+				$value = 'P' . $value . 'Y';
441
+				break;
442
+			case 'months' :
443
+				$value = 'P' . $value . 'M';
444
+				break;
445
+			case 'weeks' :
446
+				$value = 'P' . $value . 'W';
447
+				break;
448
+			case 'days' :
449
+				$value = 'P' . $value . 'D';
450
+				break;
451
+			case 'hours' :
452
+				$value = 'PT' . $value . 'H';
453
+				break;
454
+			case 'minutes' :
455
+				$value = 'PT' . $value . 'M';
456
+				break;
457
+			case 'seconds' :
458
+				$value = 'PT' . $value . 'S';
459
+				break;
460
+		}
461
+		switch ($operand) {
462
+			case '+':
463
+				$DateTime->add(new DateInterval($value));
464
+				break;
465
+			case '-':
466
+				$DateTime->sub(new DateInterval($value));
467
+				break;
468
+		}
469
+		return $DateTime;
470
+	}
471
+
472
+
473
+	/**
474
+	 * Simply takes an incoming Unix timestamp and does calculations on it based on the incoming parameters
475
+	 *
476
+	 * @param  int     $timestamp Unix timestamp
477
+	 * @param  string  $period    a value to indicate what interval is being used in the calculation. The options are
478
+	 *                            'years', 'months', 'days', 'hours', 'minutes', 'seconds'. Defaults to years.
479
+	 * @param  integer $value     What you want to increment the date by
480
+	 * @param  string  $operand   What operand you wish to use for the calculation
481
+	 * @return \DateTime return whatever type came in.
482
+	 * @throws \EE_Error
483
+	 */
484
+	protected static function _modify_timestamp($timestamp, $period = 'years', $value = 1, $operand = '+')
485
+	{
486
+		if (! preg_match(EE_Datetime_Field::unix_timestamp_regex, $timestamp)) {
487
+			throw new EE_Error(
488
+				sprintf(
489
+					__('Expected a Unix timestamp, but instead received %1$s', 'event_espresso'),
490
+					print_r($timestamp, true)
491
+				)
492
+			);
493
+		}
494
+		switch ($period) {
495
+			case 'years' :
496
+				$value = YEAR_IN_SECONDS * $value;
497
+				break;
498
+			case 'months' :
499
+				$value = YEAR_IN_SECONDS / 12 * $value;
500
+				break;
501
+			case 'weeks' :
502
+				$value = WEEK_IN_SECONDS * $value;
503
+				break;
504
+			case 'days' :
505
+				$value = DAY_IN_SECONDS * $value;
506
+				break;
507
+			case 'hours' :
508
+				$value = HOUR_IN_SECONDS * $value;
509
+				break;
510
+			case 'minutes' :
511
+				$value = MINUTE_IN_SECONDS * $value;
512
+				break;
513
+		}
514
+		switch ($operand) {
515
+			case '+':
516
+				$timestamp += $value;
517
+				break;
518
+			case '-':
519
+				$timestamp -= $value;
520
+				break;
521
+		}
522
+		return $timestamp;
523
+	}
524
+
525
+
526
+	/**
527
+	 * Simply takes an incoming UTC timestamp or DateTime object and does calculations on it based on the incoming
528
+	 * parameters and returns the new timestamp or DateTime.
529
+	 *
530
+	 * @param  int | DateTime $DateTime_or_timestamp DateTime object or Unix timestamp
531
+	 * @param  string         $period                a value to indicate what interval is being used in the
532
+	 *                                               calculation. The options are 'years', 'months', 'days', 'hours',
533
+	 *                                               'minutes', 'seconds'. Defaults to years.
534
+	 * @param  integer        $value                 What you want to increment the date by
535
+	 * @param  string         $operand               What operand you wish to use for the calculation
536
+	 * @return mixed string|DateTime          return whatever type came in.
537
+	 */
538
+	public static function calc_date($DateTime_or_timestamp, $period = 'years', $value = 1, $operand = '+')
539
+	{
540
+		if ($DateTime_or_timestamp instanceof DateTime) {
541
+			return EEH_DTT_Helper::_modify_datetime_object($DateTime_or_timestamp, $period, $value, $operand);
542
+		} else if (preg_match(EE_Datetime_Field::unix_timestamp_regex, $DateTime_or_timestamp)) {
543
+			return EEH_DTT_Helper::_modify_timestamp($DateTime_or_timestamp, $period, $value, $operand);
544
+		} else {
545
+			//error
546
+			return $DateTime_or_timestamp;
547
+		}
548
+	}
549
+
550
+
551
+	/**
552
+	 * The purpose of this helper method is to receive an incoming format string in php date/time format
553
+	 * and spit out the js and moment.js equivalent formats.
554
+	 * Note, if no format string is given, then it is assumed the user wants what is set for WP.
555
+	 * Note, js date and time formats are those used by the jquery-ui datepicker and the jquery-ui date-
556
+	 * time picker.
557
+	 *
558
+	 * @see http://stackoverflow.com/posts/16725290/ for the code inspiration.
559
+	 * @param null $date_format_string
560
+	 * @param null $time_format_string
561
+	 * @return array
562
+	 *                array(
563
+	 *                'js' => array (
564
+	 *                'date' => //date format
565
+	 *                'time' => //time format
566
+	 *                ),
567
+	 *                'moment' => //date and time format.
568
+	 *                )
569
+	 */
570
+	public static function convert_php_to_js_and_moment_date_formats(
571
+		$date_format_string = null,
572
+		$time_format_string = null
573
+	) {
574
+		if ($date_format_string === null) {
575
+			$date_format_string = get_option('date_format');
576
+		}
577
+
578
+		if ($time_format_string === null) {
579
+			$time_format_string = get_option('time_format');
580
+		}
581
+
582
+		$date_format = self::_php_to_js_moment_converter($date_format_string);
583
+		$time_format = self::_php_to_js_moment_converter($time_format_string);
584
+
585
+		return array(
586
+			'js'     => array(
587
+				'date' => $date_format['js'],
588
+				'time' => $time_format['js'],
589
+			),
590
+			'moment' => $date_format['moment'] . ' ' . $time_format['moment'],
591
+		);
592
+	}
593
+
594
+
595
+	/**
596
+	 * This converts incoming format string into js and moment variations.
597
+	 *
598
+	 * @param string $format_string incoming php format string
599
+	 * @return array js and moment formats.
600
+	 */
601
+	protected static function _php_to_js_moment_converter($format_string)
602
+	{
603
+		/**
604
+		 * This is a map of symbols for formats.
605
+		 * The index is the php symbol, the equivalent values are in the array.
606
+		 *
607
+		 * @var array
608
+		 */
609
+		$symbols_map      = array(
610
+			// Day
611
+			//01
612
+			'd' => array(
613
+				'js'     => 'dd',
614
+				'moment' => 'DD',
615
+			),
616
+			//Mon
617
+			'D' => array(
618
+				'js'     => 'D',
619
+				'moment' => 'ddd',
620
+			),
621
+			//1,2,...31
622
+			'j' => array(
623
+				'js'     => 'd',
624
+				'moment' => 'D',
625
+			),
626
+			//Monday
627
+			'l' => array(
628
+				'js'     => 'DD',
629
+				'moment' => 'dddd',
630
+			),
631
+			//ISO numeric representation of the day of the week (1-6)
632
+			'N' => array(
633
+				'js'     => '',
634
+				'moment' => 'E',
635
+			),
636
+			//st,nd.rd
637
+			'S' => array(
638
+				'js'     => '',
639
+				'moment' => 'o',
640
+			),
641
+			//numeric representation of day of week (0-6)
642
+			'w' => array(
643
+				'js'     => '',
644
+				'moment' => 'd',
645
+			),
646
+			//day of year starting from 0 (0-365)
647
+			'z' => array(
648
+				'js'     => 'o',
649
+				'moment' => 'DDD' //note moment does not start with 0 so will need to modify by subtracting 1
650
+			),
651
+			// Week
652
+			//ISO-8601 week number of year (weeks starting on monday)
653
+			'W' => array(
654
+				'js'     => '',
655
+				'moment' => 'w',
656
+			),
657
+			// Month
658
+			// January...December
659
+			'F' => array(
660
+				'js'     => 'MM',
661
+				'moment' => 'MMMM',
662
+			),
663
+			//01...12
664
+			'm' => array(
665
+				'js'     => 'mm',
666
+				'moment' => 'MM',
667
+			),
668
+			//Jan...Dec
669
+			'M' => array(
670
+				'js'     => 'M',
671
+				'moment' => 'MMM',
672
+			),
673
+			//1-12
674
+			'n' => array(
675
+				'js'     => 'm',
676
+				'moment' => 'M',
677
+			),
678
+			//number of days in given month
679
+			't' => array(
680
+				'js'     => '',
681
+				'moment' => '',
682
+			),
683
+			// Year
684
+			//whether leap year or not 1/0
685
+			'L' => array(
686
+				'js'     => '',
687
+				'moment' => '',
688
+			),
689
+			//ISO-8601 year number
690
+			'o' => array(
691
+				'js'     => '',
692
+				'moment' => 'GGGG',
693
+			),
694
+			//1999...2003
695
+			'Y' => array(
696
+				'js'     => 'yy',
697
+				'moment' => 'YYYY',
698
+			),
699
+			//99...03
700
+			'y' => array(
701
+				'js'     => 'y',
702
+				'moment' => 'YY',
703
+			),
704
+			// Time
705
+			// am/pm
706
+			'a' => array(
707
+				'js'     => 'tt',
708
+				'moment' => 'a',
709
+			),
710
+			// AM/PM
711
+			'A' => array(
712
+				'js'     => 'TT',
713
+				'moment' => 'A',
714
+			),
715
+			// Swatch Internet Time?!?
716
+			'B' => array(
717
+				'js'     => '',
718
+				'moment' => '',
719
+			),
720
+			//1...12
721
+			'g' => array(
722
+				'js'     => 'h',
723
+				'moment' => 'h',
724
+			),
725
+			//0...23
726
+			'G' => array(
727
+				'js'     => 'H',
728
+				'moment' => 'H',
729
+			),
730
+			//01...12
731
+			'h' => array(
732
+				'js'     => 'hh',
733
+				'moment' => 'hh',
734
+			),
735
+			//00...23
736
+			'H' => array(
737
+				'js'     => 'HH',
738
+				'moment' => 'HH',
739
+			),
740
+			//00..59
741
+			'i' => array(
742
+				'js'     => 'mm',
743
+				'moment' => 'mm',
744
+			),
745
+			//seconds... 00...59
746
+			's' => array(
747
+				'js'     => 'ss',
748
+				'moment' => 'ss',
749
+			),
750
+			//microseconds
751
+			'u' => array(
752
+				'js'     => '',
753
+				'moment' => '',
754
+			),
755
+		);
756
+		$jquery_ui_format = "";
757
+		$moment_format    = "";
758
+		$escaping         = false;
759
+		for ($i = 0; $i < strlen($format_string); $i++) {
760
+			$char = $format_string[$i];
761
+			if ($char === '\\') { // PHP date format escaping character
762
+				$i++;
763
+				if ($escaping) {
764
+					$jquery_ui_format .= $format_string[$i];
765
+					$moment_format .= $format_string[$i];
766
+				} else {
767
+					$jquery_ui_format .= '\'' . $format_string[$i];
768
+					$moment_format .= $format_string[$i];
769
+				}
770
+				$escaping = true;
771
+			} else {
772
+				if ($escaping) {
773
+					$jquery_ui_format .= "'";
774
+					$moment_format .= "'";
775
+					$escaping = false;
776
+				}
777
+				if (isset($symbols_map[$char])) {
778
+					$jquery_ui_format .= $symbols_map[$char]['js'];
779
+					$moment_format .= $symbols_map[$char]['moment'];
780
+				} else {
781
+					$jquery_ui_format .= $char;
782
+					$moment_format .= $char;
783
+				}
784
+			}
785
+		}
786
+		return array('js' => $jquery_ui_format, 'moment' => $moment_format);
787
+	}
788
+
789
+
790
+	/**
791
+	 * This takes an incoming format string and validates it to ensure it will work fine with PHP.
792
+	 *
793
+	 * @param string $format_string   Incoming format string for php date().
794
+	 * @return mixed bool|array  If all is okay then TRUE is returned.  Otherwise an array of validation
795
+	 *                                errors is returned.  So for client code calling, check for is_array() to
796
+	 *                                indicate failed validations.
797
+	 */
798
+	public static function validate_format_string($format_string)
799
+	{
800
+		$error_msg = array();
801
+		//time format checks
802
+		switch (true) {
803
+			case   strpos($format_string, 'h') !== false  :
804
+			case   strpos($format_string, 'g') !== false :
805
+				/**
806
+				 * if the time string has a lowercase 'h' which == 12 hour time format and there
807
+				 * is not any ante meridiem format ('a' or 'A').  Then throw an error because its
808
+				 * too ambiguous and PHP won't be able to figure out whether 1 = 1pm or 1am.
809
+				 */
810
+				if (strpos(strtoupper($format_string), 'A') === false) {
811
+					$error_msg[] = __('There is a  time format for 12 hour time but no  "a" or "A" to indicate am/pm.  Without this distinction, PHP is unable to determine if a "1" for the hour value equals "1pm" or "1am".',
812
+						'event_espresso');
813
+				}
814
+				break;
815
+
816
+		}
817
+
818
+		return empty($error_msg) ? true : $error_msg;
819
+	}
820
+
821
+
822
+	/**
823
+	 *     If the the first date starts at midnight on one day, and the next date ends at midnight on the
824
+	 *     very next day then this method will return true.
825
+	 *    If $date_1 = 2015-12-15 00:00:00 and $date_2 = 2015-12-16 00:00:00 then this function will return true.
826
+	 *    If $date_1 = 2015-12-15 03:00:00 and $date_2 = 2015-12_16 03:00:00 then this function will return false.
827
+	 *    If $date_1 = 2015-12-15 00:00:00 and $date_2 = 2015-12-15 00:00:00 then this function will return true.
828
+	 *
829
+	 * @param mixed $date_1
830
+	 * @param mixed $date_2
831
+	 * @return bool
832
+	 */
833
+	public static function dates_represent_one_24_hour_date($date_1, $date_2)
834
+	{
835
+
836
+		if (
837
+			(! $date_1 instanceof DateTime || ! $date_2 instanceof DateTime) ||
838
+			($date_1->format(EE_Datetime_Field::mysql_time_format) != '00:00:00' || $date_2->format(EE_Datetime_Field::mysql_time_format) != '00:00:00')
839
+		) {
840
+			return false;
841
+		}
842
+		return $date_2->format('U') - $date_1->format('U') == 86400 ? true : false;
843
+	}
844
+
845
+
846
+	/**
847
+	 * This returns the appropriate query interval string that can be used in sql queries involving mysql Date
848
+	 * Functions.
849
+	 *
850
+	 * @param string $timezone_string    A timezone string in a valid format to instantiate a DateTimeZone object.
851
+	 * @param string $field_for_interval The Database field that is the interval is applied to in the query.
852
+	 * @return string
853
+	 */
854
+	public static function get_sql_query_interval_for_offset($timezone_string, $field_for_interval)
855
+	{
856
+		try {
857
+			/** need to account for timezone offset on the selects */
858
+			$DateTimeZone = new DateTimeZone($timezone_string);
859
+		} catch (Exception $e) {
860
+			$DateTimeZone = null;
861
+		}
862
+
863
+		/**
864
+		 * Note get_option( 'gmt_offset') returns a value in hours, whereas DateTimeZone::getOffset returns values in seconds.
865
+		 * Hence we do the calc for DateTimeZone::getOffset.
866
+		 */
867
+		$offset         = $DateTimeZone instanceof DateTimeZone ? ($DateTimeZone->getOffset(new DateTime('now'))) / HOUR_IN_SECONDS : get_option('gmt_offset');
868
+		$query_interval = $offset < 0
869
+			? 'DATE_SUB(' . $field_for_interval . ', INTERVAL ' . $offset * -1 . ' HOUR)'
870
+			: 'DATE_ADD(' . $field_for_interval . ', INTERVAL ' . $offset . ' HOUR)';
871
+		return $query_interval;
872
+	}
873
+
874
+	/**
875
+	 * Retrieves the site's default timezone and returns it formatted so it's ready for display
876
+	 * to users. If you want to customize how its displayed feel free to fetch the 'timezone_string'
877
+	 * and 'gmt_offset' WordPress options directly; or use the filter
878
+	 * FHEE__EEH_DTT_Helper__get_timezone_string_for_display
879
+	 * (although note that we remove any HTML that may be added)
880
+	 *
881
+	 * @return string
882
+	 */
883
+	public static function get_timezone_string_for_display()
884
+	{
885
+		$pretty_timezone = apply_filters('FHEE__EEH_DTT_Helper__get_timezone_string_for_display', '');
886
+		if (! empty($pretty_timezone)) {
887
+			return esc_html($pretty_timezone);
888
+		}
889
+		$timezone_string = get_option('timezone_string');
890
+		if ($timezone_string) {
891
+			static $mo_loaded = false;
892
+			// Load translations for continents and cities just like wp_timezone_choice does
893
+			if (! $mo_loaded) {
894
+				$locale = get_locale();
895
+				$mofile = WP_LANG_DIR . '/continents-cities-' . $locale . '.mo';
896
+				load_textdomain('continents-cities', $mofile);
897
+				$mo_loaded = true;
898
+			}
899
+			//well that was easy.
900
+			$parts = explode('/', $timezone_string);
901
+			//remove the continent
902
+			unset($parts[0]);
903
+			$t_parts = array();
904
+			foreach ($parts as $part) {
905
+				$t_parts[] = translate(str_replace('_', ' ', $part), 'continents-cities');
906
+			}
907
+			return implode(' - ', $t_parts);
908
+		}
909
+		//they haven't set the timezone string, so let's return a string like "UTC+1"
910
+		$gmt_offset = get_option('gmt_offset');
911
+		if (intval($gmt_offset) >= 0) {
912
+			$prefix = '+';
913
+		} else {
914
+			$prefix = '';
915
+		}
916
+		$parts = explode('.', (string)$gmt_offset);
917
+		if (count($parts) === 1) {
918
+			$parts[1] = '00';
919
+		} else {
920
+			//convert the part after the decimal, eg "5" (from x.5) or "25" (from x.25)
921
+			//to minutes, eg 30 or 15, respectively
922
+			$hour_fraction = (float)('0.' . $parts[1]);
923
+			$parts[1]      = (string)$hour_fraction * 60;
924
+		}
925
+		return sprintf(__('UTC%1$s', 'event_espresso'), $prefix . implode(':', $parts));
926
+	}
927
+
928
+
929
+
930
+	/**
931
+	 * So PHP does this awesome thing where if you are trying to get a timestamp
932
+	 * for a month using a string like "February" or "February 2017",
933
+	 * and you don't specify a day as part of your string,
934
+	 * then PHP will use whatever the current day of the month is.
935
+	 * IF the current day of the month happens to be the 30th or 31st,
936
+	 * then PHP gets really confused by a date like February 30,
937
+	 * so instead of saying
938
+	 *      "Hey February only has 28 days (this year)...
939
+	 *      ...you must have meant the last day of the month!"
940
+	 * PHP does the next most logical thing, and bumps the date up to March 2nd,
941
+	 * because someone requesting February 30th obviously meant March 1st!
942
+	 * The way around this is to always set the day to the first,
943
+	 * so that the month will stay on the month you wanted.
944
+	 * this method will add that "1" into your date regardless of the format.
945
+	 *
946
+	 * @param string $month
947
+	 * @return string
948
+	 */
949
+	public static function first_of_month_timestamp($month = '')
950
+	{
951
+		$month = (string)$month;
952
+		$year = '';
953
+		// check if the incoming string has a year in it or not
954
+	   if (preg_match('/\b\d{4}\b/', $month, $matches)) {
955
+		   $year = $matches[0];
956
+		   // ten remove that from the month string as well as any spaces
957
+		   $month = trim(str_replace($year, '', $month));
958
+		   // add a space before the year
959
+		   $year = " {$year}";
960
+		}
961
+		// return timestamp for something like "February 1 2017"
962
+		return strtotime("{$month} 1{$year}");
963
+	}
964 964
 
965 965
 	/**
966
-     * This simply returns the timestamp for tomorrow (midnight next day) in this sites timezone.  So it may be midnight
967
-	* for this sites timezone, but the timestamp could be some other time GMT.
968
-    */
969
-    public static function tomorrow()
966
+	 * This simply returns the timestamp for tomorrow (midnight next day) in this sites timezone.  So it may be midnight
967
+	 * for this sites timezone, but the timestamp could be some other time GMT.
968
+	 */
969
+	public static function tomorrow()
970 970
 	{
971 971
 		//The multiplication of -1 ensures that we switch positive offsets to negative and negative offsets to positive
972 972
 		//before adding to the timestamp.  Why? Because we want tomorrow to be for midnight the next day in THIS timezone
Please login to merge, or discard this patch.
Spacing   +39 added lines, -40 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php
2
-if (! defined('EVENT_ESPRESSO_VERSION')) {
2
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
3 3
     exit('NO direct script access allowed');
4 4
 }
5 5
 
@@ -74,7 +74,7 @@  discard block
 block discarded – undo
74 74
             new DateTimeZone($timezone_string);
75 75
         } catch (Exception $e) {
76 76
             // sometimes we take exception to exceptions
77
-            if (! $throw_error) {
77
+            if ( ! $throw_error) {
78 78
                 return false;
79 79
             }
80 80
             throw new EE_Error(
@@ -135,7 +135,7 @@  discard block
 block discarded – undo
135 135
             }
136 136
         }
137 137
         $offset = get_option('gmt_offset');
138
-        return (int)($offset * HOUR_IN_SECONDS);
138
+        return (int) ($offset * HOUR_IN_SECONDS);
139 139
     }
140 140
 
141 141
 
@@ -149,7 +149,7 @@  discard block
 block discarded – undo
149 149
     public static function adjust_invalid_gmt_offsets($gmt_offset = 0)
150 150
     {
151 151
         //make sure $gmt_offset is int
152
-        $gmt_offset = (int)$gmt_offset;
152
+        $gmt_offset = (int) $gmt_offset;
153 153
         switch ($gmt_offset) {
154 154
 
155 155
             //			case -30600 :
@@ -233,7 +233,7 @@  discard block
 block discarded – undo
233 233
     public static function timezone_select_input($timezone_string = '')
234 234
     {
235 235
         // get WP date time format
236
-        $datetime_format = get_option('date_format') . ' ' . get_option('time_format');
236
+        $datetime_format = get_option('date_format').' '.get_option('time_format');
237 237
         // if passed a value, then use that, else get WP option
238 238
         $timezone_string = ! empty($timezone_string) ? $timezone_string : get_option('timezone_string');
239 239
         // check if the timezone is valid but don't throw any errors if it isn't
@@ -245,9 +245,9 @@  discard block
 block discarded – undo
245 245
             // Create a UTC+- zone if no timezone string exists
246 246
             $check_zone_info = false;
247 247
             if ($gmt_offset > 0) {
248
-                $timezone_string = 'UTC+' . $gmt_offset;
248
+                $timezone_string = 'UTC+'.$gmt_offset;
249 249
             } elseif ($gmt_offset < 0) {
250
-                $timezone_string = 'UTC' . $gmt_offset;
250
+                $timezone_string = 'UTC'.$gmt_offset;
251 251
             } else {
252 252
                 $timezone_string = 'UTC';
253 253
             }
@@ -269,11 +269,11 @@  discard block
 block discarded – undo
269 269
                 __('%1$sUTC%2$s time is %3$s'),
270 270
                 '<abbr title="Coordinated Universal Time">',
271 271
                 '</abbr>',
272
-                '<code>' . date_i18n($datetime_format, false, true) . '</code>'
272
+                '<code>'.date_i18n($datetime_format, false, true).'</code>'
273 273
             );
274 274
             ?></span>
275
-        <?php if (! empty($timezone_string) || ! empty($gmt_offset)) : ?>
276
-        <br/><span><?php printf(__('Local time is %1$s'), '<code>' . date_i18n($datetime_format) . '</code>'); ?></span>
275
+        <?php if ( ! empty($timezone_string) || ! empty($gmt_offset)) : ?>
276
+        <br/><span><?php printf(__('Local time is %1$s'), '<code>'.date_i18n($datetime_format).'</code>'); ?></span>
277 277
     <?php endif; ?>
278 278
 
279 279
         <?php if ($check_zone_info && $timezone_string) : ?>
@@ -306,11 +306,10 @@  discard block
 block discarded – undo
306 306
 
307 307
                 if ($found) {
308 308
                     $message = $tr['isdst'] ?
309
-                        __(' Daylight saving time begins on: %s.') :
310
-                        __(' Standard time begins  on: %s.');
309
+                        __(' Daylight saving time begins on: %s.') : __(' Standard time begins  on: %s.');
311 310
                     // Add the difference between the current offset and the new offset to ts to get the correct transition time from date_i18n().
312 311
                     printf($message,
313
-                        '<code >' . date_i18n($datetime_format, $tr['ts'] + ($tz_offset - $tr['offset'])) . '</code >');
312
+                        '<code >'.date_i18n($datetime_format, $tr['ts'] + ($tz_offset - $tr['offset'])).'</code >');
314 313
                 } else {
315 314
                     _e('This timezone does not observe daylight saving time.');
316 315
                 }
@@ -338,13 +337,13 @@  discard block
 block discarded – undo
338 337
      */
339 338
     public static function get_timestamp_with_offset($unix_timestamp = 0, $timezone_string = '')
340 339
     {
341
-        $unix_timestamp  = $unix_timestamp === 0 ? time() : (int)$unix_timestamp;
340
+        $unix_timestamp  = $unix_timestamp === 0 ? time() : (int) $unix_timestamp;
342 341
         $timezone_string = self::get_valid_timezone_string($timezone_string);
343 342
         $TimeZone        = new DateTimeZone($timezone_string);
344 343
 
345
-        $DateTime = new DateTime('@' . $unix_timestamp, $TimeZone);
344
+        $DateTime = new DateTime('@'.$unix_timestamp, $TimeZone);
346 345
         $offset   = timezone_offset_get($TimeZone, $DateTime);
347
-        return (int)$DateTime->format('U') + (int)$offset;
346
+        return (int) $DateTime->format('U') + (int) $offset;
348 347
     }
349 348
 
350 349
 
@@ -427,7 +426,7 @@  discard block
 block discarded – undo
427 426
      */
428 427
     protected static function _modify_datetime_object(DateTime $DateTime, $period = 'years', $value = 1, $operand = '+')
429 428
     {
430
-        if (! $DateTime instanceof DateTime) {
429
+        if ( ! $DateTime instanceof DateTime) {
431 430
             throw new EE_Error(
432 431
                 sprintf(
433 432
                     __('Expected a PHP DateTime object, but instead received %1$s', 'event_espresso'),
@@ -437,25 +436,25 @@  discard block
 block discarded – undo
437 436
         }
438 437
         switch ($period) {
439 438
             case 'years' :
440
-                $value = 'P' . $value . 'Y';
439
+                $value = 'P'.$value.'Y';
441 440
                 break;
442 441
             case 'months' :
443
-                $value = 'P' . $value . 'M';
442
+                $value = 'P'.$value.'M';
444 443
                 break;
445 444
             case 'weeks' :
446
-                $value = 'P' . $value . 'W';
445
+                $value = 'P'.$value.'W';
447 446
                 break;
448 447
             case 'days' :
449
-                $value = 'P' . $value . 'D';
448
+                $value = 'P'.$value.'D';
450 449
                 break;
451 450
             case 'hours' :
452
-                $value = 'PT' . $value . 'H';
451
+                $value = 'PT'.$value.'H';
453 452
                 break;
454 453
             case 'minutes' :
455
-                $value = 'PT' . $value . 'M';
454
+                $value = 'PT'.$value.'M';
456 455
                 break;
457 456
             case 'seconds' :
458
-                $value = 'PT' . $value . 'S';
457
+                $value = 'PT'.$value.'S';
459 458
                 break;
460 459
         }
461 460
         switch ($operand) {
@@ -483,7 +482,7 @@  discard block
 block discarded – undo
483 482
      */
484 483
     protected static function _modify_timestamp($timestamp, $period = 'years', $value = 1, $operand = '+')
485 484
     {
486
-        if (! preg_match(EE_Datetime_Field::unix_timestamp_regex, $timestamp)) {
485
+        if ( ! preg_match(EE_Datetime_Field::unix_timestamp_regex, $timestamp)) {
487 486
             throw new EE_Error(
488 487
                 sprintf(
489 488
                     __('Expected a Unix timestamp, but instead received %1$s', 'event_espresso'),
@@ -587,7 +586,7 @@  discard block
 block discarded – undo
587 586
                 'date' => $date_format['js'],
588 587
                 'time' => $time_format['js'],
589 588
             ),
590
-            'moment' => $date_format['moment'] . ' ' . $time_format['moment'],
589
+            'moment' => $date_format['moment'].' '.$time_format['moment'],
591 590
         );
592 591
     }
593 592
 
@@ -606,7 +605,7 @@  discard block
 block discarded – undo
606 605
          *
607 606
          * @var array
608 607
          */
609
-        $symbols_map      = array(
608
+        $symbols_map = array(
610 609
             // Day
611 610
             //01
612 611
             'd' => array(
@@ -764,7 +763,7 @@  discard block
 block discarded – undo
764 763
                     $jquery_ui_format .= $format_string[$i];
765 764
                     $moment_format .= $format_string[$i];
766 765
                 } else {
767
-                    $jquery_ui_format .= '\'' . $format_string[$i];
766
+                    $jquery_ui_format .= '\''.$format_string[$i];
768 767
                     $moment_format .= $format_string[$i];
769 768
                 }
770 769
                 $escaping = true;
@@ -834,7 +833,7 @@  discard block
 block discarded – undo
834 833
     {
835 834
 
836 835
         if (
837
-            (! $date_1 instanceof DateTime || ! $date_2 instanceof DateTime) ||
836
+            ( ! $date_1 instanceof DateTime || ! $date_2 instanceof DateTime) ||
838 837
             ($date_1->format(EE_Datetime_Field::mysql_time_format) != '00:00:00' || $date_2->format(EE_Datetime_Field::mysql_time_format) != '00:00:00')
839 838
         ) {
840 839
             return false;
@@ -866,8 +865,8 @@  discard block
 block discarded – undo
866 865
          */
867 866
         $offset         = $DateTimeZone instanceof DateTimeZone ? ($DateTimeZone->getOffset(new DateTime('now'))) / HOUR_IN_SECONDS : get_option('gmt_offset');
868 867
         $query_interval = $offset < 0
869
-            ? 'DATE_SUB(' . $field_for_interval . ', INTERVAL ' . $offset * -1 . ' HOUR)'
870
-            : 'DATE_ADD(' . $field_for_interval . ', INTERVAL ' . $offset . ' HOUR)';
868
+            ? 'DATE_SUB('.$field_for_interval.', INTERVAL '.$offset * -1.' HOUR)'
869
+            : 'DATE_ADD('.$field_for_interval.', INTERVAL '.$offset.' HOUR)';
871 870
         return $query_interval;
872 871
     }
873 872
 
@@ -883,16 +882,16 @@  discard block
 block discarded – undo
883 882
     public static function get_timezone_string_for_display()
884 883
     {
885 884
         $pretty_timezone = apply_filters('FHEE__EEH_DTT_Helper__get_timezone_string_for_display', '');
886
-        if (! empty($pretty_timezone)) {
885
+        if ( ! empty($pretty_timezone)) {
887 886
             return esc_html($pretty_timezone);
888 887
         }
889 888
         $timezone_string = get_option('timezone_string');
890 889
         if ($timezone_string) {
891 890
             static $mo_loaded = false;
892 891
             // Load translations for continents and cities just like wp_timezone_choice does
893
-            if (! $mo_loaded) {
892
+            if ( ! $mo_loaded) {
894 893
                 $locale = get_locale();
895
-                $mofile = WP_LANG_DIR . '/continents-cities-' . $locale . '.mo';
894
+                $mofile = WP_LANG_DIR.'/continents-cities-'.$locale.'.mo';
896 895
                 load_textdomain('continents-cities', $mofile);
897 896
                 $mo_loaded = true;
898 897
             }
@@ -913,16 +912,16 @@  discard block
 block discarded – undo
913 912
         } else {
914 913
             $prefix = '';
915 914
         }
916
-        $parts = explode('.', (string)$gmt_offset);
915
+        $parts = explode('.', (string) $gmt_offset);
917 916
         if (count($parts) === 1) {
918 917
             $parts[1] = '00';
919 918
         } else {
920 919
             //convert the part after the decimal, eg "5" (from x.5) or "25" (from x.25)
921 920
             //to minutes, eg 30 or 15, respectively
922
-            $hour_fraction = (float)('0.' . $parts[1]);
923
-            $parts[1]      = (string)$hour_fraction * 60;
921
+            $hour_fraction = (float) ('0.'.$parts[1]);
922
+            $parts[1]      = (string) $hour_fraction * 60;
924 923
         }
925
-        return sprintf(__('UTC%1$s', 'event_espresso'), $prefix . implode(':', $parts));
924
+        return sprintf(__('UTC%1$s', 'event_espresso'), $prefix.implode(':', $parts));
926 925
     }
927 926
 
928 927
 
@@ -948,7 +947,7 @@  discard block
 block discarded – undo
948 947
      */
949 948
     public static function first_of_month_timestamp($month = '')
950 949
     {
951
-        $month = (string)$month;
950
+        $month = (string) $month;
952 951
         $year = '';
953 952
         // check if the incoming string has a year in it or not
954 953
        if (preg_match('/\b\d{4}\b/', $month, $matches)) {
@@ -972,7 +971,7 @@  discard block
 block discarded – undo
972 971
 		//before adding to the timestamp.  Why? Because we want tomorrow to be for midnight the next day in THIS timezone
973 972
 		//not an offset from midnight in UTC.  So if we're starting with UTC 00:00:00, then we want to make sure the
974 973
 		//final timestamp is equivalent to midnight in this timezone as represented in GMT.
975
-		return strtotime('tomorrow') + (self::get_site_timezone_gmt_offset()*-1);
974
+		return strtotime('tomorrow') + (self::get_site_timezone_gmt_offset() * -1);
976 975
 	}
977 976
 
978 977
 }// end class EEH_DTT_Helper
Please login to merge, or discard this patch.
core/libraries/rest_api/controllers/model/Read.php 1 patch
Indentation   +1233 added lines, -1233 removed lines patch added patch discarded remove patch
@@ -9,7 +9,7 @@  discard block
 block discarded – undo
9 9
 use EE_Datetime_Field;
10 10
 
11 11
 if (! defined('EVENT_ESPRESSO_VERSION')) {
12
-    exit('No direct script access allowed');
12
+	exit('No direct script access allowed');
13 13
 }
14 14
 
15 15
 
@@ -27,1238 +27,1238 @@  discard block
 block discarded – undo
27 27
 
28 28
 
29 29
 
30
-    /**
31
-     * @var Calculated_Model_Fields
32
-     */
33
-    protected $_fields_calculator;
34
-
35
-
36
-
37
-    /**
38
-     * Read constructor.
39
-     */
40
-    public function __construct()
41
-    {
42
-        parent::__construct();
43
-        $this->_fields_calculator = new Calculated_Model_Fields();
44
-    }
45
-
46
-
47
-
48
-    /**
49
-     * Handles requests to get all (or a filtered subset) of entities for a particular model
50
-     *
51
-     * @param \WP_REST_Request $request
52
-     * @return \WP_REST_Response|\WP_Error
53
-     */
54
-    public static function handle_request_get_all(\WP_REST_Request $request)
55
-    {
56
-        $controller = new Read();
57
-        try {
58
-            $matches = $controller->parse_route(
59
-                $request->get_route(),
60
-                '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)~',
61
-                array('version', 'model')
62
-            );
63
-            $controller->set_requested_version($matches['version']);
64
-            $model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']);
65
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) {
66
-                return $controller->send_response(
67
-                    new \WP_Error(
68
-                        'endpoint_parsing_error',
69
-                        sprintf(
70
-                            __('There is no model for endpoint %s. Please contact event espresso support',
71
-                                'event_espresso'),
72
-                            $model_name_singular
73
-                        )
74
-                    )
75
-                );
76
-            }
77
-            return $controller->send_response(
78
-                $controller->get_entities_from_model(
79
-                    $controller->get_model_version_info()->load_model($model_name_singular),
80
-                    $request
81
-                )
82
-            );
83
-        } catch (\Exception $e) {
84
-            return $controller->send_response($e);
85
-        }
86
-    }
87
-
88
-
89
-    /**
90
-     * Prepares and returns schema for any OPTIONS request.
91
-     *
92
-     * @param string $model_name  Something like `Event` or `Registration`
93
-     * @param string $version     The API endpoint version being used.
94
-     * @return array
95
-     */
96
-    public static function handle_schema_request($model_name, $version)
97
-    {
98
-        $controller = new Read();
99
-        try {
100
-            $controller->set_requested_version($version);
101
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name)) {
102
-                return array();
103
-            }
104
-            //get the model for this version
105
-            $model = $controller->get_model_version_info()->load_model($model_name);
106
-            $model_schema = new JsonModelSchema($model);
107
-            return $model_schema->getModelSchemaForRelations(
108
-                $controller->get_model_version_info()->relation_settings($model),
109
-                $controller->_customize_schema_for_rest_response(
110
-                    $model,
111
-                    $model_schema->getModelSchemaForFields(
112
-                        $controller->get_model_version_info()->fields_on_model_in_this_version($model),
113
-                        $model_schema->getInitialSchemaStructure()
114
-                    )
115
-                )
116
-            );
117
-        } catch (\Exception $e) {
118
-            return array();
119
-        }
120
-    }
121
-
122
-
123
-    /**
124
-     * This loops through each field in the given schema for the model and does the following:
125
-     * - add any extra fields that are REST API specific and related to existing fields.
126
-     * - transform default values into the correct format for a REST API response.
127
-     *
128
-     * @param \EEM_Base $model
129
-     * @param array     $schema
130
-     * @return array  The final schema.
131
-     */
132
-    protected function _customize_schema_for_rest_response(\EEM_Base $model, array $schema)
133
-    {
134
-       foreach ($this->get_model_version_info()->fields_on_model_in_this_version($model) as $field_name => $field) {
135
-           $schema = $this->_translate_defaults_for_rest_response(
136
-               $field_name,
137
-               $field,
138
-               $this->_maybe_add_extra_fields_to_schema($field_name, $field, $schema)
139
-            );
140
-       }
141
-       return $schema;
142
-    }
143
-
144
-
145
-    /**
146
-     * This is used to ensure that the 'default' value set in the schema response is formatted correctly for the REST
147
-     * response.
148
-     *
149
-     * @param                      $field_name
150
-     * @param \EE_Model_Field_Base $field
151
-     * @param array                $schema
152
-     * @return array
153
-     */
154
-    protected function _translate_defaults_for_rest_response($field_name, \EE_Model_Field_Base $field, array $schema)
155
-    {
156
-        if (isset($schema['properties'][$field_name]['default'])) {
157
-            if (is_array($schema['properties'][$field_name]['default'])) {
158
-                foreach ($schema['properties'][$field_name]['default'] as $default_key => $default_value) {
159
-                    if ($default_key === 'raw') {
160
-                        $schema['properties'][$field_name]['default'][$default_key] = Model_Data_Translator::prepare_field_value_for_json(
161
-                            $field,
162
-                            $default_value,
163
-                            $this->get_model_version_info()->requested_version()
164
-                        );
165
-                    }
166
-                }
167
-            } else {
168
-                $schema['properties'][$field_name]['default'] = Model_Data_Translator::prepare_field_value_for_json(
169
-                    $field,
170
-                    $schema['properties'][$field_name]['default'],
171
-                    $this->get_model_version_info()->requested_version()
172
-                );
173
-            }
174
-        }
175
-        return $schema;
176
-    }
177
-
178
-
179
-    /**
180
-     * Adds additional fields to the schema
181
-     * The REST API returns a GMT value field for each datetime field in the resource.  Thus the description about this
182
-     * needs to be added to the schema.
183
-     *
184
-     * @param                      $field_name
185
-     * @param \EE_Model_Field_Base $field
186
-     * @param array                $schema
187
-     * @return array
188
-     */
189
-    protected function _maybe_add_extra_fields_to_schema($field_name, \EE_Model_Field_Base $field, array $schema)
190
-    {
191
-        if ($field instanceof EE_Datetime_Field) {
192
-            $schema['properties'][$field_name . '_gmt'] = $field->getSchema();
193
-            //modify the description
194
-            $schema['properties'][$field_name . '_gmt']['description'] = sprintf(
195
-                esc_html__('%s - the value for this field is in GMT.', 'event_espresso'),
196
-                $field->get_nicename()
197
-            );
198
-        }
199
-        return $schema;
200
-    }
201
-
202
-
203
-
204
-
205
-    /**
206
-     * Used to figure out the route from the request when a `WP_REST_Request` object is not available
207
-     * @return string
208
-     */
209
-    protected function get_route_from_request() {
210
-        if (isset($GLOBALS['wp'])
211
-            && $GLOBALS['wp'] instanceof \WP
212
-            && isset($GLOBALS['wp']->query_vars['rest_route'] )
213
-        ) {
214
-            return $GLOBALS['wp']->query_vars['rest_route'];
215
-        } else {
216
-            return isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '/';
217
-        }
218
-    }
219
-
220
-
221
-
222
-    /**
223
-     * Gets a single entity related to the model indicated in the path and its id
224
-     *
225
-     * @param \WP_REST_Request $request
226
-     * @return \WP_REST_Response|\WP_Error
227
-     */
228
-    public static function handle_request_get_one(\WP_REST_Request $request)
229
-    {
230
-        $controller = new Read();
231
-        try {
232
-            $matches = $controller->parse_route(
233
-                $request->get_route(),
234
-                '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)~',
235
-                array('version', 'model', 'id'));
236
-            $controller->set_requested_version($matches['version']);
237
-            $model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']);
238
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) {
239
-                return $controller->send_response(
240
-                    new \WP_Error(
241
-                        'endpoint_parsing_error',
242
-                        sprintf(
243
-                            __('There is no model for endpoint %s. Please contact event espresso support',
244
-                                'event_espresso'),
245
-                            $model_name_singular
246
-                        )
247
-                    )
248
-                );
249
-            }
250
-            return $controller->send_response(
251
-                $controller->get_entity_from_model(
252
-                    $controller->get_model_version_info()->load_model($model_name_singular),
253
-                    $request
254
-                )
255
-            );
256
-        } catch (\Exception $e) {
257
-            return $controller->send_response($e);
258
-        }
259
-    }
260
-
261
-
262
-
263
-    /**
264
-     * Gets all the related entities (or if its a belongs-to relation just the one)
265
-     * to the item with the given id
266
-     *
267
-     * @param \WP_REST_Request $request
268
-     * @return \WP_REST_Response|\WP_Error
269
-     */
270
-    public static function handle_request_get_related(\WP_REST_Request $request)
271
-    {
272
-        $controller = new Read();
273
-        try {
274
-            $matches = $controller->parse_route(
275
-                $request->get_route(),
276
-                '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)/(.*)~',
277
-                array('version', 'model', 'id', 'related_model')
278
-            );
279
-            $controller->set_requested_version($matches['version']);
280
-            $main_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']);
281
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($main_model_name_singular)) {
282
-                return $controller->send_response(
283
-                    new \WP_Error(
284
-                        'endpoint_parsing_error',
285
-                        sprintf(
286
-                            __('There is no model for endpoint %s. Please contact event espresso support',
287
-                                'event_espresso'),
288
-                            $main_model_name_singular
289
-                        )
290
-                    )
291
-                );
292
-            }
293
-            $main_model = $controller->get_model_version_info()->load_model($main_model_name_singular);
294
-            //assume the related model name is plural and try to find the model's name
295
-            $related_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['related_model']);
296
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) {
297
-                //so the word didn't singularize well. Maybe that's just because it's a singular word?
298
-                $related_model_name_singular = \EEH_Inflector::humanize($matches['related_model']);
299
-            }
300
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) {
301
-                return $controller->send_response(
302
-                    new \WP_Error(
303
-                        'endpoint_parsing_error',
304
-                        sprintf(
305
-                            __('There is no model for endpoint %s. Please contact event espresso support',
306
-                                'event_espresso'),
307
-                            $related_model_name_singular
308
-                        )
309
-                    )
310
-                );
311
-            }
312
-            return $controller->send_response(
313
-                $controller->get_entities_from_relation(
314
-                    $request->get_param('id'),
315
-                    $main_model->related_settings_for($related_model_name_singular),
316
-                    $request
317
-                )
318
-            );
319
-        } catch (\Exception $e) {
320
-            return $controller->send_response($e);
321
-        }
322
-    }
323
-
324
-
325
-
326
-    /**
327
-     * Gets a collection for the given model and filters
328
-     *
329
-     * @param \EEM_Base        $model
330
-     * @param \WP_REST_Request $request
331
-     * @return array|\WP_Error
332
-     */
333
-    public function get_entities_from_model($model, $request)
334
-    {
335
-        $query_params = $this->create_model_query_params($model, $request->get_params());
336
-        if (! Capabilities::current_user_has_partial_access_to($model, $query_params['caps'])) {
337
-            $model_name_plural = \EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
338
-            return new \WP_Error(
339
-                sprintf('rest_%s_cannot_list', $model_name_plural),
340
-                sprintf(
341
-                    __('Sorry, you are not allowed to list %1$s. Missing permissions: %2$s', 'event_espresso'),
342
-                    $model_name_plural,
343
-                    Capabilities::get_missing_permissions_string($model, $query_params['caps'])
344
-                ),
345
-                array('status' => 403)
346
-            );
347
-        }
348
-        if (! $request->get_header('no_rest_headers')) {
349
-            $this->_set_headers_from_query_params($model, $query_params);
350
-        }
351
-        /** @type array $results */
352
-        $results = $model->get_all_wpdb_results($query_params);
353
-        $nice_results = array();
354
-        foreach ($results as $result) {
355
-            $nice_results[] = $this->create_entity_from_wpdb_result(
356
-                $model,
357
-                $result,
358
-                $request
359
-            );
360
-        }
361
-        return $nice_results;
362
-    }
363
-
364
-
365
-
366
-    /**
367
-     * @param array                   $primary_model_query_params query params for finding the item from which
368
-     *                                                            relations will be based
369
-     * @param \EE_Model_Relation_Base $relation
370
-     * @param \WP_REST_Request        $request
371
-     * @return \WP_Error|array
372
-     */
373
-    protected function _get_entities_from_relation($primary_model_query_params, $relation, $request)
374
-    {
375
-        $context = $this->validate_context($request->get_param('caps'));
376
-        $model = $relation->get_this_model();
377
-        $related_model = $relation->get_other_model();
378
-        if (! isset($primary_model_query_params[0])) {
379
-            $primary_model_query_params[0] = array();
380
-        }
381
-        //check if they can access the 1st model object
382
-        $primary_model_query_params = array(
383
-            0       => $primary_model_query_params[0],
384
-            'limit' => 1,
385
-        );
386
-        if ($model instanceof \EEM_Soft_Delete_Base) {
387
-            $primary_model_query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($primary_model_query_params);
388
-        }
389
-        $restricted_query_params = $primary_model_query_params;
390
-        $restricted_query_params['caps'] = $context;
391
-        $this->_set_debug_info('main model query params', $restricted_query_params);
392
-        $this->_set_debug_info('missing caps', Capabilities::get_missing_permissions_string($related_model, $context));
393
-        if (
394
-        ! (
395
-            Capabilities::current_user_has_partial_access_to($related_model, $context)
396
-            && $model->exists($restricted_query_params)
397
-        )
398
-        ) {
399
-            if ($relation instanceof \EE_Belongs_To_Relation) {
400
-                $related_model_name_maybe_plural = strtolower($related_model->get_this_model_name());
401
-            } else {
402
-                $related_model_name_maybe_plural = \EEH_Inflector::pluralize_and_lower($related_model->get_this_model_name());
403
-            }
404
-            return new \WP_Error(
405
-                sprintf('rest_%s_cannot_list', $related_model_name_maybe_plural),
406
-                sprintf(
407
-                    __('Sorry, you are not allowed to list %1$s related to %2$s. Missing permissions: %3$s',
408
-                        'event_espresso'),
409
-                    $related_model_name_maybe_plural,
410
-                    $relation->get_this_model()->get_this_model_name(),
411
-                    implode(
412
-                        ',',
413
-                        array_keys(
414
-                            Capabilities::get_missing_permissions($related_model, $context)
415
-                        )
416
-                    )
417
-                ),
418
-                array('status' => 403)
419
-            );
420
-        }
421
-        $query_params = $this->create_model_query_params($relation->get_other_model(), $request->get_params());
422
-        foreach ($primary_model_query_params[0] as $where_condition_key => $where_condition_value) {
423
-            $query_params[0][$relation->get_this_model()->get_this_model_name()
424
-                             . '.'
425
-                             . $where_condition_key] = $where_condition_value;
426
-        }
427
-        $query_params['default_where_conditions'] = 'none';
428
-        $query_params['caps'] = $context;
429
-        if (! $request->get_header('no_rest_headers')) {
430
-            $this->_set_headers_from_query_params($relation->get_other_model(), $query_params);
431
-        }
432
-        /** @type array $results */
433
-        $results = $relation->get_other_model()->get_all_wpdb_results($query_params);
434
-        $nice_results = array();
435
-        foreach ($results as $result) {
436
-            $nice_result = $this->create_entity_from_wpdb_result(
437
-                $relation->get_other_model(),
438
-                $result,
439
-                $request
440
-            );
441
-            if ($relation instanceof \EE_HABTM_Relation) {
442
-                //put the unusual stuff (properties from the HABTM relation) first, and make sure
443
-                //if there are conflicts we prefer the properties from the main model
444
-                $join_model_result = $this->create_entity_from_wpdb_result(
445
-                    $relation->get_join_model(),
446
-                    $result,
447
-                    $request
448
-                );
449
-                $joined_result = array_merge($nice_result, $join_model_result);
450
-                //but keep the meta stuff from the main model
451
-                if (isset($nice_result['meta'])) {
452
-                    $joined_result['meta'] = $nice_result['meta'];
453
-                }
454
-                $nice_result = $joined_result;
455
-            }
456
-            $nice_results[] = $nice_result;
457
-        }
458
-        if ($relation instanceof \EE_Belongs_To_Relation) {
459
-            return array_shift($nice_results);
460
-        } else {
461
-            return $nice_results;
462
-        }
463
-    }
464
-
465
-
466
-
467
-    /**
468
-     * Gets the collection for given relation object
469
-     * The same as Read::get_entities_from_model(), except if the relation
470
-     * is a HABTM relation, in which case it merges any non-foreign-key fields from
471
-     * the join-model-object into the results
472
-     *
473
-     * @param string                  $id the ID of the thing we are fetching related stuff from
474
-     * @param \EE_Model_Relation_Base $relation
475
-     * @param \WP_REST_Request        $request
476
-     * @return array|\WP_Error
477
-     * @throws \EE_Error
478
-     */
479
-    public function get_entities_from_relation($id, $relation, $request)
480
-    {
481
-        if (! $relation->get_this_model()->has_primary_key_field()) {
482
-            throw new \EE_Error(
483
-                sprintf(
484
-                    __('Read::get_entities_from_relation should only be called from a model with a primary key, it was called from %1$s',
485
-                        'event_espresso'),
486
-                    $relation->get_this_model()->get_this_model_name()
487
-                )
488
-            );
489
-        }
490
-        return $this->_get_entities_from_relation(
491
-            array(
492
-                array(
493
-                    $relation->get_this_model()->primary_key_name() => $id,
494
-                ),
495
-            ),
496
-            $relation,
497
-            $request
498
-        );
499
-    }
500
-
501
-
502
-
503
-    /**
504
-     * Sets the headers that are based on the model and query params,
505
-     * like the total records. This should only be called on the original request
506
-     * from the client, not on subsequent internal
507
-     *
508
-     * @param \EEM_Base $model
509
-     * @param array     $query_params
510
-     * @return void
511
-     */
512
-    protected function _set_headers_from_query_params($model, $query_params)
513
-    {
514
-        $this->_set_debug_info('model query params', $query_params);
515
-        $this->_set_debug_info('missing caps',
516
-            Capabilities::get_missing_permissions_string($model, $query_params['caps']));
517
-        //normally the limit to a 2-part array, where the 2nd item is the limit
518
-        if (! isset($query_params['limit'])) {
519
-            $query_params['limit'] = \EED_Core_Rest_Api::get_default_query_limit();
520
-        }
521
-        if (is_array($query_params['limit'])) {
522
-            $limit_parts = $query_params['limit'];
523
-        } else {
524
-            $limit_parts = explode(',', $query_params['limit']);
525
-            if (count($limit_parts) == 1) {
526
-                $limit_parts = array(0, $limit_parts[0]);
527
-            }
528
-        }
529
-        //remove the group by and having parts of the query, as those will
530
-        //make the sql query return an array of values, instead of just a single value
531
-        unset($query_params['group_by'], $query_params['having'], $query_params['limit']);
532
-        $count = $model->count($query_params, null, true);
533
-        $pages = $count / $limit_parts[1];
534
-        $this->_set_response_header('Total', $count, false);
535
-        $this->_set_response_header('PageSize', $limit_parts[1], false);
536
-        $this->_set_response_header('TotalPages', ceil($pages), false);
537
-    }
538
-
539
-
540
-
541
-    /**
542
-     * Changes database results into REST API entities
543
-     *
544
-     * @param \EEM_Base        $model
545
-     * @param array            $db_row     like results from $wpdb->get_results()
546
-     * @param \WP_REST_Request $rest_request
547
-     * @param string           $deprecated no longer used
548
-     * @return array ready for being converted into json for sending to client
549
-     */
550
-    public function create_entity_from_wpdb_result($model, $db_row, $rest_request, $deprecated = null)
551
-    {
552
-        if (! $rest_request instanceof \WP_REST_Request) {
553
-            //ok so this was called in the old style, where the 3rd arg was
554
-            //$include, and the 4th arg was $context
555
-            //now setup the request just to avoid fatal errors, although we won't be able
556
-            //to truly make use of it because it's kinda devoid of info
557
-            $rest_request = new \WP_REST_Request();
558
-            $rest_request->set_param('include', $rest_request);
559
-            $rest_request->set_param('caps', $deprecated);
560
-        }
561
-        if ($rest_request->get_param('caps') == null) {
562
-            $rest_request->set_param('caps', \EEM_Base::caps_read);
563
-        }
564
-        $entity_array = $this->_create_bare_entity_from_wpdb_results($model, $db_row);
565
-        $entity_array = $this->_add_extra_fields($model, $db_row, $entity_array);
566
-        $entity_array['_links'] = $this->_get_entity_links($model, $db_row, $entity_array);
567
-        $entity_array['_calculated_fields'] = $this->_get_entity_calculations($model, $db_row, $rest_request);
568
-        $entity_array = $this->_include_requested_models($model, $rest_request, $entity_array, $db_row);
569
-        $entity_array = apply_filters(
570
-            'FHEE__Read__create_entity_from_wpdb_results__entity_before_inaccessible_field_removal',
571
-            $entity_array,
572
-            $model,
573
-            $rest_request->get_param('caps'),
574
-            $rest_request,
575
-            $this
576
-        );
577
-        $result_without_inaccessible_fields = Capabilities::filter_out_inaccessible_entity_fields(
578
-            $entity_array,
579
-            $model,
580
-            $rest_request->get_param('caps'),
581
-            $this->get_model_version_info(),
582
-            $model->get_index_primary_key_string(
583
-                $model->deduce_fields_n_values_from_cols_n_values($db_row)
584
-            )
585
-        );
586
-        $this->_set_debug_info(
587
-            'inaccessible fields',
588
-            array_keys(array_diff_key($entity_array, $result_without_inaccessible_fields))
589
-        );
590
-        return apply_filters(
591
-            'FHEE__Read__create_entity_from_wpdb_results__entity_return',
592
-            $result_without_inaccessible_fields,
593
-            $model,
594
-            $rest_request->get_param('caps')
595
-        );
596
-    }
597
-
598
-
599
-
600
-    /**
601
-     * Creates a REST entity array (JSON object we're going to return in the response, but
602
-     * for now still a PHP array, but soon enough we'll call json_encode on it, don't worry),
603
-     * from $wpdb->get_row( $sql, ARRAY_A)
604
-     *
605
-     * @param \EEM_Base $model
606
-     * @param array     $db_row
607
-     * @return array entity mostly ready for converting to JSON and sending in the response
608
-     */
609
-    protected function _create_bare_entity_from_wpdb_results(\EEM_Base $model, $db_row)
610
-    {
611
-        $result = $model->deduce_fields_n_values_from_cols_n_values($db_row);
612
-        $result = array_intersect_key($result,
613
-            $this->get_model_version_info()->fields_on_model_in_this_version($model));
614
-        foreach ($result as $field_name => $raw_field_value) {
615
-            $field_obj = $model->field_settings_for($field_name);
616
-            $field_value = $field_obj->prepare_for_set_from_db($raw_field_value);
617
-            if ($this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_ignored())) {
618
-                unset($result[$field_name]);
619
-            } elseif (
620
-            $this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_rendered_format())
621
-            ) {
622
-                $result[$field_name] = array(
623
-                    'raw'      => $field_obj->prepare_for_get($field_value),
624
-                    'rendered' => $field_obj->prepare_for_pretty_echoing($field_value),
625
-                );
626
-            } elseif (
627
-            $this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_pretty_format())
628
-            ) {
629
-                $result[$field_name] = array(
630
-                    'raw'    => $field_obj->prepare_for_get($field_value),
631
-                    'pretty' => $field_obj->prepare_for_pretty_echoing($field_value),
632
-                );
633
-            } elseif ($field_obj instanceof \EE_Datetime_Field) {
634
-                if ($field_value instanceof \DateTime) {
635
-                    $timezone = $field_value->getTimezone();
636
-                    $field_value->setTimezone(new \DateTimeZone('UTC'));
637
-                    $result[$field_name . '_gmt'] = Model_Data_Translator::prepare_field_value_for_json(
638
-                        $field_obj,
639
-                        $field_value,
640
-                        $this->get_model_version_info()->requested_version()
641
-                    );
642
-                    $field_value->setTimezone($timezone);
643
-                    $result[$field_name] = Model_Data_Translator::prepare_field_value_for_json(
644
-                        $field_obj,
645
-                        $field_value,
646
-                        $this->get_model_version_info()->requested_version()
647
-                    );
648
-                }
649
-            } else {
650
-                $result[$field_name] = Model_Data_Translator::prepare_field_value_for_json(
651
-                    $field_obj,
652
-                    $field_obj->prepare_for_get($field_value),
653
-                    $this->get_model_version_info()->requested_version()
654
-                );
655
-            }
656
-        }
657
-        return $result;
658
-    }
659
-
660
-
661
-
662
-    /**
663
-     * Adds a few extra fields to the entity response
664
-     *
665
-     * @param \EEM_Base $model
666
-     * @param array     $db_row
667
-     * @param array     $entity_array
668
-     * @return array modified entity
669
-     */
670
-    protected function _add_extra_fields(\EEM_Base $model, $db_row, $entity_array)
671
-    {
672
-        if ($model instanceof \EEM_CPT_Base) {
673
-            $entity_array['link'] = get_permalink($db_row[$model->get_primary_key_field()->get_qualified_column()]);
674
-        }
675
-        return $entity_array;
676
-    }
677
-
678
-
679
-
680
-    /**
681
-     * Gets links we want to add to the response
682
-     *
683
-     * @global \WP_REST_Server $wp_rest_server
684
-     * @param \EEM_Base        $model
685
-     * @param array            $db_row
686
-     * @param array            $entity_array
687
-     * @return array the _links item in the entity
688
-     */
689
-    protected function _get_entity_links($model, $db_row, $entity_array)
690
-    {
691
-        //add basic links
692
-        $links = array();
693
-        if ($model->has_primary_key_field()) {
694
-            $links['self'] = array(
695
-                array(
696
-                    'href' => $this->get_versioned_link_to(
697
-                        \EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
698
-                        . '/'
699
-                        . $entity_array[$model->primary_key_name()]
700
-                    ),
701
-                ),
702
-            );
703
-        }
704
-        $links['collection'] = array(
705
-            array(
706
-                'href' => $this->get_versioned_link_to(
707
-                    \EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
708
-                ),
709
-            ),
710
-        );
711
-        //add links to related models
712
-        if ($model->has_primary_key_field()) {
713
-            foreach ($this->get_model_version_info()->relation_settings($model) as $relation_name => $relation_obj) {
714
-                $related_model_part = Read::get_related_entity_name($relation_name, $relation_obj);
715
-                $links[\EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part] = array(
716
-                    array(
717
-                        'href'   => $this->get_versioned_link_to(
718
-                            \EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
719
-                            . '/'
720
-                            . $entity_array[$model->primary_key_name()]
721
-                            . '/'
722
-                            . $related_model_part
723
-                        ),
724
-                        'single' => $relation_obj instanceof \EE_Belongs_To_Relation ? true : false,
725
-                    ),
726
-                );
727
-            }
728
-        }
729
-        return $links;
730
-    }
731
-
732
-
733
-
734
-    /**
735
-     * Adds the included models indicated in the request to the entity provided
736
-     *
737
-     * @param \EEM_Base        $model
738
-     * @param \WP_REST_Request $rest_request
739
-     * @param array            $entity_array
740
-     * @param array            $db_row
741
-     * @return array the modified entity
742
-     */
743
-    protected function _include_requested_models(
744
-        \EEM_Base $model,
745
-        \WP_REST_Request $rest_request,
746
-        $entity_array,
747
-        $db_row = array()
748
-    ) {
749
-        //if $db_row not included, hope the entity array has what we need
750
-        if (! $db_row) {
751
-            $db_row = $entity_array;
752
-        }
753
-        $includes_for_this_model = $this->explode_and_get_items_prefixed_with($rest_request->get_param('include'), '');
754
-        $includes_for_this_model = $this->_remove_model_names_from_array($includes_for_this_model);
755
-        //if they passed in * or didn't specify any includes, return everything
756
-        if (! in_array('*', $includes_for_this_model)
757
-            && ! empty($includes_for_this_model)
758
-        ) {
759
-            if ($model->has_primary_key_field()) {
760
-                //always include the primary key. ya just gotta know that at least
761
-                $includes_for_this_model[] = $model->primary_key_name();
762
-            }
763
-            if ($this->explode_and_get_items_prefixed_with($rest_request->get_param('calculate'), '')) {
764
-                $includes_for_this_model[] = '_calculated_fields';
765
-            }
766
-            $entity_array = array_intersect_key($entity_array, array_flip($includes_for_this_model));
767
-        }
768
-        $relation_settings = $this->get_model_version_info()->relation_settings($model);
769
-        foreach ($relation_settings as $relation_name => $relation_obj) {
770
-            $related_fields_to_include = $this->explode_and_get_items_prefixed_with(
771
-                $rest_request->get_param('include'),
772
-                $relation_name
773
-            );
774
-            $related_fields_to_calculate = $this->explode_and_get_items_prefixed_with(
775
-                $rest_request->get_param('calculate'),
776
-                $relation_name
777
-            );
778
-            //did they specify they wanted to include a related model, or
779
-            //specific fields from a related model?
780
-            //or did they specify to calculate a field from a related model?
781
-            if ($related_fields_to_include || $related_fields_to_calculate) {
782
-                //if so, we should include at least some part of the related model
783
-                $pretend_related_request = new \WP_REST_Request();
784
-                $pretend_related_request->set_query_params(
785
-                    array(
786
-                        'caps'      => $rest_request->get_param('caps'),
787
-                        'include'   => $related_fields_to_include,
788
-                        'calculate' => $related_fields_to_calculate,
789
-                    )
790
-                );
791
-                $pretend_related_request->add_header('no_rest_headers', true);
792
-                $primary_model_query_params = $model->alter_query_params_to_restrict_by_ID(
793
-                    $model->get_index_primary_key_string(
794
-                        $model->deduce_fields_n_values_from_cols_n_values($db_row)
795
-                    )
796
-                );
797
-                $related_results = $this->_get_entities_from_relation(
798
-                    $primary_model_query_params,
799
-                    $relation_obj,
800
-                    $pretend_related_request
801
-                );
802
-                $entity_array[Read::get_related_entity_name($relation_name, $relation_obj)] = $related_results
803
-                                                                                              instanceof
804
-                                                                                              \WP_Error
805
-                    ? null
806
-                    : $related_results;
807
-            }
808
-        }
809
-        return $entity_array;
810
-    }
811
-
812
-
813
-
814
-    /**
815
-     * Returns a new array with all the names of models removed. Eg
816
-     * array( 'Event', 'Datetime.*', 'foobar' ) would become array( 'Datetime.*', 'foobar' )
817
-     *
818
-     * @param array $arr
819
-     * @return array
820
-     */
821
-    private function _remove_model_names_from_array($arr)
822
-    {
823
-        return array_diff($arr, array_keys(\EE_Registry::instance()->non_abstract_db_models));
824
-    }
825
-
826
-
827
-
828
-    /**
829
-     * Gets the calculated fields for the response
830
-     *
831
-     * @param \EEM_Base        $model
832
-     * @param array            $wpdb_row
833
-     * @param \WP_REST_Request $rest_request
834
-     * @return \stdClass the _calculations item in the entity
835
-     */
836
-    protected function _get_entity_calculations($model, $wpdb_row, $rest_request)
837
-    {
838
-        $calculated_fields = $this->explode_and_get_items_prefixed_with(
839
-            $rest_request->get_param('calculate'),
840
-            ''
841
-        );
842
-        //note: setting calculate=* doesn't do anything
843
-        $calculated_fields_to_return = new \stdClass();
844
-        foreach ($calculated_fields as $field_to_calculate) {
845
-            try {
846
-                $calculated_fields_to_return->$field_to_calculate = Model_Data_Translator::prepare_field_value_for_json(
847
-                    null,
848
-                    $this->_fields_calculator->retrieve_calculated_field_value(
849
-                        $model,
850
-                        $field_to_calculate,
851
-                        $wpdb_row,
852
-                        $rest_request,
853
-                        $this
854
-                    ),
855
-                    $this->get_model_version_info()->requested_version()
856
-                );
857
-            } catch (Rest_Exception $e) {
858
-                //if we don't have permission to read it, just leave it out. but let devs know about the problem
859
-                $this->_set_response_header(
860
-                    'Notices-Field-Calculation-Errors['
861
-                    . $e->get_string_code()
862
-                    . ']['
863
-                    . $model->get_this_model_name()
864
-                    . ']['
865
-                    . $field_to_calculate
866
-                    . ']',
867
-                    $e->getMessage(),
868
-                    true
869
-                );
870
-            }
871
-        }
872
-        return $calculated_fields_to_return;
873
-    }
874
-
875
-
876
-
877
-    /**
878
-     * Gets the full URL to the resource, taking the requested version into account
879
-     *
880
-     * @param string $link_part_after_version_and_slash eg "events/10/datetimes"
881
-     * @return string url eg "http://mysite.com/wp-json/ee/v4.6/events/10/datetimes"
882
-     */
883
-    public function get_versioned_link_to($link_part_after_version_and_slash)
884
-    {
885
-        return rest_url(
886
-            \EED_Core_Rest_Api::ee_api_namespace
887
-            . $this->get_model_version_info()->requested_version()
888
-            . '/'
889
-            . $link_part_after_version_and_slash
890
-        );
891
-    }
892
-
893
-
894
-
895
-    /**
896
-     * Gets the correct lowercase name for the relation in the API according
897
-     * to the relation's type
898
-     *
899
-     * @param string                  $relation_name
900
-     * @param \EE_Model_Relation_Base $relation_obj
901
-     * @return string
902
-     */
903
-    public static function get_related_entity_name($relation_name, $relation_obj)
904
-    {
905
-        if ($relation_obj instanceof \EE_Belongs_To_Relation) {
906
-            return strtolower($relation_name);
907
-        } else {
908
-            return \EEH_Inflector::pluralize_and_lower($relation_name);
909
-        }
910
-    }
911
-
912
-
913
-
914
-    /**
915
-     * Gets the one model object with the specified id for the specified model
916
-     *
917
-     * @param \EEM_Base        $model
918
-     * @param \WP_REST_Request $request
919
-     * @return array|\WP_Error
920
-     */
921
-    public function get_entity_from_model($model, $request)
922
-    {
923
-        $query_params = array(array($model->primary_key_name() => $request->get_param('id')), 'limit' => 1);
924
-        if ($model instanceof \EEM_Soft_Delete_Base) {
925
-            $query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($query_params);
926
-        }
927
-        $restricted_query_params = $query_params;
928
-        $restricted_query_params['caps'] = $this->validate_context($request->get_param('caps'));
929
-        $this->_set_debug_info('model query params', $restricted_query_params);
930
-        $model_rows = $model->get_all_wpdb_results($restricted_query_params);
931
-        if (! empty ($model_rows)) {
932
-            return $this->create_entity_from_wpdb_result(
933
-                $model,
934
-                array_shift($model_rows),
935
-                $request);
936
-        } else {
937
-            //ok let's test to see if we WOULD have found it, had we not had restrictions from missing capabilities
938
-            $lowercase_model_name = strtolower($model->get_this_model_name());
939
-            $model_rows_found_sans_restrictions = $model->get_all_wpdb_results($query_params);
940
-            if (! empty($model_rows_found_sans_restrictions)) {
941
-                //you got shafted- it existed but we didn't want to tell you!
942
-                return new \WP_Error(
943
-                    'rest_user_cannot_read',
944
-                    sprintf(
945
-                        __('Sorry, you cannot read this %1$s. Missing permissions are: %2$s', 'event_espresso'),
946
-                        strtolower($model->get_this_model_name()),
947
-                        Capabilities::get_missing_permissions_string(
948
-                            $model,
949
-                            $this->validate_context($request->get_param('caps')))
950
-                    ),
951
-                    array('status' => 403)
952
-                );
953
-            } else {
954
-                //it's not you. It just doesn't exist
955
-                return new \WP_Error(
956
-                    sprintf('rest_%s_invalid_id', $lowercase_model_name),
957
-                    sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
958
-                    array('status' => 404)
959
-                );
960
-            }
961
-        }
962
-    }
963
-
964
-
965
-
966
-    /**
967
-     * If a context is provided which isn't valid, maybe it was added in a future
968
-     * version so just treat it as a default read
969
-     *
970
-     * @param string $context
971
-     * @return string array key of EEM_Base::cap_contexts_to_cap_action_map()
972
-     */
973
-    public function validate_context($context)
974
-    {
975
-        if (! $context) {
976
-            $context = \EEM_Base::caps_read;
977
-        }
978
-        $valid_contexts = \EEM_Base::valid_cap_contexts();
979
-        if (in_array($context, $valid_contexts)) {
980
-            return $context;
981
-        } else {
982
-            return \EEM_Base::caps_read;
983
-        }
984
-    }
985
-
986
-
987
-
988
-    /**
989
-     * Verifies the passed in value is an allowable default where conditions value.
990
-     *
991
-     * @param $default_query_params
992
-     * @return string
993
-     */
994
-    public function validate_default_query_params($default_query_params)
995
-    {
996
-        $valid_default_where_conditions_for_api_calls = array(
997
-            \EEM_Base::default_where_conditions_all,
998
-            \EEM_Base::default_where_conditions_minimum_all,
999
-            \EEM_Base::default_where_conditions_minimum_others,
1000
-        );
1001
-        if (! $default_query_params) {
1002
-            $default_query_params = \EEM_Base::default_where_conditions_all;
1003
-        }
1004
-        if (
1005
-        in_array(
1006
-            $default_query_params,
1007
-            $valid_default_where_conditions_for_api_calls,
1008
-            true
1009
-        )
1010
-        ) {
1011
-            return $default_query_params;
1012
-        } else {
1013
-            return \EEM_Base::default_where_conditions_all;
1014
-        }
1015
-    }
1016
-
1017
-
1018
-
1019
-    /**
1020
-     * Translates API filter get parameter into $query_params array used by EEM_Base::get_all().
1021
-     * Note: right now the query parameter keys for fields (and related fields)
1022
-     * can be left as-is, but it's quite possible this will change someday.
1023
-     * Also, this method's contents might be candidate for moving to Model_Data_Translator
1024
-     *
1025
-     * @param \EEM_Base $model
1026
-     * @param array     $query_parameters from $_GET parameter @see Read:handle_request_get_all
1027
-     * @return array like what EEM_Base::get_all() expects or FALSE to indicate
1028
-     *                                    that absolutely no results should be returned
1029
-     * @throws \EE_Error
1030
-     */
1031
-    public function create_model_query_params($model, $query_parameters)
1032
-    {
1033
-        $model_query_params = array();
1034
-        if (isset($query_parameters['where'])) {
1035
-            $model_query_params[0] = Model_Data_Translator::prepare_conditions_query_params_for_models(
1036
-                $query_parameters['where'],
1037
-                $model,
1038
-                $this->get_model_version_info()->requested_version()
1039
-            );
1040
-        }
1041
-        if (isset($query_parameters['order_by'])) {
1042
-            $order_by = $query_parameters['order_by'];
1043
-        } elseif (isset($query_parameters['orderby'])) {
1044
-            $order_by = $query_parameters['orderby'];
1045
-        } else {
1046
-            $order_by = null;
1047
-        }
1048
-        if ($order_by !== null) {
1049
-            if (is_array($order_by)) {
1050
-                $order_by = Model_Data_Translator::prepare_field_names_in_array_keys_from_json($order_by);
1051
-            } else {
1052
-                //it's a single item
1053
-                $order_by = Model_Data_Translator::prepare_field_name_from_json($order_by);
1054
-            }
1055
-            $model_query_params['order_by'] = $order_by;
1056
-        }
1057
-        if (isset($query_parameters['group_by'])) {
1058
-            $group_by = $query_parameters['group_by'];
1059
-        } elseif (isset($query_parameters['groupby'])) {
1060
-            $group_by = $query_parameters['groupby'];
1061
-        } else {
1062
-            $group_by = array_keys($model->get_combined_primary_key_fields());
1063
-        }
1064
-        //make sure they're all real names
1065
-        if (is_array($group_by)) {
1066
-            $group_by = Model_Data_Translator::prepare_field_names_from_json($group_by);
1067
-        }
1068
-        if ($group_by !== null) {
1069
-            $model_query_params['group_by'] = $group_by;
1070
-        }
1071
-        if (isset($query_parameters['having'])) {
1072
-            $model_query_params['having'] = Model_Data_Translator::prepare_conditions_query_params_for_models(
1073
-                $query_parameters['having'],
1074
-                $model,
1075
-                $this->get_model_version_info()->requested_version()
1076
-            );
1077
-        }
1078
-        if (isset($query_parameters['order'])) {
1079
-            $model_query_params['order'] = $query_parameters['order'];
1080
-        }
1081
-        if (isset($query_parameters['mine'])) {
1082
-            $model_query_params = $model->alter_query_params_to_only_include_mine($model_query_params);
1083
-        }
1084
-        if (isset($query_parameters['limit'])) {
1085
-            //limit should be either a string like '23' or '23,43', or an array with two items in it
1086
-            if (! is_array($query_parameters['limit'])) {
1087
-                $limit_array = explode(',', (string)$query_parameters['limit']);
1088
-            } else {
1089
-                $limit_array = $query_parameters['limit'];
1090
-            }
1091
-            $sanitized_limit = array();
1092
-            foreach ($limit_array as $key => $limit_part) {
1093
-                if ($this->_debug_mode && (! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1094
-                    throw new \EE_Error(
1095
-                        sprintf(
1096
-                            __('An invalid limit filter was provided. It was: %s. If the EE4 JSON REST API weren\'t in debug mode, this message would not appear.',
1097
-                                'event_espresso'),
1098
-                            wp_json_encode($query_parameters['limit'])
1099
-                        )
1100
-                    );
1101
-                }
1102
-                $sanitized_limit[] = (int)$limit_part;
1103
-            }
1104
-            $model_query_params['limit'] = implode(',', $sanitized_limit);
1105
-        } else {
1106
-            $model_query_params['limit'] = \EED_Core_Rest_Api::get_default_query_limit();
1107
-        }
1108
-        if (isset($query_parameters['caps'])) {
1109
-            $model_query_params['caps'] = $this->validate_context($query_parameters['caps']);
1110
-        } else {
1111
-            $model_query_params['caps'] = \EEM_Base::caps_read;
1112
-        }
1113
-        if (isset($query_parameters['default_where_conditions'])) {
1114
-            $model_query_params['default_where_conditions'] = $this->validate_default_query_params($query_parameters['default_where_conditions']);
1115
-        }
1116
-        return apply_filters('FHEE__Read__create_model_query_params', $model_query_params, $query_parameters, $model);
1117
-    }
1118
-
1119
-
1120
-
1121
-    /**
1122
-     * Changes the REST-style query params for use in the models
1123
-     *
1124
-     * @deprecated
1125
-     * @param \EEM_Base $model
1126
-     * @param array     $query_params sub-array from @see EEM_Base::get_all()
1127
-     * @return array
1128
-     */
1129
-    public function prepare_rest_query_params_key_for_models($model, $query_params)
1130
-    {
1131
-        $model_ready_query_params = array();
1132
-        foreach ($query_params as $key => $value) {
1133
-            if (is_array($value)) {
1134
-                $model_ready_query_params[$key] = $this->prepare_rest_query_params_key_for_models($model, $value);
1135
-            } else {
1136
-                $model_ready_query_params[$key] = $value;
1137
-            }
1138
-        }
1139
-        return $model_ready_query_params;
1140
-    }
1141
-
1142
-
1143
-
1144
-    /**
1145
-     * @deprecated
1146
-     * @param $model
1147
-     * @param $query_params
1148
-     * @return array
1149
-     */
1150
-    public function prepare_rest_query_params_values_for_models($model, $query_params)
1151
-    {
1152
-        $model_ready_query_params = array();
1153
-        foreach ($query_params as $key => $value) {
1154
-            if (is_array($value)) {
1155
-                $model_ready_query_params[$key] = $this->prepare_rest_query_params_values_for_models($model, $value);
1156
-            } else {
1157
-                $model_ready_query_params[$key] = $value;
1158
-            }
1159
-        }
1160
-        return $model_ready_query_params;
1161
-    }
1162
-
1163
-
1164
-
1165
-    /**
1166
-     * Explodes the string on commas, and only returns items with $prefix followed by a period.
1167
-     * If no prefix is specified, returns items with no period.
1168
-     *
1169
-     * @param string|array $string_to_explode eg "jibba,jabba, blah, blaabla" or array('jibba', 'jabba' )
1170
-     * @param string       $prefix            "Event" or "foobar"
1171
-     * @return array $string_to_exploded exploded on COMMAS, and if a prefix was specified
1172
-     *                                        we only return strings starting with that and a period; if no prefix was
1173
-     *                                        specified we return all items containing NO periods
1174
-     */
1175
-    public function explode_and_get_items_prefixed_with($string_to_explode, $prefix)
1176
-    {
1177
-        if (is_string($string_to_explode)) {
1178
-            $exploded_contents = explode(',', $string_to_explode);
1179
-        } else if (is_array($string_to_explode)) {
1180
-            $exploded_contents = $string_to_explode;
1181
-        } else {
1182
-            $exploded_contents = array();
1183
-        }
1184
-        //if the string was empty, we want an empty array
1185
-        $exploded_contents = array_filter($exploded_contents);
1186
-        $contents_with_prefix = array();
1187
-        foreach ($exploded_contents as $item) {
1188
-            $item = trim($item);
1189
-            //if no prefix was provided, so we look for items with no "." in them
1190
-            if (! $prefix) {
1191
-                //does this item have a period?
1192
-                if (strpos($item, '.') === false) {
1193
-                    //if not, then its what we're looking for
1194
-                    $contents_with_prefix[] = $item;
1195
-                }
1196
-            } else if (strpos($item, $prefix . '.') === 0) {
1197
-                //this item has the prefix and a period, grab it
1198
-                $contents_with_prefix[] = substr(
1199
-                    $item,
1200
-                    strpos($item, $prefix . '.') + strlen($prefix . '.')
1201
-                );
1202
-            } else if ($item === $prefix) {
1203
-                //this item is JUST the prefix
1204
-                //so let's grab everything after, which is a blank string
1205
-                $contents_with_prefix[] = '';
1206
-            }
1207
-        }
1208
-        return $contents_with_prefix;
1209
-    }
1210
-
1211
-
1212
-
1213
-    /**
1214
-     * @deprecated since 4.8.36.rc.001 You should instead use Read::explode_and_get_items_prefixed_with.
1215
-     * Deprecated because its return values were really quite confusing- sometimes it returned
1216
-     * an empty array (when the include string was blank or '*') or sometimes it returned
1217
-     * array('*') (when you provided a model and a model of that kind was found).
1218
-     * Parses the $include_string so we fetch all the field names relating to THIS model
1219
-     * (ie have NO period in them), or for the provided model (ie start with the model
1220
-     * name and then a period).
1221
-     * @param string $include_string @see Read:handle_request_get_all
1222
-     * @param string $model_name
1223
-     * @return array of fields for this model. If $model_name is provided, then
1224
-     *                               the fields for that model, with the model's name removed from each.
1225
-     *                               If $include_string was blank or '*' returns an empty array
1226
-     */
1227
-    public function extract_includes_for_this_model($include_string, $model_name = null)
1228
-    {
1229
-        if (is_array($include_string)) {
1230
-            $include_string = implode(',', $include_string);
1231
-        }
1232
-        if ($include_string === '*' || $include_string === '') {
1233
-            return array();
1234
-        }
1235
-        $includes = explode(',', $include_string);
1236
-        $extracted_fields_to_include = array();
1237
-        if ($model_name) {
1238
-            foreach ($includes as $field_to_include) {
1239
-                $field_to_include = trim($field_to_include);
1240
-                if (strpos($field_to_include, $model_name . '.') === 0) {
1241
-                    //found the model name at the exact start
1242
-                    $field_sans_model_name = str_replace($model_name . '.', '', $field_to_include);
1243
-                    $extracted_fields_to_include[] = $field_sans_model_name;
1244
-                } elseif ($field_to_include == $model_name) {
1245
-                    $extracted_fields_to_include[] = '*';
1246
-                }
1247
-            }
1248
-        } else {
1249
-            //look for ones with no period
1250
-            foreach ($includes as $field_to_include) {
1251
-                $field_to_include = trim($field_to_include);
1252
-                if (
1253
-                    strpos($field_to_include, '.') === false
1254
-                    && ! $this->get_model_version_info()->is_model_name_in_this_version($field_to_include)
1255
-                ) {
1256
-                    $extracted_fields_to_include[] = $field_to_include;
1257
-                }
1258
-            }
1259
-        }
1260
-        return $extracted_fields_to_include;
1261
-    }
30
+	/**
31
+	 * @var Calculated_Model_Fields
32
+	 */
33
+	protected $_fields_calculator;
34
+
35
+
36
+
37
+	/**
38
+	 * Read constructor.
39
+	 */
40
+	public function __construct()
41
+	{
42
+		parent::__construct();
43
+		$this->_fields_calculator = new Calculated_Model_Fields();
44
+	}
45
+
46
+
47
+
48
+	/**
49
+	 * Handles requests to get all (or a filtered subset) of entities for a particular model
50
+	 *
51
+	 * @param \WP_REST_Request $request
52
+	 * @return \WP_REST_Response|\WP_Error
53
+	 */
54
+	public static function handle_request_get_all(\WP_REST_Request $request)
55
+	{
56
+		$controller = new Read();
57
+		try {
58
+			$matches = $controller->parse_route(
59
+				$request->get_route(),
60
+				'~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)~',
61
+				array('version', 'model')
62
+			);
63
+			$controller->set_requested_version($matches['version']);
64
+			$model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']);
65
+			if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) {
66
+				return $controller->send_response(
67
+					new \WP_Error(
68
+						'endpoint_parsing_error',
69
+						sprintf(
70
+							__('There is no model for endpoint %s. Please contact event espresso support',
71
+								'event_espresso'),
72
+							$model_name_singular
73
+						)
74
+					)
75
+				);
76
+			}
77
+			return $controller->send_response(
78
+				$controller->get_entities_from_model(
79
+					$controller->get_model_version_info()->load_model($model_name_singular),
80
+					$request
81
+				)
82
+			);
83
+		} catch (\Exception $e) {
84
+			return $controller->send_response($e);
85
+		}
86
+	}
87
+
88
+
89
+	/**
90
+	 * Prepares and returns schema for any OPTIONS request.
91
+	 *
92
+	 * @param string $model_name  Something like `Event` or `Registration`
93
+	 * @param string $version     The API endpoint version being used.
94
+	 * @return array
95
+	 */
96
+	public static function handle_schema_request($model_name, $version)
97
+	{
98
+		$controller = new Read();
99
+		try {
100
+			$controller->set_requested_version($version);
101
+			if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name)) {
102
+				return array();
103
+			}
104
+			//get the model for this version
105
+			$model = $controller->get_model_version_info()->load_model($model_name);
106
+			$model_schema = new JsonModelSchema($model);
107
+			return $model_schema->getModelSchemaForRelations(
108
+				$controller->get_model_version_info()->relation_settings($model),
109
+				$controller->_customize_schema_for_rest_response(
110
+					$model,
111
+					$model_schema->getModelSchemaForFields(
112
+						$controller->get_model_version_info()->fields_on_model_in_this_version($model),
113
+						$model_schema->getInitialSchemaStructure()
114
+					)
115
+				)
116
+			);
117
+		} catch (\Exception $e) {
118
+			return array();
119
+		}
120
+	}
121
+
122
+
123
+	/**
124
+	 * This loops through each field in the given schema for the model and does the following:
125
+	 * - add any extra fields that are REST API specific and related to existing fields.
126
+	 * - transform default values into the correct format for a REST API response.
127
+	 *
128
+	 * @param \EEM_Base $model
129
+	 * @param array     $schema
130
+	 * @return array  The final schema.
131
+	 */
132
+	protected function _customize_schema_for_rest_response(\EEM_Base $model, array $schema)
133
+	{
134
+	   foreach ($this->get_model_version_info()->fields_on_model_in_this_version($model) as $field_name => $field) {
135
+		   $schema = $this->_translate_defaults_for_rest_response(
136
+			   $field_name,
137
+			   $field,
138
+			   $this->_maybe_add_extra_fields_to_schema($field_name, $field, $schema)
139
+			);
140
+	   }
141
+	   return $schema;
142
+	}
143
+
144
+
145
+	/**
146
+	 * This is used to ensure that the 'default' value set in the schema response is formatted correctly for the REST
147
+	 * response.
148
+	 *
149
+	 * @param                      $field_name
150
+	 * @param \EE_Model_Field_Base $field
151
+	 * @param array                $schema
152
+	 * @return array
153
+	 */
154
+	protected function _translate_defaults_for_rest_response($field_name, \EE_Model_Field_Base $field, array $schema)
155
+	{
156
+		if (isset($schema['properties'][$field_name]['default'])) {
157
+			if (is_array($schema['properties'][$field_name]['default'])) {
158
+				foreach ($schema['properties'][$field_name]['default'] as $default_key => $default_value) {
159
+					if ($default_key === 'raw') {
160
+						$schema['properties'][$field_name]['default'][$default_key] = Model_Data_Translator::prepare_field_value_for_json(
161
+							$field,
162
+							$default_value,
163
+							$this->get_model_version_info()->requested_version()
164
+						);
165
+					}
166
+				}
167
+			} else {
168
+				$schema['properties'][$field_name]['default'] = Model_Data_Translator::prepare_field_value_for_json(
169
+					$field,
170
+					$schema['properties'][$field_name]['default'],
171
+					$this->get_model_version_info()->requested_version()
172
+				);
173
+			}
174
+		}
175
+		return $schema;
176
+	}
177
+
178
+
179
+	/**
180
+	 * Adds additional fields to the schema
181
+	 * The REST API returns a GMT value field for each datetime field in the resource.  Thus the description about this
182
+	 * needs to be added to the schema.
183
+	 *
184
+	 * @param                      $field_name
185
+	 * @param \EE_Model_Field_Base $field
186
+	 * @param array                $schema
187
+	 * @return array
188
+	 */
189
+	protected function _maybe_add_extra_fields_to_schema($field_name, \EE_Model_Field_Base $field, array $schema)
190
+	{
191
+		if ($field instanceof EE_Datetime_Field) {
192
+			$schema['properties'][$field_name . '_gmt'] = $field->getSchema();
193
+			//modify the description
194
+			$schema['properties'][$field_name . '_gmt']['description'] = sprintf(
195
+				esc_html__('%s - the value for this field is in GMT.', 'event_espresso'),
196
+				$field->get_nicename()
197
+			);
198
+		}
199
+		return $schema;
200
+	}
201
+
202
+
203
+
204
+
205
+	/**
206
+	 * Used to figure out the route from the request when a `WP_REST_Request` object is not available
207
+	 * @return string
208
+	 */
209
+	protected function get_route_from_request() {
210
+		if (isset($GLOBALS['wp'])
211
+			&& $GLOBALS['wp'] instanceof \WP
212
+			&& isset($GLOBALS['wp']->query_vars['rest_route'] )
213
+		) {
214
+			return $GLOBALS['wp']->query_vars['rest_route'];
215
+		} else {
216
+			return isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '/';
217
+		}
218
+	}
219
+
220
+
221
+
222
+	/**
223
+	 * Gets a single entity related to the model indicated in the path and its id
224
+	 *
225
+	 * @param \WP_REST_Request $request
226
+	 * @return \WP_REST_Response|\WP_Error
227
+	 */
228
+	public static function handle_request_get_one(\WP_REST_Request $request)
229
+	{
230
+		$controller = new Read();
231
+		try {
232
+			$matches = $controller->parse_route(
233
+				$request->get_route(),
234
+				'~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)~',
235
+				array('version', 'model', 'id'));
236
+			$controller->set_requested_version($matches['version']);
237
+			$model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']);
238
+			if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) {
239
+				return $controller->send_response(
240
+					new \WP_Error(
241
+						'endpoint_parsing_error',
242
+						sprintf(
243
+							__('There is no model for endpoint %s. Please contact event espresso support',
244
+								'event_espresso'),
245
+							$model_name_singular
246
+						)
247
+					)
248
+				);
249
+			}
250
+			return $controller->send_response(
251
+				$controller->get_entity_from_model(
252
+					$controller->get_model_version_info()->load_model($model_name_singular),
253
+					$request
254
+				)
255
+			);
256
+		} catch (\Exception $e) {
257
+			return $controller->send_response($e);
258
+		}
259
+	}
260
+
261
+
262
+
263
+	/**
264
+	 * Gets all the related entities (or if its a belongs-to relation just the one)
265
+	 * to the item with the given id
266
+	 *
267
+	 * @param \WP_REST_Request $request
268
+	 * @return \WP_REST_Response|\WP_Error
269
+	 */
270
+	public static function handle_request_get_related(\WP_REST_Request $request)
271
+	{
272
+		$controller = new Read();
273
+		try {
274
+			$matches = $controller->parse_route(
275
+				$request->get_route(),
276
+				'~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)/(.*)~',
277
+				array('version', 'model', 'id', 'related_model')
278
+			);
279
+			$controller->set_requested_version($matches['version']);
280
+			$main_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']);
281
+			if (! $controller->get_model_version_info()->is_model_name_in_this_version($main_model_name_singular)) {
282
+				return $controller->send_response(
283
+					new \WP_Error(
284
+						'endpoint_parsing_error',
285
+						sprintf(
286
+							__('There is no model for endpoint %s. Please contact event espresso support',
287
+								'event_espresso'),
288
+							$main_model_name_singular
289
+						)
290
+					)
291
+				);
292
+			}
293
+			$main_model = $controller->get_model_version_info()->load_model($main_model_name_singular);
294
+			//assume the related model name is plural and try to find the model's name
295
+			$related_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['related_model']);
296
+			if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) {
297
+				//so the word didn't singularize well. Maybe that's just because it's a singular word?
298
+				$related_model_name_singular = \EEH_Inflector::humanize($matches['related_model']);
299
+			}
300
+			if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) {
301
+				return $controller->send_response(
302
+					new \WP_Error(
303
+						'endpoint_parsing_error',
304
+						sprintf(
305
+							__('There is no model for endpoint %s. Please contact event espresso support',
306
+								'event_espresso'),
307
+							$related_model_name_singular
308
+						)
309
+					)
310
+				);
311
+			}
312
+			return $controller->send_response(
313
+				$controller->get_entities_from_relation(
314
+					$request->get_param('id'),
315
+					$main_model->related_settings_for($related_model_name_singular),
316
+					$request
317
+				)
318
+			);
319
+		} catch (\Exception $e) {
320
+			return $controller->send_response($e);
321
+		}
322
+	}
323
+
324
+
325
+
326
+	/**
327
+	 * Gets a collection for the given model and filters
328
+	 *
329
+	 * @param \EEM_Base        $model
330
+	 * @param \WP_REST_Request $request
331
+	 * @return array|\WP_Error
332
+	 */
333
+	public function get_entities_from_model($model, $request)
334
+	{
335
+		$query_params = $this->create_model_query_params($model, $request->get_params());
336
+		if (! Capabilities::current_user_has_partial_access_to($model, $query_params['caps'])) {
337
+			$model_name_plural = \EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
338
+			return new \WP_Error(
339
+				sprintf('rest_%s_cannot_list', $model_name_plural),
340
+				sprintf(
341
+					__('Sorry, you are not allowed to list %1$s. Missing permissions: %2$s', 'event_espresso'),
342
+					$model_name_plural,
343
+					Capabilities::get_missing_permissions_string($model, $query_params['caps'])
344
+				),
345
+				array('status' => 403)
346
+			);
347
+		}
348
+		if (! $request->get_header('no_rest_headers')) {
349
+			$this->_set_headers_from_query_params($model, $query_params);
350
+		}
351
+		/** @type array $results */
352
+		$results = $model->get_all_wpdb_results($query_params);
353
+		$nice_results = array();
354
+		foreach ($results as $result) {
355
+			$nice_results[] = $this->create_entity_from_wpdb_result(
356
+				$model,
357
+				$result,
358
+				$request
359
+			);
360
+		}
361
+		return $nice_results;
362
+	}
363
+
364
+
365
+
366
+	/**
367
+	 * @param array                   $primary_model_query_params query params for finding the item from which
368
+	 *                                                            relations will be based
369
+	 * @param \EE_Model_Relation_Base $relation
370
+	 * @param \WP_REST_Request        $request
371
+	 * @return \WP_Error|array
372
+	 */
373
+	protected function _get_entities_from_relation($primary_model_query_params, $relation, $request)
374
+	{
375
+		$context = $this->validate_context($request->get_param('caps'));
376
+		$model = $relation->get_this_model();
377
+		$related_model = $relation->get_other_model();
378
+		if (! isset($primary_model_query_params[0])) {
379
+			$primary_model_query_params[0] = array();
380
+		}
381
+		//check if they can access the 1st model object
382
+		$primary_model_query_params = array(
383
+			0       => $primary_model_query_params[0],
384
+			'limit' => 1,
385
+		);
386
+		if ($model instanceof \EEM_Soft_Delete_Base) {
387
+			$primary_model_query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($primary_model_query_params);
388
+		}
389
+		$restricted_query_params = $primary_model_query_params;
390
+		$restricted_query_params['caps'] = $context;
391
+		$this->_set_debug_info('main model query params', $restricted_query_params);
392
+		$this->_set_debug_info('missing caps', Capabilities::get_missing_permissions_string($related_model, $context));
393
+		if (
394
+		! (
395
+			Capabilities::current_user_has_partial_access_to($related_model, $context)
396
+			&& $model->exists($restricted_query_params)
397
+		)
398
+		) {
399
+			if ($relation instanceof \EE_Belongs_To_Relation) {
400
+				$related_model_name_maybe_plural = strtolower($related_model->get_this_model_name());
401
+			} else {
402
+				$related_model_name_maybe_plural = \EEH_Inflector::pluralize_and_lower($related_model->get_this_model_name());
403
+			}
404
+			return new \WP_Error(
405
+				sprintf('rest_%s_cannot_list', $related_model_name_maybe_plural),
406
+				sprintf(
407
+					__('Sorry, you are not allowed to list %1$s related to %2$s. Missing permissions: %3$s',
408
+						'event_espresso'),
409
+					$related_model_name_maybe_plural,
410
+					$relation->get_this_model()->get_this_model_name(),
411
+					implode(
412
+						',',
413
+						array_keys(
414
+							Capabilities::get_missing_permissions($related_model, $context)
415
+						)
416
+					)
417
+				),
418
+				array('status' => 403)
419
+			);
420
+		}
421
+		$query_params = $this->create_model_query_params($relation->get_other_model(), $request->get_params());
422
+		foreach ($primary_model_query_params[0] as $where_condition_key => $where_condition_value) {
423
+			$query_params[0][$relation->get_this_model()->get_this_model_name()
424
+							 . '.'
425
+							 . $where_condition_key] = $where_condition_value;
426
+		}
427
+		$query_params['default_where_conditions'] = 'none';
428
+		$query_params['caps'] = $context;
429
+		if (! $request->get_header('no_rest_headers')) {
430
+			$this->_set_headers_from_query_params($relation->get_other_model(), $query_params);
431
+		}
432
+		/** @type array $results */
433
+		$results = $relation->get_other_model()->get_all_wpdb_results($query_params);
434
+		$nice_results = array();
435
+		foreach ($results as $result) {
436
+			$nice_result = $this->create_entity_from_wpdb_result(
437
+				$relation->get_other_model(),
438
+				$result,
439
+				$request
440
+			);
441
+			if ($relation instanceof \EE_HABTM_Relation) {
442
+				//put the unusual stuff (properties from the HABTM relation) first, and make sure
443
+				//if there are conflicts we prefer the properties from the main model
444
+				$join_model_result = $this->create_entity_from_wpdb_result(
445
+					$relation->get_join_model(),
446
+					$result,
447
+					$request
448
+				);
449
+				$joined_result = array_merge($nice_result, $join_model_result);
450
+				//but keep the meta stuff from the main model
451
+				if (isset($nice_result['meta'])) {
452
+					$joined_result['meta'] = $nice_result['meta'];
453
+				}
454
+				$nice_result = $joined_result;
455
+			}
456
+			$nice_results[] = $nice_result;
457
+		}
458
+		if ($relation instanceof \EE_Belongs_To_Relation) {
459
+			return array_shift($nice_results);
460
+		} else {
461
+			return $nice_results;
462
+		}
463
+	}
464
+
465
+
466
+
467
+	/**
468
+	 * Gets the collection for given relation object
469
+	 * The same as Read::get_entities_from_model(), except if the relation
470
+	 * is a HABTM relation, in which case it merges any non-foreign-key fields from
471
+	 * the join-model-object into the results
472
+	 *
473
+	 * @param string                  $id the ID of the thing we are fetching related stuff from
474
+	 * @param \EE_Model_Relation_Base $relation
475
+	 * @param \WP_REST_Request        $request
476
+	 * @return array|\WP_Error
477
+	 * @throws \EE_Error
478
+	 */
479
+	public function get_entities_from_relation($id, $relation, $request)
480
+	{
481
+		if (! $relation->get_this_model()->has_primary_key_field()) {
482
+			throw new \EE_Error(
483
+				sprintf(
484
+					__('Read::get_entities_from_relation should only be called from a model with a primary key, it was called from %1$s',
485
+						'event_espresso'),
486
+					$relation->get_this_model()->get_this_model_name()
487
+				)
488
+			);
489
+		}
490
+		return $this->_get_entities_from_relation(
491
+			array(
492
+				array(
493
+					$relation->get_this_model()->primary_key_name() => $id,
494
+				),
495
+			),
496
+			$relation,
497
+			$request
498
+		);
499
+	}
500
+
501
+
502
+
503
+	/**
504
+	 * Sets the headers that are based on the model and query params,
505
+	 * like the total records. This should only be called on the original request
506
+	 * from the client, not on subsequent internal
507
+	 *
508
+	 * @param \EEM_Base $model
509
+	 * @param array     $query_params
510
+	 * @return void
511
+	 */
512
+	protected function _set_headers_from_query_params($model, $query_params)
513
+	{
514
+		$this->_set_debug_info('model query params', $query_params);
515
+		$this->_set_debug_info('missing caps',
516
+			Capabilities::get_missing_permissions_string($model, $query_params['caps']));
517
+		//normally the limit to a 2-part array, where the 2nd item is the limit
518
+		if (! isset($query_params['limit'])) {
519
+			$query_params['limit'] = \EED_Core_Rest_Api::get_default_query_limit();
520
+		}
521
+		if (is_array($query_params['limit'])) {
522
+			$limit_parts = $query_params['limit'];
523
+		} else {
524
+			$limit_parts = explode(',', $query_params['limit']);
525
+			if (count($limit_parts) == 1) {
526
+				$limit_parts = array(0, $limit_parts[0]);
527
+			}
528
+		}
529
+		//remove the group by and having parts of the query, as those will
530
+		//make the sql query return an array of values, instead of just a single value
531
+		unset($query_params['group_by'], $query_params['having'], $query_params['limit']);
532
+		$count = $model->count($query_params, null, true);
533
+		$pages = $count / $limit_parts[1];
534
+		$this->_set_response_header('Total', $count, false);
535
+		$this->_set_response_header('PageSize', $limit_parts[1], false);
536
+		$this->_set_response_header('TotalPages', ceil($pages), false);
537
+	}
538
+
539
+
540
+
541
+	/**
542
+	 * Changes database results into REST API entities
543
+	 *
544
+	 * @param \EEM_Base        $model
545
+	 * @param array            $db_row     like results from $wpdb->get_results()
546
+	 * @param \WP_REST_Request $rest_request
547
+	 * @param string           $deprecated no longer used
548
+	 * @return array ready for being converted into json for sending to client
549
+	 */
550
+	public function create_entity_from_wpdb_result($model, $db_row, $rest_request, $deprecated = null)
551
+	{
552
+		if (! $rest_request instanceof \WP_REST_Request) {
553
+			//ok so this was called in the old style, where the 3rd arg was
554
+			//$include, and the 4th arg was $context
555
+			//now setup the request just to avoid fatal errors, although we won't be able
556
+			//to truly make use of it because it's kinda devoid of info
557
+			$rest_request = new \WP_REST_Request();
558
+			$rest_request->set_param('include', $rest_request);
559
+			$rest_request->set_param('caps', $deprecated);
560
+		}
561
+		if ($rest_request->get_param('caps') == null) {
562
+			$rest_request->set_param('caps', \EEM_Base::caps_read);
563
+		}
564
+		$entity_array = $this->_create_bare_entity_from_wpdb_results($model, $db_row);
565
+		$entity_array = $this->_add_extra_fields($model, $db_row, $entity_array);
566
+		$entity_array['_links'] = $this->_get_entity_links($model, $db_row, $entity_array);
567
+		$entity_array['_calculated_fields'] = $this->_get_entity_calculations($model, $db_row, $rest_request);
568
+		$entity_array = $this->_include_requested_models($model, $rest_request, $entity_array, $db_row);
569
+		$entity_array = apply_filters(
570
+			'FHEE__Read__create_entity_from_wpdb_results__entity_before_inaccessible_field_removal',
571
+			$entity_array,
572
+			$model,
573
+			$rest_request->get_param('caps'),
574
+			$rest_request,
575
+			$this
576
+		);
577
+		$result_without_inaccessible_fields = Capabilities::filter_out_inaccessible_entity_fields(
578
+			$entity_array,
579
+			$model,
580
+			$rest_request->get_param('caps'),
581
+			$this->get_model_version_info(),
582
+			$model->get_index_primary_key_string(
583
+				$model->deduce_fields_n_values_from_cols_n_values($db_row)
584
+			)
585
+		);
586
+		$this->_set_debug_info(
587
+			'inaccessible fields',
588
+			array_keys(array_diff_key($entity_array, $result_without_inaccessible_fields))
589
+		);
590
+		return apply_filters(
591
+			'FHEE__Read__create_entity_from_wpdb_results__entity_return',
592
+			$result_without_inaccessible_fields,
593
+			$model,
594
+			$rest_request->get_param('caps')
595
+		);
596
+	}
597
+
598
+
599
+
600
+	/**
601
+	 * Creates a REST entity array (JSON object we're going to return in the response, but
602
+	 * for now still a PHP array, but soon enough we'll call json_encode on it, don't worry),
603
+	 * from $wpdb->get_row( $sql, ARRAY_A)
604
+	 *
605
+	 * @param \EEM_Base $model
606
+	 * @param array     $db_row
607
+	 * @return array entity mostly ready for converting to JSON and sending in the response
608
+	 */
609
+	protected function _create_bare_entity_from_wpdb_results(\EEM_Base $model, $db_row)
610
+	{
611
+		$result = $model->deduce_fields_n_values_from_cols_n_values($db_row);
612
+		$result = array_intersect_key($result,
613
+			$this->get_model_version_info()->fields_on_model_in_this_version($model));
614
+		foreach ($result as $field_name => $raw_field_value) {
615
+			$field_obj = $model->field_settings_for($field_name);
616
+			$field_value = $field_obj->prepare_for_set_from_db($raw_field_value);
617
+			if ($this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_ignored())) {
618
+				unset($result[$field_name]);
619
+			} elseif (
620
+			$this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_rendered_format())
621
+			) {
622
+				$result[$field_name] = array(
623
+					'raw'      => $field_obj->prepare_for_get($field_value),
624
+					'rendered' => $field_obj->prepare_for_pretty_echoing($field_value),
625
+				);
626
+			} elseif (
627
+			$this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_pretty_format())
628
+			) {
629
+				$result[$field_name] = array(
630
+					'raw'    => $field_obj->prepare_for_get($field_value),
631
+					'pretty' => $field_obj->prepare_for_pretty_echoing($field_value),
632
+				);
633
+			} elseif ($field_obj instanceof \EE_Datetime_Field) {
634
+				if ($field_value instanceof \DateTime) {
635
+					$timezone = $field_value->getTimezone();
636
+					$field_value->setTimezone(new \DateTimeZone('UTC'));
637
+					$result[$field_name . '_gmt'] = Model_Data_Translator::prepare_field_value_for_json(
638
+						$field_obj,
639
+						$field_value,
640
+						$this->get_model_version_info()->requested_version()
641
+					);
642
+					$field_value->setTimezone($timezone);
643
+					$result[$field_name] = Model_Data_Translator::prepare_field_value_for_json(
644
+						$field_obj,
645
+						$field_value,
646
+						$this->get_model_version_info()->requested_version()
647
+					);
648
+				}
649
+			} else {
650
+				$result[$field_name] = Model_Data_Translator::prepare_field_value_for_json(
651
+					$field_obj,
652
+					$field_obj->prepare_for_get($field_value),
653
+					$this->get_model_version_info()->requested_version()
654
+				);
655
+			}
656
+		}
657
+		return $result;
658
+	}
659
+
660
+
661
+
662
+	/**
663
+	 * Adds a few extra fields to the entity response
664
+	 *
665
+	 * @param \EEM_Base $model
666
+	 * @param array     $db_row
667
+	 * @param array     $entity_array
668
+	 * @return array modified entity
669
+	 */
670
+	protected function _add_extra_fields(\EEM_Base $model, $db_row, $entity_array)
671
+	{
672
+		if ($model instanceof \EEM_CPT_Base) {
673
+			$entity_array['link'] = get_permalink($db_row[$model->get_primary_key_field()->get_qualified_column()]);
674
+		}
675
+		return $entity_array;
676
+	}
677
+
678
+
679
+
680
+	/**
681
+	 * Gets links we want to add to the response
682
+	 *
683
+	 * @global \WP_REST_Server $wp_rest_server
684
+	 * @param \EEM_Base        $model
685
+	 * @param array            $db_row
686
+	 * @param array            $entity_array
687
+	 * @return array the _links item in the entity
688
+	 */
689
+	protected function _get_entity_links($model, $db_row, $entity_array)
690
+	{
691
+		//add basic links
692
+		$links = array();
693
+		if ($model->has_primary_key_field()) {
694
+			$links['self'] = array(
695
+				array(
696
+					'href' => $this->get_versioned_link_to(
697
+						\EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
698
+						. '/'
699
+						. $entity_array[$model->primary_key_name()]
700
+					),
701
+				),
702
+			);
703
+		}
704
+		$links['collection'] = array(
705
+			array(
706
+				'href' => $this->get_versioned_link_to(
707
+					\EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
708
+				),
709
+			),
710
+		);
711
+		//add links to related models
712
+		if ($model->has_primary_key_field()) {
713
+			foreach ($this->get_model_version_info()->relation_settings($model) as $relation_name => $relation_obj) {
714
+				$related_model_part = Read::get_related_entity_name($relation_name, $relation_obj);
715
+				$links[\EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part] = array(
716
+					array(
717
+						'href'   => $this->get_versioned_link_to(
718
+							\EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
719
+							. '/'
720
+							. $entity_array[$model->primary_key_name()]
721
+							. '/'
722
+							. $related_model_part
723
+						),
724
+						'single' => $relation_obj instanceof \EE_Belongs_To_Relation ? true : false,
725
+					),
726
+				);
727
+			}
728
+		}
729
+		return $links;
730
+	}
731
+
732
+
733
+
734
+	/**
735
+	 * Adds the included models indicated in the request to the entity provided
736
+	 *
737
+	 * @param \EEM_Base        $model
738
+	 * @param \WP_REST_Request $rest_request
739
+	 * @param array            $entity_array
740
+	 * @param array            $db_row
741
+	 * @return array the modified entity
742
+	 */
743
+	protected function _include_requested_models(
744
+		\EEM_Base $model,
745
+		\WP_REST_Request $rest_request,
746
+		$entity_array,
747
+		$db_row = array()
748
+	) {
749
+		//if $db_row not included, hope the entity array has what we need
750
+		if (! $db_row) {
751
+			$db_row = $entity_array;
752
+		}
753
+		$includes_for_this_model = $this->explode_and_get_items_prefixed_with($rest_request->get_param('include'), '');
754
+		$includes_for_this_model = $this->_remove_model_names_from_array($includes_for_this_model);
755
+		//if they passed in * or didn't specify any includes, return everything
756
+		if (! in_array('*', $includes_for_this_model)
757
+			&& ! empty($includes_for_this_model)
758
+		) {
759
+			if ($model->has_primary_key_field()) {
760
+				//always include the primary key. ya just gotta know that at least
761
+				$includes_for_this_model[] = $model->primary_key_name();
762
+			}
763
+			if ($this->explode_and_get_items_prefixed_with($rest_request->get_param('calculate'), '')) {
764
+				$includes_for_this_model[] = '_calculated_fields';
765
+			}
766
+			$entity_array = array_intersect_key($entity_array, array_flip($includes_for_this_model));
767
+		}
768
+		$relation_settings = $this->get_model_version_info()->relation_settings($model);
769
+		foreach ($relation_settings as $relation_name => $relation_obj) {
770
+			$related_fields_to_include = $this->explode_and_get_items_prefixed_with(
771
+				$rest_request->get_param('include'),
772
+				$relation_name
773
+			);
774
+			$related_fields_to_calculate = $this->explode_and_get_items_prefixed_with(
775
+				$rest_request->get_param('calculate'),
776
+				$relation_name
777
+			);
778
+			//did they specify they wanted to include a related model, or
779
+			//specific fields from a related model?
780
+			//or did they specify to calculate a field from a related model?
781
+			if ($related_fields_to_include || $related_fields_to_calculate) {
782
+				//if so, we should include at least some part of the related model
783
+				$pretend_related_request = new \WP_REST_Request();
784
+				$pretend_related_request->set_query_params(
785
+					array(
786
+						'caps'      => $rest_request->get_param('caps'),
787
+						'include'   => $related_fields_to_include,
788
+						'calculate' => $related_fields_to_calculate,
789
+					)
790
+				);
791
+				$pretend_related_request->add_header('no_rest_headers', true);
792
+				$primary_model_query_params = $model->alter_query_params_to_restrict_by_ID(
793
+					$model->get_index_primary_key_string(
794
+						$model->deduce_fields_n_values_from_cols_n_values($db_row)
795
+					)
796
+				);
797
+				$related_results = $this->_get_entities_from_relation(
798
+					$primary_model_query_params,
799
+					$relation_obj,
800
+					$pretend_related_request
801
+				);
802
+				$entity_array[Read::get_related_entity_name($relation_name, $relation_obj)] = $related_results
803
+																							  instanceof
804
+																							  \WP_Error
805
+					? null
806
+					: $related_results;
807
+			}
808
+		}
809
+		return $entity_array;
810
+	}
811
+
812
+
813
+
814
+	/**
815
+	 * Returns a new array with all the names of models removed. Eg
816
+	 * array( 'Event', 'Datetime.*', 'foobar' ) would become array( 'Datetime.*', 'foobar' )
817
+	 *
818
+	 * @param array $arr
819
+	 * @return array
820
+	 */
821
+	private function _remove_model_names_from_array($arr)
822
+	{
823
+		return array_diff($arr, array_keys(\EE_Registry::instance()->non_abstract_db_models));
824
+	}
825
+
826
+
827
+
828
+	/**
829
+	 * Gets the calculated fields for the response
830
+	 *
831
+	 * @param \EEM_Base        $model
832
+	 * @param array            $wpdb_row
833
+	 * @param \WP_REST_Request $rest_request
834
+	 * @return \stdClass the _calculations item in the entity
835
+	 */
836
+	protected function _get_entity_calculations($model, $wpdb_row, $rest_request)
837
+	{
838
+		$calculated_fields = $this->explode_and_get_items_prefixed_with(
839
+			$rest_request->get_param('calculate'),
840
+			''
841
+		);
842
+		//note: setting calculate=* doesn't do anything
843
+		$calculated_fields_to_return = new \stdClass();
844
+		foreach ($calculated_fields as $field_to_calculate) {
845
+			try {
846
+				$calculated_fields_to_return->$field_to_calculate = Model_Data_Translator::prepare_field_value_for_json(
847
+					null,
848
+					$this->_fields_calculator->retrieve_calculated_field_value(
849
+						$model,
850
+						$field_to_calculate,
851
+						$wpdb_row,
852
+						$rest_request,
853
+						$this
854
+					),
855
+					$this->get_model_version_info()->requested_version()
856
+				);
857
+			} catch (Rest_Exception $e) {
858
+				//if we don't have permission to read it, just leave it out. but let devs know about the problem
859
+				$this->_set_response_header(
860
+					'Notices-Field-Calculation-Errors['
861
+					. $e->get_string_code()
862
+					. ']['
863
+					. $model->get_this_model_name()
864
+					. ']['
865
+					. $field_to_calculate
866
+					. ']',
867
+					$e->getMessage(),
868
+					true
869
+				);
870
+			}
871
+		}
872
+		return $calculated_fields_to_return;
873
+	}
874
+
875
+
876
+
877
+	/**
878
+	 * Gets the full URL to the resource, taking the requested version into account
879
+	 *
880
+	 * @param string $link_part_after_version_and_slash eg "events/10/datetimes"
881
+	 * @return string url eg "http://mysite.com/wp-json/ee/v4.6/events/10/datetimes"
882
+	 */
883
+	public function get_versioned_link_to($link_part_after_version_and_slash)
884
+	{
885
+		return rest_url(
886
+			\EED_Core_Rest_Api::ee_api_namespace
887
+			. $this->get_model_version_info()->requested_version()
888
+			. '/'
889
+			. $link_part_after_version_and_slash
890
+		);
891
+	}
892
+
893
+
894
+
895
+	/**
896
+	 * Gets the correct lowercase name for the relation in the API according
897
+	 * to the relation's type
898
+	 *
899
+	 * @param string                  $relation_name
900
+	 * @param \EE_Model_Relation_Base $relation_obj
901
+	 * @return string
902
+	 */
903
+	public static function get_related_entity_name($relation_name, $relation_obj)
904
+	{
905
+		if ($relation_obj instanceof \EE_Belongs_To_Relation) {
906
+			return strtolower($relation_name);
907
+		} else {
908
+			return \EEH_Inflector::pluralize_and_lower($relation_name);
909
+		}
910
+	}
911
+
912
+
913
+
914
+	/**
915
+	 * Gets the one model object with the specified id for the specified model
916
+	 *
917
+	 * @param \EEM_Base        $model
918
+	 * @param \WP_REST_Request $request
919
+	 * @return array|\WP_Error
920
+	 */
921
+	public function get_entity_from_model($model, $request)
922
+	{
923
+		$query_params = array(array($model->primary_key_name() => $request->get_param('id')), 'limit' => 1);
924
+		if ($model instanceof \EEM_Soft_Delete_Base) {
925
+			$query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($query_params);
926
+		}
927
+		$restricted_query_params = $query_params;
928
+		$restricted_query_params['caps'] = $this->validate_context($request->get_param('caps'));
929
+		$this->_set_debug_info('model query params', $restricted_query_params);
930
+		$model_rows = $model->get_all_wpdb_results($restricted_query_params);
931
+		if (! empty ($model_rows)) {
932
+			return $this->create_entity_from_wpdb_result(
933
+				$model,
934
+				array_shift($model_rows),
935
+				$request);
936
+		} else {
937
+			//ok let's test to see if we WOULD have found it, had we not had restrictions from missing capabilities
938
+			$lowercase_model_name = strtolower($model->get_this_model_name());
939
+			$model_rows_found_sans_restrictions = $model->get_all_wpdb_results($query_params);
940
+			if (! empty($model_rows_found_sans_restrictions)) {
941
+				//you got shafted- it existed but we didn't want to tell you!
942
+				return new \WP_Error(
943
+					'rest_user_cannot_read',
944
+					sprintf(
945
+						__('Sorry, you cannot read this %1$s. Missing permissions are: %2$s', 'event_espresso'),
946
+						strtolower($model->get_this_model_name()),
947
+						Capabilities::get_missing_permissions_string(
948
+							$model,
949
+							$this->validate_context($request->get_param('caps')))
950
+					),
951
+					array('status' => 403)
952
+				);
953
+			} else {
954
+				//it's not you. It just doesn't exist
955
+				return new \WP_Error(
956
+					sprintf('rest_%s_invalid_id', $lowercase_model_name),
957
+					sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
958
+					array('status' => 404)
959
+				);
960
+			}
961
+		}
962
+	}
963
+
964
+
965
+
966
+	/**
967
+	 * If a context is provided which isn't valid, maybe it was added in a future
968
+	 * version so just treat it as a default read
969
+	 *
970
+	 * @param string $context
971
+	 * @return string array key of EEM_Base::cap_contexts_to_cap_action_map()
972
+	 */
973
+	public function validate_context($context)
974
+	{
975
+		if (! $context) {
976
+			$context = \EEM_Base::caps_read;
977
+		}
978
+		$valid_contexts = \EEM_Base::valid_cap_contexts();
979
+		if (in_array($context, $valid_contexts)) {
980
+			return $context;
981
+		} else {
982
+			return \EEM_Base::caps_read;
983
+		}
984
+	}
985
+
986
+
987
+
988
+	/**
989
+	 * Verifies the passed in value is an allowable default where conditions value.
990
+	 *
991
+	 * @param $default_query_params
992
+	 * @return string
993
+	 */
994
+	public function validate_default_query_params($default_query_params)
995
+	{
996
+		$valid_default_where_conditions_for_api_calls = array(
997
+			\EEM_Base::default_where_conditions_all,
998
+			\EEM_Base::default_where_conditions_minimum_all,
999
+			\EEM_Base::default_where_conditions_minimum_others,
1000
+		);
1001
+		if (! $default_query_params) {
1002
+			$default_query_params = \EEM_Base::default_where_conditions_all;
1003
+		}
1004
+		if (
1005
+		in_array(
1006
+			$default_query_params,
1007
+			$valid_default_where_conditions_for_api_calls,
1008
+			true
1009
+		)
1010
+		) {
1011
+			return $default_query_params;
1012
+		} else {
1013
+			return \EEM_Base::default_where_conditions_all;
1014
+		}
1015
+	}
1016
+
1017
+
1018
+
1019
+	/**
1020
+	 * Translates API filter get parameter into $query_params array used by EEM_Base::get_all().
1021
+	 * Note: right now the query parameter keys for fields (and related fields)
1022
+	 * can be left as-is, but it's quite possible this will change someday.
1023
+	 * Also, this method's contents might be candidate for moving to Model_Data_Translator
1024
+	 *
1025
+	 * @param \EEM_Base $model
1026
+	 * @param array     $query_parameters from $_GET parameter @see Read:handle_request_get_all
1027
+	 * @return array like what EEM_Base::get_all() expects or FALSE to indicate
1028
+	 *                                    that absolutely no results should be returned
1029
+	 * @throws \EE_Error
1030
+	 */
1031
+	public function create_model_query_params($model, $query_parameters)
1032
+	{
1033
+		$model_query_params = array();
1034
+		if (isset($query_parameters['where'])) {
1035
+			$model_query_params[0] = Model_Data_Translator::prepare_conditions_query_params_for_models(
1036
+				$query_parameters['where'],
1037
+				$model,
1038
+				$this->get_model_version_info()->requested_version()
1039
+			);
1040
+		}
1041
+		if (isset($query_parameters['order_by'])) {
1042
+			$order_by = $query_parameters['order_by'];
1043
+		} elseif (isset($query_parameters['orderby'])) {
1044
+			$order_by = $query_parameters['orderby'];
1045
+		} else {
1046
+			$order_by = null;
1047
+		}
1048
+		if ($order_by !== null) {
1049
+			if (is_array($order_by)) {
1050
+				$order_by = Model_Data_Translator::prepare_field_names_in_array_keys_from_json($order_by);
1051
+			} else {
1052
+				//it's a single item
1053
+				$order_by = Model_Data_Translator::prepare_field_name_from_json($order_by);
1054
+			}
1055
+			$model_query_params['order_by'] = $order_by;
1056
+		}
1057
+		if (isset($query_parameters['group_by'])) {
1058
+			$group_by = $query_parameters['group_by'];
1059
+		} elseif (isset($query_parameters['groupby'])) {
1060
+			$group_by = $query_parameters['groupby'];
1061
+		} else {
1062
+			$group_by = array_keys($model->get_combined_primary_key_fields());
1063
+		}
1064
+		//make sure they're all real names
1065
+		if (is_array($group_by)) {
1066
+			$group_by = Model_Data_Translator::prepare_field_names_from_json($group_by);
1067
+		}
1068
+		if ($group_by !== null) {
1069
+			$model_query_params['group_by'] = $group_by;
1070
+		}
1071
+		if (isset($query_parameters['having'])) {
1072
+			$model_query_params['having'] = Model_Data_Translator::prepare_conditions_query_params_for_models(
1073
+				$query_parameters['having'],
1074
+				$model,
1075
+				$this->get_model_version_info()->requested_version()
1076
+			);
1077
+		}
1078
+		if (isset($query_parameters['order'])) {
1079
+			$model_query_params['order'] = $query_parameters['order'];
1080
+		}
1081
+		if (isset($query_parameters['mine'])) {
1082
+			$model_query_params = $model->alter_query_params_to_only_include_mine($model_query_params);
1083
+		}
1084
+		if (isset($query_parameters['limit'])) {
1085
+			//limit should be either a string like '23' or '23,43', or an array with two items in it
1086
+			if (! is_array($query_parameters['limit'])) {
1087
+				$limit_array = explode(',', (string)$query_parameters['limit']);
1088
+			} else {
1089
+				$limit_array = $query_parameters['limit'];
1090
+			}
1091
+			$sanitized_limit = array();
1092
+			foreach ($limit_array as $key => $limit_part) {
1093
+				if ($this->_debug_mode && (! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1094
+					throw new \EE_Error(
1095
+						sprintf(
1096
+							__('An invalid limit filter was provided. It was: %s. If the EE4 JSON REST API weren\'t in debug mode, this message would not appear.',
1097
+								'event_espresso'),
1098
+							wp_json_encode($query_parameters['limit'])
1099
+						)
1100
+					);
1101
+				}
1102
+				$sanitized_limit[] = (int)$limit_part;
1103
+			}
1104
+			$model_query_params['limit'] = implode(',', $sanitized_limit);
1105
+		} else {
1106
+			$model_query_params['limit'] = \EED_Core_Rest_Api::get_default_query_limit();
1107
+		}
1108
+		if (isset($query_parameters['caps'])) {
1109
+			$model_query_params['caps'] = $this->validate_context($query_parameters['caps']);
1110
+		} else {
1111
+			$model_query_params['caps'] = \EEM_Base::caps_read;
1112
+		}
1113
+		if (isset($query_parameters['default_where_conditions'])) {
1114
+			$model_query_params['default_where_conditions'] = $this->validate_default_query_params($query_parameters['default_where_conditions']);
1115
+		}
1116
+		return apply_filters('FHEE__Read__create_model_query_params', $model_query_params, $query_parameters, $model);
1117
+	}
1118
+
1119
+
1120
+
1121
+	/**
1122
+	 * Changes the REST-style query params for use in the models
1123
+	 *
1124
+	 * @deprecated
1125
+	 * @param \EEM_Base $model
1126
+	 * @param array     $query_params sub-array from @see EEM_Base::get_all()
1127
+	 * @return array
1128
+	 */
1129
+	public function prepare_rest_query_params_key_for_models($model, $query_params)
1130
+	{
1131
+		$model_ready_query_params = array();
1132
+		foreach ($query_params as $key => $value) {
1133
+			if (is_array($value)) {
1134
+				$model_ready_query_params[$key] = $this->prepare_rest_query_params_key_for_models($model, $value);
1135
+			} else {
1136
+				$model_ready_query_params[$key] = $value;
1137
+			}
1138
+		}
1139
+		return $model_ready_query_params;
1140
+	}
1141
+
1142
+
1143
+
1144
+	/**
1145
+	 * @deprecated
1146
+	 * @param $model
1147
+	 * @param $query_params
1148
+	 * @return array
1149
+	 */
1150
+	public function prepare_rest_query_params_values_for_models($model, $query_params)
1151
+	{
1152
+		$model_ready_query_params = array();
1153
+		foreach ($query_params as $key => $value) {
1154
+			if (is_array($value)) {
1155
+				$model_ready_query_params[$key] = $this->prepare_rest_query_params_values_for_models($model, $value);
1156
+			} else {
1157
+				$model_ready_query_params[$key] = $value;
1158
+			}
1159
+		}
1160
+		return $model_ready_query_params;
1161
+	}
1162
+
1163
+
1164
+
1165
+	/**
1166
+	 * Explodes the string on commas, and only returns items with $prefix followed by a period.
1167
+	 * If no prefix is specified, returns items with no period.
1168
+	 *
1169
+	 * @param string|array $string_to_explode eg "jibba,jabba, blah, blaabla" or array('jibba', 'jabba' )
1170
+	 * @param string       $prefix            "Event" or "foobar"
1171
+	 * @return array $string_to_exploded exploded on COMMAS, and if a prefix was specified
1172
+	 *                                        we only return strings starting with that and a period; if no prefix was
1173
+	 *                                        specified we return all items containing NO periods
1174
+	 */
1175
+	public function explode_and_get_items_prefixed_with($string_to_explode, $prefix)
1176
+	{
1177
+		if (is_string($string_to_explode)) {
1178
+			$exploded_contents = explode(',', $string_to_explode);
1179
+		} else if (is_array($string_to_explode)) {
1180
+			$exploded_contents = $string_to_explode;
1181
+		} else {
1182
+			$exploded_contents = array();
1183
+		}
1184
+		//if the string was empty, we want an empty array
1185
+		$exploded_contents = array_filter($exploded_contents);
1186
+		$contents_with_prefix = array();
1187
+		foreach ($exploded_contents as $item) {
1188
+			$item = trim($item);
1189
+			//if no prefix was provided, so we look for items with no "." in them
1190
+			if (! $prefix) {
1191
+				//does this item have a period?
1192
+				if (strpos($item, '.') === false) {
1193
+					//if not, then its what we're looking for
1194
+					$contents_with_prefix[] = $item;
1195
+				}
1196
+			} else if (strpos($item, $prefix . '.') === 0) {
1197
+				//this item has the prefix and a period, grab it
1198
+				$contents_with_prefix[] = substr(
1199
+					$item,
1200
+					strpos($item, $prefix . '.') + strlen($prefix . '.')
1201
+				);
1202
+			} else if ($item === $prefix) {
1203
+				//this item is JUST the prefix
1204
+				//so let's grab everything after, which is a blank string
1205
+				$contents_with_prefix[] = '';
1206
+			}
1207
+		}
1208
+		return $contents_with_prefix;
1209
+	}
1210
+
1211
+
1212
+
1213
+	/**
1214
+	 * @deprecated since 4.8.36.rc.001 You should instead use Read::explode_and_get_items_prefixed_with.
1215
+	 * Deprecated because its return values were really quite confusing- sometimes it returned
1216
+	 * an empty array (when the include string was blank or '*') or sometimes it returned
1217
+	 * array('*') (when you provided a model and a model of that kind was found).
1218
+	 * Parses the $include_string so we fetch all the field names relating to THIS model
1219
+	 * (ie have NO period in them), or for the provided model (ie start with the model
1220
+	 * name and then a period).
1221
+	 * @param string $include_string @see Read:handle_request_get_all
1222
+	 * @param string $model_name
1223
+	 * @return array of fields for this model. If $model_name is provided, then
1224
+	 *                               the fields for that model, with the model's name removed from each.
1225
+	 *                               If $include_string was blank or '*' returns an empty array
1226
+	 */
1227
+	public function extract_includes_for_this_model($include_string, $model_name = null)
1228
+	{
1229
+		if (is_array($include_string)) {
1230
+			$include_string = implode(',', $include_string);
1231
+		}
1232
+		if ($include_string === '*' || $include_string === '') {
1233
+			return array();
1234
+		}
1235
+		$includes = explode(',', $include_string);
1236
+		$extracted_fields_to_include = array();
1237
+		if ($model_name) {
1238
+			foreach ($includes as $field_to_include) {
1239
+				$field_to_include = trim($field_to_include);
1240
+				if (strpos($field_to_include, $model_name . '.') === 0) {
1241
+					//found the model name at the exact start
1242
+					$field_sans_model_name = str_replace($model_name . '.', '', $field_to_include);
1243
+					$extracted_fields_to_include[] = $field_sans_model_name;
1244
+				} elseif ($field_to_include == $model_name) {
1245
+					$extracted_fields_to_include[] = '*';
1246
+				}
1247
+			}
1248
+		} else {
1249
+			//look for ones with no period
1250
+			foreach ($includes as $field_to_include) {
1251
+				$field_to_include = trim($field_to_include);
1252
+				if (
1253
+					strpos($field_to_include, '.') === false
1254
+					&& ! $this->get_model_version_info()->is_model_name_in_this_version($field_to_include)
1255
+				) {
1256
+					$extracted_fields_to_include[] = $field_to_include;
1257
+				}
1258
+			}
1259
+		}
1260
+		return $extracted_fields_to_include;
1261
+	}
1262 1262
 }
1263 1263
 
1264 1264
 
Please login to merge, or discard this patch.
admin/extend/registrations/EE_Event_Registrations_List_Table.class.php 2 patches
Indentation   +63 added lines, -63 removed lines patch added patch discarded remove patch
@@ -87,7 +87,7 @@  discard block
 block discarded – undo
87 87
 		$this->_columns = array_merge( $columns, $this->_columns );
88 88
 		$this->_primary_column = '_REG_att_checked_in';
89 89
 		if ( ! empty( $evt_id )
90
-		     && EE_Registry::instance()->CAP->current_user_can(
90
+			 && EE_Registry::instance()->CAP->current_user_can(
91 91
 				'ee_read_registrations',
92 92
 				'espresso_registrations_registrations_reports',
93 93
 				$evt_id
@@ -104,44 +104,44 @@  discard block
 block discarded – undo
104 104
 				),
105 105
 			);
106 106
 		}
107
-        $this->_bottom_buttons['report_filtered'] = array(
108
-            'route'         => 'registrations_checkin_report',
109
-            'extra_request' => array(
110
-                'use_filters' => true,
111
-                'filters'     => array_merge(
112
-                    array(
113
-                        'EVT_ID' => $evt_id,
114
-                    ),
115
-                    array_diff_key(
116
-                        $this->_req_data,
117
-                        array_flip(
118
-                            array(
119
-                                'page',
120
-                                'action',
121
-                                'default_nonce',
122
-                            )
123
-                        )
124
-                    )
125
-                ),
126
-                'return_url'  => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"),
127
-            ),
128
-        );
107
+		$this->_bottom_buttons['report_filtered'] = array(
108
+			'route'         => 'registrations_checkin_report',
109
+			'extra_request' => array(
110
+				'use_filters' => true,
111
+				'filters'     => array_merge(
112
+					array(
113
+						'EVT_ID' => $evt_id,
114
+					),
115
+					array_diff_key(
116
+						$this->_req_data,
117
+						array_flip(
118
+							array(
119
+								'page',
120
+								'action',
121
+								'default_nonce',
122
+							)
123
+						)
124
+					)
125
+				),
126
+				'return_url'  => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"),
127
+			),
128
+		);
129 129
 		$this->_sortable_columns = array(
130
-            /**
131
-             * Allows users to change the default sort if they wish.
132
-             * Returning a falsey on this filter will result in the default sort to be by firstname rather than last name.
133
-             *
134
-             * Note: usual naming conventions for filters aren't followed here so that just one filter can be used to
135
-             * change the sorts on any list table involving registration contacts.  If you want to only change the filter
136
-             * for a specific list table you can use the provided reference to this object instance.
137
-             */
130
+			/**
131
+			 * Allows users to change the default sort if they wish.
132
+			 * Returning a falsey on this filter will result in the default sort to be by firstname rather than last name.
133
+			 *
134
+			 * Note: usual naming conventions for filters aren't followed here so that just one filter can be used to
135
+			 * change the sorts on any list table involving registration contacts.  If you want to only change the filter
136
+			 * for a specific list table you can use the provided reference to this object instance.
137
+			 */
138 138
 			'ATT_name' => array(
139
-                    'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name',
140
-                    true,
141
-                    $this
142
-                )
143
-                ? array( 'ATT_lname' => true )
144
-                : array( 'ATT_fname' => true ),
139
+					'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name',
140
+					true,
141
+					$this
142
+				)
143
+				? array( 'ATT_lname' => true )
144
+				: array( 'ATT_fname' => true ),
145 145
 			'Event'    => array( 'Event.EVT.Name' => false ),
146 146
 		);
147 147
 		$this->_hidden_columns = array();
@@ -200,7 +200,7 @@  discard block
 block discarded – undo
200 200
 				if ( ! $evt->get_count_of_all_registrations() ) {
201 201
 					continue;
202 202
 				}
203
-                                $evts[] = array(
203
+								$evts[] = array(
204 204
 					'id'    => $evt->ID(),
205 205
 					'text'  => apply_filters('FHEE__EE_Event_Registrations___get_table_filters__event_name', $evt->get( 'EVT_name' ), $evt),
206 206
 					'class' => $evt->is_expired() ? 'ee-expired-event' : '',
@@ -224,8 +224,8 @@  discard block
 block discarded – undo
224 224
 			if ( count( $this->_dtts_for_event ) > 1 ) {
225 225
 				$dtts[0] = __( 'To toggle check-in status, select a datetime.', 'event_espresso' );
226 226
 				foreach ( $this->_dtts_for_event as $dtt ) {
227
-                    $datetime_string = $dtt->name();
228
-                    $datetime_string = ! empty($datetime_string ) ? ' (' . $datetime_string . ')' : '';
227
+					$datetime_string = $dtt->name();
228
+					$datetime_string = ! empty($datetime_string ) ? ' (' . $datetime_string . ')' : '';
229 229
 					$datetime_string = $dtt->start_date_and_time() . ' - ' . $dtt->end_date_and_time() . $datetime_string;
230 230
 					$dtts[ $dtt->ID() ] = $datetime_string;
231 231
 				}
@@ -319,7 +319,7 @@  discard block
 block discarded – undo
319 319
 		$checkinstatus = $item->check_in_status_for_datetime( $this->_cur_dtt_id );
320 320
 		$nonce = wp_create_nonce( 'checkin_nonce' );
321 321
 		$toggle_active = ! empty ( $this->_cur_dtt_id )
322
-		                 && EE_Registry::instance()->CAP->current_user_can(
322
+						 && EE_Registry::instance()->CAP->current_user_can(
323 323
 			'ee_edit_checkin',
324 324
 			'espresso_registrations_toggle_checkin_status',
325 325
 			$item->ID()
@@ -328,11 +328,11 @@  discard block
 block discarded – undo
328 328
 			: '';
329 329
 		$mobile_view_content = ' <span class="show-on-mobile-view-only">' . $attendee_name . '</span>';
330 330
 		return '<span class="checkin-icons checkedin-status-' . $checkinstatus . $toggle_active . '"'
331
-		       . ' data-_regid="' . $item->ID() . '"'
332
-		       . ' data-dttid="' . $this->_cur_dtt_id . '"'
333
-		       . ' data-nonce="' . $nonce . '">'
334
-		       . '</span>'
335
-		       . $mobile_view_content;
331
+			   . ' data-_regid="' . $item->ID() . '"'
332
+			   . ' data-dttid="' . $this->_cur_dtt_id . '"'
333
+			   . ' data-nonce="' . $nonce . '">'
334
+			   . '</span>'
335
+			   . $mobile_view_content;
336 336
 	}
337 337
 
338 338
 
@@ -357,8 +357,8 @@  discard block
 block discarded – undo
357 357
 			'espresso_registrations_edit_attendee'
358 358
 		)
359 359
 			? '<a href="' . $edit_lnk_url . '" title="' . esc_attr__( 'View Registration Details', 'event_espresso' ) . '">'
360
-			    . $item->attendee()->full_name()
361
-			    . '</a>'
360
+				. $item->attendee()->full_name()
361
+				. '</a>'
362 362
 			: $item->attendee()->full_name();
363 363
 		$name_link .= $item->count() === 1
364 364
 			? '&nbsp;<sup><div class="dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8"></div></sup>	'
@@ -393,7 +393,7 @@  discard block
 block discarded – undo
393 393
 			? $latest_related_datetime->ID()
394 394
 			: $DTT_ID;
395 395
 		if ( ! empty( $DTT_ID )
396
-		     && EE_Registry::instance()->CAP->current_user_can(
396
+			 && EE_Registry::instance()->CAP->current_user_can(
397 397
 				'ee_read_checkins',
398 398
 				'espresso_registrations_registration_checkins'
399 399
 			)
@@ -493,15 +493,15 @@  discard block
 block discarded – undo
493 493
 				) ? '
494 494
 				<span class="reg-pad-rght">
495 495
 					<a class="status-'
496
-				    . $item->transaction()->status_ID()
497
-				    . '" href="'
498
-				    . $view_txn_lnk_url
499
-				    . '"  title="'
500
-				    . esc_attr__( 'View Transaction', 'event_espresso' )
501
-				    . '">
496
+					. $item->transaction()->status_ID()
497
+					. '" href="'
498
+					. $view_txn_lnk_url
499
+					. '"  title="'
500
+					. esc_attr__( 'View Transaction', 'event_espresso' )
501
+					. '">
502 502
 						'
503
-				    . $item->transaction()->pretty_paid()
504
-				    . '
503
+					. $item->transaction()->pretty_paid()
504
+					. '
505 505
 					</a>
506 506
 				<span>' : '<span class="reg-pad-rght">' . $item->transaction()->pretty_paid() . '</span>';
507 507
 			}
@@ -534,12 +534,12 @@  discard block
 block discarded – undo
534 534
 				'ee_read_transaction',
535 535
 				'espresso_transactions_view_transaction'
536 536
 			) ? '<a href="'
537
-			    . $view_txn_url
538
-			    . '" title="'
539
-			    . esc_attr__( 'View Transaction', 'event_espresso' )
540
-			    . '"><span class="reg-pad-rght">'
541
-			    . $txn_total
542
-			    . '</span></a>' : '<span class="reg-pad-rght">' . $txn_total . '</span>';
537
+				. $view_txn_url
538
+				. '" title="'
539
+				. esc_attr__( 'View Transaction', 'event_espresso' )
540
+				. '"><span class="reg-pad-rght">'
541
+				. $txn_total
542
+				. '</span></a>' : '<span class="reg-pad-rght">' . $txn_total . '</span>';
543 543
 		} else {
544 544
 			return '<span class="reg-pad-rght"></span>';
545 545
 		}
Please login to merge, or discard this patch.
Spacing   +111 added lines, -111 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1
-<?php if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) {
2
-	exit( 'No direct script access allowed' );
1
+<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 
5 5
 
@@ -42,51 +42,51 @@  discard block
 block discarded – undo
42 42
 	 *
43 43
 	 * @param \Registrations_Admin_Page $admin_page
44 44
 	 */
45
-	public function __construct( $admin_page ) {
46
-		parent::__construct( $admin_page );
45
+	public function __construct($admin_page) {
46
+		parent::__construct($admin_page);
47 47
 		$this->_status = $this->_admin_page->get_registration_status_array();
48 48
 	}
49 49
 
50 50
 
51 51
 
52 52
 	protected function _setup_data() {
53
-		$this->_data = $this->_view !== 'trash' ? $this->_admin_page->get_event_attendees( $this->_per_page )
54
-			: $this->_admin_page->get_event_attendees( $this->_per_page, false, true );
53
+		$this->_data = $this->_view !== 'trash' ? $this->_admin_page->get_event_attendees($this->_per_page)
54
+			: $this->_admin_page->get_event_attendees($this->_per_page, false, true);
55 55
 		$this->_all_data_count = $this->_view !== 'trash' ? $this->_admin_page->get_event_attendees(
56 56
 			$this->_per_page,
57 57
 			true
58
-		) : $this->_admin_page->get_event_attendees( $this->_per_page, true, true );
58
+		) : $this->_admin_page->get_event_attendees($this->_per_page, true, true);
59 59
 	}
60 60
 
61 61
 
62 62
 
63 63
 	protected function _set_properties() {
64
-		$evt_id = isset( $this->_req_data['event_id'] ) ? $this->_req_data['event_id'] : null;
64
+		$evt_id = isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null;
65 65
 		$this->_wp_list_args = array(
66
-			'singular' => __( 'registrant', 'event_espresso' ),
67
-			'plural'   => __( 'registrants', 'event_espresso' ),
66
+			'singular' => __('registrant', 'event_espresso'),
67
+			'plural'   => __('registrants', 'event_espresso'),
68 68
 			'ajax'     => true,
69 69
 			'screen'   => $this->_admin_page->get_current_screen()->id,
70 70
 		);
71 71
 		$columns = array();
72 72
 		//$columns['_Reg_Status'] = '';
73
-		if ( ! empty( $evt_id ) ) {
73
+		if ( ! empty($evt_id)) {
74 74
 			$columns['cb'] = '<input type="checkbox" />'; //Render a checkbox instead of text
75 75
 			$this->_has_checkbox_column = true;
76 76
 		}
77 77
 		$this->_columns = array(
78 78
 			'_REG_att_checked_in' => '<span class="dashicons dashicons-yes ee-icon-size-18"></span>',
79
-			'ATT_name'            => __( 'Registrant', 'event_espresso' ),
80
-			'ATT_email'           => __( 'Email Address', 'event_espresso' ),
81
-			'Event'               => __( 'Event', 'event_espresso' ),
82
-			'PRC_name'            => __( 'TKT Option', 'event_espresso' ),
83
-			'_REG_final_price'    => __( 'Price', 'event_espresso' ),
84
-			'TXN_paid'            => __( 'Paid', 'event_espresso' ),
85
-			'TXN_total'           => __( 'Total', 'event_espresso' ),
79
+			'ATT_name'            => __('Registrant', 'event_espresso'),
80
+			'ATT_email'           => __('Email Address', 'event_espresso'),
81
+			'Event'               => __('Event', 'event_espresso'),
82
+			'PRC_name'            => __('TKT Option', 'event_espresso'),
83
+			'_REG_final_price'    => __('Price', 'event_espresso'),
84
+			'TXN_paid'            => __('Paid', 'event_espresso'),
85
+			'TXN_total'           => __('Total', 'event_espresso'),
86 86
 		);
87
-		$this->_columns = array_merge( $columns, $this->_columns );
87
+		$this->_columns = array_merge($columns, $this->_columns);
88 88
 		$this->_primary_column = '_REG_att_checked_in';
89
-		if ( ! empty( $evt_id )
89
+		if ( ! empty($evt_id)
90 90
 		     && EE_Registry::instance()->CAP->current_user_can(
91 91
 				'ee_read_registrations',
92 92
 				'espresso_registrations_registrations_reports',
@@ -99,7 +99,7 @@  discard block
 block discarded – undo
99 99
 					'extra_request' =>
100 100
 						array(
101 101
 							'EVT_ID'     => $evt_id,
102
-							'return_url' => urlencode( "//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}" ),
102
+							'return_url' => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"),
103 103
 						),
104 104
 				),
105 105
 			);
@@ -140,12 +140,12 @@  discard block
 block discarded – undo
140 140
                     true,
141 141
                     $this
142 142
                 )
143
-                ? array( 'ATT_lname' => true )
144
-                : array( 'ATT_fname' => true ),
145
-			'Event'    => array( 'Event.EVT.Name' => false ),
143
+                ? array('ATT_lname' => true)
144
+                : array('ATT_fname' => true),
145
+			'Event'    => array('Event.EVT.Name' => false),
146 146
 		);
147 147
 		$this->_hidden_columns = array();
148
-		$this->_evt = EEM_Event::instance()->get_one_by_ID( $evt_id );
148
+		$this->_evt = EEM_Event::instance()->get_one_by_ID($evt_id);
149 149
 		$this->_dtts_for_event = $this->_evt instanceof EE_Event ? $this->_evt->datetimes_ordered() : array();
150 150
 	}
151 151
 
@@ -155,11 +155,11 @@  discard block
 block discarded – undo
155 155
 	 * @param \EE_Registration $item
156 156
 	 * @return string
157 157
 	 */
158
-	protected function _get_row_class( $item ) {
159
-		$class = parent::_get_row_class( $item );
158
+	protected function _get_row_class($item) {
159
+		$class = parent::_get_row_class($item);
160 160
 		//add status class
161
-		$class .= ' ee-status-strip reg-status-' . $item->status_ID();
162
-		if ( $this->_has_checkbox_column ) {
161
+		$class .= ' ee-status-strip reg-status-'.$item->status_ID();
162
+		if ($this->_has_checkbox_column) {
163 163
 			$class .= ' has-checkbox-column';
164 164
 		}
165 165
 		return $class;
@@ -173,61 +173,61 @@  discard block
 block discarded – undo
173 173
 	 */
174 174
 	protected function _get_table_filters() {
175 175
 		$filters = $where = array();
176
-		$current_EVT_ID = isset( $this->_req_data['event_id'] ) ? (int) $this->_req_data['event_id'] : 0;
177
-		if ( empty( $this->_dtts_for_event ) || count( $this->_dtts_for_event ) === 1 ) {
176
+		$current_EVT_ID = isset($this->_req_data['event_id']) ? (int) $this->_req_data['event_id'] : 0;
177
+		if (empty($this->_dtts_for_event) || count($this->_dtts_for_event) === 1) {
178 178
 			//this means we don't have an event so let's setup a filter dropdown for all the events to select
179 179
 			//note possible capability restrictions
180
-			if ( ! EE_Registry::instance()->CAP->current_user_can( 'ee_read_private_events', 'get_events' ) ) {
181
-				$where['status**'] = array( '!=', 'private' );
180
+			if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
181
+				$where['status**'] = array('!=', 'private');
182 182
 			}
183
-			if ( ! EE_Registry::instance()->CAP->current_user_can( 'ee_read_others_events', 'get_events' ) ) {
183
+			if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
184 184
 				$where['EVT_wp_user'] = get_current_user_id();
185 185
 			}
186 186
 			$events = EEM_Event::instance()->get_all(
187 187
 				array(
188 188
 					$where,
189
-					'order_by' => array( 'Datetime.DTT_EVT_start' => 'DESC' ),
189
+					'order_by' => array('Datetime.DTT_EVT_start' => 'DESC'),
190 190
 				)
191 191
 			);
192 192
 			$evts[] = array(
193 193
 				'id'   => 0,
194
-				'text' => __( 'To toggle Check-in status, select an event', 'event_espresso' ),
194
+				'text' => __('To toggle Check-in status, select an event', 'event_espresso'),
195 195
 			);
196 196
 			$checked = 'checked';
197 197
 			/** @var EE_Event $evt */
198
-			foreach ( $events as $evt ) {
198
+			foreach ($events as $evt) {
199 199
 				//any registrations for this event?
200
-				if ( ! $evt->get_count_of_all_registrations() ) {
200
+				if ( ! $evt->get_count_of_all_registrations()) {
201 201
 					continue;
202 202
 				}
203 203
                                 $evts[] = array(
204 204
 					'id'    => $evt->ID(),
205
-					'text'  => apply_filters('FHEE__EE_Event_Registrations___get_table_filters__event_name', $evt->get( 'EVT_name' ), $evt),
205
+					'text'  => apply_filters('FHEE__EE_Event_Registrations___get_table_filters__event_name', $evt->get('EVT_name'), $evt),
206 206
 					'class' => $evt->is_expired() ? 'ee-expired-event' : '',
207 207
 				);
208
-				if ( $evt->ID() === $current_EVT_ID && $evt->is_expired() ) {
208
+				if ($evt->ID() === $current_EVT_ID && $evt->is_expired()) {
209 209
 					$checked = '';
210 210
 				}
211 211
 			}
212 212
 			$event_filter = '<div class="ee-event-filter">';
213
-			$event_filter .= EEH_Form_Fields::select_input( 'event_id', $evts, $current_EVT_ID );
213
+			$event_filter .= EEH_Form_Fields::select_input('event_id', $evts, $current_EVT_ID);
214 214
 			$event_filter .= '<span class="ee-event-filter-toggle">';
215
-			$event_filter .= '<input type="checkbox" id="js-ee-hide-expired-events" ' . $checked . '> ';
216
-			$event_filter .= __( 'Hide Expired Events', 'event_espresso' );
215
+			$event_filter .= '<input type="checkbox" id="js-ee-hide-expired-events" '.$checked.'> ';
216
+			$event_filter .= __('Hide Expired Events', 'event_espresso');
217 217
 			$event_filter .= '</span>';
218 218
 			$event_filter .= '</div>';
219 219
 			$filters[] = $event_filter;
220 220
 		}
221
-		if ( ! empty( $this->_dtts_for_event ) ) {
221
+		if ( ! empty($this->_dtts_for_event)) {
222 222
 			//DTT datetimes filter
223
-			$this->_cur_dtt_id = isset( $this->_req_data['DTT_ID'] ) ? $this->_req_data['DTT_ID'] : 0;
224
-			if ( count( $this->_dtts_for_event ) > 1 ) {
225
-				$dtts[0] = __( 'To toggle check-in status, select a datetime.', 'event_espresso' );
226
-				foreach ( $this->_dtts_for_event as $dtt ) {
223
+			$this->_cur_dtt_id = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0;
224
+			if (count($this->_dtts_for_event) > 1) {
225
+				$dtts[0] = __('To toggle check-in status, select a datetime.', 'event_espresso');
226
+				foreach ($this->_dtts_for_event as $dtt) {
227 227
                     $datetime_string = $dtt->name();
228
-                    $datetime_string = ! empty($datetime_string ) ? ' (' . $datetime_string . ')' : '';
229
-					$datetime_string = $dtt->start_date_and_time() . ' - ' . $dtt->end_date_and_time() . $datetime_string;
230
-					$dtts[ $dtt->ID() ] = $datetime_string;
228
+                    $datetime_string = ! empty($datetime_string) ? ' ('.$datetime_string.')' : '';
229
+					$datetime_string = $dtt->start_date_and_time().' - '.$dtt->end_date_and_time().$datetime_string;
230
+					$dtts[$dtt->ID()] = $datetime_string;
231 231
 				}
232 232
 				$input = new EE_Select_Input(
233 233
 					$dtts,
@@ -238,7 +238,7 @@  discard block
 block discarded – undo
238 238
 					)
239 239
 				);
240 240
 				$filters[] = $input->get_html_for_input();
241
-				$filters[] = '<input type="hidden" name="event_id" value="' . $current_EVT_ID . '">';
241
+				$filters[] = '<input type="hidden" name="event_id" value="'.$current_EVT_ID.'">';
242 242
 			}
243 243
 		}
244 244
 		return $filters;
@@ -257,22 +257,22 @@  discard block
 block discarded – undo
257 257
 	 * @throws \EE_Error
258 258
 	 */
259 259
 	protected function _get_total_event_attendees() {
260
-		$EVT_ID = isset( $this->_req_data['event_id'] ) ? absint( $this->_req_data['event_id'] ) : false;
260
+		$EVT_ID = isset($this->_req_data['event_id']) ? absint($this->_req_data['event_id']) : false;
261 261
 		$DTT_ID = $this->_cur_dtt_id;
262 262
 		$query_params = array();
263
-		if ( $EVT_ID ) {
263
+		if ($EVT_ID) {
264 264
 			$query_params[0]['EVT_ID'] = $EVT_ID;
265 265
 		}
266 266
 		//if DTT is included we only show for that datetime.  Otherwise we're showing for all datetimes (the event).
267
-		if ( $DTT_ID ) {
267
+		if ($DTT_ID) {
268 268
 			$query_params[0]['Ticket.Datetime.DTT_ID'] = $DTT_ID;
269 269
 		}
270 270
 		$status_ids_array = apply_filters(
271 271
 			'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
272
-			array( EEM_Registration::status_id_pending_payment, EEM_Registration::status_id_approved )
272
+			array(EEM_Registration::status_id_pending_payment, EEM_Registration::status_id_approved)
273 273
 		);
274
-		$query_params[0]['STS_ID'] = array( 'IN', $status_ids_array );
275
-		return EEM_Registration::instance()->count( $query_params );
274
+		$query_params[0]['STS_ID'] = array('IN', $status_ids_array);
275
+		return EEM_Registration::instance()->count($query_params);
276 276
 	}
277 277
 
278 278
 
@@ -281,8 +281,8 @@  discard block
 block discarded – undo
281 281
 	 * @param \EE_Registration $item
282 282
 	 * @return string
283 283
 	 */
284
-	public function column__Reg_Status( EE_Registration $item ) {
285
-		return '<span class="ee-status-strip ee-status-strip-td reg-status-' . $item->status_ID() . '"></span>';
284
+	public function column__Reg_Status(EE_Registration $item) {
285
+		return '<span class="ee-status-strip ee-status-strip-td reg-status-'.$item->status_ID().'"></span>';
286 286
 	}
287 287
 
288 288
 
@@ -292,8 +292,8 @@  discard block
 block discarded – undo
292 292
 	 * @return string
293 293
 	 * @throws \EE_Error
294 294
 	 */
295
-	public function column_cb( $item ) {
296
-		return sprintf( '<input type="checkbox" name="checkbox[%1$s]" value="%1$s" />', $item->ID() );
295
+	public function column_cb($item) {
296
+		return sprintf('<input type="checkbox" name="checkbox[%1$s]" value="%1$s" />', $item->ID());
297 297
 	}
298 298
 
299 299
 
@@ -305,20 +305,20 @@  discard block
 block discarded – undo
305 305
 	 * @return string
306 306
 	 * @throws \EE_Error
307 307
 	 */
308
-	public function column__REG_att_checked_in( EE_Registration $item ) {
308
+	public function column__REG_att_checked_in(EE_Registration $item) {
309 309
 		$attendee = $item->attendee();
310 310
 		$attendee_name = $attendee instanceof EE_Attendee ? $attendee->full_name() : '';
311 311
 
312
-		if ( $this->_cur_dtt_id === 0 && count( $this->_dtts_for_event ) === 1 ) {
312
+		if ($this->_cur_dtt_id === 0 && count($this->_dtts_for_event) === 1) {
313 313
 			$latest_related_datetime = $item->get_latest_related_datetime();
314
-			if ( $latest_related_datetime instanceof EE_Datetime ) {
314
+			if ($latest_related_datetime instanceof EE_Datetime) {
315 315
 				$this->_cur_dtt_id = $latest_related_datetime->ID();
316 316
 			}
317 317
 		}
318 318
 
319
-		$checkinstatus = $item->check_in_status_for_datetime( $this->_cur_dtt_id );
320
-		$nonce = wp_create_nonce( 'checkin_nonce' );
321
-		$toggle_active = ! empty ( $this->_cur_dtt_id )
319
+		$checkinstatus = $item->check_in_status_for_datetime($this->_cur_dtt_id);
320
+		$nonce = wp_create_nonce('checkin_nonce');
321
+		$toggle_active = ! empty ($this->_cur_dtt_id)
322 322
 		                 && EE_Registry::instance()->CAP->current_user_can(
323 323
 			'ee_edit_checkin',
324 324
 			'espresso_registrations_toggle_checkin_status',
@@ -326,11 +326,11 @@  discard block
 block discarded – undo
326 326
 		)
327 327
 			? ' clickable trigger-checkin'
328 328
 			: '';
329
-		$mobile_view_content = ' <span class="show-on-mobile-view-only">' . $attendee_name . '</span>';
330
-		return '<span class="checkin-icons checkedin-status-' . $checkinstatus . $toggle_active . '"'
331
-		       . ' data-_regid="' . $item->ID() . '"'
332
-		       . ' data-dttid="' . $this->_cur_dtt_id . '"'
333
-		       . ' data-nonce="' . $nonce . '">'
329
+		$mobile_view_content = ' <span class="show-on-mobile-view-only">'.$attendee_name.'</span>';
330
+		return '<span class="checkin-icons checkedin-status-'.$checkinstatus.$toggle_active.'"'
331
+		       . ' data-_regid="'.$item->ID().'"'
332
+		       . ' data-dttid="'.$this->_cur_dtt_id.'"'
333
+		       . ' data-nonce="'.$nonce.'">'
334 334
 		       . '</span>'
335 335
 		       . $mobile_view_content;
336 336
 	}
@@ -342,21 +342,21 @@  discard block
 block discarded – undo
342 342
 	 * @return mixed|string|void
343 343
 	 * @throws \EE_Error
344 344
 	 */
345
-	public function column_ATT_name( EE_Registration $item ) {
345
+	public function column_ATT_name(EE_Registration $item) {
346 346
 		$attendee = $item->attendee();
347
-		if ( ! $attendee instanceof EE_Attendee ) {
348
-			return __( 'No contact record for this registration.', 'event_espresso' );
347
+		if ( ! $attendee instanceof EE_Attendee) {
348
+			return __('No contact record for this registration.', 'event_espresso');
349 349
 		}
350 350
 		// edit attendee link
351 351
 		$edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
352
-			array( 'action' => 'view_registration', '_REG_ID' => $item->ID() ),
352
+			array('action' => 'view_registration', '_REG_ID' => $item->ID()),
353 353
 			REG_ADMIN_URL
354 354
 		);
355 355
 		$name_link = EE_Registry::instance()->CAP->current_user_can(
356 356
 			'ee_edit_contacts',
357 357
 			'espresso_registrations_edit_attendee'
358 358
 		)
359
-			? '<a href="' . $edit_lnk_url . '" title="' . esc_attr__( 'View Registration Details', 'event_espresso' ) . '">'
359
+			? '<a href="'.$edit_lnk_url.'" title="'.esc_attr__('View Registration Details', 'event_espresso').'">'
360 360
 			    . $item->attendee()->full_name()
361 361
 			    . '</a>'
362 362
 			: $item->attendee()->full_name();
@@ -364,10 +364,10 @@  discard block
 block discarded – undo
364 364
 			? '&nbsp;<sup><div class="dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8"></div></sup>	'
365 365
 			: '';
366 366
 		//add group details
367
-		$name_link .= '&nbsp;' . sprintf( __( '(%s of %s)', 'event_espresso' ), $item->count(), $item->group_size() );
367
+		$name_link .= '&nbsp;'.sprintf(__('(%s of %s)', 'event_espresso'), $item->count(), $item->group_size());
368 368
 		//add regcode
369 369
 		$link = EE_Admin_Page::add_query_args_and_nonce(
370
-			array( 'action' => 'view_registration', '_REG_ID' => $item->ID() ),
370
+			array('action' => 'view_registration', '_REG_ID' => $item->ID()),
371 371
 			REG_ADMIN_URL
372 372
 		);
373 373
 		$name_link .= '<br>';
@@ -376,37 +376,37 @@  discard block
 block discarded – undo
376 376
 			'view_registration',
377 377
 			$item->ID()
378 378
 		)
379
-			? '<a href="' . $link . '" title="' . esc_attr__( 'View Registration Details', 'event_espresso' ) . '">'
379
+			? '<a href="'.$link.'" title="'.esc_attr__('View Registration Details', 'event_espresso').'">'
380 380
 			  . $item->reg_code()
381 381
 			  . '</a>'
382 382
 			: $item->reg_code();
383 383
 		//status
384 384
 		$name_link .= '<br><span class="ee-status-text-small">';
385
-		$name_link .= EEH_Template::pretty_status( $item->status_ID(), false, 'sentence' );
385
+		$name_link .= EEH_Template::pretty_status($item->status_ID(), false, 'sentence');
386 386
 		$name_link .= '</span>';
387 387
 		$actions = array();
388 388
 		$DTT_ID = $this->_cur_dtt_id;
389
-		$latest_related_datetime = empty( $DTT_ID ) && ! empty( $this->_req_data['event_id'] ) && $item instanceof EE_Registration
389
+		$latest_related_datetime = empty($DTT_ID) && ! empty($this->_req_data['event_id']) && $item instanceof EE_Registration
390 390
 			? $item->get_latest_related_datetime()
391 391
 			: null;
392 392
 		$DTT_ID = $latest_related_datetime instanceof EE_Datetime
393 393
 			? $latest_related_datetime->ID()
394 394
 			: $DTT_ID;
395
-		if ( ! empty( $DTT_ID )
395
+		if ( ! empty($DTT_ID)
396 396
 		     && EE_Registry::instance()->CAP->current_user_can(
397 397
 				'ee_read_checkins',
398 398
 				'espresso_registrations_registration_checkins'
399 399
 			)
400 400
 		) {
401 401
 			$checkin_list_url = EE_Admin_Page::add_query_args_and_nonce(
402
-				array( 'action' => 'registration_checkins', '_REGID' => $item->ID(), 'DTT_ID' => $DTT_ID )
402
+				array('action' => 'registration_checkins', '_REGID' => $item->ID(), 'DTT_ID' => $DTT_ID)
403 403
 			);
404
-			$actions['checkin'] = '<a href="' . $checkin_list_url . '" title="' . esc_attr__(
404
+			$actions['checkin'] = '<a href="'.$checkin_list_url.'" title="'.esc_attr__(
405 405
 					'View all the check-ins/checkouts for this registrant',
406 406
 					'event_espresso'
407
-				) . '">' . __( 'View', 'event_espresso' ) . '</a>';
407
+				).'">'.__('View', 'event_espresso').'</a>';
408 408
 		}
409
-		return ! empty( $DTT_ID ) ? sprintf( '%1$s %2$s', $name_link, $this->row_actions( $actions ) ) : $name_link;
409
+		return ! empty($DTT_ID) ? sprintf('%1$s %2$s', $name_link, $this->row_actions($actions)) : $name_link;
410 410
 	}
411 411
 
412 412
 
@@ -415,7 +415,7 @@  discard block
 block discarded – undo
415 415
 	 * @param \EE_Registration $item
416 416
 	 * @return string
417 417
 	 */
418
-	public function column_ATT_email( EE_Registration $item ) {
418
+	public function column_ATT_email(EE_Registration $item) {
419 419
 		$attendee = $item->attendee();
420 420
 		return $attendee instanceof EE_Attendee ? $attendee->email() : '';
421 421
 	}
@@ -427,22 +427,22 @@  discard block
 block discarded – undo
427 427
 	 * @return bool|string
428 428
 	 * @throws \EE_Error
429 429
 	 */
430
-	public function column_Event( EE_Registration $item ) {
430
+	public function column_Event(EE_Registration $item) {
431 431
 		try {
432 432
 			$event = $this->_evt instanceof EE_Event ? $this->_evt : $item->event();
433 433
 			$chkin_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
434
-				array( 'action' => 'event_registrations', 'event_id' => $event->ID() ),
434
+				array('action' => 'event_registrations', 'event_id' => $event->ID()),
435 435
 				REG_ADMIN_URL
436 436
 			);
437 437
 			$event_label = EE_Registry::instance()->CAP->current_user_can(
438 438
 				'ee_read_checkins',
439 439
 				'espresso_registrations_registration_checkins'
440
-			) ? '<a href="' . $chkin_lnk_url . '" title="' . esc_attr__(
440
+			) ? '<a href="'.$chkin_lnk_url.'" title="'.esc_attr__(
441 441
 					'View Checkins for this Event',
442 442
 					'event_espresso'
443
-				) . '">' . $event->name() . '</a>' : $event->name();
444
-		} catch ( \EventEspresso\core\exceptions\EntityNotFoundException $e ) {
445
-			$event_label = esc_html__( 'Unknown', 'event_espresso' );
443
+				).'">'.$event->name().'</a>' : $event->name();
444
+		} catch (\EventEspresso\core\exceptions\EntityNotFoundException $e) {
445
+			$event_label = esc_html__('Unknown', 'event_espresso');
446 446
 		}
447 447
 		return $event_label;
448 448
 	}
@@ -453,8 +453,8 @@  discard block
 block discarded – undo
453 453
 	 * @param \EE_Registration $item
454 454
 	 * @return mixed|string|void
455 455
 	 */
456
-	public function column_PRC_name( EE_Registration $item ) {
457
-		return $item->ticket() instanceof EE_Ticket ? $item->ticket()->name() : __( "Unknown", "event_espresso" );
456
+	public function column_PRC_name(EE_Registration $item) {
457
+		return $item->ticket() instanceof EE_Ticket ? $item->ticket()->name() : __("Unknown", "event_espresso");
458 458
 	}
459 459
 
460 460
 
@@ -465,8 +465,8 @@  discard block
 block discarded – undo
465 465
 	 * @param \EE_Registration $item
466 466
 	 * @return string
467 467
 	 */
468
-	public function column__REG_final_price( EE_Registration $item ) {
469
-		return '<span class="reg-pad-rght">' . ' ' . $item->pretty_final_price() . '</span>';
468
+	public function column__REG_final_price(EE_Registration $item) {
469
+		return '<span class="reg-pad-rght">'.' '.$item->pretty_final_price().'</span>';
470 470
 	}
471 471
 
472 472
 
@@ -478,13 +478,13 @@  discard block
 block discarded – undo
478 478
 	 * @return string
479 479
 	 * @throws \EE_Error
480 480
 	 */
481
-	public function column_TXN_paid( EE_Registration $item ) {
482
-		if ( $item->count() === 1 ) {
483
-			if ( $item->transaction()->paid() >= $item->transaction()->total() ) {
481
+	public function column_TXN_paid(EE_Registration $item) {
482
+		if ($item->count() === 1) {
483
+			if ($item->transaction()->paid() >= $item->transaction()->total()) {
484 484
 				return '<span class="reg-pad-rght"><div class="dashicons dashicons-yes green-icon"></div></span>';
485 485
 			} else {
486 486
 				$view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
487
-					array( 'action' => 'view_transaction', 'TXN_ID' => $item->transaction_ID() ),
487
+					array('action' => 'view_transaction', 'TXN_ID' => $item->transaction_ID()),
488 488
 					TXN_ADMIN_URL
489 489
 				);
490 490
 				return EE_Registry::instance()->CAP->current_user_can(
@@ -497,13 +497,13 @@  discard block
 block discarded – undo
497 497
 				    . '" href="'
498 498
 				    . $view_txn_lnk_url
499 499
 				    . '"  title="'
500
-				    . esc_attr__( 'View Transaction', 'event_espresso' )
500
+				    . esc_attr__('View Transaction', 'event_espresso')
501 501
 				    . '">
502 502
 						'
503 503
 				    . $item->transaction()->pretty_paid()
504 504
 				    . '
505 505
 					</a>
506
-				<span>' : '<span class="reg-pad-rght">' . $item->transaction()->pretty_paid() . '</span>';
506
+				<span>' : '<span class="reg-pad-rght">'.$item->transaction()->pretty_paid().'</span>';
507 507
 			}
508 508
 		} else {
509 509
 			return '<span class="reg-pad-rght"></span>';
@@ -519,13 +519,13 @@  discard block
 block discarded – undo
519 519
 	 * @return string
520 520
 	 * @throws \EE_Error
521 521
 	 */
522
-	public function column_TXN_total( EE_Registration $item ) {
522
+	public function column_TXN_total(EE_Registration $item) {
523 523
 		$txn = $item->transaction();
524
-		$view_txn_url = add_query_arg( array( 'action' => 'view_transaction', 'TXN_ID' => $txn->ID() ), TXN_ADMIN_URL );
525
-		if ( $item->get( 'REG_count' ) === 1 ) {
524
+		$view_txn_url = add_query_arg(array('action' => 'view_transaction', 'TXN_ID' => $txn->ID()), TXN_ADMIN_URL);
525
+		if ($item->get('REG_count') === 1) {
526 526
 			$line_total_obj = $txn->total_line_item();
527 527
 			$txn_total = $line_total_obj instanceof EE_Line_Item
528
-				? $line_total_obj->get_pretty( 'LIN_total' )
528
+				? $line_total_obj->get_pretty('LIN_total')
529 529
 				: __(
530 530
 					'View Transaction',
531 531
 					'event_espresso'
@@ -536,10 +536,10 @@  discard block
 block discarded – undo
536 536
 			) ? '<a href="'
537 537
 			    . $view_txn_url
538 538
 			    . '" title="'
539
-			    . esc_attr__( 'View Transaction', 'event_espresso' )
539
+			    . esc_attr__('View Transaction', 'event_espresso')
540 540
 			    . '"><span class="reg-pad-rght">'
541 541
 			    . $txn_total
542
-			    . '</span></a>' : '<span class="reg-pad-rght">' . $txn_total . '</span>';
542
+			    . '</span></a>' : '<span class="reg-pad-rght">'.$txn_total.'</span>';
543 543
 		} else {
544 544
 			return '<span class="reg-pad-rght"></span>';
545 545
 		}
Please login to merge, or discard this patch.
core/helpers/EEH_Schema.helper.php 2 patches
Indentation   +65 added lines, -65 removed lines patch added patch discarded remove patch
@@ -17,67 +17,67 @@  discard block
 block discarded – undo
17 17
 class EEH_Schema {
18 18
 
19 19
 
20
-    /**
21
-     * generates JSON-based linked data for an event
22
-     *
23
-     * @param \EE_Event $event
24
-     */
25
-    public static function add_json_linked_data_for_event(\EE_Event $event)
26
-    {
27
-    	//Check we have a valid datetime for the event
28
-    	if(! $event->primary_datetime() instanceof EE_Datetime) {
29
-    		return;
30
-    	}
31
-
32
-        $template_args = array(
33
-            'event_permalink' => '',
34
-            'event_name' => '',
35
-            'event_description' => '',
36
-            'event_start' => '',
37
-            'event_end' => '',
38
-            'currency' => '',
39
-            'event_tickets' => array(),
40
-            'venue_name' => '',
41
-            'venue_url' => '',
42
-            'venue_locality' => '',
43
-            'venue_region' => '',
44
-            'event_image' => '',
45
-        );
46
-        $template_args['event_permalink'] = $event->get_permalink();
47
-        $template_args['event_name'] = $event->name();
48
-        $template_args['event_description'] = wp_strip_all_tags($event->short_description(200));
49
-        $template_args['event_start'] = $event->primary_datetime()->start_date(DateTime::ATOM);
50
-        $template_args['event_end'] = $event->primary_datetime()->end_date(DateTime::ATOM);
51
-        $template_args['currency'] = EE_Registry::instance()->CFG->currency->code;
52
-        foreach ($event->tickets() as $ticket) {
53
-            $ID = $ticket->ID();
54
-            $template_args['event_tickets'][$ID]['start_date'] = $ticket->start_date(DateTime::ATOM, null);
55
-            $template_args['event_tickets'][$ID]['end_date'] = $ticket->end_date(DateTime::ATOM, null);
56
-            $template_args['event_tickets'][$ID]['price'] = number_format(
57
-                $ticket->price(),
58
-                EE_Registry::instance()->CFG->currency->dec_plc,
59
-                EE_Registry::instance()->CFG->currency->dec_mrk,
60
-                EE_Registry::instance()->CFG->currency->thsnds
61
-            );
62
-        }
63
-        $VNU_ID = espresso_venue_id();
64
-        if ( ! empty($VNU_ID) && ! espresso_is_venue_private($VNU_ID)) {
65
-            $venue = EEH_Venue_View::get_venue($VNU_ID);
66
-            $template_args['venue_name'] = get_the_title($VNU_ID);
67
-            $template_args['venue_url'] = get_permalink($VNU_ID);
68
-            $template_args['venue_locality'] = $venue->city();
69
-            $template_args['venue_region'] = $venue->state_name();
70
-        }
71
-        $template_args['event_image'] = $event->feature_image_url();
72
-        $template_args = apply_filters(
73
-            'FHEE__EEH_Schema__add_json_linked_data_for_event__template_args',
74
-            $template_args,
75
-            $event,
76
-            $VNU_ID
77
-        );
78
-        extract($template_args, EXTR_OVERWRITE);
79
-        include EE_TEMPLATES . 'json_linked_data_for_event.template.php';
80
-    }
20
+	/**
21
+	 * generates JSON-based linked data for an event
22
+	 *
23
+	 * @param \EE_Event $event
24
+	 */
25
+	public static function add_json_linked_data_for_event(\EE_Event $event)
26
+	{
27
+		//Check we have a valid datetime for the event
28
+		if(! $event->primary_datetime() instanceof EE_Datetime) {
29
+			return;
30
+		}
31
+
32
+		$template_args = array(
33
+			'event_permalink' => '',
34
+			'event_name' => '',
35
+			'event_description' => '',
36
+			'event_start' => '',
37
+			'event_end' => '',
38
+			'currency' => '',
39
+			'event_tickets' => array(),
40
+			'venue_name' => '',
41
+			'venue_url' => '',
42
+			'venue_locality' => '',
43
+			'venue_region' => '',
44
+			'event_image' => '',
45
+		);
46
+		$template_args['event_permalink'] = $event->get_permalink();
47
+		$template_args['event_name'] = $event->name();
48
+		$template_args['event_description'] = wp_strip_all_tags($event->short_description(200));
49
+		$template_args['event_start'] = $event->primary_datetime()->start_date(DateTime::ATOM);
50
+		$template_args['event_end'] = $event->primary_datetime()->end_date(DateTime::ATOM);
51
+		$template_args['currency'] = EE_Registry::instance()->CFG->currency->code;
52
+		foreach ($event->tickets() as $ticket) {
53
+			$ID = $ticket->ID();
54
+			$template_args['event_tickets'][$ID]['start_date'] = $ticket->start_date(DateTime::ATOM, null);
55
+			$template_args['event_tickets'][$ID]['end_date'] = $ticket->end_date(DateTime::ATOM, null);
56
+			$template_args['event_tickets'][$ID]['price'] = number_format(
57
+				$ticket->price(),
58
+				EE_Registry::instance()->CFG->currency->dec_plc,
59
+				EE_Registry::instance()->CFG->currency->dec_mrk,
60
+				EE_Registry::instance()->CFG->currency->thsnds
61
+			);
62
+		}
63
+		$VNU_ID = espresso_venue_id();
64
+		if ( ! empty($VNU_ID) && ! espresso_is_venue_private($VNU_ID)) {
65
+			$venue = EEH_Venue_View::get_venue($VNU_ID);
66
+			$template_args['venue_name'] = get_the_title($VNU_ID);
67
+			$template_args['venue_url'] = get_permalink($VNU_ID);
68
+			$template_args['venue_locality'] = $venue->city();
69
+			$template_args['venue_region'] = $venue->state_name();
70
+		}
71
+		$template_args['event_image'] = $event->feature_image_url();
72
+		$template_args = apply_filters(
73
+			'FHEE__EEH_Schema__add_json_linked_data_for_event__template_args',
74
+			$template_args,
75
+			$event,
76
+			$VNU_ID
77
+		);
78
+		extract($template_args, EXTR_OVERWRITE);
79
+		include EE_TEMPLATES . 'json_linked_data_for_event.template.php';
80
+	}
81 81
 
82 82
 
83 83
 	/**
@@ -91,8 +91,8 @@  discard block
 block discarded – undo
91 91
 	 */
92 92
 	public static function location( $location = null ) {
93 93
 		return ! empty( $location ) ? '<div itemprop="location" itemscope itemtype="http://schema.org/Place">'
94
-		                              . $location
95
-		                              . '</div>' : '';
94
+									  . $location
95
+									  . '</div>' : '';
96 96
 	}
97 97
 
98 98
 
@@ -212,8 +212,8 @@  discard block
 block discarded – undo
212 212
 	 */
213 213
 	public static function postalCode( EEI_Address $obj_with_address = null ) {
214 214
 		return $obj_with_address->zip() !== null && $obj_with_address->zip() !== '' ? '<span itemprop="postalCode">'
215
-		                                                                              . $obj_with_address->zip()
216
-		                                                                              . '</span>' : '';
215
+																					  . $obj_with_address->zip()
216
+																					  . '</span>' : '';
217 217
 	}
218 218
 
219 219
 
Please login to merge, or discard this patch.
Spacing   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -1,7 +1,7 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3
-if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) {
4
-	exit( 'No direct script access allowed' );
3
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
4
+	exit('No direct script access allowed');
5 5
 }
6 6
 
7 7
 
@@ -25,7 +25,7 @@  discard block
 block discarded – undo
25 25
     public static function add_json_linked_data_for_event(\EE_Event $event)
26 26
     {
27 27
     	//Check we have a valid datetime for the event
28
-    	if(! $event->primary_datetime() instanceof EE_Datetime) {
28
+    	if ( ! $event->primary_datetime() instanceof EE_Datetime) {
29 29
     		return;
30 30
     	}
31 31
 
@@ -76,7 +76,7 @@  discard block
 block discarded – undo
76 76
             $VNU_ID
77 77
         );
78 78
         extract($template_args, EXTR_OVERWRITE);
79
-        include EE_TEMPLATES . 'json_linked_data_for_event.template.php';
79
+        include EE_TEMPLATES.'json_linked_data_for_event.template.php';
80 80
     }
81 81
 
82 82
 
@@ -89,8 +89,8 @@  discard block
 block discarded – undo
89 89
 	 * @param string $location
90 90
 	 * @return string
91 91
 	 */
92
-	public static function location( $location = null ) {
93
-		return ! empty( $location ) ? '<div itemprop="location" itemscope itemtype="http://schema.org/Place">'
92
+	public static function location($location = null) {
93
+		return ! empty($location) ? '<div itemprop="location" itemscope itemtype="http://schema.org/Place">'
94 94
 		                              . $location
95 95
 		                              . '</div>' : '';
96 96
 	}
@@ -105,8 +105,8 @@  discard block
 block discarded – undo
105 105
 	 * @param string $name
106 106
 	 * @return string
107 107
 	 */
108
-	public static function name( $name = null ) {
109
-		return ! empty( $name ) ? '<span itemprop="name">' . $name . '</span>' : '';
108
+	public static function name($name = null) {
109
+		return ! empty($name) ? '<span itemprop="name">'.$name.'</span>' : '';
110 110
 	}
111 111
 
112 112
 
@@ -119,9 +119,9 @@  discard block
 block discarded – undo
119 119
 	 * @param EEI_Address $obj_with_address
120 120
 	 * @return string
121 121
 	 */
122
-	public static function streetAddress( EEI_Address $obj_with_address = null ) {
122
+	public static function streetAddress(EEI_Address $obj_with_address = null) {
123 123
 		return $obj_with_address->address() !== null && $obj_with_address->address() !== ''
124
-			? '<span itemprop="streetAddress">' . $obj_with_address->address() . '</span>' : '';
124
+			? '<span itemprop="streetAddress">'.$obj_with_address->address().'</span>' : '';
125 125
 	}
126 126
 
127 127
 
@@ -134,14 +134,14 @@  discard block
 block discarded – undo
134 134
 	 * @param EEI_Address $obj_with_address
135 135
 	 * @return string
136 136
 	 */
137
-	public static function postOfficeBoxNumber( EEI_Address $obj_with_address = null ) {
137
+	public static function postOfficeBoxNumber(EEI_Address $obj_with_address = null) {
138 138
 		// regex check for some form of PO Box or P.O. Box, etc, etc, etc
139
-		if ( preg_match(
139
+		if (preg_match(
140 140
 			"/^\s*((P(OST)?.?\s*(O(FF(ICE)?)?)?.?\s+(B(IN|OX))?)|B(IN|OX))/i",
141 141
 			$obj_with_address->address2()
142
-		) ) {
142
+		)) {
143 143
 			return $obj_with_address->address2() !== null && $obj_with_address->address2() !== ''
144
-				? '<span itemprop="postOfficeBoxNumber">' . $obj_with_address->address2() . '</span>' : '';
144
+				? '<span itemprop="postOfficeBoxNumber">'.$obj_with_address->address2().'</span>' : '';
145 145
 		} else {
146 146
 			return $obj_with_address->address2();
147 147
 		}
@@ -157,9 +157,9 @@  discard block
 block discarded – undo
157 157
 	 * @param EEI_Address $obj_with_address
158 158
 	 * @return string
159 159
 	 */
160
-	public static function addressLocality( EEI_Address $obj_with_address = null ) {
160
+	public static function addressLocality(EEI_Address $obj_with_address = null) {
161 161
 		return $obj_with_address->city() !== null && $obj_with_address->city() !== ''
162
-			? '<span itemprop="addressLocality">' . $obj_with_address->city() . '</span>' : '';
162
+			? '<span itemprop="addressLocality">'.$obj_with_address->city().'</span>' : '';
163 163
 	}
164 164
 
165 165
 
@@ -172,10 +172,10 @@  discard block
 block discarded – undo
172 172
 	 * @param EEI_Address $obj_with_address
173 173
 	 * @return string
174 174
 	 */
175
-	public static function addressRegion( EEI_Address $obj_with_address = null ) {
175
+	public static function addressRegion(EEI_Address $obj_with_address = null) {
176 176
 		$state = $obj_with_address->state_name();
177
-		if ( ! empty( $state ) ) {
178
-			return '<span itemprop="addressRegion">' . $state . '</span>';
177
+		if ( ! empty($state)) {
178
+			return '<span itemprop="addressRegion">'.$state.'</span>';
179 179
 		} else {
180 180
 			return '';
181 181
 		}
@@ -191,10 +191,10 @@  discard block
 block discarded – undo
191 191
 	 * @param EEI_Address $obj_with_address
192 192
 	 * @return string
193 193
 	 */
194
-	public static function addressCountry( EEI_Address $obj_with_address = null ) {
194
+	public static function addressCountry(EEI_Address $obj_with_address = null) {
195 195
 		$country = $obj_with_address->country_name();
196
-		if ( ! empty( $country ) ) {
197
-			return '<span itemprop="addressCountry">' . $country . '</span>';
196
+		if ( ! empty($country)) {
197
+			return '<span itemprop="addressCountry">'.$country.'</span>';
198 198
 		} else {
199 199
 			return '';
200 200
 		}
@@ -210,7 +210,7 @@  discard block
 block discarded – undo
210 210
 	 * @param EEI_Address $obj_with_address
211 211
 	 * @return string
212 212
 	 */
213
-	public static function postalCode( EEI_Address $obj_with_address = null ) {
213
+	public static function postalCode(EEI_Address $obj_with_address = null) {
214 214
 		return $obj_with_address->zip() !== null && $obj_with_address->zip() !== '' ? '<span itemprop="postalCode">'
215 215
 		                                                                              . $obj_with_address->zip()
216 216
 		                                                                              . '</span>' : '';
@@ -226,8 +226,8 @@  discard block
 block discarded – undo
226 226
 	 * @param string $phone_nmbr
227 227
 	 * @return string
228 228
 	 */
229
-	public static function telephone( $phone_nmbr = null ) {
230
-		return $phone_nmbr !== null && $phone_nmbr !== '' ? '<span itemprop="telephone">' . $phone_nmbr . '</span>'
229
+	public static function telephone($phone_nmbr = null) {
230
+		return $phone_nmbr !== null && $phone_nmbr !== '' ? '<span itemprop="telephone">'.$phone_nmbr.'</span>'
231 231
 			: '';
232 232
 	}
233 233
 
@@ -243,13 +243,13 @@  discard block
 block discarded – undo
243 243
 	 * @param array  $attributes - array of additional link attributes in  attribute_name => value pairs. ie: array( 'title' => 'click here', 'class' => 'link-class' )
244 244
 	 * @return string (link)
245 245
 	 */
246
-	public static function url( $url = null, $text = null, $attributes = array() ) {
246
+	public static function url($url = null, $text = null, $attributes = array()) {
247 247
 		$atts = '';
248
-		foreach ( $attributes as $attribute => $value ) {
249
-			$atts .= ' ' . $attribute . '="' . $value . '"';
248
+		foreach ($attributes as $attribute => $value) {
249
+			$atts .= ' '.$attribute.'="'.$value.'"';
250 250
 		}
251 251
 		$text = $text !== null && $text !== '' ? $text : $url;
252
-		return $url !== null && $url !== '' ? '<a itemprop="url" href="' . $url . '"' . $atts . '>' . $text . '</a>'
252
+		return $url !== null && $url !== '' ? '<a itemprop="url" href="'.$url.'"'.$atts.'>'.$text.'</a>'
253 253
 			: '';
254 254
 	}
255 255
 
Please login to merge, or discard this patch.
core/db_models/fields/EE_Model_Field_Base.php 1 patch
Indentation   +634 added lines, -635 removed lines patch added patch discarded remove patch
@@ -21,639 +21,638 @@
 block discarded – undo
21 21
  */
22 22
 abstract class EE_Model_Field_Base implements HasSchemaInterface
23 23
 {
24
-    /**
25
-     * The alias for the table the column belongs to.
26
-     * @var string
27
-     */
28
-    protected $_table_alias;
29
-
30
-    /**
31
-     * The actual db column name for the table
32
-     * @var string
33
-     */
34
-    protected $_table_column;
35
-
36
-
37
-    /**
38
-     * The authoritative name for the table column (used by client code to reference the field).
39
-     * @var string
40
-     */
41
-    protected $_name;
42
-
43
-
44
-    /**
45
-     * A description for the field.
46
-     * @var string
47
-     */
48
-    protected $_nicename;
49
-
50
-
51
-    /**
52
-     * Whether the field is nullable or not
53
-     * @var bool
54
-     */
55
-    protected $_nullable;
56
-
57
-
58
-    /**
59
-     * What the default value for the field should be.
60
-     * @var mixed
61
-     */
62
-    protected $_default_value;
63
-
64
-
65
-    /**
66
-     * Other configuration for the field
67
-     * @var mixed
68
-     */
69
-    protected $_other_config;
70
-
71
-
72
-    /**
73
-     * The name of the model this field is instantiated for.
74
-     * @var string
75
-     */
76
-    protected $_model_name;
77
-
78
-
79
-    /**
80
-     * This should be a json-schema valid data type for the field.
81
-     * @link http://json-schema.org/latest/json-schema-core.html#rfc.section.4.2
82
-     * @var string
83
-     */
84
-    private $_schema_type = 'string';
85
-
86
-
87
-    /**
88
-     * If the schema has a defined format then it should be defined via this property.
89
-     * @link http://json-schema.org/latest/json-schema-validation.html#rfc.section.7
90
-     * @var string
91
-     */
92
-    private $_schema_format = '';
93
-
94
-
95
-    /**
96
-     * Indicates that the value of the field is managed exclusively by the server/model and not something
97
-     * settable by client code.
98
-     * @link http://json-schema.org/latest/json-schema-hypermedia.html#rfc.section.4.4
99
-     * @var bool
100
-     */
101
-    private $_schema_readonly = false;
102
-
103
-
104
-    /**
105
-     * @param string $table_column
106
-     * @param string $nicename
107
-     * @param bool   $nullable
108
-     * @param null   $default_value
109
-     */
110
-    public function __construct($table_column, $nicename, $nullable, $default_value = null)
111
-    {
112
-        $this->_table_column  = $table_column;
113
-        $this->_nicename      = $nicename;
114
-        $this->_nullable      = $nullable;
115
-        $this->_default_value = $default_value;
116
-    }
117
-
118
-
119
-    /**
120
-     * @param $table_alias
121
-     * @param $name
122
-     * @param $model_name
123
-     */
124
-    public function _construct_finalize($table_alias, $name, $model_name)
125
-    {
126
-        $this->_table_alias = $table_alias;
127
-        $this->_name        = $name;
128
-        $this->_model_name  = $model_name;
129
-        /**
130
-         * allow for changing the defaults
131
-         */
132
-        $this->_nicename      = apply_filters('FHEE__EE_Model_Field_Base___construct_finalize___nicename',
133
-            $this->_nicename, $this);
134
-        $this->_default_value = apply_filters('FHEE__EE_Model_Field_Base___construct_finalize___default_value',
135
-            $this->_default_value, $this);
136
-    }
137
-
138
-    public function get_table_alias()
139
-    {
140
-        return $this->_table_alias;
141
-    }
142
-
143
-    public function get_table_column()
144
-    {
145
-        return $this->_table_column;
146
-    }
147
-
148
-    /**
149
-     * Returns the name of the model this field is on. Eg 'Event' or 'Ticket_Datetime'
150
-     *
151
-     * @return string
152
-     */
153
-    public function get_model_name()
154
-    {
155
-        return $this->_model_name;
156
-    }
157
-
158
-    /**
159
-     * @throws \EE_Error
160
-     * @return string
161
-     */
162
-    public function get_name()
163
-    {
164
-        if ($this->_name) {
165
-            return $this->_name;
166
-        } else {
167
-            throw new EE_Error(sprintf(__("Model field '%s' has no name set. Did you make a model and forget to call the parent model constructor?",
168
-                "event_espresso"), get_class($this)));
169
-        }
170
-    }
171
-
172
-    public function get_nicename()
173
-    {
174
-        return $this->_nicename;
175
-    }
176
-
177
-    public function is_nullable()
178
-    {
179
-        return $this->_nullable;
180
-    }
181
-
182
-    /**
183
-     * returns whether this field is an auto-increment field or not. If it is, then
184
-     * on insertion it can be null. However, on updates it must be present.
185
-     *
186
-     * @return boolean
187
-     */
188
-    public function is_auto_increment()
189
-    {
190
-        return false;
191
-    }
192
-
193
-    /**
194
-     * The default value in the model object's value domain. See lengthy comment about
195
-     * value domains at the top of EEM_Base
196
-     *
197
-     * @return mixed
198
-     */
199
-    public function get_default_value()
200
-    {
201
-        return $this->_default_value;
202
-    }
203
-
204
-    /**
205
-     * Returns the table alias joined to the table column, however this isn't the right
206
-     * table alias if the aliased table is being joined to. In that case, you can use
207
-     * EE_Model_Parser::extract_table_alias_model_relation_chain_prefix() to find the table's current alias
208
-     * in the current query
209
-     *
210
-     * @return string
211
-     */
212
-    public function get_qualified_column()
213
-    {
214
-        return $this->get_table_alias() . "." . $this->get_table_column();
215
-    }
216
-
217
-    /**
218
-     * When get() is called on a model object (eg EE_Event), before returning its value,
219
-     * call this function on it, allowing us to customize the returned value based on
220
-     * the field's type. Eg, we may want ot serialize it, strip tags, etc. By default,
221
-     * we simply return it.
222
-     *
223
-     * @param mixed $value_of_field_on_model_object
224
-     * @return mixed
225
-     */
226
-    public function prepare_for_get($value_of_field_on_model_object)
227
-    {
228
-        return $value_of_field_on_model_object;
229
-    }
230
-
231
-    /**
232
-     * When inserting or updating a field on a model object, run this function on each
233
-     * value to prepare it for insertion into the db. We may want to add slashes, serialize it, etc.
234
-     * By default, we do nothing.
235
-     *
236
-     * @param mixed $value_of_field_on_model_object
237
-     * @return mixed
238
-     */
239
-    public function prepare_for_use_in_db($value_of_field_on_model_object)
240
-    {
241
-        return $value_of_field_on_model_object;
242
-    }
243
-
244
-    /**
245
-     * When creating a brand-new model object, or setting a particular value for one of its fields, this function
246
-     * is called before setting it on the model object. We may want to strip slashes, unserialize the value, etc.
247
-     * By default, we do nothing.
248
-     *
249
-     * @param mixed $value_inputted_for_field_on_model_object
250
-     * @return mixed
251
-     */
252
-    public function prepare_for_set($value_inputted_for_field_on_model_object)
253
-    {
254
-        return $value_inputted_for_field_on_model_object;
255
-    }
256
-
257
-
258
-    /**
259
-     * When instantiating a model object from DB results, this function is called before setting each field.
260
-     * We may want to serialize the value, etc. By default, we return the value using prepare_for_set() method as that
261
-     * is the one child classes will most often define.
262
-     *
263
-     * @param mixed $value_found_in_db_for_model_object
264
-     * @return mixed
265
-     */
266
-    public function prepare_for_set_from_db($value_found_in_db_for_model_object)
267
-    {
268
-        return $this->prepare_for_set($value_found_in_db_for_model_object);
269
-    }
270
-
271
-    /**
272
-     * When echoing a field's value on a model object, this function is run to prepare the value for presentation in a
273
-     * webpage. For example, we may want to output floats with 2 decimal places by default, dates as "Monday Jan 12,
274
-     * 2013, at 3:23pm" instead of
275
-     * "8765678632", or any other modifications to how the value should be displayed, but not modified itself.
276
-     *
277
-     * @param mixed $value_on_field_to_be_outputted
278
-     * @return mixed
279
-     */
280
-    public function prepare_for_pretty_echoing($value_on_field_to_be_outputted)
281
-    {
282
-        return $value_on_field_to_be_outputted;
283
-    }
284
-
285
-
286
-    /**
287
-     * Returns whatever is set as the nicename for the object.
288
-     * @return string
289
-     */
290
-    public function getSchemaDescription()
291
-    {
292
-        return $this->get_nicename();
293
-    }
294
-
295
-
296
-    /**
297
-     * Returns whatever is set as the $_schema_type property for the object.
298
-     * Note: this will automatically add 'null' to the schema if the object is_nullable()
299
-     * @return string|array
300
-     */
301
-    public function getSchemaType()
302
-    {
303
-        if ($this->is_nullable()) {
304
-            $this->_schema_type = (array) $this->_schema_type;
305
-            if (! in_array('null', $this->_schema_type)) {
306
-                $this->_schema_type[] = 'null';
307
-            };
308
-        }
309
-        return $this->_schema_type;
310
-    }
311
-
312
-
313
-    /**
314
-     * Sets the _schema_type property.  Child classes should call this in their constructors to override the default state
315
-     * for this property.
316
-     * @param string|array $type
317
-     * @throws InvalidArgumentException
318
-     */
319
-    protected function setSchemaType($type)
320
-    {
321
-        $this->validateSchemaType($type);
322
-        $this->_schema_type = $type;
323
-    }
324
-
325
-
326
-    /**
327
-     * This is usually present when the $_schema_type property is 'object'.  Any child classes will need to override
328
-     * this method and return the properties for the schema.
329
-     *
330
-     * The reason this is not a property on the class is because there may be filters set on the values for the property
331
-     * that won't be exposed on construct.  For example enum type schemas may have the enum values filtered.
332
-     *
333
-     * @return array
334
-     */
335
-    public function getSchemaProperties()
336
-    {
337
-        return array();
338
-    }
339
-
340
-
341
-
342
-    /**
343
-     * By default this returns the scalar default value that was sent in on the class prepped according to the class type
344
-     * as the default.  However, when there are schema properties, then the default property is setup to mirror the
345
-     * property keys and correctly prepare the default according to that expected property value.
346
-     * The getSchema method validates whether the schema for default is setup correctly or not according to the schema type
347
-     *
348
-     * @return mixed
349
-     */
350
-    public function getSchemaDefault()
351
-    {
352
-        $default_value = $this->prepare_for_use_in_db($this->prepare_for_set($this->get_default_value()));
353
-        $schema_properties = $this->getSchemaProperties();
354
-
355
-        //if this schema has properties than shape the default value to match the properties shape.
356
-        if ($schema_properties) {
357
-            $value_to_return = array();
358
-            foreach ($schema_properties as $property_key => $property_schema) {
359
-                switch ($property_key) {
360
-                    case 'pretty':
361
-                    case 'rendered':
362
-                        $value_to_return[$property_key] = $this->prepare_for_pretty_echoing($this->prepare_for_set($default_value));
363
-                        break;
364
-                    default:
365
-                        $value_to_return[$property_key] = $default_value;
366
-                        break;
367
-                }
368
-            }
369
-            $default_value = $value_to_return;
370
-        }
371
-        return $default_value;
372
-    }
373
-
374
-
375
-
376
-
377
-    /**
378
-     * If a child class has enum values, they should override this method and provide a simple array
379
-     * of the enum values.
380
-
381
-     * The reason this is not a property on the class is because there may be filterable enum values that
382
-     * are set on the instantiated object that could be filtered after construct.
383
-     *
384
-     * @return array
385
-     */
386
-    public function getSchemaEnum()
387
-    {
388
-        return array();
389
-    }
390
-
391
-
392
-    /**
393
-     * This returns the value of the $_schema_format property on the object.
394
-     * @return string
395
-     */
396
-    public function getSchemaFormat()
397
-    {
398
-        return $this->_schema_format;
399
-    }
400
-
401
-
402
-    /**
403
-     * Sets the schema format property.
404
-     * @throws InvalidArgumentException
405
-     * @param string $format
406
-     */
407
-    protected function setSchemaFormat($format)
408
-    {
409
-        $this->validateSchemaFormat($format);
410
-        $this->_schema_format = $format;
411
-    }
412
-
413
-
414
-    /**
415
-     * This returns the value of the $_schema_readonly property on the object.
416
-     * @return bool
417
-     */
418
-    public function getSchemaReadonly()
419
-    {
420
-        return $this->_schema_readonly;
421
-    }
422
-
423
-
424
-    /**
425
-     * This sets the value for the $_schema_readonly property.
426
-     * @param bool $readonly  (only explicit boolean values are accepted)
427
-     */
428
-    protected function setSchemaReadOnly($readonly)
429
-    {
430
-        if (! is_bool($readonly)) {
431
-            throw new InvalidArgumentException(
432
-                sprintf(
433
-                    esc_html__('The incoming argument (%s) must be a boolean.', 'event_espresso'),
434
-                    print_r($readonly, true)
435
-                )
436
-            );
437
-        }
438
-
439
-        $this->_schema_readonly = $readonly;
440
-    }
441
-
442
-
443
-
444
-
445
-    /**
446
-     * Return `%d`, `%s` or `%f` to indicate the data type for the field.
447
-     * @uses _get_wpdb_data_type()
448
-     *
449
-     * @return string
450
-     */
451
-    public function get_wpdb_data_type()
452
-    {
453
-        return $this->_get_wpdb_data_type();
454
-    }
455
-
456
-
457
-    /**
458
-     * Return `%d`, `%s` or `%f` to indicate the data type for the field that should be indicated in wpdb queries.
459
-     * @param string $type  Included if a specific type is requested.
460
-     * @uses get_schema_type()
461
-     * @return string
462
-     */
463
-    protected function _get_wpdb_data_type($type='')
464
-    {
465
-        $type = empty($type) ? $this->getSchemaType() : $type;
466
-
467
-        //if type is an array, then different parsing is required.
468
-        if (is_array($type)) {
469
-            return $this->_get_wpdb_data_type_for_type_array($type);
470
-        }
471
-
472
-        $wpdb_type = '%s';
473
-        switch ($type) {
474
-            case 'number':
475
-                $wpdb_type = '%f';
476
-                break;
477
-            case 'integer':
478
-            case 'boolean':
479
-                $wpdb_type = '%d';
480
-                break;
481
-            case 'object':
482
-                $properties = $this->getSchemaProperties();
483
-                if (isset($properties['raw'], $properties['raw']['type'])) {
484
-                    $wpdb_type = $this->_get_wpdb_data_type($properties['raw']['type']);
485
-                }
486
-                break; //leave at default
487
-        }
488
-        return $wpdb_type;
489
-    }
490
-
491
-
492
-
493
-    protected function _get_wpdb_data_type_for_type_array($type)
494
-    {
495
-        $type = (array) $type;
496
-        //first let's flip because then we can do a faster key check
497
-        $type = array_flip($type);
498
-
499
-        //check for things that mean '%s'
500
-        if (isset($type['string'],$type['object'],$type['array'])) {
501
-            return '%s';
502
-        }
503
-
504
-        //if makes it past the above condition and there's float in the array
505
-        //then the type is %f
506
-        if (isset($type['number'])) {
507
-            return '%f';
508
-        }
509
-
510
-        //if it makes it above the above conditions and there is an integer in the array
511
-        //then the type is %d
512
-        if (isset($type['integer'])) {
513
-            return '%d';
514
-        }
515
-
516
-        //anything else is a string
517
-        return '%s';
518
-    }
519
-
520
-
521
-    /**
522
-     * This returns elements used to represent this field in the json schema.
523
-     *
524
-     * @link http://json-schema.org/
525
-     * @return array
526
-     */
527
-    public function getSchema()
528
-    {
529
-        $schema = array(
530
-            'description' => $this->getSchemaDescription(),
531
-            'type' => $this->getSchemaType(),
532
-            'readonly' => $this->getSchemaReadonly(),
533
-            'default' => $this->getSchemaDefault()
534
-        );
535
-
536
-        //optional properties of the schema
537
-        $enum = $this->getSchemaEnum();
538
-        $properties = $this->getSchemaProperties();
539
-        $format = $this->getSchemaFormat();
540
-        if ($enum) {
541
-            $schema['enum'] = $enum;
542
-        }
543
-
544
-        if ($properties) {
545
-            $schema['properties'] = $properties;
546
-        }
547
-
548
-        if ($format) {
549
-            $schema['format'] = $format;
550
-        }
551
-        return $schema;
552
-    }
553
-
554
-    /**
555
-     * Some fields are in the database-only, (ie, used in queries etc), but shouldn't necessarily be part
556
-     * of the model objects (ie, client code shouldn't care to ever see their value... if client code does
557
-     * want to see their value, then they shouldn't be db-only fields!)
558
-     * Eg, when doing events as custom post types, querying the post_type is essential, but
559
-     * post_type is irrelevant for EE_Event objects (because they will ALL be of post_type 'esp_event').
560
-     * By default, all fields aren't db-only.
561
-     *
562
-     * @return boolean
563
-     */
564
-    public function is_db_only_field()
565
-    {
566
-        return false;
567
-    }
568
-
569
-
570
-    /**
571
-     * Validates the incoming string|array to ensure its an allowable type.
572
-     * @throws InvalidArgumentException
573
-     * @param string|array $type
574
-     */
575
-    private function validateSchemaType($type)
576
-    {
577
-        if (! (is_string($type) || is_array($type))) {
578
-            throw new InvalidArgumentException(
579
-                sprintf(
580
-                    esc_html__('The incoming argument (%s) must be a string or an array.', 'event_espresso'),
581
-                    print_r($type, true)
582
-                )
583
-            );
584
-        }
585
-
586
-        //validate allowable types.
587
-        //@link http://json-schema.org/latest/json-schema-core.html#rfc.section.4.2
588
-        $allowable_types = array_flip(
589
-            array(
590
-                'string',
591
-                'number',
592
-                'null',
593
-                'object',
594
-                'array',
595
-                'boolean',
596
-                'integer'
597
-            )
598
-        );
599
-
600
-        if (is_array($type)) {
601
-            foreach ($type as $item_in_type) {
602
-                $this->validateSchemaType($item_in_type);
603
-            }
604
-            return;
605
-        }
606
-
607
-        if (! isset($allowable_types[$type])) {
608
-            throw new InvalidArgumentException(
609
-                sprintf(
610
-                    esc_html__('The incoming argument (%1$s) must be one of the allowable types: %2$s', 'event_espresso'),
611
-                    $type,
612
-                    implode(',', array_flip($allowable_types))
613
-                )
614
-            );
615
-        }
616
-    }
617
-
618
-
619
-    /**
620
-     * Validates that the incoming format is an allowable string to use for the _schema_format property
621
-     * @throws InvalidArgumentException
622
-     * @param $format
623
-     */
624
-    private function validateSchemaFormat($format)
625
-    {
626
-        if (! is_string($format)) {
627
-            throw new InvalidArgumentException(
628
-                sprintf(
629
-                    esc_html__('The incoming argument (%s) must be a string.', 'event_espresso'),
630
-                    print_r($format, true)
631
-                )
632
-            );
633
-        }
634
-
635
-        //validate allowable format values
636
-        //@link http://json-schema.org/latest/json-schema-validation.html#rfc.section.7
637
-        $allowable_formats = array_flip(
638
-            array(
639
-                'date-time',
640
-                'email',
641
-                'hostname',
642
-                'ipv4',
643
-                'ipv6',
644
-                'uri',
645
-                'uriref'
646
-            )
647
-        );
648
-
649
-        if (! isset($allowable_formats[$format])) {
650
-            throw new InvalidArgumentException(
651
-                sprintf(
652
-                    esc_html__('The incoming argument (%1$s) must be one of the allowable formats: %2$s', 'event_espresso'),
653
-                    $format,
654
-                    implode(',', array_flip($allowable_formats))
655
-                )
656
-            );
657
-        }
658
-    }
24
+	/**
25
+	 * The alias for the table the column belongs to.
26
+	 * @var string
27
+	 */
28
+	protected $_table_alias;
29
+
30
+	/**
31
+	 * The actual db column name for the table
32
+	 * @var string
33
+	 */
34
+	protected $_table_column;
35
+
36
+
37
+	/**
38
+	 * The authoritative name for the table column (used by client code to reference the field).
39
+	 * @var string
40
+	 */
41
+	protected $_name;
42
+
43
+
44
+	/**
45
+	 * A description for the field.
46
+	 * @var string
47
+	 */
48
+	protected $_nicename;
49
+
50
+
51
+	/**
52
+	 * Whether the field is nullable or not
53
+	 * @var bool
54
+	 */
55
+	protected $_nullable;
56
+
57
+
58
+	/**
59
+	 * What the default value for the field should be.
60
+	 * @var mixed
61
+	 */
62
+	protected $_default_value;
63
+
64
+
65
+	/**
66
+	 * Other configuration for the field
67
+	 * @var mixed
68
+	 */
69
+	protected $_other_config;
70
+
71
+
72
+	/**
73
+	 * The name of the model this field is instantiated for.
74
+	 * @var string
75
+	 */
76
+	protected $_model_name;
77
+
78
+
79
+	/**
80
+	 * This should be a json-schema valid data type for the field.
81
+	 * @link http://json-schema.org/latest/json-schema-core.html#rfc.section.4.2
82
+	 * @var string
83
+	 */
84
+	private $_schema_type = 'string';
85
+
86
+
87
+	/**
88
+	 * If the schema has a defined format then it should be defined via this property.
89
+	 * @link http://json-schema.org/latest/json-schema-validation.html#rfc.section.7
90
+	 * @var string
91
+	 */
92
+	private $_schema_format = '';
93
+
94
+
95
+	/**
96
+	 * Indicates that the value of the field is managed exclusively by the server/model and not something
97
+	 * settable by client code.
98
+	 * @link http://json-schema.org/latest/json-schema-hypermedia.html#rfc.section.4.4
99
+	 * @var bool
100
+	 */
101
+	private $_schema_readonly = false;
102
+
103
+
104
+	/**
105
+	 * @param string $table_column
106
+	 * @param string $nicename
107
+	 * @param bool   $nullable
108
+	 * @param null   $default_value
109
+	 */
110
+	public function __construct($table_column, $nicename, $nullable, $default_value = null)
111
+	{
112
+		$this->_table_column  = $table_column;
113
+		$this->_nicename      = $nicename;
114
+		$this->_nullable      = $nullable;
115
+		$this->_default_value = $default_value;
116
+	}
117
+
118
+
119
+	/**
120
+	 * @param $table_alias
121
+	 * @param $name
122
+	 * @param $model_name
123
+	 */
124
+	public function _construct_finalize($table_alias, $name, $model_name)
125
+	{
126
+		$this->_table_alias = $table_alias;
127
+		$this->_name        = $name;
128
+		$this->_model_name  = $model_name;
129
+		/**
130
+		 * allow for changing the defaults
131
+		 */
132
+		$this->_nicename      = apply_filters('FHEE__EE_Model_Field_Base___construct_finalize___nicename',
133
+			$this->_nicename, $this);
134
+		$this->_default_value = apply_filters('FHEE__EE_Model_Field_Base___construct_finalize___default_value',
135
+			$this->_default_value, $this);
136
+	}
137
+
138
+	public function get_table_alias()
139
+	{
140
+		return $this->_table_alias;
141
+	}
142
+
143
+	public function get_table_column()
144
+	{
145
+		return $this->_table_column;
146
+	}
147
+
148
+	/**
149
+	 * Returns the name of the model this field is on. Eg 'Event' or 'Ticket_Datetime'
150
+	 *
151
+	 * @return string
152
+	 */
153
+	public function get_model_name()
154
+	{
155
+		return $this->_model_name;
156
+	}
157
+
158
+	/**
159
+	 * @throws \EE_Error
160
+	 * @return string
161
+	 */
162
+	public function get_name()
163
+	{
164
+		if ($this->_name) {
165
+			return $this->_name;
166
+		} else {
167
+			throw new EE_Error(sprintf(__("Model field '%s' has no name set. Did you make a model and forget to call the parent model constructor?",
168
+				"event_espresso"), get_class($this)));
169
+		}
170
+	}
171
+
172
+	public function get_nicename()
173
+	{
174
+		return $this->_nicename;
175
+	}
176
+
177
+	public function is_nullable()
178
+	{
179
+		return $this->_nullable;
180
+	}
181
+
182
+	/**
183
+	 * returns whether this field is an auto-increment field or not. If it is, then
184
+	 * on insertion it can be null. However, on updates it must be present.
185
+	 *
186
+	 * @return boolean
187
+	 */
188
+	public function is_auto_increment()
189
+	{
190
+		return false;
191
+	}
192
+
193
+	/**
194
+	 * The default value in the model object's value domain. See lengthy comment about
195
+	 * value domains at the top of EEM_Base
196
+	 *
197
+	 * @return mixed
198
+	 */
199
+	public function get_default_value()
200
+	{
201
+		return $this->_default_value;
202
+	}
203
+
204
+	/**
205
+	 * Returns the table alias joined to the table column, however this isn't the right
206
+	 * table alias if the aliased table is being joined to. In that case, you can use
207
+	 * EE_Model_Parser::extract_table_alias_model_relation_chain_prefix() to find the table's current alias
208
+	 * in the current query
209
+	 *
210
+	 * @return string
211
+	 */
212
+	public function get_qualified_column()
213
+	{
214
+		return $this->get_table_alias() . "." . $this->get_table_column();
215
+	}
216
+
217
+	/**
218
+	 * When get() is called on a model object (eg EE_Event), before returning its value,
219
+	 * call this function on it, allowing us to customize the returned value based on
220
+	 * the field's type. Eg, we may want ot serialize it, strip tags, etc. By default,
221
+	 * we simply return it.
222
+	 *
223
+	 * @param mixed $value_of_field_on_model_object
224
+	 * @return mixed
225
+	 */
226
+	public function prepare_for_get($value_of_field_on_model_object)
227
+	{
228
+		return $value_of_field_on_model_object;
229
+	}
230
+
231
+	/**
232
+	 * When inserting or updating a field on a model object, run this function on each
233
+	 * value to prepare it for insertion into the db. We may want to add slashes, serialize it, etc.
234
+	 * By default, we do nothing.
235
+	 *
236
+	 * @param mixed $value_of_field_on_model_object
237
+	 * @return mixed
238
+	 */
239
+	public function prepare_for_use_in_db($value_of_field_on_model_object)
240
+	{
241
+		return $value_of_field_on_model_object;
242
+	}
243
+
244
+	/**
245
+	 * When creating a brand-new model object, or setting a particular value for one of its fields, this function
246
+	 * is called before setting it on the model object. We may want to strip slashes, unserialize the value, etc.
247
+	 * By default, we do nothing.
248
+	 *
249
+	 * @param mixed $value_inputted_for_field_on_model_object
250
+	 * @return mixed
251
+	 */
252
+	public function prepare_for_set($value_inputted_for_field_on_model_object)
253
+	{
254
+		return $value_inputted_for_field_on_model_object;
255
+	}
256
+
257
+
258
+	/**
259
+	 * When instantiating a model object from DB results, this function is called before setting each field.
260
+	 * We may want to serialize the value, etc. By default, we return the value using prepare_for_set() method as that
261
+	 * is the one child classes will most often define.
262
+	 *
263
+	 * @param mixed $value_found_in_db_for_model_object
264
+	 * @return mixed
265
+	 */
266
+	public function prepare_for_set_from_db($value_found_in_db_for_model_object)
267
+	{
268
+		return $this->prepare_for_set($value_found_in_db_for_model_object);
269
+	}
270
+
271
+	/**
272
+	 * When echoing a field's value on a model object, this function is run to prepare the value for presentation in a
273
+	 * webpage. For example, we may want to output floats with 2 decimal places by default, dates as "Monday Jan 12,
274
+	 * 2013, at 3:23pm" instead of
275
+	 * "8765678632", or any other modifications to how the value should be displayed, but not modified itself.
276
+	 *
277
+	 * @param mixed $value_on_field_to_be_outputted
278
+	 * @return mixed
279
+	 */
280
+	public function prepare_for_pretty_echoing($value_on_field_to_be_outputted)
281
+	{
282
+		return $value_on_field_to_be_outputted;
283
+	}
284
+
285
+
286
+	/**
287
+	 * Returns whatever is set as the nicename for the object.
288
+	 * @return string
289
+	 */
290
+	public function getSchemaDescription()
291
+	{
292
+		return $this->get_nicename();
293
+	}
294
+
295
+
296
+	/**
297
+	 * Returns whatever is set as the $_schema_type property for the object.
298
+	 * Note: this will automatically add 'null' to the schema if the object is_nullable()
299
+	 * @return string|array
300
+	 */
301
+	public function getSchemaType()
302
+	{
303
+		if ($this->is_nullable()) {
304
+			$this->_schema_type = (array) $this->_schema_type;
305
+			if (! in_array('null', $this->_schema_type)) {
306
+				$this->_schema_type[] = 'null';
307
+			};
308
+		}
309
+		return $this->_schema_type;
310
+	}
311
+
312
+
313
+	/**
314
+	 * Sets the _schema_type property.  Child classes should call this in their constructors to override the default state
315
+	 * for this property.
316
+	 * @param string|array $type
317
+	 * @throws InvalidArgumentException
318
+	 */
319
+	protected function setSchemaType($type)
320
+	{
321
+		$this->validateSchemaType($type);
322
+		$this->_schema_type = $type;
323
+	}
324
+
325
+
326
+	/**
327
+	 * This is usually present when the $_schema_type property is 'object'.  Any child classes will need to override
328
+	 * this method and return the properties for the schema.
329
+	 *
330
+	 * The reason this is not a property on the class is because there may be filters set on the values for the property
331
+	 * that won't be exposed on construct.  For example enum type schemas may have the enum values filtered.
332
+	 *
333
+	 * @return array
334
+	 */
335
+	public function getSchemaProperties()
336
+	{
337
+		return array();
338
+	}
339
+
340
+
341
+
342
+	/**
343
+	 * By default this returns the scalar default value that was sent in on the class prepped according to the class type
344
+	 * as the default.  However, when there are schema properties, then the default property is setup to mirror the
345
+	 * property keys and correctly prepare the default according to that expected property value.
346
+	 * The getSchema method validates whether the schema for default is setup correctly or not according to the schema type
347
+	 *
348
+	 * @return mixed
349
+	 */
350
+	public function getSchemaDefault()
351
+	{
352
+		$default_value = $this->prepare_for_use_in_db($this->prepare_for_set($this->get_default_value()));
353
+		$schema_properties = $this->getSchemaProperties();
354
+
355
+		//if this schema has properties than shape the default value to match the properties shape.
356
+		if ($schema_properties) {
357
+			$value_to_return = array();
358
+			foreach ($schema_properties as $property_key => $property_schema) {
359
+				switch ($property_key) {
360
+					case 'pretty':
361
+					case 'rendered':
362
+						$value_to_return[$property_key] = $this->prepare_for_pretty_echoing($this->prepare_for_set($default_value));
363
+						break;
364
+					default:
365
+						$value_to_return[$property_key] = $default_value;
366
+						break;
367
+				}
368
+			}
369
+			$default_value = $value_to_return;
370
+		}
371
+		return $default_value;
372
+	}
373
+
374
+
375
+
376
+
377
+	/**
378
+	 * If a child class has enum values, they should override this method and provide a simple array
379
+	 * of the enum values.
380
+	 * The reason this is not a property on the class is because there may be filterable enum values that
381
+	 * are set on the instantiated object that could be filtered after construct.
382
+	 *
383
+	 * @return array
384
+	 */
385
+	public function getSchemaEnum()
386
+	{
387
+		return array();
388
+	}
389
+
390
+
391
+	/**
392
+	 * This returns the value of the $_schema_format property on the object.
393
+	 * @return string
394
+	 */
395
+	public function getSchemaFormat()
396
+	{
397
+		return $this->_schema_format;
398
+	}
399
+
400
+
401
+	/**
402
+	 * Sets the schema format property.
403
+	 * @throws InvalidArgumentException
404
+	 * @param string $format
405
+	 */
406
+	protected function setSchemaFormat($format)
407
+	{
408
+		$this->validateSchemaFormat($format);
409
+		$this->_schema_format = $format;
410
+	}
411
+
412
+
413
+	/**
414
+	 * This returns the value of the $_schema_readonly property on the object.
415
+	 * @return bool
416
+	 */
417
+	public function getSchemaReadonly()
418
+	{
419
+		return $this->_schema_readonly;
420
+	}
421
+
422
+
423
+	/**
424
+	 * This sets the value for the $_schema_readonly property.
425
+	 * @param bool $readonly  (only explicit boolean values are accepted)
426
+	 */
427
+	protected function setSchemaReadOnly($readonly)
428
+	{
429
+		if (! is_bool($readonly)) {
430
+			throw new InvalidArgumentException(
431
+				sprintf(
432
+					esc_html__('The incoming argument (%s) must be a boolean.', 'event_espresso'),
433
+					print_r($readonly, true)
434
+				)
435
+			);
436
+		}
437
+
438
+		$this->_schema_readonly = $readonly;
439
+	}
440
+
441
+
442
+
443
+
444
+	/**
445
+	 * Return `%d`, `%s` or `%f` to indicate the data type for the field.
446
+	 * @uses _get_wpdb_data_type()
447
+	 *
448
+	 * @return string
449
+	 */
450
+	public function get_wpdb_data_type()
451
+	{
452
+		return $this->_get_wpdb_data_type();
453
+	}
454
+
455
+
456
+	/**
457
+	 * Return `%d`, `%s` or `%f` to indicate the data type for the field that should be indicated in wpdb queries.
458
+	 * @param string $type  Included if a specific type is requested.
459
+	 * @uses get_schema_type()
460
+	 * @return string
461
+	 */
462
+	protected function _get_wpdb_data_type($type='')
463
+	{
464
+		$type = empty($type) ? $this->getSchemaType() : $type;
465
+
466
+		//if type is an array, then different parsing is required.
467
+		if (is_array($type)) {
468
+			return $this->_get_wpdb_data_type_for_type_array($type);
469
+		}
470
+
471
+		$wpdb_type = '%s';
472
+		switch ($type) {
473
+			case 'number':
474
+				$wpdb_type = '%f';
475
+				break;
476
+			case 'integer':
477
+			case 'boolean':
478
+				$wpdb_type = '%d';
479
+				break;
480
+			case 'object':
481
+				$properties = $this->getSchemaProperties();
482
+				if (isset($properties['raw'], $properties['raw']['type'])) {
483
+					$wpdb_type = $this->_get_wpdb_data_type($properties['raw']['type']);
484
+				}
485
+				break; //leave at default
486
+		}
487
+		return $wpdb_type;
488
+	}
489
+
490
+
491
+
492
+	protected function _get_wpdb_data_type_for_type_array($type)
493
+	{
494
+		$type = (array) $type;
495
+		//first let's flip because then we can do a faster key check
496
+		$type = array_flip($type);
497
+
498
+		//check for things that mean '%s'
499
+		if (isset($type['string'],$type['object'],$type['array'])) {
500
+			return '%s';
501
+		}
502
+
503
+		//if makes it past the above condition and there's float in the array
504
+		//then the type is %f
505
+		if (isset($type['number'])) {
506
+			return '%f';
507
+		}
508
+
509
+		//if it makes it above the above conditions and there is an integer in the array
510
+		//then the type is %d
511
+		if (isset($type['integer'])) {
512
+			return '%d';
513
+		}
514
+
515
+		//anything else is a string
516
+		return '%s';
517
+	}
518
+
519
+
520
+	/**
521
+	 * This returns elements used to represent this field in the json schema.
522
+	 *
523
+	 * @link http://json-schema.org/
524
+	 * @return array
525
+	 */
526
+	public function getSchema()
527
+	{
528
+		$schema = array(
529
+			'description' => $this->getSchemaDescription(),
530
+			'type' => $this->getSchemaType(),
531
+			'readonly' => $this->getSchemaReadonly(),
532
+			'default' => $this->getSchemaDefault()
533
+		);
534
+
535
+		//optional properties of the schema
536
+		$enum = $this->getSchemaEnum();
537
+		$properties = $this->getSchemaProperties();
538
+		$format = $this->getSchemaFormat();
539
+		if ($enum) {
540
+			$schema['enum'] = $enum;
541
+		}
542
+
543
+		if ($properties) {
544
+			$schema['properties'] = $properties;
545
+		}
546
+
547
+		if ($format) {
548
+			$schema['format'] = $format;
549
+		}
550
+		return $schema;
551
+	}
552
+
553
+	/**
554
+	 * Some fields are in the database-only, (ie, used in queries etc), but shouldn't necessarily be part
555
+	 * of the model objects (ie, client code shouldn't care to ever see their value... if client code does
556
+	 * want to see their value, then they shouldn't be db-only fields!)
557
+	 * Eg, when doing events as custom post types, querying the post_type is essential, but
558
+	 * post_type is irrelevant for EE_Event objects (because they will ALL be of post_type 'esp_event').
559
+	 * By default, all fields aren't db-only.
560
+	 *
561
+	 * @return boolean
562
+	 */
563
+	public function is_db_only_field()
564
+	{
565
+		return false;
566
+	}
567
+
568
+
569
+	/**
570
+	 * Validates the incoming string|array to ensure its an allowable type.
571
+	 * @throws InvalidArgumentException
572
+	 * @param string|array $type
573
+	 */
574
+	private function validateSchemaType($type)
575
+	{
576
+		if (! (is_string($type) || is_array($type))) {
577
+			throw new InvalidArgumentException(
578
+				sprintf(
579
+					esc_html__('The incoming argument (%s) must be a string or an array.', 'event_espresso'),
580
+					print_r($type, true)
581
+				)
582
+			);
583
+		}
584
+
585
+		//validate allowable types.
586
+		//@link http://json-schema.org/latest/json-schema-core.html#rfc.section.4.2
587
+		$allowable_types = array_flip(
588
+			array(
589
+				'string',
590
+				'number',
591
+				'null',
592
+				'object',
593
+				'array',
594
+				'boolean',
595
+				'integer'
596
+			)
597
+		);
598
+
599
+		if (is_array($type)) {
600
+			foreach ($type as $item_in_type) {
601
+				$this->validateSchemaType($item_in_type);
602
+			}
603
+			return;
604
+		}
605
+
606
+		if (! isset($allowable_types[$type])) {
607
+			throw new InvalidArgumentException(
608
+				sprintf(
609
+					esc_html__('The incoming argument (%1$s) must be one of the allowable types: %2$s', 'event_espresso'),
610
+					$type,
611
+					implode(',', array_flip($allowable_types))
612
+				)
613
+			);
614
+		}
615
+	}
616
+
617
+
618
+	/**
619
+	 * Validates that the incoming format is an allowable string to use for the _schema_format property
620
+	 * @throws InvalidArgumentException
621
+	 * @param $format
622
+	 */
623
+	private function validateSchemaFormat($format)
624
+	{
625
+		if (! is_string($format)) {
626
+			throw new InvalidArgumentException(
627
+				sprintf(
628
+					esc_html__('The incoming argument (%s) must be a string.', 'event_espresso'),
629
+					print_r($format, true)
630
+				)
631
+			);
632
+		}
633
+
634
+		//validate allowable format values
635
+		//@link http://json-schema.org/latest/json-schema-validation.html#rfc.section.7
636
+		$allowable_formats = array_flip(
637
+			array(
638
+				'date-time',
639
+				'email',
640
+				'hostname',
641
+				'ipv4',
642
+				'ipv6',
643
+				'uri',
644
+				'uriref'
645
+			)
646
+		);
647
+
648
+		if (! isset($allowable_formats[$format])) {
649
+			throw new InvalidArgumentException(
650
+				sprintf(
651
+					esc_html__('The incoming argument (%1$s) must be one of the allowable formats: %2$s', 'event_espresso'),
652
+					$format,
653
+					implode(',', array_flip($allowable_formats))
654
+				)
655
+			);
656
+		}
657
+	}
659 658
 }
660 659
\ No newline at end of file
Please login to merge, or discard this patch.
core/services/cache/TransientCacheStorage.php 3 patches
Unused Use Statements   -4 removed lines patch added patch discarded remove patch
@@ -1,10 +1,6 @@
 block discarded – undo
1 1
 <?php
2 2
 namespace EventEspresso\core\services\cache;
3 3
 
4
-use EE_Error;
5
-use WP_Error;
6
-use wpdb;
7
-
8 4
 defined('EVENT_ESPRESSO_VERSION') || exit;
9 5
 
10 6
 
Please login to merge, or discard this patch.
Indentation   +355 added lines, -355 removed lines patch added patch discarded remove patch
@@ -23,361 +23,361 @@
 block discarded – undo
23 23
 class TransientCacheStorage implements CacheStorageInterface
24 24
 {
25 25
 
26
-    /**
27
-     * wp-option option_name for tracking transients
28
-     *
29
-     * @type string
30
-     */
31
-    const TRANSIENT_SCHEDULE_OPTIONS_KEY = 'ee_transient_schedule';
32
-
33
-    /**
34
-     * @var int $current_time
35
-     */
36
-    private $current_time = 0;
37
-
38
-    /**
39
-     * how often to perform transient cleanup
40
-     *
41
-     * @var string $transient_cleanup_frequency
42
-     */
43
-    private $transient_cleanup_frequency = 'hour';
44
-
45
-    /**
46
-     * options for how often to perform transient cleanup
47
-     *
48
-     * @var array $transient_cleanup_frequency_options
49
-     */
50
-    private $transient_cleanup_frequency_options = array();
51
-
52
-    /**
53
-     * @var array $transients
54
-     */
55
-    private $transients = array();
56
-
57
-
58
-
59
-    /**
60
-     * TransientCacheStorage constructor.
61
-     */
62
-    public function __construct()
63
-    {
64
-        $this->transient_cleanup_frequency = $this->setTransientCleanupFrequency();
65
-        // round current time down to closest 5 minutes to simplify scheduling
66
-        $this->current_time = $this->roundTimestamp(time(), '5-minutes', false);
67
-        $this->transients = (array)get_option(TransientCacheStorage::TRANSIENT_SCHEDULE_OPTIONS_KEY, array());
68
-        if ( ! (defined('DOING_AJAX') && DOING_AJAX) && $this->transient_cleanup_frequency !== 'off') {
69
-            add_action('shutdown', array($this, 'checkTransientCleanupSchedule'), 999);
70
-        }
71
-    }
72
-
73
-
74
-
75
-    /**
76
-     * Sets how often transient cleanup occurs
77
-     *
78
-     * @return int
79
-     */
80
-    private function setTransientCleanupFrequency()
81
-    {
82
-        // sets how often transients are cleaned up
83
-        $this->transient_cleanup_frequency_options = apply_filters(
84
-            'FHEE__TransientCacheStorage__transient_cleanup_schedule_options',
85
-            array(
86
-                'off',
87
-                '15-minutes',
88
-                'hour',
89
-                '12-hours',
90
-                'day',
91
-            )
92
-        );
93
-        $transient_cleanup_frequency = apply_filters(
94
-            'FHEE__TransientCacheStorage__transient_cleanup_schedule',
95
-            'hour'
96
-        );
97
-        return in_array(
98
-            $transient_cleanup_frequency,
99
-            $this->transient_cleanup_frequency_options,
100
-            true
101
-        )
102
-            ? $transient_cleanup_frequency
103
-            : 'hour';
104
-    }
105
-
106
-
107
-
108
-    /**
109
-     * we need to be able to round timestamps off to match the set transient cleanup frequency
110
-     * so if a transient is set to expire at 1:17 pm for example, and our cleanup schedule is every hour,
111
-     * then that timestamp needs to be rounded up to 2:00 pm so that it is removed
112
-     * during the next scheduled cleanup after its expiration.
113
-     * We also round off the current time timestamp to the closest 5 minutes
114
-     * just to make the timestamps a little easier to round which helps with debugging.
115
-     *
116
-     * @param int    $timestamp [required]
117
-     * @param string $cleanup_frequency
118
-     * @param bool   $round_up
119
-     * @return false|int
120
-     */
121
-    private function roundTimestamp($timestamp, $cleanup_frequency = 'hour', $round_up = true)
122
-    {
123
-        $cleanup_frequency = $cleanup_frequency ? $cleanup_frequency : $this->transient_cleanup_frequency;
124
-        // in order to round the time to the closest xx minutes (or hours),
125
-        // we take the minutes (or hours) portion of the timestamp and divide it by xx,
126
-        // round down to a whole number, then multiply by xx to bring us almost back up to where we were
127
-        // why round down ? so the minutes (or hours) don't go over 60 (or 24)
128
-        // and bump the hour, which could bump the day, which could bump the month, etc,
129
-        // which would be bad because we don't always want to round up,
130
-        // but when we do we can easily achieve that by simply adding the desired offset,
131
-        $minutes = '00';
132
-        $hours = 'H';
133
-        switch ($cleanup_frequency) {
134
-            case '5-minutes' :
135
-                $minutes = floor((int)date('i', $timestamp) / 5) * 5;
136
-                $minutes = str_pad($minutes, 2, '0', STR_PAD_LEFT);
137
-                $offset = MINUTE_IN_SECONDS * 5;
138
-                break;
139
-            case '15-minutes' :
140
-                $minutes = floor((int)date('i', $timestamp) / 15) * 15;
141
-                $minutes = str_pad($minutes, 2, '0', STR_PAD_LEFT);
142
-                $offset = MINUTE_IN_SECONDS * 15;
143
-                break;
144
-            case '12-hours' :
145
-                $hours = floor((int)date('H', $timestamp) / 12) * 12;
146
-                $hours = str_pad($hours, 2, '0', STR_PAD_LEFT);
147
-                $offset = HOUR_IN_SECONDS * 12;
148
-                break;
149
-            case 'day' :
150
-                $hours = '03'; // run cleanup at 3:00 am (or first site hit after that)
151
-                $offset = DAY_IN_SECONDS;
152
-                break;
153
-            case 'hour' :
154
-            default :
155
-                $offset = HOUR_IN_SECONDS;
156
-                break;
157
-        }
158
-        $rounded_timestamp = strtotime(date("Y-m-d {$hours}:{$minutes}:00", $timestamp));
159
-        $rounded_timestamp += $round_up ? $offset : 0;
160
-        return apply_filters(
161
-            'FHEE__TransientCacheStorage__roundTimestamp__timestamp',
162
-            $rounded_timestamp,
163
-            $timestamp,
164
-            $cleanup_frequency,
165
-            $round_up
166
-        );
167
-    }
168
-
169
-
170
-
171
-    /**
172
-     * Saves supplied data to a transient
173
-     * if an expiration is set, then it automatically schedules the transient for cleanup
174
-     *
175
-     * @param string $transient_key [required]
176
-     * @param string $data          [required]
177
-     * @param int    $expiration    number of seconds until the cache expires
178
-     * @return bool
179
-     */
180
-    public function add($transient_key, $data, $expiration = 0)
181
-    {
182
-        $expiration = (int)abs($expiration);
183
-        $saved = set_transient($transient_key, $data, $expiration);
184
-        if ($saved && $expiration) {
185
-            $this->scheduleTransientCleanup($transient_key, $expiration);
186
-        }
187
-        return $saved;
188
-    }
189
-
190
-
191
-
192
-    /**
193
-     * retrieves transient data
194
-     * automatically triggers early cache refresh for standard cache items
195
-     * in order to avoid cache stampedes on busy sites.
196
-     * For non-standard cache items like PHP Session data where early refreshing is not wanted,
197
-     * the $standard_cache parameter should be set to false when retrieving data
198
-     *
199
-     * @param string $transient_key [required]
200
-     * @param bool   $standard_cache
201
-     * @return mixed|null
202
-     */
203
-    public function get($transient_key, $standard_cache = true)
204
-    {
205
-        // to avoid cache stampedes (AKA:dogpiles) for standard cache items,
206
-        // check if known cache expires within the next minute,
207
-        // and if so, remove it from our tracking and and return nothing.
208
-        // this should trigger the cache content to be regenerated during this request,
209
-        // while allowing any following requests to still access the existing cache
210
-        // until it gets replaced with the refreshed content
211
-        if (
212
-            $standard_cache
213
-            && isset($this->transients[$transient_key])
214
-            && $this->transients[$transient_key] - time() <= MINUTE_IN_SECONDS
215
-        ) {
216
-            unset($this->transients[$transient_key]);
217
-            $this->updateTransients();
218
-            return null;
219
-        }
220
-        $content = get_transient($transient_key);
221
-        return $content !== false ? $content : null;
222
-    }
223
-
224
-
225
-
226
-    /**
227
-     * delete a single transient and remove tracking
228
-     *
229
-     * @param string $transient_key [required] full or partial transient key to be deleted
230
-     */
231
-    public function delete($transient_key)
232
-    {
233
-        $this->deleteMany(array($transient_key));
234
-    }
235
-
236
-
237
-
238
-    /**
239
-     * delete multiple transients and remove tracking
240
-     *
241
-     * @param array $transient_keys [required] array of full or partial transient keys to be deleted
242
-     */
243
-    public function deleteMany(array $transient_keys)
244
-    {
245
-        $full_transient_keys = array();
246
-        foreach ($this->transients as $transient_key => $expiration) {
247
-            foreach ($transient_keys as $transient_key_to_delete) {
248
-                if (strpos($transient_key, $transient_key_to_delete) !== false) {
249
-                    $full_transient_keys[] = $transient_key;
250
-                }
251
-            }
252
-        }
253
-        if ($this->deleteTransientKeys($full_transient_keys)) {
254
-            $this->updateTransients();
255
-        }
256
-    }
257
-
258
-
259
-
260
-    /**
261
-     * sorts transients numerically by timestamp
262
-     * then saves the transient schedule to a WP option
263
-     */
264
-    private function updateTransients()
265
-    {
266
-        asort($this->transients, SORT_NUMERIC);
267
-        update_option(
268
-            TransientCacheStorage::TRANSIENT_SCHEDULE_OPTIONS_KEY,
269
-            $this->transients
270
-        );
271
-    }
272
-
273
-
274
-
275
-    /**
276
-     * schedules a transient for cleanup by adding it to the transient tracking
277
-     *
278
-     * @param string $transient_key [required]
279
-     * @param int    $expiration    [required]
280
-     */
281
-    private function scheduleTransientCleanup($transient_key, $expiration)
282
-    {
283
-        // make sure a valid future timestamp is set
284
-        $expiration += $expiration < time() ? time() : 0;
285
-        // and round to the closest 15 minutes
286
-        $expiration = $this->roundTimestamp($expiration);
287
-        // save transients to clear using their ID as the key to avoid duplicates
288
-        $this->transients[$transient_key] = $expiration;
289
-        $this->updateTransients();
290
-    }
291
-
292
-
293
-
294
-    /**
295
-     * Since our tracked transients are sorted by their timestamps
296
-     * we can grab the first transient and see when it is scheduled for cleanup.
297
-     * If that timestamp is less than or equal to the current time,
298
-     * then cleanup is triggered
299
-     */
300
-    public function checkTransientCleanupSchedule()
301
-    {
302
-        if (empty($this->transients)) {
303
-            return;
304
-        }
305
-        // when do we run the next cleanup job?
306
-        reset($this->transients);
307
-        $next_scheduled_cleanup = current($this->transients);
308
-        // if the next cleanup job is scheduled for the current hour
309
-        if ($next_scheduled_cleanup <= $this->current_time) {
310
-            if ($this->cleanupExpiredTransients()) {
311
-                $this->updateTransients();
312
-            }
313
-        }
314
-    }
315
-
316
-
317
-
318
-    /**
319
-     * loops through the array of tracked transients,
320
-     * compiles a list of those that have expired, and sends that list off for deletion.
321
-     * Also removes any bad records from the transients array
322
-     *
323
-     * @return bool
324
-     */
325
-    private function cleanupExpiredTransients()
326
-    {
327
-        $update = false;
328
-        // filter the query limit. Set to 0 to turn off garbage collection
329
-        $limit = (int)abs(
330
-            apply_filters(
331
-                'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
332
-                50
333
-            )
334
-        );
335
-        // non-zero LIMIT means take out the trash
336
-        if ($limit) {
337
-            $transient_keys = array();
338
-            foreach ($this->transients as $transient_key => $expiration) {
339
-                if ($expiration > $this->current_time) {
340
-                    continue;
341
-                }
342
-                if ( ! $expiration || ! $transient_key) {
343
-                    unset($this->transients[$transient_key]);
344
-                    $update = true;
345
-                    continue;
346
-                }
347
-                $transient_keys[] = $transient_key;
348
-            }
349
-            // delete expired keys, but maintain value of $update if nothing is deleted
350
-            $update = $this->deleteTransientKeys($transient_keys, $limit) ? true : $update;
351
-            do_action( 'FHEE__TransientCacheStorage__clearExpiredTransients__end', $this);
352
-        }
353
-        return $update;
354
-    }
355
-
356
-
357
-
358
-    /**
359
-     * calls delete_transient() on each transient key provided, up to the specified limit
360
-     *
361
-     * @param array $transient_keys [required]
362
-     * @param int   $limit
363
-     * @return bool
364
-     */
365
-    private function deleteTransientKeys(array $transient_keys, $limit = 50)
366
-    {
367
-        if (empty($transient_keys)) {
368
-            return false;
369
-        }
370
-        $counter = 0;
371
-        foreach ($transient_keys as $transient_key) {
372
-            if($counter === $limit){
373
-                break;
374
-            }
375
-            delete_transient($transient_key);
376
-            unset($this->transients[$transient_key]);
377
-            $counter++;
378
-        }
379
-        return $counter > 0;
380
-    }
26
+	/**
27
+	 * wp-option option_name for tracking transients
28
+	 *
29
+	 * @type string
30
+	 */
31
+	const TRANSIENT_SCHEDULE_OPTIONS_KEY = 'ee_transient_schedule';
32
+
33
+	/**
34
+	 * @var int $current_time
35
+	 */
36
+	private $current_time = 0;
37
+
38
+	/**
39
+	 * how often to perform transient cleanup
40
+	 *
41
+	 * @var string $transient_cleanup_frequency
42
+	 */
43
+	private $transient_cleanup_frequency = 'hour';
44
+
45
+	/**
46
+	 * options for how often to perform transient cleanup
47
+	 *
48
+	 * @var array $transient_cleanup_frequency_options
49
+	 */
50
+	private $transient_cleanup_frequency_options = array();
51
+
52
+	/**
53
+	 * @var array $transients
54
+	 */
55
+	private $transients = array();
56
+
57
+
58
+
59
+	/**
60
+	 * TransientCacheStorage constructor.
61
+	 */
62
+	public function __construct()
63
+	{
64
+		$this->transient_cleanup_frequency = $this->setTransientCleanupFrequency();
65
+		// round current time down to closest 5 minutes to simplify scheduling
66
+		$this->current_time = $this->roundTimestamp(time(), '5-minutes', false);
67
+		$this->transients = (array)get_option(TransientCacheStorage::TRANSIENT_SCHEDULE_OPTIONS_KEY, array());
68
+		if ( ! (defined('DOING_AJAX') && DOING_AJAX) && $this->transient_cleanup_frequency !== 'off') {
69
+			add_action('shutdown', array($this, 'checkTransientCleanupSchedule'), 999);
70
+		}
71
+	}
72
+
73
+
74
+
75
+	/**
76
+	 * Sets how often transient cleanup occurs
77
+	 *
78
+	 * @return int
79
+	 */
80
+	private function setTransientCleanupFrequency()
81
+	{
82
+		// sets how often transients are cleaned up
83
+		$this->transient_cleanup_frequency_options = apply_filters(
84
+			'FHEE__TransientCacheStorage__transient_cleanup_schedule_options',
85
+			array(
86
+				'off',
87
+				'15-minutes',
88
+				'hour',
89
+				'12-hours',
90
+				'day',
91
+			)
92
+		);
93
+		$transient_cleanup_frequency = apply_filters(
94
+			'FHEE__TransientCacheStorage__transient_cleanup_schedule',
95
+			'hour'
96
+		);
97
+		return in_array(
98
+			$transient_cleanup_frequency,
99
+			$this->transient_cleanup_frequency_options,
100
+			true
101
+		)
102
+			? $transient_cleanup_frequency
103
+			: 'hour';
104
+	}
105
+
106
+
107
+
108
+	/**
109
+	 * we need to be able to round timestamps off to match the set transient cleanup frequency
110
+	 * so if a transient is set to expire at 1:17 pm for example, and our cleanup schedule is every hour,
111
+	 * then that timestamp needs to be rounded up to 2:00 pm so that it is removed
112
+	 * during the next scheduled cleanup after its expiration.
113
+	 * We also round off the current time timestamp to the closest 5 minutes
114
+	 * just to make the timestamps a little easier to round which helps with debugging.
115
+	 *
116
+	 * @param int    $timestamp [required]
117
+	 * @param string $cleanup_frequency
118
+	 * @param bool   $round_up
119
+	 * @return false|int
120
+	 */
121
+	private function roundTimestamp($timestamp, $cleanup_frequency = 'hour', $round_up = true)
122
+	{
123
+		$cleanup_frequency = $cleanup_frequency ? $cleanup_frequency : $this->transient_cleanup_frequency;
124
+		// in order to round the time to the closest xx minutes (or hours),
125
+		// we take the minutes (or hours) portion of the timestamp and divide it by xx,
126
+		// round down to a whole number, then multiply by xx to bring us almost back up to where we were
127
+		// why round down ? so the minutes (or hours) don't go over 60 (or 24)
128
+		// and bump the hour, which could bump the day, which could bump the month, etc,
129
+		// which would be bad because we don't always want to round up,
130
+		// but when we do we can easily achieve that by simply adding the desired offset,
131
+		$minutes = '00';
132
+		$hours = 'H';
133
+		switch ($cleanup_frequency) {
134
+			case '5-minutes' :
135
+				$minutes = floor((int)date('i', $timestamp) / 5) * 5;
136
+				$minutes = str_pad($minutes, 2, '0', STR_PAD_LEFT);
137
+				$offset = MINUTE_IN_SECONDS * 5;
138
+				break;
139
+			case '15-minutes' :
140
+				$minutes = floor((int)date('i', $timestamp) / 15) * 15;
141
+				$minutes = str_pad($minutes, 2, '0', STR_PAD_LEFT);
142
+				$offset = MINUTE_IN_SECONDS * 15;
143
+				break;
144
+			case '12-hours' :
145
+				$hours = floor((int)date('H', $timestamp) / 12) * 12;
146
+				$hours = str_pad($hours, 2, '0', STR_PAD_LEFT);
147
+				$offset = HOUR_IN_SECONDS * 12;
148
+				break;
149
+			case 'day' :
150
+				$hours = '03'; // run cleanup at 3:00 am (or first site hit after that)
151
+				$offset = DAY_IN_SECONDS;
152
+				break;
153
+			case 'hour' :
154
+			default :
155
+				$offset = HOUR_IN_SECONDS;
156
+				break;
157
+		}
158
+		$rounded_timestamp = strtotime(date("Y-m-d {$hours}:{$minutes}:00", $timestamp));
159
+		$rounded_timestamp += $round_up ? $offset : 0;
160
+		return apply_filters(
161
+			'FHEE__TransientCacheStorage__roundTimestamp__timestamp',
162
+			$rounded_timestamp,
163
+			$timestamp,
164
+			$cleanup_frequency,
165
+			$round_up
166
+		);
167
+	}
168
+
169
+
170
+
171
+	/**
172
+	 * Saves supplied data to a transient
173
+	 * if an expiration is set, then it automatically schedules the transient for cleanup
174
+	 *
175
+	 * @param string $transient_key [required]
176
+	 * @param string $data          [required]
177
+	 * @param int    $expiration    number of seconds until the cache expires
178
+	 * @return bool
179
+	 */
180
+	public function add($transient_key, $data, $expiration = 0)
181
+	{
182
+		$expiration = (int)abs($expiration);
183
+		$saved = set_transient($transient_key, $data, $expiration);
184
+		if ($saved && $expiration) {
185
+			$this->scheduleTransientCleanup($transient_key, $expiration);
186
+		}
187
+		return $saved;
188
+	}
189
+
190
+
191
+
192
+	/**
193
+	 * retrieves transient data
194
+	 * automatically triggers early cache refresh for standard cache items
195
+	 * in order to avoid cache stampedes on busy sites.
196
+	 * For non-standard cache items like PHP Session data where early refreshing is not wanted,
197
+	 * the $standard_cache parameter should be set to false when retrieving data
198
+	 *
199
+	 * @param string $transient_key [required]
200
+	 * @param bool   $standard_cache
201
+	 * @return mixed|null
202
+	 */
203
+	public function get($transient_key, $standard_cache = true)
204
+	{
205
+		// to avoid cache stampedes (AKA:dogpiles) for standard cache items,
206
+		// check if known cache expires within the next minute,
207
+		// and if so, remove it from our tracking and and return nothing.
208
+		// this should trigger the cache content to be regenerated during this request,
209
+		// while allowing any following requests to still access the existing cache
210
+		// until it gets replaced with the refreshed content
211
+		if (
212
+			$standard_cache
213
+			&& isset($this->transients[$transient_key])
214
+			&& $this->transients[$transient_key] - time() <= MINUTE_IN_SECONDS
215
+		) {
216
+			unset($this->transients[$transient_key]);
217
+			$this->updateTransients();
218
+			return null;
219
+		}
220
+		$content = get_transient($transient_key);
221
+		return $content !== false ? $content : null;
222
+	}
223
+
224
+
225
+
226
+	/**
227
+	 * delete a single transient and remove tracking
228
+	 *
229
+	 * @param string $transient_key [required] full or partial transient key to be deleted
230
+	 */
231
+	public function delete($transient_key)
232
+	{
233
+		$this->deleteMany(array($transient_key));
234
+	}
235
+
236
+
237
+
238
+	/**
239
+	 * delete multiple transients and remove tracking
240
+	 *
241
+	 * @param array $transient_keys [required] array of full or partial transient keys to be deleted
242
+	 */
243
+	public function deleteMany(array $transient_keys)
244
+	{
245
+		$full_transient_keys = array();
246
+		foreach ($this->transients as $transient_key => $expiration) {
247
+			foreach ($transient_keys as $transient_key_to_delete) {
248
+				if (strpos($transient_key, $transient_key_to_delete) !== false) {
249
+					$full_transient_keys[] = $transient_key;
250
+				}
251
+			}
252
+		}
253
+		if ($this->deleteTransientKeys($full_transient_keys)) {
254
+			$this->updateTransients();
255
+		}
256
+	}
257
+
258
+
259
+
260
+	/**
261
+	 * sorts transients numerically by timestamp
262
+	 * then saves the transient schedule to a WP option
263
+	 */
264
+	private function updateTransients()
265
+	{
266
+		asort($this->transients, SORT_NUMERIC);
267
+		update_option(
268
+			TransientCacheStorage::TRANSIENT_SCHEDULE_OPTIONS_KEY,
269
+			$this->transients
270
+		);
271
+	}
272
+
273
+
274
+
275
+	/**
276
+	 * schedules a transient for cleanup by adding it to the transient tracking
277
+	 *
278
+	 * @param string $transient_key [required]
279
+	 * @param int    $expiration    [required]
280
+	 */
281
+	private function scheduleTransientCleanup($transient_key, $expiration)
282
+	{
283
+		// make sure a valid future timestamp is set
284
+		$expiration += $expiration < time() ? time() : 0;
285
+		// and round to the closest 15 minutes
286
+		$expiration = $this->roundTimestamp($expiration);
287
+		// save transients to clear using their ID as the key to avoid duplicates
288
+		$this->transients[$transient_key] = $expiration;
289
+		$this->updateTransients();
290
+	}
291
+
292
+
293
+
294
+	/**
295
+	 * Since our tracked transients are sorted by their timestamps
296
+	 * we can grab the first transient and see when it is scheduled for cleanup.
297
+	 * If that timestamp is less than or equal to the current time,
298
+	 * then cleanup is triggered
299
+	 */
300
+	public function checkTransientCleanupSchedule()
301
+	{
302
+		if (empty($this->transients)) {
303
+			return;
304
+		}
305
+		// when do we run the next cleanup job?
306
+		reset($this->transients);
307
+		$next_scheduled_cleanup = current($this->transients);
308
+		// if the next cleanup job is scheduled for the current hour
309
+		if ($next_scheduled_cleanup <= $this->current_time) {
310
+			if ($this->cleanupExpiredTransients()) {
311
+				$this->updateTransients();
312
+			}
313
+		}
314
+	}
315
+
316
+
317
+
318
+	/**
319
+	 * loops through the array of tracked transients,
320
+	 * compiles a list of those that have expired, and sends that list off for deletion.
321
+	 * Also removes any bad records from the transients array
322
+	 *
323
+	 * @return bool
324
+	 */
325
+	private function cleanupExpiredTransients()
326
+	{
327
+		$update = false;
328
+		// filter the query limit. Set to 0 to turn off garbage collection
329
+		$limit = (int)abs(
330
+			apply_filters(
331
+				'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
332
+				50
333
+			)
334
+		);
335
+		// non-zero LIMIT means take out the trash
336
+		if ($limit) {
337
+			$transient_keys = array();
338
+			foreach ($this->transients as $transient_key => $expiration) {
339
+				if ($expiration > $this->current_time) {
340
+					continue;
341
+				}
342
+				if ( ! $expiration || ! $transient_key) {
343
+					unset($this->transients[$transient_key]);
344
+					$update = true;
345
+					continue;
346
+				}
347
+				$transient_keys[] = $transient_key;
348
+			}
349
+			// delete expired keys, but maintain value of $update if nothing is deleted
350
+			$update = $this->deleteTransientKeys($transient_keys, $limit) ? true : $update;
351
+			do_action( 'FHEE__TransientCacheStorage__clearExpiredTransients__end', $this);
352
+		}
353
+		return $update;
354
+	}
355
+
356
+
357
+
358
+	/**
359
+	 * calls delete_transient() on each transient key provided, up to the specified limit
360
+	 *
361
+	 * @param array $transient_keys [required]
362
+	 * @param int   $limit
363
+	 * @return bool
364
+	 */
365
+	private function deleteTransientKeys(array $transient_keys, $limit = 50)
366
+	{
367
+		if (empty($transient_keys)) {
368
+			return false;
369
+		}
370
+		$counter = 0;
371
+		foreach ($transient_keys as $transient_key) {
372
+			if($counter === $limit){
373
+				break;
374
+			}
375
+			delete_transient($transient_key);
376
+			unset($this->transients[$transient_key]);
377
+			$counter++;
378
+		}
379
+		return $counter > 0;
380
+	}
381 381
 
382 382
 
383 383
 }
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -64,7 +64,7 @@  discard block
 block discarded – undo
64 64
         $this->transient_cleanup_frequency = $this->setTransientCleanupFrequency();
65 65
         // round current time down to closest 5 minutes to simplify scheduling
66 66
         $this->current_time = $this->roundTimestamp(time(), '5-minutes', false);
67
-        $this->transients = (array)get_option(TransientCacheStorage::TRANSIENT_SCHEDULE_OPTIONS_KEY, array());
67
+        $this->transients = (array) get_option(TransientCacheStorage::TRANSIENT_SCHEDULE_OPTIONS_KEY, array());
68 68
         if ( ! (defined('DOING_AJAX') && DOING_AJAX) && $this->transient_cleanup_frequency !== 'off') {
69 69
             add_action('shutdown', array($this, 'checkTransientCleanupSchedule'), 999);
70 70
         }
@@ -132,17 +132,17 @@  discard block
 block discarded – undo
132 132
         $hours = 'H';
133 133
         switch ($cleanup_frequency) {
134 134
             case '5-minutes' :
135
-                $minutes = floor((int)date('i', $timestamp) / 5) * 5;
135
+                $minutes = floor((int) date('i', $timestamp) / 5) * 5;
136 136
                 $minutes = str_pad($minutes, 2, '0', STR_PAD_LEFT);
137 137
                 $offset = MINUTE_IN_SECONDS * 5;
138 138
                 break;
139 139
             case '15-minutes' :
140
-                $minutes = floor((int)date('i', $timestamp) / 15) * 15;
140
+                $minutes = floor((int) date('i', $timestamp) / 15) * 15;
141 141
                 $minutes = str_pad($minutes, 2, '0', STR_PAD_LEFT);
142 142
                 $offset = MINUTE_IN_SECONDS * 15;
143 143
                 break;
144 144
             case '12-hours' :
145
-                $hours = floor((int)date('H', $timestamp) / 12) * 12;
145
+                $hours = floor((int) date('H', $timestamp) / 12) * 12;
146 146
                 $hours = str_pad($hours, 2, '0', STR_PAD_LEFT);
147 147
                 $offset = HOUR_IN_SECONDS * 12;
148 148
                 break;
@@ -179,7 +179,7 @@  discard block
 block discarded – undo
179 179
      */
180 180
     public function add($transient_key, $data, $expiration = 0)
181 181
     {
182
-        $expiration = (int)abs($expiration);
182
+        $expiration = (int) abs($expiration);
183 183
         $saved = set_transient($transient_key, $data, $expiration);
184 184
         if ($saved && $expiration) {
185 185
             $this->scheduleTransientCleanup($transient_key, $expiration);
@@ -326,7 +326,7 @@  discard block
 block discarded – undo
326 326
     {
327 327
         $update = false;
328 328
         // filter the query limit. Set to 0 to turn off garbage collection
329
-        $limit = (int)abs(
329
+        $limit = (int) abs(
330 330
             apply_filters(
331 331
                 'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
332 332
                 50
@@ -348,7 +348,7 @@  discard block
 block discarded – undo
348 348
             }
349 349
             // delete expired keys, but maintain value of $update if nothing is deleted
350 350
             $update = $this->deleteTransientKeys($transient_keys, $limit) ? true : $update;
351
-            do_action( 'FHEE__TransientCacheStorage__clearExpiredTransients__end', $this);
351
+            do_action('FHEE__TransientCacheStorage__clearExpiredTransients__end', $this);
352 352
         }
353 353
         return $update;
354 354
     }
@@ -369,7 +369,7 @@  discard block
 block discarded – undo
369 369
         }
370 370
         $counter = 0;
371 371
         foreach ($transient_keys as $transient_key) {
372
-            if($counter === $limit){
372
+            if ($counter === $limit) {
373 373
                 break;
374 374
             }
375 375
             delete_transient($transient_key);
Please login to merge, or discard this patch.