Completed
Branch FET-8394-RULES (1ae5e4)
by
unknown
50:31 queued 37:22
created
core/db_models/fields/EE_Full_HTML_Field.php 2 patches
Indentation   +48 added lines, -48 removed lines patch added patch discarded remove patch
@@ -15,57 +15,57 @@
 block discarded – undo
15 15
 class EE_Full_HTML_Field extends EE_Text_Field_Base
16 16
 {
17 17
 
18
-    /**
19
-     * @param string $table_column
20
-     * @param string $nicename
21
-     * @param bool   $nullable
22
-     * @param null   $default_value
23
-     */
24
-    public function __construct($table_column, $nicename, $nullable, $default_value = null)
25
-    {
26
-        parent::__construct($table_column, $nicename, $nullable, $default_value);
27
-        $this->setSchemaType('object');
28
-    }
18
+	/**
19
+	 * @param string $table_column
20
+	 * @param string $nicename
21
+	 * @param bool   $nullable
22
+	 * @param null   $default_value
23
+	 */
24
+	public function __construct($table_column, $nicename, $nullable, $default_value = null)
25
+	{
26
+		parent::__construct($table_column, $nicename, $nullable, $default_value);
27
+		$this->setSchemaType('object');
28
+	}
29 29
 
30 30
 
31
-    /**
32
-     * Does shortcodes and auto-paragraphs the content (unless schema is 'no_wpautop')
33
-     *
34
-     * @param type $value_on_field_to_be_outputted
35
-     * @param type $schema
36
-     * @return string
37
-     */
38
-    function prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema = null)
39
-    {
40
-        if ($schema == 'form_input') {
41
-            return parent::prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema);
42
-        } elseif ($schema == 'no_wpautop') {
43
-            return do_shortcode(parent::prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema));
44
-        } else {
45
-            return wpautop(do_shortcode(parent::prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema)));
46
-        }
47
-    }
31
+	/**
32
+	 * Does shortcodes and auto-paragraphs the content (unless schema is 'no_wpautop')
33
+	 *
34
+	 * @param type $value_on_field_to_be_outputted
35
+	 * @param type $schema
36
+	 * @return string
37
+	 */
38
+	function prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema = null)
39
+	{
40
+		if ($schema == 'form_input') {
41
+			return parent::prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema);
42
+		} elseif ($schema == 'no_wpautop') {
43
+			return do_shortcode(parent::prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema));
44
+		} else {
45
+			return wpautop(do_shortcode(parent::prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema)));
46
+		}
47
+	}
48 48
 
49 49
 
50 50
 
51
-    public function getSchemaProperties()
52
-    {
53
-        return array(
54
-            'raw' => array(
55
-                'description' =>  sprintf(
56
-                    __('%s - the value in the database.', 'event_espresso'),
57
-                    $this->get_nicename()
58
-                ),
59
-                'type' => 'string'
60
-            ),
61
-            'rendered' => array(
62
-                'description' =>  sprintf(
63
-                    __('%s - transformed for display.', 'event_espresso'),
64
-                    $this->get_nicename()
65
-                ),
66
-                'type' => 'string',
67
-                'readonly' => true
68
-            )
69
-        );
70
-    }
51
+	public function getSchemaProperties()
52
+	{
53
+		return array(
54
+			'raw' => array(
55
+				'description' =>  sprintf(
56
+					__('%s - the value in the database.', 'event_espresso'),
57
+					$this->get_nicename()
58
+				),
59
+				'type' => 'string'
60
+			),
61
+			'rendered' => array(
62
+				'description' =>  sprintf(
63
+					__('%s - transformed for display.', 'event_espresso'),
64
+					$this->get_nicename()
65
+				),
66
+				'type' => 'string',
67
+				'readonly' => true
68
+			)
69
+		);
70
+	}
71 71
 }
72 72
\ No newline at end of file
Please login to merge, or discard this patch.
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -13,7 +13,7 @@
 block discarded – undo
13 13
      * @param string $table_column
14 14
      * @param string $nicename
15 15
      * @param bool   $nullable
16
-     * @param null   $default_value
16
+     * @param string   $default_value
17 17
      */
18 18
     public function __construct($table_column, $nicename, $nullable, $default_value = null)
19 19
     {
Please login to merge, or discard this patch.
modules/ticket_selector/ProcessTicketSelector.php 3 patches
Doc Comments   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -32,7 +32,7 @@  discard block
 block discarded – undo
32 32
     /**
33 33
      * cancelTicketSelections
34 34
      *
35
-     * @return        string
35
+     * @return        false|null
36 36
      */
37 37
     public function cancelTicketSelections()
38 38
     {
@@ -99,7 +99,7 @@  discard block
 block discarded – undo
99 99
     /**
100 100
      * process_ticket_selections
101 101
      *
102
-     * @return array|bool
102
+     * @return boolean|null
103 103
      * @throws \EE_Error
104 104
      */
105 105
     public function processTicketSelections()
@@ -273,7 +273,7 @@  discard block
 block discarded – undo
273 273
      * validate_post_data
274 274
      *
275 275
      * @param int $id
276
-     * @return array|FALSE
276
+     * @return string
277 277
      */
278 278
     private function validatePostData($id = 0)
279 279
     {
@@ -390,7 +390,7 @@  discard block
 block discarded – undo
390 390
      *
391 391
      * @param \EE_Ticket $ticket
392 392
      * @param int        $qty
393
-     * @return TRUE on success, FALSE on fail
393
+     * @return boolean on success, FALSE on fail
394 394
      * @throws \EE_Error
395 395
      */
396 396
     private function addTicketToCart(\EE_Ticket $ticket = null, $qty = 1)
Please login to merge, or discard this patch.
Indentation   +569 added lines, -569 removed lines patch added patch discarded remove patch
@@ -2,7 +2,7 @@  discard block
 block discarded – undo
2 2
 namespace EventEspresso\modules\ticket_selector;
3 3
 
4 4
 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
5
-    exit('No direct script access allowed');
5
+	exit('No direct script access allowed');
6 6
 }
7 7
 
8 8
 
@@ -19,574 +19,574 @@  discard block
 block discarded – undo
19 19
 class ProcessTicketSelector
20 20
 {
21 21
 
22
-    /**
23
-     * array of datetimes and the spaces available for them
24
-     *
25
-     * @access private
26
-     * @var array
27
-     */
28
-    private static $_available_spaces = array();
29
-
30
-
31
-
32
-    /**
33
-     * cancelTicketSelections
34
-     *
35
-     * @return        string
36
-     */
37
-    public function cancelTicketSelections()
38
-    {
39
-        // check nonce
40
-        if ( ! $this->processTicketSelectorNonce('cancel_ticket_selections')) {
41
-            return false;
42
-        }
43
-        \EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
44
-        if (\EE_Registry::instance()->REQ->is_set('event_id')) {
45
-            wp_safe_redirect(
46
-                \EEH_Event_View::event_link_url(
47
-                    \EE_Registry::instance()->REQ->get('event_id')
48
-                )
49
-            );
50
-        } else {
51
-            wp_safe_redirect(
52
-                site_url('/' . \EE_Registry::instance()->CFG->core->event_cpt_slug . '/')
53
-            );
54
-        }
55
-        exit();
56
-    }
57
-
58
-
59
-
60
-    /**
61
-     * processTicketSelectorNonce
62
-     *
63
-     * @param  string $nonce_name
64
-     * @param string  $id
65
-     * @return bool
66
-     */
67
-    private function processTicketSelectorNonce($nonce_name, $id = '')
68
-    {
69
-        $nonce_name_with_id = ! empty($id) ? "{$nonce_name}_nonce_{$id}" : "{$nonce_name}_nonce";
70
-        if (
71
-            ! is_admin()
72
-            && (
73
-                ! \EE_Registry::instance()->REQ->is_set($nonce_name_with_id)
74
-                || ! wp_verify_nonce(
75
-                    \EE_Registry::instance()->REQ->get($nonce_name_with_id),
76
-                    $nonce_name
77
-                )
78
-            )
79
-        ) {
80
-            \EE_Error::add_error(
81
-                sprintf(
82
-                    __(
83
-                        'We\'re sorry but your request failed to pass a security check.%sPlease click the back button on your browser and try again.',
84
-                        'event_espresso'
85
-                    ),
86
-                    '<br/>'
87
-                ),
88
-                __FILE__,
89
-                __FUNCTION__,
90
-                __LINE__
91
-            );
92
-            return false;
93
-        }
94
-        return true;
95
-    }
96
-
97
-
98
-
99
-    /**
100
-     * process_ticket_selections
101
-     *
102
-     * @return array|bool
103
-     * @throws \EE_Error
104
-     */
105
-    public function processTicketSelections()
106
-    {
107
-        do_action('EED_Ticket_Selector__process_ticket_selections__before');
108
-        // do we have an event id?
109
-        if ( ! \EE_Registry::instance()->REQ->is_set('tkt-slctr-event-id')) {
110
-            // $_POST['tkt-slctr-event-id'] was not set ?!?!?!?
111
-            \EE_Error::add_error(
112
-                sprintf(
113
-                    __(
114
-                        'An event id was not provided or was not received.%sPlease click the back button on your browser and try again.',
115
-                        'event_espresso'
116
-                    ),
117
-                    '<br/>'
118
-                ),
119
-                __FILE__,
120
-                __FUNCTION__,
121
-                __LINE__
122
-            );
123
-        }
124
-        //if event id is valid
125
-        $id = absint(\EE_Registry::instance()->REQ->get('tkt-slctr-event-id'));
126
-        // check nonce
127
-        if ( ! $this->processTicketSelectorNonce('process_ticket_selections', $id)) {
128
-            return false;
129
-        }
130
-        //		d( \EE_Registry::instance()->REQ );
131
-        self::$_available_spaces = array(
132
-            'tickets'   => array(),
133
-            'datetimes' => array(),
134
-        );
135
-        //we should really only have 1 registration in the works now (ie, no MER) so clear any previous items in the cart.
136
-        // When MER happens this will probably need to be tweaked, possibly wrapped in a conditional checking for some constant defined in MER etc.
137
-        \EE_Registry::instance()->load_core('Session');
138
-        // unless otherwise requested, clear the session
139
-        if (apply_filters('FHEE__EE_Ticket_Selector__process_ticket_selections__clear_session', true)) {
140
-            \EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
141
-        }
142
-        //d( \EE_Registry::instance()->SSN );
143
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
144
-        // validate/sanitize data
145
-        $valid = $this->validatePostData($id);
146
-        //EEH_Debug_Tools::printr( $_REQUEST, '$_REQUEST', __FILE__, __LINE__ );
147
-        //EEH_Debug_Tools::printr( $valid, '$valid', __FILE__, __LINE__ );
148
-        //EEH_Debug_Tools::printr( $valid[ 'total_tickets' ], 'total_tickets', __FILE__, __LINE__ );
149
-        //EEH_Debug_Tools::printr( $valid[ 'max_atndz' ], 'max_atndz', __FILE__, __LINE__ );
150
-        //check total tickets ordered vs max number of attendees that can register
151
-        if ($valid['total_tickets'] > $valid['max_atndz']) {
152
-            // ordering too many tickets !!!
153
-            $total_tickets_string = _n(
154
-                'You have attempted to purchase %s ticket.',
155
-                'You have attempted to purchase %s tickets.',
156
-                $valid['total_tickets'],
157
-                'event_espresso'
158
-            );
159
-            $limit_error_1 = sprintf($total_tickets_string, $valid['total_tickets']);
160
-            // dev only message
161
-            $max_atndz_string = _n(
162
-                'The registration limit for this event is %s ticket per registration, therefore the total number of tickets you may purchase at a time can not exceed %s.',
163
-                'The registration limit for this event is %s tickets per registration, therefore the total number of tickets you may purchase at a time can not exceed %s.',
164
-                $valid['max_atndz'],
165
-                'event_espresso'
166
-            );
167
-            $limit_error_2 = sprintf($max_atndz_string, $valid['max_atndz'], $valid['max_atndz']);
168
-            \EE_Error::add_error($limit_error_1 . '<br/>' . $limit_error_2, __FILE__, __FUNCTION__, __LINE__);
169
-        } else {
170
-            // all data appears to be valid
171
-            $tckts_slctd = false;
172
-            $tickets_added = 0;
173
-            $valid = apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__valid_post_data', $valid);
174
-            if ($valid['total_tickets'] > 0) {
175
-                // load cart
176
-                \EE_Registry::instance()->load_core('Cart');
177
-                // cycle thru the number of data rows sent from the event listing
178
-                for ($x = 0; $x < $valid['rows']; $x++) {
179
-                    // does this row actually contain a ticket quantity?
180
-                    if (isset($valid['qty'][$x]) && $valid['qty'][$x] > 0) {
181
-                        // YES we have a ticket quantity
182
-                        $tckts_slctd = true;
183
-                        //						d( $valid['ticket_obj'][$x] );
184
-                        if ($valid['ticket_obj'][$x] instanceof \EE_Ticket) {
185
-                            // then add ticket to cart
186
-                            $tickets_added += $this->addTicketToCart(
187
-                                $valid['ticket_obj'][$x],
188
-                                $valid['qty'][$x]
189
-                            );
190
-                            if (\EE_Error::has_error()) {
191
-                                break;
192
-                            }
193
-                        } else {
194
-                            // nothing added to cart retrieved
195
-                            \EE_Error::add_error(
196
-                                sprintf(
197
-                                    __(
198
-                                        'A valid ticket could not be retrieved for the event.%sPlease click the back button on your browser and try again.',
199
-                                        'event_espresso'
200
-                                    ),
201
-                                    '<br/>'
202
-                                ),
203
-                                __FILE__, __FUNCTION__, __LINE__
204
-                            );
205
-                        }
206
-                    }
207
-                }
208
-            }
209
-            do_action(
210
-                'AHEE__EE_Ticket_Selector__process_ticket_selections__after_tickets_added_to_cart',
211
-                \EE_Registry::instance()->CART,
212
-                $this
213
-            );
214
-            //d( \EE_Registry::instance()->CART );
215
-            //die(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< KILL REDIRECT HERE BEFORE CART UPDATE
216
-            if (apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__tckts_slctd', $tckts_slctd)) {
217
-                if (apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__success', $tickets_added)) {
218
-                    do_action(
219
-                        'FHEE__EE_Ticket_Selector__process_ticket_selections__before_redirecting_to_checkout',
220
-                        \EE_Registry::instance()->CART,
221
-                        $this
222
-                    );
223
-                    \EE_Registry::instance()->CART->recalculate_all_cart_totals();
224
-                    \EE_Registry::instance()->CART->save_cart(false);
225
-                    // exit('KILL REDIRECT AFTER CART UPDATE'); // <<<<<<<<  OR HERE TO KILL REDIRECT AFTER CART UPDATE
226
-                    // just return TRUE for registrations being made from admin
227
-                    if (is_admin()) {
228
-                        return true;
229
-                    }
230
-                    \EE_Error::get_notices(false, true);
231
-                    wp_safe_redirect(
232
-                        apply_filters(
233
-                            'FHEE__EE_Ticket_Selector__process_ticket_selections__success_redirect_url',
234
-                            \EE_Registry::instance()->CFG->core->reg_page_url()
235
-                        )
236
-                    );
237
-                    exit();
238
-                } else {
239
-                    if ( ! \EE_Error::has_error() && ! \EE_Error::has_error(true, 'attention')) {
240
-                        // nothing added to cart
241
-                        \EE_Error::add_attention(__('No tickets were added for the event', 'event_espresso'),
242
-                            __FILE__, __FUNCTION__, __LINE__);
243
-                    }
244
-                }
245
-            } else {
246
-                // no ticket quantities were selected
247
-                \EE_Error::add_error(__('You need to select a ticket quantity before you can proceed.',
248
-                    'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
249
-            }
250
-        }
251
-        //die(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< KILL BEFORE REDIRECT
252
-        // at this point, just return if registration is being made from admin
253
-        if (is_admin()) {
254
-            return false;
255
-        }
256
-        if ($valid['return_url']) {
257
-            \EE_Error::get_notices(false, true);
258
-            wp_safe_redirect($valid['return_url']);
259
-            exit();
260
-        } elseif (isset($event_to_add['id'])) {
261
-            \EE_Error::get_notices(false, true);
262
-            wp_safe_redirect(get_permalink($event_to_add['id']));
263
-            exit();
264
-        } else {
265
-            echo \EE_Error::get_notices();
266
-        }
267
-        return false;
268
-    }
269
-
270
-
271
-
272
-    /**
273
-     * validate_post_data
274
-     *
275
-     * @param int $id
276
-     * @return array|FALSE
277
-     */
278
-    private function validatePostData($id = 0)
279
-    {
280
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
281
-        if ( ! $id) {
282
-            \EE_Error::add_error(
283
-                __('The event id provided was not valid.', 'event_espresso'),
284
-                __FILE__,
285
-                __FUNCTION__,
286
-                __LINE__
287
-            );
288
-            return false;
289
-        }
290
-        // start with an empty array()
291
-        $valid_data = array();
292
-        // grab valid id
293
-        $valid_data['id'] = $id;
294
-        // array of other form names
295
-        $inputs_to_clean = array(
296
-            'event_id'   => 'tkt-slctr-event-id',
297
-            'max_atndz'  => 'tkt-slctr-max-atndz-',
298
-            'rows'       => 'tkt-slctr-rows-',
299
-            'qty'        => 'tkt-slctr-qty-',
300
-            'ticket_id'  => 'tkt-slctr-ticket-id-',
301
-            'return_url' => 'tkt-slctr-return-url-',
302
-        );
303
-        // let's track the total number of tickets ordered.'
304
-        $valid_data['total_tickets'] = 0;
305
-        // cycle through $inputs_to_clean array
306
-        foreach ($inputs_to_clean as $what => $input_to_clean) {
307
-            // check for POST data
308
-            if (\EE_Registry::instance()->REQ->is_set($input_to_clean . $id)) {
309
-                // grab value
310
-                $input_value = \EE_Registry::instance()->REQ->get($input_to_clean . $id);
311
-                switch ($what) {
312
-                    // integers
313
-                    case 'event_id':
314
-                        $valid_data[$what] = absint($input_value);
315
-                        // get event via the event id we put in the form
316
-                        $valid_data['event'] = \EE_Registry::instance()
317
-                                                           ->load_model('Event')
318
-                                                           ->get_one_by_ID($valid_data['event_id']);
319
-                        break;
320
-                    case 'rows':
321
-                    case 'max_atndz':
322
-                        $valid_data[$what] = absint($input_value);
323
-                        break;
324
-                    // arrays of integers
325
-                    case 'qty':
326
-                        /** @var array $row_qty */
327
-                        $row_qty = $input_value;
328
-                        // if qty is coming from a radio button input, then we need to assemble an array of rows
329
-                        if ( ! is_array($row_qty)) {
330
-                            // get number of rows
331
-                            $rows = \EE_Registry::instance()->REQ->is_set('tkt-slctr-rows-' . $id)
332
-                                ? absint(\EE_Registry::instance()->REQ->get('tkt-slctr-rows-' . $id))
333
-                                : 1;
334
-                            // explode ints by the dash
335
-                            $row_qty = explode('-', $row_qty);
336
-                            $row = isset($row_qty[0]) ? absint($row_qty[0]) : 1;
337
-                            $qty = isset($row_qty[1]) ? absint($row_qty[1]) : 0;
338
-                            $row_qty = array($row => $qty);
339
-                            for ($x = 1; $x <= $rows; $x++) {
340
-                                if ( ! isset($row_qty[$x])) {
341
-                                    $row_qty[$x] = 0;
342
-                                }
343
-                            }
344
-                        }
345
-                        ksort($row_qty);
346
-                        // cycle thru values
347
-                        foreach ($row_qty as $qty) {
348
-                            $qty = absint($qty);
349
-                            // sanitize as integers
350
-                            $valid_data[$what][] = $qty;
351
-                            $valid_data['total_tickets'] += $qty;
352
-                        }
353
-                        break;
354
-                    // array of integers
355
-                    case 'ticket_id':
356
-                        $value_array = array();
357
-                        // cycle thru values
358
-                        foreach ((array)$input_value as $key => $value) {
359
-                            // allow only numbers, letters,  spaces, commas and dashes
360
-                            $value_array[$key] = wp_strip_all_tags($value);
361
-                            // get ticket via the ticket id we put in the form
362
-                            $ticket_obj = \EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($value);
363
-                            $valid_data['ticket_obj'][$key] = $ticket_obj;
364
-                        }
365
-                        $valid_data[$what] = $value_array;
366
-                        break;
367
-                    case 'return_url' :
368
-                        // grab and sanitize return-url
369
-                        $input_value = esc_url_raw($input_value);
370
-                        // was the request coming from an iframe ? if so, then:
371
-                        if (strpos($input_value, 'event_list=iframe')) {
372
-                            // get anchor fragment
373
-                            $input_value = explode('#', $input_value);
374
-                            $input_value = end($input_value);
375
-                            // use event list url instead, but append anchor
376
-                            $input_value = \EEH_Event_View::event_archive_url() . '#' . $input_value;
377
-                        }
378
-                        $valid_data[$what] = $input_value;
379
-                        break;
380
-                }    // end switch $what
381
-            }
382
-        }    // end foreach $inputs_to_clean
383
-        return $valid_data;
384
-    }
385
-
386
-
387
-
388
-    /**
389
-     * adds a ticket to the cart
390
-     *
391
-     * @param \EE_Ticket $ticket
392
-     * @param int        $qty
393
-     * @return TRUE on success, FALSE on fail
394
-     * @throws \EE_Error
395
-     */
396
-    private function addTicketToCart(\EE_Ticket $ticket = null, $qty = 1)
397
-    {
398
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
399
-        // get the number of spaces left for this datetime ticket
400
-        $available_spaces = $this->ticketDatetimeAvailability($ticket);
401
-        // compare available spaces against the number of tickets being purchased
402
-        if ($available_spaces >= $qty) {
403
-            // allow addons to prevent a ticket from being added to cart
404
-            if (
405
-            ! apply_filters(
406
-                'FHEE__EE_Ticket_Selector___add_ticket_to_cart__allow_add_to_cart',
407
-                true,
408
-                $ticket,
409
-                $qty,
410
-                $available_spaces
411
-            )
412
-            ) {
413
-                return false;
414
-            }
415
-            $qty = absint(apply_filters('FHEE__EE_Ticket_Selector___add_ticket_to_cart__ticket_qty', $qty, $ticket));
416
-            // add event to cart
417
-            if (\EE_Registry::instance()->CART->add_ticket_to_cart($ticket, $qty)) {
418
-                $this->recalculateTicketDatetimeAvailability($ticket, $qty);
419
-                return true;
420
-            }
421
-            return false;
422
-        }
423
-        // tickets can not be purchased but let's find the exact number left
424
-        // for the last ticket selected PRIOR to subtracting tickets
425
-        $available_spaces = $this->ticketDatetimeAvailability($ticket, true);
426
-        // greedy greedy greedy eh?
427
-        if ($available_spaces > 0) {
428
-            if (
429
-            apply_filters(
430
-                'FHEE__EE_Ticket_Selector___add_ticket_to_cart__allow_display_availability_error',
431
-                true,
432
-                $ticket,
433
-                $qty,
434
-                $available_spaces
435
-            )
436
-            ) {
437
-                $this->displayAvailabilityError($available_spaces);
438
-            }
439
-        } else {
440
-            \EE_Error::add_error(
441
-                __(
442
-                    'We\'re sorry, but there are no available spaces left for this event at this particular date and time.',
443
-                    'event_espresso'
444
-                ),
445
-                __FILE__, __FUNCTION__, __LINE__
446
-            );
447
-        }
448
-        return false;
449
-    }
450
-
451
-
452
-
453
-    /**
454
-     * @param int $available_spaces
455
-     * @throws \EE_Error
456
-     */
457
-    private function displayAvailabilityError($available_spaces = 1)
458
-    {
459
-        // add error messaging - we're using the _n function that will generate
460
-        // the appropriate singular or plural message based on the number of $available_spaces
461
-        if (\EE_Registry::instance()->CART->all_ticket_quantity_count()) {
462
-            $msg = sprintf(
463
-                _n(
464
-                    'We\'re sorry, but there is only %1$s available space left for this event at this particular date and time. Please select a different number (or different combination) of tickets by cancelling the current selection and choosing again, or proceed to registration.',
465
-                    'We\'re sorry, but there are only %1$s available spaces left for this event at this particular date and time. Please select a different number (or different combination) of tickets by cancelling the current selection and choosing again, or proceed to registration.',
466
-                    $available_spaces,
467
-                    'event_espresso'
468
-                ),
469
-                $available_spaces,
470
-                '<br />'
471
-            );
472
-        } else {
473
-            $msg = sprintf(
474
-                _n(
475
-                    'We\'re sorry, but there is only %1$s available space left for this event at this particular date and time. Please select a different number (or different combination) of tickets.',
476
-                    'We\'re sorry, but there are only %1$s available spaces left for this event at this particular date and time. Please select a different number (or different combination) of tickets.',
477
-                    $available_spaces,
478
-                    'event_espresso'
479
-                ),
480
-                $available_spaces,
481
-                '<br />'
482
-            );
483
-        }
484
-        \EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
485
-    }
486
-
487
-
488
-
489
-    /**
490
-     * ticketDatetimeAvailability
491
-     * creates an array of tickets plus all of the datetimes available to each ticket
492
-     * and tracks the spaces remaining for each of those datetimes
493
-     *
494
-     * @param \EE_Ticket $ticket - selected ticket
495
-     * @param bool       $get_original_ticket_spaces
496
-     * @return int
497
-     * @throws \EE_Error
498
-     */
499
-    private function ticketDatetimeAvailability(\EE_Ticket $ticket, $get_original_ticket_spaces = false)
500
-    {
501
-        // if the $_available_spaces array has not been set up yet...
502
-        if ( ! isset(self::$_available_spaces['tickets'][$ticket->ID()])) {
503
-            $this->setInitialTicketDatetimeAvailability($ticket);
504
-        }
505
-        $available_spaces = $ticket->qty() - $ticket->sold();
506
-        if (isset(self::$_available_spaces['tickets'][$ticket->ID()])) {
507
-            // loop thru tickets, which will ALSO include individual ticket records AND a total
508
-            foreach (self::$_available_spaces['tickets'][$ticket->ID()] as $DTD_ID => $spaces) {
509
-                // if we want the original datetime availability BEFORE we started subtracting tickets ?
510
-                if ($get_original_ticket_spaces) {
511
-                    // then grab the available spaces from the "tickets" array
512
-                    // and compare with the above to get the lowest number
513
-                    $available_spaces = min(
514
-                        $available_spaces,
515
-                        self::$_available_spaces['tickets'][$ticket->ID()][$DTD_ID]
516
-                    );
517
-                } else {
518
-                    // we want the updated ticket availability as stored in the "datetimes" array
519
-                    $available_spaces = min($available_spaces, self::$_available_spaces['datetimes'][$DTD_ID]);
520
-                }
521
-            }
522
-        }
523
-        return $available_spaces;
524
-    }
525
-
526
-
527
-
528
-    /**
529
-     * @param \EE_Ticket $ticket
530
-     * @return void
531
-     * @throws \EE_Error
532
-     */
533
-    private function setInitialTicketDatetimeAvailability(\EE_Ticket $ticket)
534
-    {
535
-        // first, get all of the datetimes that are available to this ticket
536
-        $datetimes = $ticket->get_many_related(
537
-            'Datetime',
538
-            array(
539
-                array(
540
-                    'DTT_EVT_end' => array(
541
-                        '>=',
542
-                        \EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
543
-                    ),
544
-                ),
545
-                'order_by' => array('DTT_EVT_start' => 'ASC'),
546
-            )
547
-        );
548
-        if ( ! empty($datetimes)) {
549
-            // now loop thru all of the datetimes
550
-            foreach ($datetimes as $datetime) {
551
-                if ($datetime instanceof \EE_Datetime) {
552
-                    // the number of spaces available for the datetime without considering individual ticket quantities
553
-                    $spaces_remaining = $datetime->spaces_remaining();
554
-                    // save the total available spaces ( the lesser of the ticket qty minus the number of tickets sold
555
-                    // or the datetime spaces remaining) to this ticket using the datetime ID as the key
556
-                    self::$_available_spaces['tickets'][$ticket->ID()][$datetime->ID()] = min(
557
-                        $ticket->qty() - $ticket->sold(),
558
-                        $spaces_remaining
559
-                    );
560
-                    // if the remaining spaces for this datetime is already set,
561
-                    // then compare that against the datetime spaces remaining, and take the lowest number,
562
-                    // else just take the datetime spaces remaining, and assign to the datetimes array
563
-                    self::$_available_spaces['datetimes'][$datetime->ID()] = isset(
564
-                        self::$_available_spaces['datetimes'][$datetime->ID()]
565
-                    )
566
-                        ? min(self::$_available_spaces['datetimes'][$datetime->ID()], $spaces_remaining)
567
-                        : $spaces_remaining;
568
-                }
569
-            }
570
-        }
571
-    }
572
-
573
-
574
-
575
-    /**
576
-     * @param    \EE_Ticket $ticket
577
-     * @param    int        $qty
578
-     * @return    void
579
-     */
580
-    private function recalculateTicketDatetimeAvailability(\EE_Ticket $ticket, $qty = 0)
581
-    {
582
-        if (isset(self::$_available_spaces['tickets'][$ticket->ID()])) {
583
-            // loop thru tickets, which will ALSO include individual ticket records AND a total
584
-            foreach (self::$_available_spaces['tickets'][$ticket->ID()] as $DTD_ID => $spaces) {
585
-                // subtract the qty of selected tickets from each datetime's available spaces this ticket has access to,
586
-                self::$_available_spaces['datetimes'][$DTD_ID] -= $qty;
587
-            }
588
-        }
589
-    }
22
+	/**
23
+	 * array of datetimes and the spaces available for them
24
+	 *
25
+	 * @access private
26
+	 * @var array
27
+	 */
28
+	private static $_available_spaces = array();
29
+
30
+
31
+
32
+	/**
33
+	 * cancelTicketSelections
34
+	 *
35
+	 * @return        string
36
+	 */
37
+	public function cancelTicketSelections()
38
+	{
39
+		// check nonce
40
+		if ( ! $this->processTicketSelectorNonce('cancel_ticket_selections')) {
41
+			return false;
42
+		}
43
+		\EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
44
+		if (\EE_Registry::instance()->REQ->is_set('event_id')) {
45
+			wp_safe_redirect(
46
+				\EEH_Event_View::event_link_url(
47
+					\EE_Registry::instance()->REQ->get('event_id')
48
+				)
49
+			);
50
+		} else {
51
+			wp_safe_redirect(
52
+				site_url('/' . \EE_Registry::instance()->CFG->core->event_cpt_slug . '/')
53
+			);
54
+		}
55
+		exit();
56
+	}
57
+
58
+
59
+
60
+	/**
61
+	 * processTicketSelectorNonce
62
+	 *
63
+	 * @param  string $nonce_name
64
+	 * @param string  $id
65
+	 * @return bool
66
+	 */
67
+	private function processTicketSelectorNonce($nonce_name, $id = '')
68
+	{
69
+		$nonce_name_with_id = ! empty($id) ? "{$nonce_name}_nonce_{$id}" : "{$nonce_name}_nonce";
70
+		if (
71
+			! is_admin()
72
+			&& (
73
+				! \EE_Registry::instance()->REQ->is_set($nonce_name_with_id)
74
+				|| ! wp_verify_nonce(
75
+					\EE_Registry::instance()->REQ->get($nonce_name_with_id),
76
+					$nonce_name
77
+				)
78
+			)
79
+		) {
80
+			\EE_Error::add_error(
81
+				sprintf(
82
+					__(
83
+						'We\'re sorry but your request failed to pass a security check.%sPlease click the back button on your browser and try again.',
84
+						'event_espresso'
85
+					),
86
+					'<br/>'
87
+				),
88
+				__FILE__,
89
+				__FUNCTION__,
90
+				__LINE__
91
+			);
92
+			return false;
93
+		}
94
+		return true;
95
+	}
96
+
97
+
98
+
99
+	/**
100
+	 * process_ticket_selections
101
+	 *
102
+	 * @return array|bool
103
+	 * @throws \EE_Error
104
+	 */
105
+	public function processTicketSelections()
106
+	{
107
+		do_action('EED_Ticket_Selector__process_ticket_selections__before');
108
+		// do we have an event id?
109
+		if ( ! \EE_Registry::instance()->REQ->is_set('tkt-slctr-event-id')) {
110
+			// $_POST['tkt-slctr-event-id'] was not set ?!?!?!?
111
+			\EE_Error::add_error(
112
+				sprintf(
113
+					__(
114
+						'An event id was not provided or was not received.%sPlease click the back button on your browser and try again.',
115
+						'event_espresso'
116
+					),
117
+					'<br/>'
118
+				),
119
+				__FILE__,
120
+				__FUNCTION__,
121
+				__LINE__
122
+			);
123
+		}
124
+		//if event id is valid
125
+		$id = absint(\EE_Registry::instance()->REQ->get('tkt-slctr-event-id'));
126
+		// check nonce
127
+		if ( ! $this->processTicketSelectorNonce('process_ticket_selections', $id)) {
128
+			return false;
129
+		}
130
+		//		d( \EE_Registry::instance()->REQ );
131
+		self::$_available_spaces = array(
132
+			'tickets'   => array(),
133
+			'datetimes' => array(),
134
+		);
135
+		//we should really only have 1 registration in the works now (ie, no MER) so clear any previous items in the cart.
136
+		// When MER happens this will probably need to be tweaked, possibly wrapped in a conditional checking for some constant defined in MER etc.
137
+		\EE_Registry::instance()->load_core('Session');
138
+		// unless otherwise requested, clear the session
139
+		if (apply_filters('FHEE__EE_Ticket_Selector__process_ticket_selections__clear_session', true)) {
140
+			\EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
141
+		}
142
+		//d( \EE_Registry::instance()->SSN );
143
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
144
+		// validate/sanitize data
145
+		$valid = $this->validatePostData($id);
146
+		//EEH_Debug_Tools::printr( $_REQUEST, '$_REQUEST', __FILE__, __LINE__ );
147
+		//EEH_Debug_Tools::printr( $valid, '$valid', __FILE__, __LINE__ );
148
+		//EEH_Debug_Tools::printr( $valid[ 'total_tickets' ], 'total_tickets', __FILE__, __LINE__ );
149
+		//EEH_Debug_Tools::printr( $valid[ 'max_atndz' ], 'max_atndz', __FILE__, __LINE__ );
150
+		//check total tickets ordered vs max number of attendees that can register
151
+		if ($valid['total_tickets'] > $valid['max_atndz']) {
152
+			// ordering too many tickets !!!
153
+			$total_tickets_string = _n(
154
+				'You have attempted to purchase %s ticket.',
155
+				'You have attempted to purchase %s tickets.',
156
+				$valid['total_tickets'],
157
+				'event_espresso'
158
+			);
159
+			$limit_error_1 = sprintf($total_tickets_string, $valid['total_tickets']);
160
+			// dev only message
161
+			$max_atndz_string = _n(
162
+				'The registration limit for this event is %s ticket per registration, therefore the total number of tickets you may purchase at a time can not exceed %s.',
163
+				'The registration limit for this event is %s tickets per registration, therefore the total number of tickets you may purchase at a time can not exceed %s.',
164
+				$valid['max_atndz'],
165
+				'event_espresso'
166
+			);
167
+			$limit_error_2 = sprintf($max_atndz_string, $valid['max_atndz'], $valid['max_atndz']);
168
+			\EE_Error::add_error($limit_error_1 . '<br/>' . $limit_error_2, __FILE__, __FUNCTION__, __LINE__);
169
+		} else {
170
+			// all data appears to be valid
171
+			$tckts_slctd = false;
172
+			$tickets_added = 0;
173
+			$valid = apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__valid_post_data', $valid);
174
+			if ($valid['total_tickets'] > 0) {
175
+				// load cart
176
+				\EE_Registry::instance()->load_core('Cart');
177
+				// cycle thru the number of data rows sent from the event listing
178
+				for ($x = 0; $x < $valid['rows']; $x++) {
179
+					// does this row actually contain a ticket quantity?
180
+					if (isset($valid['qty'][$x]) && $valid['qty'][$x] > 0) {
181
+						// YES we have a ticket quantity
182
+						$tckts_slctd = true;
183
+						//						d( $valid['ticket_obj'][$x] );
184
+						if ($valid['ticket_obj'][$x] instanceof \EE_Ticket) {
185
+							// then add ticket to cart
186
+							$tickets_added += $this->addTicketToCart(
187
+								$valid['ticket_obj'][$x],
188
+								$valid['qty'][$x]
189
+							);
190
+							if (\EE_Error::has_error()) {
191
+								break;
192
+							}
193
+						} else {
194
+							// nothing added to cart retrieved
195
+							\EE_Error::add_error(
196
+								sprintf(
197
+									__(
198
+										'A valid ticket could not be retrieved for the event.%sPlease click the back button on your browser and try again.',
199
+										'event_espresso'
200
+									),
201
+									'<br/>'
202
+								),
203
+								__FILE__, __FUNCTION__, __LINE__
204
+							);
205
+						}
206
+					}
207
+				}
208
+			}
209
+			do_action(
210
+				'AHEE__EE_Ticket_Selector__process_ticket_selections__after_tickets_added_to_cart',
211
+				\EE_Registry::instance()->CART,
212
+				$this
213
+			);
214
+			//d( \EE_Registry::instance()->CART );
215
+			//die(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< KILL REDIRECT HERE BEFORE CART UPDATE
216
+			if (apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__tckts_slctd', $tckts_slctd)) {
217
+				if (apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__success', $tickets_added)) {
218
+					do_action(
219
+						'FHEE__EE_Ticket_Selector__process_ticket_selections__before_redirecting_to_checkout',
220
+						\EE_Registry::instance()->CART,
221
+						$this
222
+					);
223
+					\EE_Registry::instance()->CART->recalculate_all_cart_totals();
224
+					\EE_Registry::instance()->CART->save_cart(false);
225
+					// exit('KILL REDIRECT AFTER CART UPDATE'); // <<<<<<<<  OR HERE TO KILL REDIRECT AFTER CART UPDATE
226
+					// just return TRUE for registrations being made from admin
227
+					if (is_admin()) {
228
+						return true;
229
+					}
230
+					\EE_Error::get_notices(false, true);
231
+					wp_safe_redirect(
232
+						apply_filters(
233
+							'FHEE__EE_Ticket_Selector__process_ticket_selections__success_redirect_url',
234
+							\EE_Registry::instance()->CFG->core->reg_page_url()
235
+						)
236
+					);
237
+					exit();
238
+				} else {
239
+					if ( ! \EE_Error::has_error() && ! \EE_Error::has_error(true, 'attention')) {
240
+						// nothing added to cart
241
+						\EE_Error::add_attention(__('No tickets were added for the event', 'event_espresso'),
242
+							__FILE__, __FUNCTION__, __LINE__);
243
+					}
244
+				}
245
+			} else {
246
+				// no ticket quantities were selected
247
+				\EE_Error::add_error(__('You need to select a ticket quantity before you can proceed.',
248
+					'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
249
+			}
250
+		}
251
+		//die(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< KILL BEFORE REDIRECT
252
+		// at this point, just return if registration is being made from admin
253
+		if (is_admin()) {
254
+			return false;
255
+		}
256
+		if ($valid['return_url']) {
257
+			\EE_Error::get_notices(false, true);
258
+			wp_safe_redirect($valid['return_url']);
259
+			exit();
260
+		} elseif (isset($event_to_add['id'])) {
261
+			\EE_Error::get_notices(false, true);
262
+			wp_safe_redirect(get_permalink($event_to_add['id']));
263
+			exit();
264
+		} else {
265
+			echo \EE_Error::get_notices();
266
+		}
267
+		return false;
268
+	}
269
+
270
+
271
+
272
+	/**
273
+	 * validate_post_data
274
+	 *
275
+	 * @param int $id
276
+	 * @return array|FALSE
277
+	 */
278
+	private function validatePostData($id = 0)
279
+	{
280
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
281
+		if ( ! $id) {
282
+			\EE_Error::add_error(
283
+				__('The event id provided was not valid.', 'event_espresso'),
284
+				__FILE__,
285
+				__FUNCTION__,
286
+				__LINE__
287
+			);
288
+			return false;
289
+		}
290
+		// start with an empty array()
291
+		$valid_data = array();
292
+		// grab valid id
293
+		$valid_data['id'] = $id;
294
+		// array of other form names
295
+		$inputs_to_clean = array(
296
+			'event_id'   => 'tkt-slctr-event-id',
297
+			'max_atndz'  => 'tkt-slctr-max-atndz-',
298
+			'rows'       => 'tkt-slctr-rows-',
299
+			'qty'        => 'tkt-slctr-qty-',
300
+			'ticket_id'  => 'tkt-slctr-ticket-id-',
301
+			'return_url' => 'tkt-slctr-return-url-',
302
+		);
303
+		// let's track the total number of tickets ordered.'
304
+		$valid_data['total_tickets'] = 0;
305
+		// cycle through $inputs_to_clean array
306
+		foreach ($inputs_to_clean as $what => $input_to_clean) {
307
+			// check for POST data
308
+			if (\EE_Registry::instance()->REQ->is_set($input_to_clean . $id)) {
309
+				// grab value
310
+				$input_value = \EE_Registry::instance()->REQ->get($input_to_clean . $id);
311
+				switch ($what) {
312
+					// integers
313
+					case 'event_id':
314
+						$valid_data[$what] = absint($input_value);
315
+						// get event via the event id we put in the form
316
+						$valid_data['event'] = \EE_Registry::instance()
317
+														   ->load_model('Event')
318
+														   ->get_one_by_ID($valid_data['event_id']);
319
+						break;
320
+					case 'rows':
321
+					case 'max_atndz':
322
+						$valid_data[$what] = absint($input_value);
323
+						break;
324
+					// arrays of integers
325
+					case 'qty':
326
+						/** @var array $row_qty */
327
+						$row_qty = $input_value;
328
+						// if qty is coming from a radio button input, then we need to assemble an array of rows
329
+						if ( ! is_array($row_qty)) {
330
+							// get number of rows
331
+							$rows = \EE_Registry::instance()->REQ->is_set('tkt-slctr-rows-' . $id)
332
+								? absint(\EE_Registry::instance()->REQ->get('tkt-slctr-rows-' . $id))
333
+								: 1;
334
+							// explode ints by the dash
335
+							$row_qty = explode('-', $row_qty);
336
+							$row = isset($row_qty[0]) ? absint($row_qty[0]) : 1;
337
+							$qty = isset($row_qty[1]) ? absint($row_qty[1]) : 0;
338
+							$row_qty = array($row => $qty);
339
+							for ($x = 1; $x <= $rows; $x++) {
340
+								if ( ! isset($row_qty[$x])) {
341
+									$row_qty[$x] = 0;
342
+								}
343
+							}
344
+						}
345
+						ksort($row_qty);
346
+						// cycle thru values
347
+						foreach ($row_qty as $qty) {
348
+							$qty = absint($qty);
349
+							// sanitize as integers
350
+							$valid_data[$what][] = $qty;
351
+							$valid_data['total_tickets'] += $qty;
352
+						}
353
+						break;
354
+					// array of integers
355
+					case 'ticket_id':
356
+						$value_array = array();
357
+						// cycle thru values
358
+						foreach ((array)$input_value as $key => $value) {
359
+							// allow only numbers, letters,  spaces, commas and dashes
360
+							$value_array[$key] = wp_strip_all_tags($value);
361
+							// get ticket via the ticket id we put in the form
362
+							$ticket_obj = \EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($value);
363
+							$valid_data['ticket_obj'][$key] = $ticket_obj;
364
+						}
365
+						$valid_data[$what] = $value_array;
366
+						break;
367
+					case 'return_url' :
368
+						// grab and sanitize return-url
369
+						$input_value = esc_url_raw($input_value);
370
+						// was the request coming from an iframe ? if so, then:
371
+						if (strpos($input_value, 'event_list=iframe')) {
372
+							// get anchor fragment
373
+							$input_value = explode('#', $input_value);
374
+							$input_value = end($input_value);
375
+							// use event list url instead, but append anchor
376
+							$input_value = \EEH_Event_View::event_archive_url() . '#' . $input_value;
377
+						}
378
+						$valid_data[$what] = $input_value;
379
+						break;
380
+				}    // end switch $what
381
+			}
382
+		}    // end foreach $inputs_to_clean
383
+		return $valid_data;
384
+	}
385
+
386
+
387
+
388
+	/**
389
+	 * adds a ticket to the cart
390
+	 *
391
+	 * @param \EE_Ticket $ticket
392
+	 * @param int        $qty
393
+	 * @return TRUE on success, FALSE on fail
394
+	 * @throws \EE_Error
395
+	 */
396
+	private function addTicketToCart(\EE_Ticket $ticket = null, $qty = 1)
397
+	{
398
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
399
+		// get the number of spaces left for this datetime ticket
400
+		$available_spaces = $this->ticketDatetimeAvailability($ticket);
401
+		// compare available spaces against the number of tickets being purchased
402
+		if ($available_spaces >= $qty) {
403
+			// allow addons to prevent a ticket from being added to cart
404
+			if (
405
+			! apply_filters(
406
+				'FHEE__EE_Ticket_Selector___add_ticket_to_cart__allow_add_to_cart',
407
+				true,
408
+				$ticket,
409
+				$qty,
410
+				$available_spaces
411
+			)
412
+			) {
413
+				return false;
414
+			}
415
+			$qty = absint(apply_filters('FHEE__EE_Ticket_Selector___add_ticket_to_cart__ticket_qty', $qty, $ticket));
416
+			// add event to cart
417
+			if (\EE_Registry::instance()->CART->add_ticket_to_cart($ticket, $qty)) {
418
+				$this->recalculateTicketDatetimeAvailability($ticket, $qty);
419
+				return true;
420
+			}
421
+			return false;
422
+		}
423
+		// tickets can not be purchased but let's find the exact number left
424
+		// for the last ticket selected PRIOR to subtracting tickets
425
+		$available_spaces = $this->ticketDatetimeAvailability($ticket, true);
426
+		// greedy greedy greedy eh?
427
+		if ($available_spaces > 0) {
428
+			if (
429
+			apply_filters(
430
+				'FHEE__EE_Ticket_Selector___add_ticket_to_cart__allow_display_availability_error',
431
+				true,
432
+				$ticket,
433
+				$qty,
434
+				$available_spaces
435
+			)
436
+			) {
437
+				$this->displayAvailabilityError($available_spaces);
438
+			}
439
+		} else {
440
+			\EE_Error::add_error(
441
+				__(
442
+					'We\'re sorry, but there are no available spaces left for this event at this particular date and time.',
443
+					'event_espresso'
444
+				),
445
+				__FILE__, __FUNCTION__, __LINE__
446
+			);
447
+		}
448
+		return false;
449
+	}
450
+
451
+
452
+
453
+	/**
454
+	 * @param int $available_spaces
455
+	 * @throws \EE_Error
456
+	 */
457
+	private function displayAvailabilityError($available_spaces = 1)
458
+	{
459
+		// add error messaging - we're using the _n function that will generate
460
+		// the appropriate singular or plural message based on the number of $available_spaces
461
+		if (\EE_Registry::instance()->CART->all_ticket_quantity_count()) {
462
+			$msg = sprintf(
463
+				_n(
464
+					'We\'re sorry, but there is only %1$s available space left for this event at this particular date and time. Please select a different number (or different combination) of tickets by cancelling the current selection and choosing again, or proceed to registration.',
465
+					'We\'re sorry, but there are only %1$s available spaces left for this event at this particular date and time. Please select a different number (or different combination) of tickets by cancelling the current selection and choosing again, or proceed to registration.',
466
+					$available_spaces,
467
+					'event_espresso'
468
+				),
469
+				$available_spaces,
470
+				'<br />'
471
+			);
472
+		} else {
473
+			$msg = sprintf(
474
+				_n(
475
+					'We\'re sorry, but there is only %1$s available space left for this event at this particular date and time. Please select a different number (or different combination) of tickets.',
476
+					'We\'re sorry, but there are only %1$s available spaces left for this event at this particular date and time. Please select a different number (or different combination) of tickets.',
477
+					$available_spaces,
478
+					'event_espresso'
479
+				),
480
+				$available_spaces,
481
+				'<br />'
482
+			);
483
+		}
484
+		\EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
485
+	}
486
+
487
+
488
+
489
+	/**
490
+	 * ticketDatetimeAvailability
491
+	 * creates an array of tickets plus all of the datetimes available to each ticket
492
+	 * and tracks the spaces remaining for each of those datetimes
493
+	 *
494
+	 * @param \EE_Ticket $ticket - selected ticket
495
+	 * @param bool       $get_original_ticket_spaces
496
+	 * @return int
497
+	 * @throws \EE_Error
498
+	 */
499
+	private function ticketDatetimeAvailability(\EE_Ticket $ticket, $get_original_ticket_spaces = false)
500
+	{
501
+		// if the $_available_spaces array has not been set up yet...
502
+		if ( ! isset(self::$_available_spaces['tickets'][$ticket->ID()])) {
503
+			$this->setInitialTicketDatetimeAvailability($ticket);
504
+		}
505
+		$available_spaces = $ticket->qty() - $ticket->sold();
506
+		if (isset(self::$_available_spaces['tickets'][$ticket->ID()])) {
507
+			// loop thru tickets, which will ALSO include individual ticket records AND a total
508
+			foreach (self::$_available_spaces['tickets'][$ticket->ID()] as $DTD_ID => $spaces) {
509
+				// if we want the original datetime availability BEFORE we started subtracting tickets ?
510
+				if ($get_original_ticket_spaces) {
511
+					// then grab the available spaces from the "tickets" array
512
+					// and compare with the above to get the lowest number
513
+					$available_spaces = min(
514
+						$available_spaces,
515
+						self::$_available_spaces['tickets'][$ticket->ID()][$DTD_ID]
516
+					);
517
+				} else {
518
+					// we want the updated ticket availability as stored in the "datetimes" array
519
+					$available_spaces = min($available_spaces, self::$_available_spaces['datetimes'][$DTD_ID]);
520
+				}
521
+			}
522
+		}
523
+		return $available_spaces;
524
+	}
525
+
526
+
527
+
528
+	/**
529
+	 * @param \EE_Ticket $ticket
530
+	 * @return void
531
+	 * @throws \EE_Error
532
+	 */
533
+	private function setInitialTicketDatetimeAvailability(\EE_Ticket $ticket)
534
+	{
535
+		// first, get all of the datetimes that are available to this ticket
536
+		$datetimes = $ticket->get_many_related(
537
+			'Datetime',
538
+			array(
539
+				array(
540
+					'DTT_EVT_end' => array(
541
+						'>=',
542
+						\EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
543
+					),
544
+				),
545
+				'order_by' => array('DTT_EVT_start' => 'ASC'),
546
+			)
547
+		);
548
+		if ( ! empty($datetimes)) {
549
+			// now loop thru all of the datetimes
550
+			foreach ($datetimes as $datetime) {
551
+				if ($datetime instanceof \EE_Datetime) {
552
+					// the number of spaces available for the datetime without considering individual ticket quantities
553
+					$spaces_remaining = $datetime->spaces_remaining();
554
+					// save the total available spaces ( the lesser of the ticket qty minus the number of tickets sold
555
+					// or the datetime spaces remaining) to this ticket using the datetime ID as the key
556
+					self::$_available_spaces['tickets'][$ticket->ID()][$datetime->ID()] = min(
557
+						$ticket->qty() - $ticket->sold(),
558
+						$spaces_remaining
559
+					);
560
+					// if the remaining spaces for this datetime is already set,
561
+					// then compare that against the datetime spaces remaining, and take the lowest number,
562
+					// else just take the datetime spaces remaining, and assign to the datetimes array
563
+					self::$_available_spaces['datetimes'][$datetime->ID()] = isset(
564
+						self::$_available_spaces['datetimes'][$datetime->ID()]
565
+					)
566
+						? min(self::$_available_spaces['datetimes'][$datetime->ID()], $spaces_remaining)
567
+						: $spaces_remaining;
568
+				}
569
+			}
570
+		}
571
+	}
572
+
573
+
574
+
575
+	/**
576
+	 * @param    \EE_Ticket $ticket
577
+	 * @param    int        $qty
578
+	 * @return    void
579
+	 */
580
+	private function recalculateTicketDatetimeAvailability(\EE_Ticket $ticket, $qty = 0)
581
+	{
582
+		if (isset(self::$_available_spaces['tickets'][$ticket->ID()])) {
583
+			// loop thru tickets, which will ALSO include individual ticket records AND a total
584
+			foreach (self::$_available_spaces['tickets'][$ticket->ID()] as $DTD_ID => $spaces) {
585
+				// subtract the qty of selected tickets from each datetime's available spaces this ticket has access to,
586
+				self::$_available_spaces['datetimes'][$DTD_ID] -= $qty;
587
+			}
588
+		}
589
+	}
590 590
 
591 591
 
592 592
 }
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -49,7 +49,7 @@  discard block
 block discarded – undo
49 49
             );
50 50
         } else {
51 51
             wp_safe_redirect(
52
-                site_url('/' . \EE_Registry::instance()->CFG->core->event_cpt_slug . '/')
52
+                site_url('/'.\EE_Registry::instance()->CFG->core->event_cpt_slug.'/')
53 53
             );
54 54
         }
55 55
         exit();
@@ -165,7 +165,7 @@  discard block
 block discarded – undo
165 165
                 'event_espresso'
166 166
             );
167 167
             $limit_error_2 = sprintf($max_atndz_string, $valid['max_atndz'], $valid['max_atndz']);
168
-            \EE_Error::add_error($limit_error_1 . '<br/>' . $limit_error_2, __FILE__, __FUNCTION__, __LINE__);
168
+            \EE_Error::add_error($limit_error_1.'<br/>'.$limit_error_2, __FILE__, __FUNCTION__, __LINE__);
169 169
         } else {
170 170
             // all data appears to be valid
171 171
             $tckts_slctd = false;
@@ -305,9 +305,9 @@  discard block
 block discarded – undo
305 305
         // cycle through $inputs_to_clean array
306 306
         foreach ($inputs_to_clean as $what => $input_to_clean) {
307 307
             // check for POST data
308
-            if (\EE_Registry::instance()->REQ->is_set($input_to_clean . $id)) {
308
+            if (\EE_Registry::instance()->REQ->is_set($input_to_clean.$id)) {
309 309
                 // grab value
310
-                $input_value = \EE_Registry::instance()->REQ->get($input_to_clean . $id);
310
+                $input_value = \EE_Registry::instance()->REQ->get($input_to_clean.$id);
311 311
                 switch ($what) {
312 312
                     // integers
313 313
                     case 'event_id':
@@ -328,8 +328,8 @@  discard block
 block discarded – undo
328 328
                         // if qty is coming from a radio button input, then we need to assemble an array of rows
329 329
                         if ( ! is_array($row_qty)) {
330 330
                             // get number of rows
331
-                            $rows = \EE_Registry::instance()->REQ->is_set('tkt-slctr-rows-' . $id)
332
-                                ? absint(\EE_Registry::instance()->REQ->get('tkt-slctr-rows-' . $id))
331
+                            $rows = \EE_Registry::instance()->REQ->is_set('tkt-slctr-rows-'.$id)
332
+                                ? absint(\EE_Registry::instance()->REQ->get('tkt-slctr-rows-'.$id))
333 333
                                 : 1;
334 334
                             // explode ints by the dash
335 335
                             $row_qty = explode('-', $row_qty);
@@ -355,7 +355,7 @@  discard block
 block discarded – undo
355 355
                     case 'ticket_id':
356 356
                         $value_array = array();
357 357
                         // cycle thru values
358
-                        foreach ((array)$input_value as $key => $value) {
358
+                        foreach ((array) $input_value as $key => $value) {
359 359
                             // allow only numbers, letters,  spaces, commas and dashes
360 360
                             $value_array[$key] = wp_strip_all_tags($value);
361 361
                             // get ticket via the ticket id we put in the form
@@ -373,7 +373,7 @@  discard block
 block discarded – undo
373 373
                             $input_value = explode('#', $input_value);
374 374
                             $input_value = end($input_value);
375 375
                             // use event list url instead, but append anchor
376
-                            $input_value = \EEH_Event_View::event_archive_url() . '#' . $input_value;
376
+                            $input_value = \EEH_Event_View::event_archive_url().'#'.$input_value;
377 377
                         }
378 378
                         $valid_data[$what] = $input_value;
379 379
                         break;
Please login to merge, or discard this patch.
core/db_models/EEM_Datetime.model.php 1 patch
Indentation   +581 added lines, -581 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
  * Class Datetime Model
@@ -11,586 +11,586 @@  discard block
 block discarded – undo
11 11
 class EEM_Datetime extends EEM_Soft_Delete_Base
12 12
 {
13 13
 
14
-    /**
15
-     * @var EEM_Datetime $_instance
16
-     */
17
-    protected static $_instance;
18
-
19
-
20
-
21
-    /**
22
-     *        private constructor to prevent direct creation
23
-     *
24
-     * @Constructor
25
-     * @access private
26
-     * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and any
27
-     *                         incoming timezone data that gets saved).  Note this just sends the timezone info to the
28
-     *                         date time model field objects.  Default is NULL (and will be assumed using the set
29
-     *                         timezone in the 'timezone_string' wp option)
30
-     * @throws \EE_Error
31
-     */
32
-    protected function __construct($timezone)
33
-    {
34
-        $this->singular_item = __('Datetime', 'event_espresso');
35
-        $this->plural_item = __('Datetimes', 'event_espresso');
36
-        $this->_tables = array(
37
-            'Datetime' => new EE_Primary_Table('esp_datetime', 'DTT_ID'),
38
-        );
39
-        $this->_fields = array(
40
-            'Datetime' => array(
41
-                'DTT_ID'          => new EE_Primary_Key_Int_Field('DTT_ID', __('Datetime ID', 'event_espresso')),
42
-                'EVT_ID'          => new EE_Foreign_Key_Int_Field(
43
-                    'EVT_ID', __('Event ID', 'event_espresso'), false, 0, 'Event'
44
-                ),
45
-                'DTT_name'        => new EE_Plain_Text_Field(
46
-                    'DTT_name', __('Datetime Name', 'event_espresso'), false, ''
47
-                ),
48
-                'DTT_description' => new EE_Post_Content_Field(
49
-                    'DTT_description', __('Description for Datetime', 'event_espresso'), false, ''
50
-                ),
51
-                'DTT_EVT_start'   => new EE_Datetime_Field(
52
-                    'DTT_EVT_start', __('Start time/date of Event', 'event_espresso'), false, EE_Datetime_Field::now,
53
-                    $timezone
54
-                ),
55
-                'DTT_EVT_end'     => new EE_Datetime_Field(
56
-                    'DTT_EVT_end', __('End time/date of Event', 'event_espresso'), false, EE_Datetime_Field::now,
57
-                    $timezone
58
-                ),
59
-                'DTT_reg_limit'   => new EE_Infinite_Integer_Field(
60
-                    'DTT_reg_limit', __('Registration Limit for this time', 'event_espresso'), true, EE_INF),
61
-                'DTT_sold'        => new EE_Integer_Field(
62
-                    'DTT_sold', __('How many sales for this Datetime that have occurred', 'event_espresso'), true, 0
63
-                ),
64
-                'DTT_reserved' => new EE_Integer_Field('DTT_reserved',
65
-                    __('Quantity of tickets reserved, but not yet fully purchased', 'event_espresso'), false, 0
66
-                ),
67
-                'DTT_is_primary'  => new EE_Boolean_Field(
68
-                    'DTT_is_primary', __('Flag indicating datetime is primary one for event', 'event_espresso'),
69
-                    false, false
70
-                ),
71
-                'DTT_order'       => new EE_Integer_Field(
72
-                    'DTT_order', __('The order in which the Datetime is displayed', 'event_espresso'), false, 0
73
-                ),
74
-                'DTT_parent'      => new EE_Integer_Field(
75
-                    'DTT_parent', __('Indicates what DTT_ID is the parent of this DTT_ID'), true, 0
76
-                ),
77
-                'DTT_deleted'     => new EE_Trashed_Flag_Field(
78
-                    'DTT_deleted', __('Flag indicating datetime is archived', 'event_espresso'), false, false
79
-                ),
80
-            ),
81
-        );
82
-        $this->_model_relations = array(
83
-            'Ticket'  => new EE_HABTM_Relation('Datetime_Ticket'),
84
-            'Event'   => new EE_Belongs_To_Relation(),
85
-            'Checkin' => new EE_Has_Many_Relation(),
86
-        );
87
-        $this->_model_chain_to_wp_user = 'Event';
88
-        //this model is generally available for reading
89
-        $this->_cap_restriction_generators[EEM_Base::caps_read] = new EE_Restriction_Generator_Event_Related_Public('Event');
90
-        $this->_cap_restriction_generators[EEM_Base::caps_read_admin] = new EE_Restriction_Generator_Event_Related_Protected('Event');
91
-        $this->_cap_restriction_generators[EEM_Base::caps_edit] = new EE_Restriction_Generator_Event_Related_Protected('Event');
92
-        $this->_cap_restriction_generators[EEM_Base::caps_delete] = new EE_Restriction_Generator_Event_Related_Protected('Event',
93
-            EEM_Base::caps_edit);
94
-        parent::__construct($timezone);
95
-    }
96
-
97
-
98
-
99
-    /**
100
-     * create new blank datetime
101
-     *
102
-     * @access public
103
-     * @return EE_Datetime[] array on success, FALSE on fail
104
-     * @throws \EE_Error
105
-     */
106
-    public function create_new_blank_datetime()
107
-    {
108
-        //makes sure timezone is always set.
109
-        $timezone_string = $this->get_timezone();
110
-        $blank_datetime = EE_Datetime::new_instance(
111
-            array(
112
-                'DTT_EVT_start' => $this->current_time_for_query('DTT_EVT_start', true) + MONTH_IN_SECONDS,
113
-                'DTT_EVT_end'   => $this->current_time_for_query('DTT_EVT_end', true) + MONTH_IN_SECONDS,
114
-                'DTT_order'     => 1,
115
-                'DTT_reg_limit' => EE_INF,
116
-            ),
117
-            $timezone_string
118
-        );
119
-        $blank_datetime->set_start_time($this->convert_datetime_for_query('DTT_EVT_start', '8am', 'ga',
120
-            $timezone_string));
121
-        $blank_datetime->set_end_time($this->convert_datetime_for_query('DTT_EVT_end', '5pm', 'ga', $timezone_string));
122
-        return array($blank_datetime);
123
-    }
124
-
125
-
126
-
127
-    /**
128
-     * get event start date from db
129
-     *
130
-     * @access public
131
-     * @param  int $EVT_ID
132
-     * @return EE_Datetime[] array on success, FALSE on fail
133
-     * @throws \EE_Error
134
-     */
135
-    public function get_all_event_dates($EVT_ID = 0)
136
-    {
137
-        if ( ! $EVT_ID) { // on add_new_event event_id gets set to 0
138
-            return $this->create_new_blank_datetime();
139
-        }
140
-        $results = $this->get_datetimes_for_event_ordered_by_DTT_order($EVT_ID);
141
-        if (empty($results)) {
142
-            return $this->create_new_blank_datetime();
143
-        }
144
-        return $results;
145
-    }
146
-
147
-
148
-
149
-    /**
150
-     * get all datetimes attached to an event ordered by the DTT_order field
151
-     *
152
-     * @public
153
-     * @param  int    $EVT_ID     event id
154
-     * @param boolean $include_expired
155
-     * @param boolean $include_deleted
156
-     * @param  int    $limit      If included then limit the count of results by
157
-     *                            the given number
158
-     * @return EE_Datetime[]
159
-     * @throws \EE_Error
160
-     */
161
-    public function get_datetimes_for_event_ordered_by_DTT_order(
162
-        $EVT_ID,
163
-        $include_expired = true,
164
-        $include_deleted = true,
165
-        $limit = null
166
-    ) {
167
-        //sanitize EVT_ID
168
-        $EVT_ID = absint($EVT_ID);
169
-        $old_assumption = $this->get_assumption_concerning_values_already_prepared_by_model_object();
170
-        $this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
171
-        $where_params = array('Event.EVT_ID' => $EVT_ID);
172
-        $query_params = ! empty($limit)
173
-            ? array(
174
-                $where_params,
175
-                'limit'                    => $limit,
176
-                'order_by'                 => array('DTT_order' => 'ASC'),
177
-                'default_where_conditions' => 'none',
178
-            )
179
-            : array(
180
-                $where_params,
181
-                'order_by'                 => array('DTT_order' => 'ASC'),
182
-                'default_where_conditions' => 'none',
183
-            );
184
-        if ( ! $include_expired) {
185
-            $query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
186
-        }
187
-        if ($include_deleted) {
188
-            $query_params[0]['DTT_deleted'] = array('IN', array(true, false));
189
-        }
190
-        /** @var EE_Datetime[] $result */
191
-        $result = $this->get_all($query_params);
192
-        $this->assume_values_already_prepared_by_model_object($old_assumption);
193
-        return $result;
194
-    }
195
-
196
-
197
-
198
-    /**
199
-     * Gets the datetimes for the event (with the given limit), and orders them by "importance". By importance, we mean
200
-     * that the primary datetimes are most important (DEPRECATED FOR NOW), and then the earlier datetimes are the most
201
-     * important. Maybe we'll want this to take into account datetimes that haven't already passed, but we don't yet.
202
-     *
203
-     * @param int $EVT_ID
204
-     * @param int $limit
205
-     * @return EE_Datetime[]|EE_Base_Class[]
206
-     * @throws \EE_Error
207
-     */
208
-    public function get_datetimes_for_event_ordered_by_importance($EVT_ID = 0, $limit = null)
209
-    {
210
-        return $this->get_all(
211
-            array(
212
-                array('Event.EVT_ID' => $EVT_ID),
213
-                'limit'                    => $limit,
214
-                'order_by'                 => array('DTT_EVT_start' => 'ASC'),
215
-                'default_where_conditions' => 'none',
216
-            )
217
-        );
218
-    }
219
-
220
-
221
-
222
-    /**
223
-     * @param int     $EVT_ID
224
-     * @param boolean $include_expired
225
-     * @param boolean $include_deleted
226
-     * @return EE_Datetime
227
-     * @throws \EE_Error
228
-     */
229
-    public function get_oldest_datetime_for_event($EVT_ID, $include_expired = false, $include_deleted = false)
230
-    {
231
-        $results = $this->get_datetimes_for_event_ordered_by_start_time($EVT_ID, $include_expired, $include_deleted, 1);
232
-        if ($results) {
233
-            return array_shift($results);
234
-        } else {
235
-            return null;
236
-        }
237
-    }
238
-
239
-
240
-
241
-    /**
242
-     * Gets the 'primary' datetime for an event.
243
-     *
244
-     * @param int  $EVT_ID
245
-     * @param bool $try_to_exclude_expired
246
-     * @param bool $try_to_exclude_deleted
247
-     * @return \EE_Datetime
248
-     * @throws \EE_Error
249
-     */
250
-    public function get_primary_datetime_for_event(
251
-        $EVT_ID,
252
-        $try_to_exclude_expired = true,
253
-        $try_to_exclude_deleted = true
254
-    ) {
255
-        if ($try_to_exclude_expired) {
256
-            $non_expired = $this->get_oldest_datetime_for_event($EVT_ID, false, false);
257
-            if ($non_expired) {
258
-                return $non_expired;
259
-            }
260
-        }
261
-        if ($try_to_exclude_deleted) {
262
-            $expired_even = $this->get_oldest_datetime_for_event($EVT_ID, true);
263
-            if ($expired_even) {
264
-                return $expired_even;
265
-            }
266
-        }
267
-        return $this->get_oldest_datetime_for_event($EVT_ID, true, true);
268
-    }
269
-
270
-
271
-
272
-    /**
273
-     * Gets ALL the datetimes for an event (including trashed ones, for now), ordered
274
-     * only by start date
275
-     *
276
-     * @param int     $EVT_ID
277
-     * @param boolean $include_expired
278
-     * @param boolean $include_deleted
279
-     * @param int     $limit
280
-     * @return EE_Datetime[]
281
-     * @throws \EE_Error
282
-     */
283
-    public function get_datetimes_for_event_ordered_by_start_time(
284
-        $EVT_ID,
285
-        $include_expired = true,
286
-        $include_deleted = true,
287
-        $limit = null
288
-    ) {
289
-        //sanitize EVT_ID
290
-        $EVT_ID = absint($EVT_ID);
291
-        $old_assumption = $this->get_assumption_concerning_values_already_prepared_by_model_object();
292
-        $this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
293
-        $query_params = array(array('Event.EVT_ID' => $EVT_ID), 'order_by' => array('DTT_EVT_start' => 'asc'));
294
-        if ( ! $include_expired) {
295
-            $query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
296
-        }
297
-        if ($include_deleted) {
298
-            $query_params[0]['DTT_deleted'] = array('IN', array(true, false));
299
-        }
300
-        if ($limit) {
301
-            $query_params['limit'] = $limit;
302
-        }
303
-        /** @var EE_Datetime[] $result */
304
-        $result = $this->get_all($query_params);
305
-        $this->assume_values_already_prepared_by_model_object($old_assumption);
306
-        return $result;
307
-    }
308
-
309
-
310
-
311
-    /**
312
-     * Gets ALL the datetimes for an ticket (including trashed ones, for now), ordered
313
-     * only by start date
314
-     *
315
-     * @param int     $TKT_ID
316
-     * @param boolean $include_expired
317
-     * @param boolean $include_deleted
318
-     * @param int     $limit
319
-     * @return EE_Datetime[]
320
-     * @throws \EE_Error
321
-     */
322
-    public function get_datetimes_for_ticket_ordered_by_start_time(
323
-        $TKT_ID,
324
-        $include_expired = true,
325
-        $include_deleted = true,
326
-        $limit = null
327
-    ) {
328
-        //sanitize TKT_ID
329
-        $TKT_ID = absint($TKT_ID);
330
-        $old_assumption = $this->get_assumption_concerning_values_already_prepared_by_model_object();
331
-        $this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
332
-        $query_params = array(array('Ticket.TKT_ID' => $TKT_ID), 'order_by' => array('DTT_EVT_start' => 'asc'));
333
-        if ( ! $include_expired) {
334
-            $query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
335
-        }
336
-        if ($include_deleted) {
337
-            $query_params[0]['DTT_deleted'] = array('IN', array(true, false));
338
-        }
339
-        if ($limit) {
340
-            $query_params['limit'] = $limit;
341
-        }
342
-        /** @var EE_Datetime[] $result */
343
-        $result = $this->get_all($query_params);
344
-        $this->assume_values_already_prepared_by_model_object($old_assumption);
345
-        return $result;
346
-    }
347
-
348
-
349
-
350
-    /**
351
-     * Gets all the datetimes for a ticket (including trashed ones, for now), ordered by the DTT_order for the
352
-     * datetimes.
353
-     *
354
-     * @param  int      $TKT_ID          ID of ticket to retrieve the datetimes for
355
-     * @param  boolean  $include_expired whether to include expired datetimes or not
356
-     * @param  boolean  $include_deleted whether to include trashed datetimes or not.
357
-     * @param  int|null $limit           if null, no limit, if int then limit results by
358
-     *                                   that number
359
-     * @return EE_Datetime[]
360
-     * @throws \EE_Error
361
-     */
362
-    public function get_datetimes_for_ticket_ordered_by_DTT_order(
363
-        $TKT_ID,
364
-        $include_expired = true,
365
-        $include_deleted = true,
366
-        $limit = null
367
-    ) {
368
-        //sanitize id.
369
-        $TKT_ID = absint($TKT_ID);
370
-        $old_assumption = $this->get_assumption_concerning_values_already_prepared_by_model_object();
371
-        $this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
372
-        $where_params = array('Ticket.TKT_ID' => $TKT_ID);
373
-        $query_params = array($where_params, 'order_by' => array('DTT_order' => 'ASC'));
374
-        if ( ! $include_expired) {
375
-            $query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
376
-        }
377
-        if ($include_deleted) {
378
-            $query_params[0]['DTT_deleted'] = array('IN', array(true, false));
379
-        }
380
-        if ($limit) {
381
-            $query_params['limit'] = $limit;
382
-        }
383
-        /** @var EE_Datetime[] $result */
384
-        $result = $this->get_all($query_params);
385
-        $this->assume_values_already_prepared_by_model_object($old_assumption);
386
-        return $result;
387
-    }
388
-
389
-
390
-
391
-    /**
392
-     * Gets the most important datetime for a particular event (ie, the primary event usually. But if for some WACK
393
-     * reason it doesn't exist, we consider the earliest event the most important)
394
-     *
395
-     * @param int $EVT_ID
396
-     * @return EE_Datetime
397
-     * @throws \EE_Error
398
-     */
399
-    public function get_most_important_datetime_for_event($EVT_ID)
400
-    {
401
-        $results = $this->get_datetimes_for_event_ordered_by_importance($EVT_ID, 1);
402
-        if ($results) {
403
-            return array_shift($results);
404
-        } else {
405
-            return null;
406
-        }
407
-    }
408
-
409
-
410
-
411
-    /**
412
-     * This returns a wpdb->results        Array of all DTT month and years matching the incoming query params and
413
-     * grouped by month and year.
414
-     *
415
-     * @param  array  $where_params      Array of query_params as described in the comments for EEM_Base::get_all()
416
-     * @param  string $evt_active_status A string representing the evt active status to filter the months by.
417
-     *                                   Can be:
418
-     *                                   - '' = no filter
419
-     *                                   - upcoming = Published events with at least one upcoming datetime.
420
-     *                                   - expired = Events with all datetimes expired.
421
-     *                                   - active = Events that are published and have at least one datetime that
422
-     *                                   starts before now and ends after now.
423
-     *                                   - inactive = Events that are either not published.
424
-     * @return EE_Base_Class[]
425
-     * @throws \EE_Error
426
-     */
427
-    public function get_dtt_months_and_years($where_params, $evt_active_status = '')
428
-    {
429
-        $current_time_for_DTT_EVT_start = $this->current_time_for_query('DTT_EVT_start');
430
-        $current_time_for_DTT_EVT_end = $this->current_time_for_query('DTT_EVT_end');
431
-        switch ($evt_active_status) {
432
-            case 'upcoming' :
433
-                $where_params['Event.status'] = 'publish';
434
-                //if there are already query_params matching DTT_EVT_start then we need to modify that to add them.
435
-                if (isset($where_params['DTT_EVT_start'])) {
436
-                    $where_params['DTT_EVT_start*****'] = $where_params['DTT_EVT_start'];
437
-                }
438
-                $where_params['DTT_EVT_start'] = array('>', $current_time_for_DTT_EVT_start);
439
-                break;
440
-            case 'expired' :
441
-                if (isset($where_params['Event.status'])) {
442
-                    unset($where_params['Event.status']);
443
-                }
444
-                //get events to exclude
445
-                $exclude_query[0] = array_merge($where_params,
446
-                    array('DTT_EVT_end' => array('>', $current_time_for_DTT_EVT_end)));
447
-                //first get all events that have datetimes where its not expired.
448
-                $event_ids = $this->_get_all_wpdb_results($exclude_query, OBJECT_K, 'Datetime.EVT_ID');
449
-                $event_ids = array_keys($event_ids);
450
-                if (isset($where_params['DTT_EVT_end'])) {
451
-                    $where_params['DTT_EVT_end****'] = $where_params['DTT_EVT_end'];
452
-                }
453
-                $where_params['DTT_EVT_end'] = array('<', $current_time_for_DTT_EVT_end);
454
-                $where_params['Event.EVT_ID'] = array('NOT IN', $event_ids);
455
-                break;
456
-            case 'active' :
457
-                $where_params['Event.status'] = 'publish';
458
-                if (isset($where_params['DTT_EVT_start'])) {
459
-                    $where_params['Datetime.DTT_EVT_start******'] = $where_params['DTT_EVT_start'];
460
-                }
461
-                if (isset($where_params['Datetime.DTT_EVT_end'])) {
462
-                    $where_params['Datetime.DTT_EVT_end*****'] = $where_params['DTT_EVT_end'];
463
-                }
464
-                $where_params['DTT_EVT_start'] = array('<', $current_time_for_DTT_EVT_start);
465
-                $where_params['DTT_EVT_end'] = array('>', $current_time_for_DTT_EVT_end);
466
-                break;
467
-            case 'inactive' :
468
-                if (isset($where_params['Event.status'])) {
469
-                    unset($where_params['Event.status']);
470
-                }
471
-                if (isset($where_params['OR'])) {
472
-                    $where_params['AND']['OR'] = $where_params['OR'];
473
-                }
474
-                if (isset($where_params['DTT_EVT_end'])) {
475
-                    $where_params['AND']['DTT_EVT_end****'] = $where_params['DTT_EVT_end'];
476
-                    unset($where_params['DTT_EVT_end']);
477
-                }
478
-                if (isset($where_params['DTT_EVT_start'])) {
479
-                    $where_params['AND']['DTT_EVT_start'] = $where_params['DTT_EVT_start'];
480
-                    unset($where_params['DTT_EVT_start']);
481
-                }
482
-                $where_params['AND']['Event.status'] = array('!=', 'publish');
483
-                break;
484
-        }
485
-        $query_params[0] = $where_params;
486
-        $query_params['group_by'] = array('dtt_year', 'dtt_month');
487
-        $query_params['order_by'] = array('DTT_EVT_start' => 'DESC');
488
-        $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'DTT_EVT_start');
489
-        $columns_to_select = array(
490
-            'dtt_year'      => array('YEAR(' . $query_interval . ')', '%s'),
491
-            'dtt_month'     => array('MONTHNAME(' . $query_interval . ')', '%s'),
492
-            'dtt_month_num' => array('MONTH(' . $query_interval . ')', '%s'),
493
-        );
494
-        return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select);
495
-    }
496
-
497
-
498
-
499
-    /**
500
-     * Updates the DTT_sold attribute on each datetime (based on the registrations
501
-     * for the tickets for each datetime)
502
-     *
503
-     * @param EE_Datetime[] $datetimes
504
-     */
505
-    public function update_sold($datetimes)
506
-    {
507
-        foreach ($datetimes as $datetime) {
508
-            $datetime->update_sold();
509
-        }
510
-    }
511
-
512
-
513
-
514
-    /**
515
-     *    Gets the total number of tickets available at a particular datetime
516
-     *    (does NOT take into account the datetime's spaces available)
517
-     *
518
-     * @param int   $DTT_ID
519
-     * @param array $query_params
520
-     * @return int of tickets available. If sold out, return less than 1. If infinite, returns EE_INF,  IF there are NO
521
-     *             tickets attached to datetime then FALSE is returned.
522
-     */
523
-    public function sum_tickets_currently_available_at_datetime($DTT_ID, array $query_params = array())
524
-    {
525
-        $datetime = $this->get_one_by_ID($DTT_ID);
526
-        if ($datetime instanceof EE_Datetime) {
527
-            return $datetime->tickets_remaining($query_params);
528
-        }
529
-        return 0;
530
-    }
531
-
532
-
533
-
534
-    /**
535
-     * This returns an array of counts of datetimes in the database for each Datetime status that can be queried.
536
-     *
537
-     * @param  array $stati_to_include If included you can restrict the statuses we return counts for by including the
538
-     *                                 stati you want counts for as values in the array.  An empty array returns counts
539
-     *                                 for all valid stati.
540
-     * @param  array $query_params     If included can be used to refine the conditions for returning the count (i.e.
541
-     *                                 only for Datetimes connected to a specific event, or specific ticket.
542
-     * @return array  The value returned is an array indexed by Datetime Status and the values are the counts.  The
543
-     * @throws \EE_Error
544
-     *                                 stati used as index keys are: EE_Datetime::active EE_Datetime::upcoming EE_Datetime::expired
545
-     */
546
-    public function get_datetime_counts_by_status(array $stati_to_include = array(), array $query_params = array())
547
-    {
548
-        //only accept where conditions for this query.
549
-        $_where = isset($query_params[0]) ? $query_params[0] : array();
550
-        $status_query_args = array(
551
-            EE_Datetime::active   => array_merge(
552
-                $_where,
553
-                array('DTT_EVT_start' => array('<', time()), 'DTT_EVT_end' => array('>', time()))
554
-            ),
555
-            EE_Datetime::upcoming => array_merge(
556
-                $_where,
557
-                array('DTT_EVT_start' => array('>', time()))
558
-            ),
559
-            EE_Datetime::expired  => array_merge(
560
-                $_where,
561
-                array('DTT_EVT_end' => array('<', time()))
562
-            ),
563
-        );
564
-        if ( ! empty($stati_to_include)) {
565
-            foreach (array_keys($status_query_args) as $status) {
566
-                if ( ! in_array($status, $stati_to_include, true)) {
567
-                    unset($status_query_args[$status]);
568
-                }
569
-            }
570
-        }
571
-        //loop through and query counts for each stati.
572
-        $status_query_results = array();
573
-        foreach ($status_query_args as $status => $status_where_conditions) {
574
-            $status_query_results[$status] = EEM_Datetime::count(array($status_where_conditions), 'DTT_ID', true);
575
-        }
576
-        return $status_query_results;
577
-    }
578
-
579
-
580
-
581
-    /**
582
-     * Returns the specific count for a given Datetime status matching any given query_params.
583
-     *
584
-     * @param string $status Valid string representation for Datetime status requested. (Defaults to Active).
585
-     * @param array  $query_params
586
-     * @return int
587
-     * @throws \EE_Error
588
-     */
589
-    public function get_datetime_count_for_status($status = EE_Datetime::active, array $query_params = array())
590
-    {
591
-        $count = $this->get_datetime_counts_by_status(array($status), $query_params);
592
-        return ! empty($count[$status]) ? $count[$status] : 0;
593
-    }
14
+	/**
15
+	 * @var EEM_Datetime $_instance
16
+	 */
17
+	protected static $_instance;
18
+
19
+
20
+
21
+	/**
22
+	 *        private constructor to prevent direct creation
23
+	 *
24
+	 * @Constructor
25
+	 * @access private
26
+	 * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and any
27
+	 *                         incoming timezone data that gets saved).  Note this just sends the timezone info to the
28
+	 *                         date time model field objects.  Default is NULL (and will be assumed using the set
29
+	 *                         timezone in the 'timezone_string' wp option)
30
+	 * @throws \EE_Error
31
+	 */
32
+	protected function __construct($timezone)
33
+	{
34
+		$this->singular_item = __('Datetime', 'event_espresso');
35
+		$this->plural_item = __('Datetimes', 'event_espresso');
36
+		$this->_tables = array(
37
+			'Datetime' => new EE_Primary_Table('esp_datetime', 'DTT_ID'),
38
+		);
39
+		$this->_fields = array(
40
+			'Datetime' => array(
41
+				'DTT_ID'          => new EE_Primary_Key_Int_Field('DTT_ID', __('Datetime ID', 'event_espresso')),
42
+				'EVT_ID'          => new EE_Foreign_Key_Int_Field(
43
+					'EVT_ID', __('Event ID', 'event_espresso'), false, 0, 'Event'
44
+				),
45
+				'DTT_name'        => new EE_Plain_Text_Field(
46
+					'DTT_name', __('Datetime Name', 'event_espresso'), false, ''
47
+				),
48
+				'DTT_description' => new EE_Post_Content_Field(
49
+					'DTT_description', __('Description for Datetime', 'event_espresso'), false, ''
50
+				),
51
+				'DTT_EVT_start'   => new EE_Datetime_Field(
52
+					'DTT_EVT_start', __('Start time/date of Event', 'event_espresso'), false, EE_Datetime_Field::now,
53
+					$timezone
54
+				),
55
+				'DTT_EVT_end'     => new EE_Datetime_Field(
56
+					'DTT_EVT_end', __('End time/date of Event', 'event_espresso'), false, EE_Datetime_Field::now,
57
+					$timezone
58
+				),
59
+				'DTT_reg_limit'   => new EE_Infinite_Integer_Field(
60
+					'DTT_reg_limit', __('Registration Limit for this time', 'event_espresso'), true, EE_INF),
61
+				'DTT_sold'        => new EE_Integer_Field(
62
+					'DTT_sold', __('How many sales for this Datetime that have occurred', 'event_espresso'), true, 0
63
+				),
64
+				'DTT_reserved' => new EE_Integer_Field('DTT_reserved',
65
+					__('Quantity of tickets reserved, but not yet fully purchased', 'event_espresso'), false, 0
66
+				),
67
+				'DTT_is_primary'  => new EE_Boolean_Field(
68
+					'DTT_is_primary', __('Flag indicating datetime is primary one for event', 'event_espresso'),
69
+					false, false
70
+				),
71
+				'DTT_order'       => new EE_Integer_Field(
72
+					'DTT_order', __('The order in which the Datetime is displayed', 'event_espresso'), false, 0
73
+				),
74
+				'DTT_parent'      => new EE_Integer_Field(
75
+					'DTT_parent', __('Indicates what DTT_ID is the parent of this DTT_ID'), true, 0
76
+				),
77
+				'DTT_deleted'     => new EE_Trashed_Flag_Field(
78
+					'DTT_deleted', __('Flag indicating datetime is archived', 'event_espresso'), false, false
79
+				),
80
+			),
81
+		);
82
+		$this->_model_relations = array(
83
+			'Ticket'  => new EE_HABTM_Relation('Datetime_Ticket'),
84
+			'Event'   => new EE_Belongs_To_Relation(),
85
+			'Checkin' => new EE_Has_Many_Relation(),
86
+		);
87
+		$this->_model_chain_to_wp_user = 'Event';
88
+		//this model is generally available for reading
89
+		$this->_cap_restriction_generators[EEM_Base::caps_read] = new EE_Restriction_Generator_Event_Related_Public('Event');
90
+		$this->_cap_restriction_generators[EEM_Base::caps_read_admin] = new EE_Restriction_Generator_Event_Related_Protected('Event');
91
+		$this->_cap_restriction_generators[EEM_Base::caps_edit] = new EE_Restriction_Generator_Event_Related_Protected('Event');
92
+		$this->_cap_restriction_generators[EEM_Base::caps_delete] = new EE_Restriction_Generator_Event_Related_Protected('Event',
93
+			EEM_Base::caps_edit);
94
+		parent::__construct($timezone);
95
+	}
96
+
97
+
98
+
99
+	/**
100
+	 * create new blank datetime
101
+	 *
102
+	 * @access public
103
+	 * @return EE_Datetime[] array on success, FALSE on fail
104
+	 * @throws \EE_Error
105
+	 */
106
+	public function create_new_blank_datetime()
107
+	{
108
+		//makes sure timezone is always set.
109
+		$timezone_string = $this->get_timezone();
110
+		$blank_datetime = EE_Datetime::new_instance(
111
+			array(
112
+				'DTT_EVT_start' => $this->current_time_for_query('DTT_EVT_start', true) + MONTH_IN_SECONDS,
113
+				'DTT_EVT_end'   => $this->current_time_for_query('DTT_EVT_end', true) + MONTH_IN_SECONDS,
114
+				'DTT_order'     => 1,
115
+				'DTT_reg_limit' => EE_INF,
116
+			),
117
+			$timezone_string
118
+		);
119
+		$blank_datetime->set_start_time($this->convert_datetime_for_query('DTT_EVT_start', '8am', 'ga',
120
+			$timezone_string));
121
+		$blank_datetime->set_end_time($this->convert_datetime_for_query('DTT_EVT_end', '5pm', 'ga', $timezone_string));
122
+		return array($blank_datetime);
123
+	}
124
+
125
+
126
+
127
+	/**
128
+	 * get event start date from db
129
+	 *
130
+	 * @access public
131
+	 * @param  int $EVT_ID
132
+	 * @return EE_Datetime[] array on success, FALSE on fail
133
+	 * @throws \EE_Error
134
+	 */
135
+	public function get_all_event_dates($EVT_ID = 0)
136
+	{
137
+		if ( ! $EVT_ID) { // on add_new_event event_id gets set to 0
138
+			return $this->create_new_blank_datetime();
139
+		}
140
+		$results = $this->get_datetimes_for_event_ordered_by_DTT_order($EVT_ID);
141
+		if (empty($results)) {
142
+			return $this->create_new_blank_datetime();
143
+		}
144
+		return $results;
145
+	}
146
+
147
+
148
+
149
+	/**
150
+	 * get all datetimes attached to an event ordered by the DTT_order field
151
+	 *
152
+	 * @public
153
+	 * @param  int    $EVT_ID     event id
154
+	 * @param boolean $include_expired
155
+	 * @param boolean $include_deleted
156
+	 * @param  int    $limit      If included then limit the count of results by
157
+	 *                            the given number
158
+	 * @return EE_Datetime[]
159
+	 * @throws \EE_Error
160
+	 */
161
+	public function get_datetimes_for_event_ordered_by_DTT_order(
162
+		$EVT_ID,
163
+		$include_expired = true,
164
+		$include_deleted = true,
165
+		$limit = null
166
+	) {
167
+		//sanitize EVT_ID
168
+		$EVT_ID = absint($EVT_ID);
169
+		$old_assumption = $this->get_assumption_concerning_values_already_prepared_by_model_object();
170
+		$this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
171
+		$where_params = array('Event.EVT_ID' => $EVT_ID);
172
+		$query_params = ! empty($limit)
173
+			? array(
174
+				$where_params,
175
+				'limit'                    => $limit,
176
+				'order_by'                 => array('DTT_order' => 'ASC'),
177
+				'default_where_conditions' => 'none',
178
+			)
179
+			: array(
180
+				$where_params,
181
+				'order_by'                 => array('DTT_order' => 'ASC'),
182
+				'default_where_conditions' => 'none',
183
+			);
184
+		if ( ! $include_expired) {
185
+			$query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
186
+		}
187
+		if ($include_deleted) {
188
+			$query_params[0]['DTT_deleted'] = array('IN', array(true, false));
189
+		}
190
+		/** @var EE_Datetime[] $result */
191
+		$result = $this->get_all($query_params);
192
+		$this->assume_values_already_prepared_by_model_object($old_assumption);
193
+		return $result;
194
+	}
195
+
196
+
197
+
198
+	/**
199
+	 * Gets the datetimes for the event (with the given limit), and orders them by "importance". By importance, we mean
200
+	 * that the primary datetimes are most important (DEPRECATED FOR NOW), and then the earlier datetimes are the most
201
+	 * important. Maybe we'll want this to take into account datetimes that haven't already passed, but we don't yet.
202
+	 *
203
+	 * @param int $EVT_ID
204
+	 * @param int $limit
205
+	 * @return EE_Datetime[]|EE_Base_Class[]
206
+	 * @throws \EE_Error
207
+	 */
208
+	public function get_datetimes_for_event_ordered_by_importance($EVT_ID = 0, $limit = null)
209
+	{
210
+		return $this->get_all(
211
+			array(
212
+				array('Event.EVT_ID' => $EVT_ID),
213
+				'limit'                    => $limit,
214
+				'order_by'                 => array('DTT_EVT_start' => 'ASC'),
215
+				'default_where_conditions' => 'none',
216
+			)
217
+		);
218
+	}
219
+
220
+
221
+
222
+	/**
223
+	 * @param int     $EVT_ID
224
+	 * @param boolean $include_expired
225
+	 * @param boolean $include_deleted
226
+	 * @return EE_Datetime
227
+	 * @throws \EE_Error
228
+	 */
229
+	public function get_oldest_datetime_for_event($EVT_ID, $include_expired = false, $include_deleted = false)
230
+	{
231
+		$results = $this->get_datetimes_for_event_ordered_by_start_time($EVT_ID, $include_expired, $include_deleted, 1);
232
+		if ($results) {
233
+			return array_shift($results);
234
+		} else {
235
+			return null;
236
+		}
237
+	}
238
+
239
+
240
+
241
+	/**
242
+	 * Gets the 'primary' datetime for an event.
243
+	 *
244
+	 * @param int  $EVT_ID
245
+	 * @param bool $try_to_exclude_expired
246
+	 * @param bool $try_to_exclude_deleted
247
+	 * @return \EE_Datetime
248
+	 * @throws \EE_Error
249
+	 */
250
+	public function get_primary_datetime_for_event(
251
+		$EVT_ID,
252
+		$try_to_exclude_expired = true,
253
+		$try_to_exclude_deleted = true
254
+	) {
255
+		if ($try_to_exclude_expired) {
256
+			$non_expired = $this->get_oldest_datetime_for_event($EVT_ID, false, false);
257
+			if ($non_expired) {
258
+				return $non_expired;
259
+			}
260
+		}
261
+		if ($try_to_exclude_deleted) {
262
+			$expired_even = $this->get_oldest_datetime_for_event($EVT_ID, true);
263
+			if ($expired_even) {
264
+				return $expired_even;
265
+			}
266
+		}
267
+		return $this->get_oldest_datetime_for_event($EVT_ID, true, true);
268
+	}
269
+
270
+
271
+
272
+	/**
273
+	 * Gets ALL the datetimes for an event (including trashed ones, for now), ordered
274
+	 * only by start date
275
+	 *
276
+	 * @param int     $EVT_ID
277
+	 * @param boolean $include_expired
278
+	 * @param boolean $include_deleted
279
+	 * @param int     $limit
280
+	 * @return EE_Datetime[]
281
+	 * @throws \EE_Error
282
+	 */
283
+	public function get_datetimes_for_event_ordered_by_start_time(
284
+		$EVT_ID,
285
+		$include_expired = true,
286
+		$include_deleted = true,
287
+		$limit = null
288
+	) {
289
+		//sanitize EVT_ID
290
+		$EVT_ID = absint($EVT_ID);
291
+		$old_assumption = $this->get_assumption_concerning_values_already_prepared_by_model_object();
292
+		$this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
293
+		$query_params = array(array('Event.EVT_ID' => $EVT_ID), 'order_by' => array('DTT_EVT_start' => 'asc'));
294
+		if ( ! $include_expired) {
295
+			$query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
296
+		}
297
+		if ($include_deleted) {
298
+			$query_params[0]['DTT_deleted'] = array('IN', array(true, false));
299
+		}
300
+		if ($limit) {
301
+			$query_params['limit'] = $limit;
302
+		}
303
+		/** @var EE_Datetime[] $result */
304
+		$result = $this->get_all($query_params);
305
+		$this->assume_values_already_prepared_by_model_object($old_assumption);
306
+		return $result;
307
+	}
308
+
309
+
310
+
311
+	/**
312
+	 * Gets ALL the datetimes for an ticket (including trashed ones, for now), ordered
313
+	 * only by start date
314
+	 *
315
+	 * @param int     $TKT_ID
316
+	 * @param boolean $include_expired
317
+	 * @param boolean $include_deleted
318
+	 * @param int     $limit
319
+	 * @return EE_Datetime[]
320
+	 * @throws \EE_Error
321
+	 */
322
+	public function get_datetimes_for_ticket_ordered_by_start_time(
323
+		$TKT_ID,
324
+		$include_expired = true,
325
+		$include_deleted = true,
326
+		$limit = null
327
+	) {
328
+		//sanitize TKT_ID
329
+		$TKT_ID = absint($TKT_ID);
330
+		$old_assumption = $this->get_assumption_concerning_values_already_prepared_by_model_object();
331
+		$this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
332
+		$query_params = array(array('Ticket.TKT_ID' => $TKT_ID), 'order_by' => array('DTT_EVT_start' => 'asc'));
333
+		if ( ! $include_expired) {
334
+			$query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
335
+		}
336
+		if ($include_deleted) {
337
+			$query_params[0]['DTT_deleted'] = array('IN', array(true, false));
338
+		}
339
+		if ($limit) {
340
+			$query_params['limit'] = $limit;
341
+		}
342
+		/** @var EE_Datetime[] $result */
343
+		$result = $this->get_all($query_params);
344
+		$this->assume_values_already_prepared_by_model_object($old_assumption);
345
+		return $result;
346
+	}
347
+
348
+
349
+
350
+	/**
351
+	 * Gets all the datetimes for a ticket (including trashed ones, for now), ordered by the DTT_order for the
352
+	 * datetimes.
353
+	 *
354
+	 * @param  int      $TKT_ID          ID of ticket to retrieve the datetimes for
355
+	 * @param  boolean  $include_expired whether to include expired datetimes or not
356
+	 * @param  boolean  $include_deleted whether to include trashed datetimes or not.
357
+	 * @param  int|null $limit           if null, no limit, if int then limit results by
358
+	 *                                   that number
359
+	 * @return EE_Datetime[]
360
+	 * @throws \EE_Error
361
+	 */
362
+	public function get_datetimes_for_ticket_ordered_by_DTT_order(
363
+		$TKT_ID,
364
+		$include_expired = true,
365
+		$include_deleted = true,
366
+		$limit = null
367
+	) {
368
+		//sanitize id.
369
+		$TKT_ID = absint($TKT_ID);
370
+		$old_assumption = $this->get_assumption_concerning_values_already_prepared_by_model_object();
371
+		$this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
372
+		$where_params = array('Ticket.TKT_ID' => $TKT_ID);
373
+		$query_params = array($where_params, 'order_by' => array('DTT_order' => 'ASC'));
374
+		if ( ! $include_expired) {
375
+			$query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
376
+		}
377
+		if ($include_deleted) {
378
+			$query_params[0]['DTT_deleted'] = array('IN', array(true, false));
379
+		}
380
+		if ($limit) {
381
+			$query_params['limit'] = $limit;
382
+		}
383
+		/** @var EE_Datetime[] $result */
384
+		$result = $this->get_all($query_params);
385
+		$this->assume_values_already_prepared_by_model_object($old_assumption);
386
+		return $result;
387
+	}
388
+
389
+
390
+
391
+	/**
392
+	 * Gets the most important datetime for a particular event (ie, the primary event usually. But if for some WACK
393
+	 * reason it doesn't exist, we consider the earliest event the most important)
394
+	 *
395
+	 * @param int $EVT_ID
396
+	 * @return EE_Datetime
397
+	 * @throws \EE_Error
398
+	 */
399
+	public function get_most_important_datetime_for_event($EVT_ID)
400
+	{
401
+		$results = $this->get_datetimes_for_event_ordered_by_importance($EVT_ID, 1);
402
+		if ($results) {
403
+			return array_shift($results);
404
+		} else {
405
+			return null;
406
+		}
407
+	}
408
+
409
+
410
+
411
+	/**
412
+	 * This returns a wpdb->results        Array of all DTT month and years matching the incoming query params and
413
+	 * grouped by month and year.
414
+	 *
415
+	 * @param  array  $where_params      Array of query_params as described in the comments for EEM_Base::get_all()
416
+	 * @param  string $evt_active_status A string representing the evt active status to filter the months by.
417
+	 *                                   Can be:
418
+	 *                                   - '' = no filter
419
+	 *                                   - upcoming = Published events with at least one upcoming datetime.
420
+	 *                                   - expired = Events with all datetimes expired.
421
+	 *                                   - active = Events that are published and have at least one datetime that
422
+	 *                                   starts before now and ends after now.
423
+	 *                                   - inactive = Events that are either not published.
424
+	 * @return EE_Base_Class[]
425
+	 * @throws \EE_Error
426
+	 */
427
+	public function get_dtt_months_and_years($where_params, $evt_active_status = '')
428
+	{
429
+		$current_time_for_DTT_EVT_start = $this->current_time_for_query('DTT_EVT_start');
430
+		$current_time_for_DTT_EVT_end = $this->current_time_for_query('DTT_EVT_end');
431
+		switch ($evt_active_status) {
432
+			case 'upcoming' :
433
+				$where_params['Event.status'] = 'publish';
434
+				//if there are already query_params matching DTT_EVT_start then we need to modify that to add them.
435
+				if (isset($where_params['DTT_EVT_start'])) {
436
+					$where_params['DTT_EVT_start*****'] = $where_params['DTT_EVT_start'];
437
+				}
438
+				$where_params['DTT_EVT_start'] = array('>', $current_time_for_DTT_EVT_start);
439
+				break;
440
+			case 'expired' :
441
+				if (isset($where_params['Event.status'])) {
442
+					unset($where_params['Event.status']);
443
+				}
444
+				//get events to exclude
445
+				$exclude_query[0] = array_merge($where_params,
446
+					array('DTT_EVT_end' => array('>', $current_time_for_DTT_EVT_end)));
447
+				//first get all events that have datetimes where its not expired.
448
+				$event_ids = $this->_get_all_wpdb_results($exclude_query, OBJECT_K, 'Datetime.EVT_ID');
449
+				$event_ids = array_keys($event_ids);
450
+				if (isset($where_params['DTT_EVT_end'])) {
451
+					$where_params['DTT_EVT_end****'] = $where_params['DTT_EVT_end'];
452
+				}
453
+				$where_params['DTT_EVT_end'] = array('<', $current_time_for_DTT_EVT_end);
454
+				$where_params['Event.EVT_ID'] = array('NOT IN', $event_ids);
455
+				break;
456
+			case 'active' :
457
+				$where_params['Event.status'] = 'publish';
458
+				if (isset($where_params['DTT_EVT_start'])) {
459
+					$where_params['Datetime.DTT_EVT_start******'] = $where_params['DTT_EVT_start'];
460
+				}
461
+				if (isset($where_params['Datetime.DTT_EVT_end'])) {
462
+					$where_params['Datetime.DTT_EVT_end*****'] = $where_params['DTT_EVT_end'];
463
+				}
464
+				$where_params['DTT_EVT_start'] = array('<', $current_time_for_DTT_EVT_start);
465
+				$where_params['DTT_EVT_end'] = array('>', $current_time_for_DTT_EVT_end);
466
+				break;
467
+			case 'inactive' :
468
+				if (isset($where_params['Event.status'])) {
469
+					unset($where_params['Event.status']);
470
+				}
471
+				if (isset($where_params['OR'])) {
472
+					$where_params['AND']['OR'] = $where_params['OR'];
473
+				}
474
+				if (isset($where_params['DTT_EVT_end'])) {
475
+					$where_params['AND']['DTT_EVT_end****'] = $where_params['DTT_EVT_end'];
476
+					unset($where_params['DTT_EVT_end']);
477
+				}
478
+				if (isset($where_params['DTT_EVT_start'])) {
479
+					$where_params['AND']['DTT_EVT_start'] = $where_params['DTT_EVT_start'];
480
+					unset($where_params['DTT_EVT_start']);
481
+				}
482
+				$where_params['AND']['Event.status'] = array('!=', 'publish');
483
+				break;
484
+		}
485
+		$query_params[0] = $where_params;
486
+		$query_params['group_by'] = array('dtt_year', 'dtt_month');
487
+		$query_params['order_by'] = array('DTT_EVT_start' => 'DESC');
488
+		$query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'DTT_EVT_start');
489
+		$columns_to_select = array(
490
+			'dtt_year'      => array('YEAR(' . $query_interval . ')', '%s'),
491
+			'dtt_month'     => array('MONTHNAME(' . $query_interval . ')', '%s'),
492
+			'dtt_month_num' => array('MONTH(' . $query_interval . ')', '%s'),
493
+		);
494
+		return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select);
495
+	}
496
+
497
+
498
+
499
+	/**
500
+	 * Updates the DTT_sold attribute on each datetime (based on the registrations
501
+	 * for the tickets for each datetime)
502
+	 *
503
+	 * @param EE_Datetime[] $datetimes
504
+	 */
505
+	public function update_sold($datetimes)
506
+	{
507
+		foreach ($datetimes as $datetime) {
508
+			$datetime->update_sold();
509
+		}
510
+	}
511
+
512
+
513
+
514
+	/**
515
+	 *    Gets the total number of tickets available at a particular datetime
516
+	 *    (does NOT take into account the datetime's spaces available)
517
+	 *
518
+	 * @param int   $DTT_ID
519
+	 * @param array $query_params
520
+	 * @return int of tickets available. If sold out, return less than 1. If infinite, returns EE_INF,  IF there are NO
521
+	 *             tickets attached to datetime then FALSE is returned.
522
+	 */
523
+	public function sum_tickets_currently_available_at_datetime($DTT_ID, array $query_params = array())
524
+	{
525
+		$datetime = $this->get_one_by_ID($DTT_ID);
526
+		if ($datetime instanceof EE_Datetime) {
527
+			return $datetime->tickets_remaining($query_params);
528
+		}
529
+		return 0;
530
+	}
531
+
532
+
533
+
534
+	/**
535
+	 * This returns an array of counts of datetimes in the database for each Datetime status that can be queried.
536
+	 *
537
+	 * @param  array $stati_to_include If included you can restrict the statuses we return counts for by including the
538
+	 *                                 stati you want counts for as values in the array.  An empty array returns counts
539
+	 *                                 for all valid stati.
540
+	 * @param  array $query_params     If included can be used to refine the conditions for returning the count (i.e.
541
+	 *                                 only for Datetimes connected to a specific event, or specific ticket.
542
+	 * @return array  The value returned is an array indexed by Datetime Status and the values are the counts.  The
543
+	 * @throws \EE_Error
544
+	 *                                 stati used as index keys are: EE_Datetime::active EE_Datetime::upcoming EE_Datetime::expired
545
+	 */
546
+	public function get_datetime_counts_by_status(array $stati_to_include = array(), array $query_params = array())
547
+	{
548
+		//only accept where conditions for this query.
549
+		$_where = isset($query_params[0]) ? $query_params[0] : array();
550
+		$status_query_args = array(
551
+			EE_Datetime::active   => array_merge(
552
+				$_where,
553
+				array('DTT_EVT_start' => array('<', time()), 'DTT_EVT_end' => array('>', time()))
554
+			),
555
+			EE_Datetime::upcoming => array_merge(
556
+				$_where,
557
+				array('DTT_EVT_start' => array('>', time()))
558
+			),
559
+			EE_Datetime::expired  => array_merge(
560
+				$_where,
561
+				array('DTT_EVT_end' => array('<', time()))
562
+			),
563
+		);
564
+		if ( ! empty($stati_to_include)) {
565
+			foreach (array_keys($status_query_args) as $status) {
566
+				if ( ! in_array($status, $stati_to_include, true)) {
567
+					unset($status_query_args[$status]);
568
+				}
569
+			}
570
+		}
571
+		//loop through and query counts for each stati.
572
+		$status_query_results = array();
573
+		foreach ($status_query_args as $status => $status_where_conditions) {
574
+			$status_query_results[$status] = EEM_Datetime::count(array($status_where_conditions), 'DTT_ID', true);
575
+		}
576
+		return $status_query_results;
577
+	}
578
+
579
+
580
+
581
+	/**
582
+	 * Returns the specific count for a given Datetime status matching any given query_params.
583
+	 *
584
+	 * @param string $status Valid string representation for Datetime status requested. (Defaults to Active).
585
+	 * @param array  $query_params
586
+	 * @return int
587
+	 * @throws \EE_Error
588
+	 */
589
+	public function get_datetime_count_for_status($status = EE_Datetime::active, array $query_params = array())
590
+	{
591
+		$count = $this->get_datetime_counts_by_status(array($status), $query_params);
592
+		return ! empty($count[$status]) ? $count[$status] : 0;
593
+	}
594 594
 
595 595
 
596 596
 
Please login to merge, or discard this patch.
modules/ticket_selector/DisplayTicketSelector.php 2 patches
Spacing   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -1,8 +1,8 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 namespace EventEspresso\modules\ticket_selector;
3 3
 
4
-if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) {
5
-    exit( 'No direct script access allowed' );
4
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
5
+    exit('No direct script access allowed');
6 6
 }
7 7
 
8 8
 
@@ -73,9 +73,9 @@  discard block
 block discarded – undo
73 73
     /**
74 74
      * @param boolean $iframe
75 75
      */
76
-    public function setIframe( $iframe = true )
76
+    public function setIframe($iframe = true)
77 77
     {
78
-        $this->iframe = filter_var( $iframe, FILTER_VALIDATE_BOOLEAN );
78
+        $this->iframe = filter_var($iframe, FILTER_VALIDATE_BOOLEAN);
79 79
     }
80 80
 
81 81
 
@@ -86,28 +86,28 @@  discard block
 block discarded – undo
86 86
      * @param    mixed $event
87 87
      * @return    bool
88 88
      */
89
-    protected function setEvent( $event = null )
89
+    protected function setEvent($event = null)
90 90
     {
91
-        if ( $event === null ) {
91
+        if ($event === null) {
92 92
             global $post;
93 93
             $event = $post;
94 94
         }
95
-        if ( $event instanceof \EE_Event ) {
95
+        if ($event instanceof \EE_Event) {
96 96
             $this->event = $event;
97
-        } else if ( $event instanceof \WP_Post ) {
98
-            if ( isset( $event->EE_Event ) && $event->EE_Event instanceof \EE_Event ) {
97
+        } else if ($event instanceof \WP_Post) {
98
+            if (isset($event->EE_Event) && $event->EE_Event instanceof \EE_Event) {
99 99
                 $this->event = $event->EE_Event;
100
-            } else if ( $event->post_type === 'espresso_events' ) {
101
-                $event->EE_Event = \EEM_Event::instance()->instantiate_class_from_post_object( $event );
100
+            } else if ($event->post_type === 'espresso_events') {
101
+                $event->EE_Event = \EEM_Event::instance()->instantiate_class_from_post_object($event);
102 102
                 $this->event = $event->EE_Event;
103 103
             }
104 104
         } else {
105
-            $user_msg = __( 'No Event object or an invalid Event object was supplied.', 'event_espresso' );
106
-            $dev_msg = $user_msg . __(
105
+            $user_msg = __('No Event object or an invalid Event object was supplied.', 'event_espresso');
106
+            $dev_msg = $user_msg.__(
107 107
                     'In order to generate a ticket selector, please ensure you are passing either an EE_Event object or a WP_Post object of the post type "espresso_event" to the EE_Ticket_Selector class constructor.',
108 108
                     'event_espresso'
109 109
                 );
110
-            \EE_Error::add_error( $user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__ );
110
+            \EE_Error::add_error($user_msg.'||'.$dev_msg, __FILE__, __FUNCTION__, __LINE__);
111 111
             return false;
112 112
         }
113 113
         return true;
@@ -148,17 +148,17 @@  discard block
 block discarded – undo
148 148
      * @return string
149 149
      * @throws \EE_Error
150 150
      */
151
-    public function display( $event = null, $view_details = false )
151
+    public function display($event = null, $view_details = false)
152 152
     {
153 153
         // reset filter for displaying submit button
154
-        remove_filter( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true' );
154
+        remove_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true');
155 155
         // poke and prod incoming event till it tells us what it is
156
-        if ( ! $this->setEvent( $event ) ) {
156
+        if ( ! $this->setEvent($event)) {
157 157
             return false;
158 158
         }
159 159
         // begin gathering template arguments by getting event status
160
-        $template_args = array( 'event_status' => $this->event->get_active_status() );
161
-        if ( $this->activeEventAndShowTicketSelector($event, $template_args['event_status'], $view_details) ) {
160
+        $template_args = array('event_status' => $this->event->get_active_status());
161
+        if ($this->activeEventAndShowTicketSelector($event, $template_args['event_status'], $view_details)) {
162 162
             return ! is_single() ? $this->displayViewDetailsButton() : '';
163 163
         }
164 164
         // filter the maximum qty that can appear in the Ticket Selector qty dropdowns
@@ -168,7 +168,7 @@  discard block
 block discarded – undo
168 168
         }
169 169
         // is the event expired ?
170 170
         $template_args['event_is_expired'] = $this->event->is_expired();
171
-        if ( $template_args[ 'event_is_expired' ] ) {
171
+        if ($template_args['event_is_expired']) {
172 172
             return $this->expiredEventMessage();
173 173
         }
174 174
         // get all tickets for this event ordered by the datetime
@@ -181,10 +181,10 @@  discard block
 block discarded – undo
181 181
         // if redirecting to another site for registration, then we don't load the TS
182 182
         $ticket_selector = $external_url
183 183
             ? $this->externalEventRegistration()
184
-            : $this->loadTicketSelector($tickets,$template_args);
184
+            : $this->loadTicketSelector($tickets, $template_args);
185 185
         // now set up the form (but not for the admin)
186 186
         $ticket_selector = ! is_admin()
187
-            ? $this->formOpen($this->event->ID(), $external_url) . $ticket_selector
187
+            ? $this->formOpen($this->event->ID(), $external_url).$ticket_selector
188 188
             : $ticket_selector;
189 189
         // submit button and form close tag
190 190
         $ticket_selector .= ! is_admin() ? $this->displaySubmitButton($external_url) : '';
@@ -234,10 +234,10 @@  discard block
 block discarded – undo
234 234
      */
235 235
     protected function expiredEventMessage()
236 236
     {
237
-        return '<div class="ee-event-expired-notice"><span class="important-notice">' . esc_html__(
237
+        return '<div class="ee-event-expired-notice"><span class="important-notice">'.esc_html__(
238 238
             'We\'re sorry, but all tickets sales have ended because the event is expired.',
239 239
             'event_espresso'
240
-        ) . '</span></div>';
240
+        ).'</span></div>';
241 241
     }
242 242
 
243 243
 
@@ -251,7 +251,7 @@  discard block
 block discarded – undo
251 251
      */
252 252
     protected function noTicketAvailableMessage()
253 253
     {
254
-        $no_ticket_available_msg = esc_html__( 'We\'re sorry, but all ticket sales have ended.', 'event_espresso' );
254
+        $no_ticket_available_msg = esc_html__('We\'re sorry, but all ticket sales have ended.', 'event_espresso');
255 255
         if (current_user_can('edit_post', $this->event->ID())) {
256 256
             $no_ticket_available_msg .= sprintf(
257 257
                 esc_html__(
@@ -266,7 +266,7 @@  discard block
 block discarded – undo
266 266
         }
267 267
         return '
268 268
             <div class="ee-event-expired-notice">
269
-                <span class="important-notice">' . $no_ticket_available_msg . '</span>
269
+                <span class="important-notice">' . $no_ticket_available_msg.'</span>
270 270
             </div>';
271 271
     }
272 272
 
@@ -297,7 +297,7 @@  discard block
 block discarded – undo
297 297
                 '</a></span></div>'
298 298
             );
299 299
         }
300
-        return '<p><span class="important-notice">' . $sales_closed_msg . '</span></p>';
300
+        return '<p><span class="important-notice">'.$sales_closed_msg.'</span></p>';
301 301
     }
302 302
 
303 303
 
@@ -359,12 +359,12 @@  discard block
 block discarded – undo
359 359
          */
360 360
         $template_args['anchor_id'] = apply_filters(
361 361
             'FHEE__EE_Ticket_Selector__redirect_anchor_id',
362
-            '#tkt-slctr-tbl-' . $this->event->ID(),
362
+            '#tkt-slctr-tbl-'.$this->event->ID(),
363 363
             $this->event->ID()
364 364
         );
365 365
         $template_args['tickets'] = $tickets;
366 366
         $template_args['ticket_count'] = count($tickets);
367
-        $ticket_selector = $this->simpleTicketSelector( $tickets, $template_args);
367
+        $ticket_selector = $this->simpleTicketSelector($tickets, $template_args);
368 368
         return $ticket_selector instanceof TicketSelectorSimple
369 369
             ? $ticket_selector
370 370
             : new TicketSelectorStandard(
@@ -445,11 +445,11 @@  discard block
 block discarded – undo
445 445
      * @param        string $external_url
446 446
      * @return        string
447 447
      */
448
-    public function formOpen( $ID = 0, $external_url = '' )
448
+    public function formOpen($ID = 0, $external_url = '')
449 449
     {
450 450
         // if redirecting, we don't need any anything else
451
-        if ( $external_url ) {
452
-            $html = '<form method="GET" action="' . \EEH_URL::refactor_url($external_url) . '"';
451
+        if ($external_url) {
452
+            $html = '<form method="GET" action="'.\EEH_URL::refactor_url($external_url).'"';
453 453
             // open link in new window ?
454 454
             $html .= apply_filters(
455 455
                 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__formOpen__external_url_target_blank',
@@ -458,21 +458,21 @@  discard block
 block discarded – undo
458 458
                 ? ' target="_blank"'
459 459
                 : '';
460 460
             $html .= '>';
461
-            $query_args = \EEH_URL::get_query_string( $external_url );
462
-            foreach ( (array)$query_args as $query_arg => $value ) {
463
-                $html .= '<input type="hidden" name="' . $query_arg . '" value="' . $value . '">';
461
+            $query_args = \EEH_URL::get_query_string($external_url);
462
+            foreach ((array) $query_args as $query_arg => $value) {
463
+                $html .= '<input type="hidden" name="'.$query_arg.'" value="'.$value.'">';
464 464
             }
465 465
             return $html;
466 466
         }
467 467
         // if there is no submit button, then don't start building a form
468 468
         // because the "View Details" button will build its own form
469
-        if ( ! apply_filters( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false ) ) {
469
+        if ( ! apply_filters('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false)) {
470 470
             return '';
471 471
         }
472
-        $checkout_url = \EEH_Event_View::event_link_url( $ID );
473
-        if ( ! $checkout_url ) {
472
+        $checkout_url = \EEH_Event_View::event_link_url($ID);
473
+        if ( ! $checkout_url) {
474 474
             \EE_Error::add_error(
475
-                esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ),
475
+                esc_html__('The URL for the Event Details page could not be retrieved.', 'event_espresso'),
476 476
                 __FILE__,
477 477
                 __FUNCTION__,
478 478
                 __LINE__
@@ -481,10 +481,10 @@  discard block
 block discarded – undo
481 481
         // set no cache headers and constants
482 482
         \EE_System::do_not_cache();
483 483
         $extra_params = $this->iframe ? ' target="_blank"' : '';
484
-        $html = '<form method="POST" action="' . $checkout_url . '"' . $extra_params . '>';
485
-        $html .= wp_nonce_field( 'process_ticket_selections', 'process_ticket_selections_nonce_' . $ID, true, false );
484
+        $html = '<form method="POST" action="'.$checkout_url.'"'.$extra_params.'>';
485
+        $html .= wp_nonce_field('process_ticket_selections', 'process_ticket_selections_nonce_'.$ID, true, false);
486 486
         $html .= '<input type="hidden" name="ee" value="process_ticket_selections">';
487
-        $html = apply_filters( 'FHEE__EE_Ticket_Selector__ticket_selector_form_open__html', $html, $this->event );
487
+        $html = apply_filters('FHEE__EE_Ticket_Selector__ticket_selector_form_open__html', $html, $this->event);
488 488
         return $html;
489 489
     }
490 490
 
@@ -507,7 +507,7 @@  discard block
 block discarded – undo
507 507
                 $html .= empty($external_url)
508 508
                     ? $this->ticketSelectorEndDiv()
509 509
                     : $this->clearTicketSelector();
510
-                $html .= '<br/>' . $this->formClose();
510
+                $html .= '<br/>'.$this->formClose();
511 511
             } else if ($this->getMaxAttendees() === 1) {
512 512
                 // its a "Dude Where's my Ticket Selector?" (DWMTS) type event (ie: $_max_atndz === 1)
513 513
                 if ($this->event->is_sold_out()) {
@@ -585,16 +585,16 @@  discard block
 block discarded – undo
585 585
         );
586 586
         $external_url = $this->event->external_url();
587 587
         $html = \EEH_HTML::div(
588
-            '', 'ticket-selector-submit-' . $this->event->ID() . '-btn-wrap', 'ticket-selector-submit-btn-wrap'
588
+            '', 'ticket-selector-submit-'.$this->event->ID().'-btn-wrap', 'ticket-selector-submit-btn-wrap'
589 589
         );
590 590
         $html .= \EEH_HTML::span(
591 591
             esc_html__('please select a datetime', 'event_espresso'),
592 592
             '', 'ticket-selector-disabled-submit-btn-msg important-notice'
593 593
         );
594
-        $html .= '<input id="ticket-selector-submit-' . $this->event->ID() . '-btn"';
594
+        $html .= '<input id="ticket-selector-submit-'.$this->event->ID().'-btn"';
595 595
         $html .= ' class="ticket-selector-submit-btn ';
596 596
         $html .= empty($external_url) ? 'ticket-selector-submit-ajax"' : '"';
597
-        $html .= ' type="submit" value="' . $btn_text . '" />';
597
+        $html .= ' type="submit" value="'.$btn_text.'" />';
598 598
         $html .= \EEH_HTML::divx();
599 599
         $html .= apply_filters(
600 600
             'FHEE__EE_Ticket_Selector__after_ticket_selector_submit',
@@ -615,11 +615,11 @@  discard block
 block discarded – undo
615 615
      * @return string
616 616
      * @throws \EE_Error
617 617
      */
618
-    public function displayViewDetailsButton( $DWMTS = false )
618
+    public function displayViewDetailsButton($DWMTS = false)
619 619
     {
620
-        if ( ! $this->event->get_permalink() ) {
620
+        if ( ! $this->event->get_permalink()) {
621 621
             \EE_Error::add_error(
622
-                esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ),
622
+                esc_html__('The URL for the Event Details page could not be retrieved.', 'event_espresso'),
623 623
                 __FILE__, __FUNCTION__, __LINE__
624 624
             );
625 625
         }
@@ -640,7 +640,7 @@  discard block
 block discarded – undo
640 640
                              . '-btn" class="ticket-selector-submit-btn view-details-btn" type="submit" value="'
641 641
                              . $btn_text
642 642
                              . '" />';
643
-        $view_details_btn .= apply_filters( 'FHEE__EE_Ticket_Selector__after_view_details_btn', '', $this->event );
643
+        $view_details_btn .= apply_filters('FHEE__EE_Ticket_Selector__after_view_details_btn', '', $this->event);
644 644
         if ($DWMTS) {
645 645
             $view_details_btn .= $this->formClose();
646 646
             $view_details_btn .= $this->ticketSelectorEndDiv();
Please login to merge, or discard this patch.
Indentation   +663 added lines, -663 removed lines patch added patch discarded remove patch
@@ -2,7 +2,7 @@  discard block
 block discarded – undo
2 2
 namespace EventEspresso\modules\ticket_selector;
3 3
 
4 4
 if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) {
5
-    exit( 'No direct script access allowed' );
5
+	exit( 'No direct script access allowed' );
6 6
 }
7 7
 
8 8
 
@@ -19,671 +19,671 @@  discard block
 block discarded – undo
19 19
 class DisplayTicketSelector
20 20
 {
21 21
 
22
-    /**
23
-     * event that ticket selector is being generated for
24
-     *
25
-     * @access protected
26
-     * @var \EE_Event $event
27
-     */
28
-    protected $event;
29
-
30
-    /**
31
-     * Used to flag when the ticket selector is being called from an external iframe.
32
-     *
33
-     * @var bool $iframe
34
-     */
35
-    protected $iframe = false;
36
-
37
-    /**
38
-     * max attendees that can register for event at one time
39
-     *
40
-     * @var int $max_attendees
41
-     */
42
-    private $max_attendees = EE_INF;
43
-
44
-    /**
45
-     *@var string $date_format
46
-     */
47
-    private $date_format = '';
48
-
49
-    /**
50
-     *@var string $time_format
51
-     */
52
-    private $time_format = '';
53
-
54
-
55
-
56
-    /**
57
-     * DisplayTicketSelector constructor.
58
-     */
59
-    public function __construct()
60
-    {
61
-        $this->date_format = apply_filters(
62
-            'FHEE__EED_Ticket_Selector__display_ticket_selector__date_format',
63
-            get_option('date_format')
64
-        );
65
-        $this->time_format = apply_filters(
66
-            'FHEE__EED_Ticket_Selector__display_ticket_selector__time_format',
67
-            get_option('time_format')
68
-        );
69
-    }
70
-
71
-
72
-
73
-    /**
74
-     * @param boolean $iframe
75
-     */
76
-    public function setIframe( $iframe = true )
77
-    {
78
-        $this->iframe = filter_var( $iframe, FILTER_VALIDATE_BOOLEAN );
79
-    }
80
-
81
-
82
-
83
-    /**
84
-     * finds and sets the \EE_Event object for use throughout class
85
-     *
86
-     * @param    mixed $event
87
-     * @return    bool
88
-     */
89
-    protected function setEvent( $event = null )
90
-    {
91
-        if ( $event === null ) {
92
-            global $post;
93
-            $event = $post;
94
-        }
95
-        if ( $event instanceof \EE_Event ) {
96
-            $this->event = $event;
97
-        } else if ( $event instanceof \WP_Post ) {
98
-            if ( isset( $event->EE_Event ) && $event->EE_Event instanceof \EE_Event ) {
99
-                $this->event = $event->EE_Event;
100
-            } else if ( $event->post_type === 'espresso_events' ) {
101
-                $event->EE_Event = \EEM_Event::instance()->instantiate_class_from_post_object( $event );
102
-                $this->event = $event->EE_Event;
103
-            }
104
-        } else {
105
-            $user_msg = __( 'No Event object or an invalid Event object was supplied.', 'event_espresso' );
106
-            $dev_msg = $user_msg . __(
107
-                    'In order to generate a ticket selector, please ensure you are passing either an EE_Event object or a WP_Post object of the post type "espresso_event" to the EE_Ticket_Selector class constructor.',
108
-                    'event_espresso'
109
-                );
110
-            \EE_Error::add_error( $user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__ );
111
-            return false;
112
-        }
113
-        return true;
114
-    }
115
-
116
-
117
-
118
-    /**
119
-     * @return int
120
-     */
121
-    public function getMaxAttendees()
122
-    {
123
-        return $this->max_attendees;
124
-    }
125
-
126
-
127
-
128
-    /**
129
-     * @param int $max_attendees
130
-     */
131
-    public function setMaxAttendees($max_attendees)
132
-    {
133
-        $this->max_attendees = absint(
134
-            apply_filters(
135
-                'FHEE__EE_Ticket_Selector__display_ticket_selector__max_tickets',
136
-                $max_attendees
137
-            )
138
-        );
139
-    }
140
-
141
-
142
-
143
-    /**
144
-     * creates buttons for selecting number of attendees for an event
145
-     *
146
-     * @param \WP_Post|int $event
147
-     * @param bool         $view_details
148
-     * @return string
149
-     * @throws \EE_Error
150
-     */
151
-    public function display( $event = null, $view_details = false )
152
-    {
153
-        // reset filter for displaying submit button
154
-        remove_filter( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true' );
155
-        // poke and prod incoming event till it tells us what it is
156
-        if ( ! $this->setEvent( $event ) ) {
157
-            return false;
158
-        }
159
-        // begin gathering template arguments by getting event status
160
-        $template_args = array( 'event_status' => $this->event->get_active_status() );
161
-        if ( $this->activeEventAndShowTicketSelector($event, $template_args['event_status'], $view_details) ) {
162
-            return ! is_single() ? $this->displayViewDetailsButton() : '';
163
-        }
164
-        // filter the maximum qty that can appear in the Ticket Selector qty dropdowns
165
-        $this->setMaxAttendees($this->event->additional_limit());
166
-        if ($this->getMaxAttendees() < 1) {
167
-            return $this->ticketSalesClosedMessage();
168
-        }
169
-        // is the event expired ?
170
-        $template_args['event_is_expired'] = $this->event->is_expired();
171
-        if ( $template_args[ 'event_is_expired' ] ) {
172
-            return $this->expiredEventMessage();
173
-        }
174
-        // get all tickets for this event ordered by the datetime
175
-        $tickets = $this->getTickets();
176
-        if (count($tickets) < 1) {
177
-            return $this->noTicketAvailableMessage();
178
-        }
179
-        // redirecting to another site for registration ??
180
-        $external_url = (string) $this->event->external_url();
181
-        // if redirecting to another site for registration, then we don't load the TS
182
-        $ticket_selector = $external_url
183
-            ? $this->externalEventRegistration()
184
-            : $this->loadTicketSelector($tickets,$template_args);
185
-        // now set up the form (but not for the admin)
186
-        $ticket_selector = ! is_admin()
187
-            ? $this->formOpen($this->event->ID(), $external_url) . $ticket_selector
188
-            : $ticket_selector;
189
-        // submit button and form close tag
190
-        $ticket_selector .= ! is_admin() ? $this->displaySubmitButton($external_url) : '';
191
-        return $ticket_selector;
192
-    }
193
-
194
-
195
-
196
-    /**
197
-     * displayTicketSelector
198
-     * examines the event properties and determines whether a Ticket Selector should be displayed
199
-     *
200
-     * @param \WP_Post|int $event
201
-     * @param string       $_event_active_status
202
-     * @param bool         $view_details
203
-     * @return bool
204
-     * @throws \EE_Error
205
-     */
206
-    protected function activeEventAndShowTicketSelector($event, $_event_active_status, $view_details)
207
-    {
208
-        $event_post = $this->event instanceof \EE_Event ? $this->event->ID() : $event;
209
-        return ! is_admin()
210
-               && (
211
-                   ! $this->event->display_ticket_selector()
212
-                   || $view_details
213
-                   || post_password_required($event_post)
214
-                   || (
215
-                       $_event_active_status !== \EE_Datetime::active
216
-                       && $_event_active_status !== \EE_Datetime::upcoming
217
-                       && $_event_active_status !== \EE_Datetime::sold_out
218
-                       && ! (
219
-                           $_event_active_status === \EE_Datetime::inactive
220
-                           && is_user_logged_in()
221
-                       )
222
-                   )
223
-               );
224
-    }
225
-
226
-
227
-
228
-    /**
229
-     * noTicketAvailableMessage
230
-     * notice displayed if event is expired
231
-     *
232
-     * @return string
233
-     * @throws \EE_Error
234
-     */
235
-    protected function expiredEventMessage()
236
-    {
237
-        return '<div class="ee-event-expired-notice"><span class="important-notice">' . esc_html__(
238
-            'We\'re sorry, but all tickets sales have ended because the event is expired.',
239
-            'event_espresso'
240
-        ) . '</span></div>';
241
-    }
242
-
243
-
244
-
245
-    /**
246
-     * noTicketAvailableMessage
247
-     * notice displayed if event has no more tickets available
248
-     *
249
-     * @return string
250
-     * @throws \EE_Error
251
-     */
252
-    protected function noTicketAvailableMessage()
253
-    {
254
-        $no_ticket_available_msg = esc_html__( 'We\'re sorry, but all ticket sales have ended.', 'event_espresso' );
255
-        if (current_user_can('edit_post', $this->event->ID())) {
256
-            $no_ticket_available_msg .= sprintf(
257
-                esc_html__(
258
-                    '%1$sNote to Event Admin:%2$sNo tickets were found for this event. This effectively turns off ticket sales. Please ensure that at least one ticket is available for if you want people to be able to register.%3$s(click to edit this event)%4$s',
259
-                    'event_espresso'
260
-                ),
261
-                '<div class="ee-attention" style="text-align: left;"><b>',
262
-                '</b><br />',
263
-                '<span class="edit-link"><a class="post-edit-link" href="'.get_edit_post_link($this->event->ID()).'">',
264
-                '</a></span></div>'
265
-            );
266
-        }
267
-        return '
22
+	/**
23
+	 * event that ticket selector is being generated for
24
+	 *
25
+	 * @access protected
26
+	 * @var \EE_Event $event
27
+	 */
28
+	protected $event;
29
+
30
+	/**
31
+	 * Used to flag when the ticket selector is being called from an external iframe.
32
+	 *
33
+	 * @var bool $iframe
34
+	 */
35
+	protected $iframe = false;
36
+
37
+	/**
38
+	 * max attendees that can register for event at one time
39
+	 *
40
+	 * @var int $max_attendees
41
+	 */
42
+	private $max_attendees = EE_INF;
43
+
44
+	/**
45
+	 *@var string $date_format
46
+	 */
47
+	private $date_format = '';
48
+
49
+	/**
50
+	 *@var string $time_format
51
+	 */
52
+	private $time_format = '';
53
+
54
+
55
+
56
+	/**
57
+	 * DisplayTicketSelector constructor.
58
+	 */
59
+	public function __construct()
60
+	{
61
+		$this->date_format = apply_filters(
62
+			'FHEE__EED_Ticket_Selector__display_ticket_selector__date_format',
63
+			get_option('date_format')
64
+		);
65
+		$this->time_format = apply_filters(
66
+			'FHEE__EED_Ticket_Selector__display_ticket_selector__time_format',
67
+			get_option('time_format')
68
+		);
69
+	}
70
+
71
+
72
+
73
+	/**
74
+	 * @param boolean $iframe
75
+	 */
76
+	public function setIframe( $iframe = true )
77
+	{
78
+		$this->iframe = filter_var( $iframe, FILTER_VALIDATE_BOOLEAN );
79
+	}
80
+
81
+
82
+
83
+	/**
84
+	 * finds and sets the \EE_Event object for use throughout class
85
+	 *
86
+	 * @param    mixed $event
87
+	 * @return    bool
88
+	 */
89
+	protected function setEvent( $event = null )
90
+	{
91
+		if ( $event === null ) {
92
+			global $post;
93
+			$event = $post;
94
+		}
95
+		if ( $event instanceof \EE_Event ) {
96
+			$this->event = $event;
97
+		} else if ( $event instanceof \WP_Post ) {
98
+			if ( isset( $event->EE_Event ) && $event->EE_Event instanceof \EE_Event ) {
99
+				$this->event = $event->EE_Event;
100
+			} else if ( $event->post_type === 'espresso_events' ) {
101
+				$event->EE_Event = \EEM_Event::instance()->instantiate_class_from_post_object( $event );
102
+				$this->event = $event->EE_Event;
103
+			}
104
+		} else {
105
+			$user_msg = __( 'No Event object or an invalid Event object was supplied.', 'event_espresso' );
106
+			$dev_msg = $user_msg . __(
107
+					'In order to generate a ticket selector, please ensure you are passing either an EE_Event object or a WP_Post object of the post type "espresso_event" to the EE_Ticket_Selector class constructor.',
108
+					'event_espresso'
109
+				);
110
+			\EE_Error::add_error( $user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__ );
111
+			return false;
112
+		}
113
+		return true;
114
+	}
115
+
116
+
117
+
118
+	/**
119
+	 * @return int
120
+	 */
121
+	public function getMaxAttendees()
122
+	{
123
+		return $this->max_attendees;
124
+	}
125
+
126
+
127
+
128
+	/**
129
+	 * @param int $max_attendees
130
+	 */
131
+	public function setMaxAttendees($max_attendees)
132
+	{
133
+		$this->max_attendees = absint(
134
+			apply_filters(
135
+				'FHEE__EE_Ticket_Selector__display_ticket_selector__max_tickets',
136
+				$max_attendees
137
+			)
138
+		);
139
+	}
140
+
141
+
142
+
143
+	/**
144
+	 * creates buttons for selecting number of attendees for an event
145
+	 *
146
+	 * @param \WP_Post|int $event
147
+	 * @param bool         $view_details
148
+	 * @return string
149
+	 * @throws \EE_Error
150
+	 */
151
+	public function display( $event = null, $view_details = false )
152
+	{
153
+		// reset filter for displaying submit button
154
+		remove_filter( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true' );
155
+		// poke and prod incoming event till it tells us what it is
156
+		if ( ! $this->setEvent( $event ) ) {
157
+			return false;
158
+		}
159
+		// begin gathering template arguments by getting event status
160
+		$template_args = array( 'event_status' => $this->event->get_active_status() );
161
+		if ( $this->activeEventAndShowTicketSelector($event, $template_args['event_status'], $view_details) ) {
162
+			return ! is_single() ? $this->displayViewDetailsButton() : '';
163
+		}
164
+		// filter the maximum qty that can appear in the Ticket Selector qty dropdowns
165
+		$this->setMaxAttendees($this->event->additional_limit());
166
+		if ($this->getMaxAttendees() < 1) {
167
+			return $this->ticketSalesClosedMessage();
168
+		}
169
+		// is the event expired ?
170
+		$template_args['event_is_expired'] = $this->event->is_expired();
171
+		if ( $template_args[ 'event_is_expired' ] ) {
172
+			return $this->expiredEventMessage();
173
+		}
174
+		// get all tickets for this event ordered by the datetime
175
+		$tickets = $this->getTickets();
176
+		if (count($tickets) < 1) {
177
+			return $this->noTicketAvailableMessage();
178
+		}
179
+		// redirecting to another site for registration ??
180
+		$external_url = (string) $this->event->external_url();
181
+		// if redirecting to another site for registration, then we don't load the TS
182
+		$ticket_selector = $external_url
183
+			? $this->externalEventRegistration()
184
+			: $this->loadTicketSelector($tickets,$template_args);
185
+		// now set up the form (but not for the admin)
186
+		$ticket_selector = ! is_admin()
187
+			? $this->formOpen($this->event->ID(), $external_url) . $ticket_selector
188
+			: $ticket_selector;
189
+		// submit button and form close tag
190
+		$ticket_selector .= ! is_admin() ? $this->displaySubmitButton($external_url) : '';
191
+		return $ticket_selector;
192
+	}
193
+
194
+
195
+
196
+	/**
197
+	 * displayTicketSelector
198
+	 * examines the event properties and determines whether a Ticket Selector should be displayed
199
+	 *
200
+	 * @param \WP_Post|int $event
201
+	 * @param string       $_event_active_status
202
+	 * @param bool         $view_details
203
+	 * @return bool
204
+	 * @throws \EE_Error
205
+	 */
206
+	protected function activeEventAndShowTicketSelector($event, $_event_active_status, $view_details)
207
+	{
208
+		$event_post = $this->event instanceof \EE_Event ? $this->event->ID() : $event;
209
+		return ! is_admin()
210
+			   && (
211
+				   ! $this->event->display_ticket_selector()
212
+				   || $view_details
213
+				   || post_password_required($event_post)
214
+				   || (
215
+					   $_event_active_status !== \EE_Datetime::active
216
+					   && $_event_active_status !== \EE_Datetime::upcoming
217
+					   && $_event_active_status !== \EE_Datetime::sold_out
218
+					   && ! (
219
+						   $_event_active_status === \EE_Datetime::inactive
220
+						   && is_user_logged_in()
221
+					   )
222
+				   )
223
+			   );
224
+	}
225
+
226
+
227
+
228
+	/**
229
+	 * noTicketAvailableMessage
230
+	 * notice displayed if event is expired
231
+	 *
232
+	 * @return string
233
+	 * @throws \EE_Error
234
+	 */
235
+	protected function expiredEventMessage()
236
+	{
237
+		return '<div class="ee-event-expired-notice"><span class="important-notice">' . esc_html__(
238
+			'We\'re sorry, but all tickets sales have ended because the event is expired.',
239
+			'event_espresso'
240
+		) . '</span></div>';
241
+	}
242
+
243
+
244
+
245
+	/**
246
+	 * noTicketAvailableMessage
247
+	 * notice displayed if event has no more tickets available
248
+	 *
249
+	 * @return string
250
+	 * @throws \EE_Error
251
+	 */
252
+	protected function noTicketAvailableMessage()
253
+	{
254
+		$no_ticket_available_msg = esc_html__( 'We\'re sorry, but all ticket sales have ended.', 'event_espresso' );
255
+		if (current_user_can('edit_post', $this->event->ID())) {
256
+			$no_ticket_available_msg .= sprintf(
257
+				esc_html__(
258
+					'%1$sNote to Event Admin:%2$sNo tickets were found for this event. This effectively turns off ticket sales. Please ensure that at least one ticket is available for if you want people to be able to register.%3$s(click to edit this event)%4$s',
259
+					'event_espresso'
260
+				),
261
+				'<div class="ee-attention" style="text-align: left;"><b>',
262
+				'</b><br />',
263
+				'<span class="edit-link"><a class="post-edit-link" href="'.get_edit_post_link($this->event->ID()).'">',
264
+				'</a></span></div>'
265
+			);
266
+		}
267
+		return '
268 268
             <div class="ee-event-expired-notice">
269 269
                 <span class="important-notice">' . $no_ticket_available_msg . '</span>
270 270
             </div>';
271
-    }
272
-
273
-
274
-
275
-    /**
276
-     * ticketSalesClosed
277
-     * notice displayed if event ticket sales are turned off
278
-     *
279
-     * @return string
280
-     * @throws \EE_Error
281
-     */
282
-    protected function ticketSalesClosedMessage()
283
-    {
284
-        $sales_closed_msg = esc_html__(
285
-            'We\'re sorry, but ticket sales have been closed at this time. Please check back again later.',
286
-            'event_espresso'
287
-        );
288
-        if (current_user_can('edit_post', $this->event->ID())) {
289
-            $sales_closed_msg .= sprintf(
290
-                esc_html__(
291
-                    '%sNote to Event Admin:%sThe "Maximum number of tickets allowed per order for this event" in the Event Registration Options has been set to "0". This effectively turns off ticket sales. %s(click to edit this event)%s',
292
-                    'event_espresso'
293
-                ),
294
-                '<div class="ee-attention" style="text-align: left;"><b>',
295
-                '</b><br />',
296
-                '<span class="edit-link"><a class="post-edit-link" href="'.get_edit_post_link($this->event->ID()).'">',
297
-                '</a></span></div>'
298
-            );
299
-        }
300
-        return '<p><span class="important-notice">' . $sales_closed_msg . '</span></p>';
301
-    }
302
-
303
-
304
-
305
-    /**
306
-     * getTickets
307
-     *
308
-     * @return \EE_Base_Class[]|\EE_Ticket[]
309
-     * @throws \EE_Error
310
-     */
311
-    protected function getTickets()
312
-    {
313
-        $ticket_query_args = array(
314
-            array('Datetime.EVT_ID' => $this->event->ID()),
315
-            'order_by' => array(
316
-                'TKT_order'              => 'ASC',
317
-                'TKT_required'           => 'DESC',
318
-                'TKT_start_date'         => 'ASC',
319
-                'TKT_end_date'           => 'ASC',
320
-                'Datetime.DTT_EVT_start' => 'DESC',
321
-            ),
322
-        );
323
-        if ( ! \EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector->show_expired_tickets) {
324
-            //use the correct applicable time query depending on what version of core is being run.
325
-            $current_time = method_exists('EEM_Datetime', 'current_time_for_query')
326
-                ? time()
327
-                : current_time('timestamp');
328
-            $ticket_query_args[0]['TKT_end_date'] = array('>', $current_time);
329
-        }
330
-        return \EEM_Ticket::instance()->get_all($ticket_query_args);
331
-    }
332
-
333
-
334
-
335
-    /**
336
-     * loadTicketSelector
337
-     * begins to assemble template arguments
338
-     * and decides whether to load a "simple" ticket selector, or the standard
339
-     *
340
-     * @param \EE_Ticket[] $tickets
341
-     * @param array $template_args
342
-     * @return string
343
-     * @throws \EE_Error
344
-     */
345
-    protected function loadTicketSelector(array $tickets, array $template_args)
346
-    {
347
-        $template_args['event'] = $this->event;
348
-        $template_args['EVT_ID'] = $this->event->ID();
349
-        $template_args['event_is_expired'] = $this->event->is_expired();
350
-        $template_args['max_atndz'] = $this->getMaxAttendees();
351
-        $template_args['date_format'] = $this->date_format;
352
-        $template_args['time_format'] = $this->time_format;
353
-        /**
354
-         * Filters the anchor ID used when redirecting to the Ticket Selector if no quantity selected
355
-         *
356
-         * @since 4.9.13
357
-         * @param     string  '#tkt-slctr-tbl-' . $EVT_ID The html ID to anchor to
358
-         * @param int $EVT_ID The Event ID
359
-         */
360
-        $template_args['anchor_id'] = apply_filters(
361
-            'FHEE__EE_Ticket_Selector__redirect_anchor_id',
362
-            '#tkt-slctr-tbl-' . $this->event->ID(),
363
-            $this->event->ID()
364
-        );
365
-        $template_args['tickets'] = $tickets;
366
-        $template_args['ticket_count'] = count($tickets);
367
-        $ticket_selector = $this->simpleTicketSelector( $tickets, $template_args);
368
-        return $ticket_selector instanceof TicketSelectorSimple
369
-            ? $ticket_selector
370
-            : new TicketSelectorStandard(
371
-                $this->event,
372
-                $tickets,
373
-                $this->getMaxAttendees(),
374
-                $template_args,
375
-                $this->date_format,
376
-                $this->time_format
377
-            );
378
-    }
379
-
380
-
381
-
382
-    /**
383
-     * simpleTicketSelector
384
-     * there's one ticket, and max attendees is set to one,
385
-     * so if the event is free, then this is a "simple" ticket selector
386
-     * a.k.a. "Dude Where's my Ticket Selector?"
387
-     *
388
-     * @param \EE_Ticket[] $tickets
389
-     * @param array  $template_args
390
-     * @return string
391
-     * @throws \EE_Error
392
-     */
393
-    protected function simpleTicketSelector($tickets, array $template_args)
394
-    {
395
-        // if there is only ONE ticket with a max qty of ONE
396
-        if (count($tickets) > 1 || $this->getMaxAttendees() !== 1) {
397
-            return '';
398
-        }
399
-        /** @var \EE_Ticket $ticket */
400
-        $ticket = reset($tickets);
401
-        // if the ticket is free... then not much need for the ticket selector
402
-        if (
403
-            apply_filters(
404
-                'FHEE__ticket_selector_chart_template__hide_ticket_selector',
405
-                $ticket->is_free(),
406
-                $this->event->ID()
407
-            )
408
-        ) {
409
-            return new TicketSelectorSimple(
410
-                $this->event,
411
-                $ticket,
412
-                $this->getMaxAttendees(),
413
-                $template_args
414
-            );
415
-        }
416
-        return '';
417
-    }
418
-
419
-
420
-
421
-    /**
422
-     * externalEventRegistration
423
-     *
424
-     * @return string
425
-     */
426
-    public function externalEventRegistration()
427
-    {
428
-        // if not we still need to trigger the display of the submit button
429
-        add_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true');
430
-        //display notice to admin that registration is external
431
-        return is_admin()
432
-            ? esc_html__(
433
-                'Registration is at an external URL for this event.',
434
-                'event_espresso'
435
-            )
436
-            : '';
437
-    }
438
-
439
-
440
-
441
-    /**
442
-     * formOpen
443
-     *
444
-     * @param        int    $ID
445
-     * @param        string $external_url
446
-     * @return        string
447
-     */
448
-    public function formOpen( $ID = 0, $external_url = '' )
449
-    {
450
-        // if redirecting, we don't need any anything else
451
-        if ( $external_url ) {
452
-            $html = '<form method="GET" action="' . \EEH_URL::refactor_url($external_url) . '"';
453
-            // open link in new window ?
454
-            $html .= apply_filters(
455
-                'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__formOpen__external_url_target_blank',
456
-                false
457
-            )
458
-                ? ' target="_blank"'
459
-                : '';
460
-            $html .= '>';
461
-            $query_args = \EEH_URL::get_query_string( $external_url );
462
-            foreach ( (array)$query_args as $query_arg => $value ) {
463
-                $html .= '<input type="hidden" name="' . $query_arg . '" value="' . $value . '">';
464
-            }
465
-            return $html;
466
-        }
467
-        // if there is no submit button, then don't start building a form
468
-        // because the "View Details" button will build its own form
469
-        if ( ! apply_filters( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false ) ) {
470
-            return '';
471
-        }
472
-        $checkout_url = \EEH_Event_View::event_link_url( $ID );
473
-        if ( ! $checkout_url ) {
474
-            \EE_Error::add_error(
475
-                esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ),
476
-                __FILE__,
477
-                __FUNCTION__,
478
-                __LINE__
479
-            );
480
-        }
481
-        // set no cache headers and constants
482
-        \EE_System::do_not_cache();
483
-        $extra_params = $this->iframe ? ' target="_blank"' : '';
484
-        $html = '<form method="POST" action="' . $checkout_url . '"' . $extra_params . '>';
485
-        $html .= wp_nonce_field( 'process_ticket_selections', 'process_ticket_selections_nonce_' . $ID, true, false );
486
-        $html .= '<input type="hidden" name="ee" value="process_ticket_selections">';
487
-        $html = apply_filters( 'FHEE__EE_Ticket_Selector__ticket_selector_form_open__html', $html, $this->event );
488
-        return $html;
489
-    }
490
-
491
-
492
-
493
-    /**
494
-     * displaySubmitButton
495
-     *
496
-     * @param  string $external_url
497
-     * @return string
498
-     * @throws \EE_Error
499
-     */
500
-    public function displaySubmitButton($external_url = '')
501
-    {
502
-        $html = '';
503
-        if ( ! is_admin()) {
504
-            // standard TS displayed with submit button, ie: "Register Now"
505
-            if (apply_filters('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false)) {
506
-                $html .= $this->displayRegisterNowButton();
507
-                $html .= empty($external_url)
508
-                    ? $this->ticketSelectorEndDiv()
509
-                    : $this->clearTicketSelector();
510
-                $html .= '<br/>' . $this->formClose();
511
-            } else if ($this->getMaxAttendees() === 1) {
512
-                // its a "Dude Where's my Ticket Selector?" (DWMTS) type event (ie: $_max_atndz === 1)
513
-                if ($this->event->is_sold_out()) {
514
-                    // then instead of a View Details or Submit button, just display a "Sold Out" message
515
-                    $html .= apply_filters(
516
-                        'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__sold_out_msg',
517
-                        sprintf(
518
-                            __(
519
-                                '%1$s"%2$s" is currently sold out.%4$sPlease check back again later, as spots may become available.%3$s',
520
-                                'event_espresso'
521
-                            ),
522
-                            '<p class="no-ticket-selector-msg clear-float">',
523
-                            $this->event->name(),
524
-                            '</p>',
525
-                            '<br />'
526
-                        ),
527
-                        $this->event
528
-                    );
529
-                    if (
530
-                    apply_filters(
531
-                        'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button',
532
-                        false,
533
-                        $this->event
534
-                    )
535
-                    ) {
536
-                        $html .= $this->displayRegisterNowButton();
537
-                    }
538
-                    // sold out DWMTS event, no TS, no submit or view details button, but has additional content
539
-                    $html .= $this->ticketSelectorEndDiv();
540
-                } else if (
541
-                    apply_filters('FHEE__EE_Ticket_Selector__hide_ticket_selector', false)
542
-                    && ! is_single()
543
-                ) {
544
-                    // this is a "Dude Where's my Ticket Selector?" (DWMTS) type event,
545
-                    // but no tickets are available, so display event's "View Details" button.
546
-                    // it is being viewed via somewhere other than a single post
547
-                    $html .= $this->displayViewDetailsButton(true);
548
-                }
549
-            } else if (is_archive()) {
550
-                // event list, no tickets available so display event's "View Details" button
551
-                $html .= $this->ticketSelectorEndDiv();
552
-                $html .= $this->displayViewDetailsButton();
553
-            } else {
554
-                if (
555
-                apply_filters(
556
-                    'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button',
557
-                    false,
558
-                    $this->event
559
-                )
560
-                ) {
561
-                    $html .= $this->displayRegisterNowButton();
562
-                }
563
-                // no submit or view details button, and no additional content
564
-                $html .= $this->ticketSelectorEndDiv();
565
-            }
566
-            if ( ! $this->iframe && ! is_archive()) {
567
-                $html .= \EEH_Template::powered_by_event_espresso('', '', array('utm_content' => 'ticket_selector'));
568
-            }
569
-        }
570
-        return $html;
571
-    }
572
-
573
-
574
-
575
-    /**
576
-     * @return string
577
-     * @throws \EE_Error
578
-     */
579
-    public function displayRegisterNowButton()
580
-    {
581
-        $btn_text = apply_filters(
582
-            'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__btn_text',
583
-            __('Register Now', 'event_espresso'),
584
-            $this->event
585
-        );
586
-        $external_url = $this->event->external_url();
587
-        $html = \EEH_HTML::div(
588
-            '', 'ticket-selector-submit-' . $this->event->ID() . '-btn-wrap', 'ticket-selector-submit-btn-wrap'
589
-        );
590
-        $html .= \EEH_HTML::span(
591
-            esc_html__('please select a datetime', 'event_espresso'),
592
-            '', 'ticket-selector-disabled-submit-btn-msg important-notice'
593
-        );
594
-        $html .= '<input id="ticket-selector-submit-' . $this->event->ID() . '-btn"';
595
-        $html .= ' class="ticket-selector-submit-btn ';
596
-        $html .= empty($external_url) ? 'ticket-selector-submit-ajax"' : '"';
597
-        $html .= ' type="submit" value="' . $btn_text . '" />';
598
-        $html .= \EEH_HTML::divx();
599
-        $html .= apply_filters(
600
-            'FHEE__EE_Ticket_Selector__after_ticket_selector_submit',
601
-            '',
602
-            $this->event
603
-        );
604
-        return $html;
605
-    }
606
-
607
-
608
-    /**
609
-     * displayViewDetailsButton
610
-     *
611
-     * @param bool $DWMTS indicates a "Dude Where's my Ticket Selector?" (DWMTS) type event
612
-     *                    (ie: $_max_atndz === 1) where there are no available tickets,
613
-     *                    either because they are sold out, expired, or not yet on sale.
614
-     *                    In this case, we need to close the form BEFORE adding any closing divs
615
-     * @return string
616
-     * @throws \EE_Error
617
-     */
618
-    public function displayViewDetailsButton( $DWMTS = false )
619
-    {
620
-        if ( ! $this->event->get_permalink() ) {
621
-            \EE_Error::add_error(
622
-                esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ),
623
-                __FILE__, __FUNCTION__, __LINE__
624
-            );
625
-        }
626
-        $view_details_btn = '<form method="POST" action="';
627
-        $view_details_btn .= apply_filters(
628
-            'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_url',
629
-            $this->event->get_permalink(),
630
-            $this->event
631
-        );
632
-        $view_details_btn .= '">';
633
-        $btn_text = apply_filters(
634
-            'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_text',
635
-            esc_html__('View Details', 'event_espresso'),
636
-            $this->event
637
-        );
638
-        $view_details_btn .= '<input id="ticket-selector-submit-'
639
-                             . $this->event->ID()
640
-                             . '-btn" class="ticket-selector-submit-btn view-details-btn" type="submit" value="'
641
-                             . $btn_text
642
-                             . '" />';
643
-        $view_details_btn .= apply_filters( 'FHEE__EE_Ticket_Selector__after_view_details_btn', '', $this->event );
644
-        if ($DWMTS) {
645
-            $view_details_btn .= $this->formClose();
646
-            $view_details_btn .= $this->ticketSelectorEndDiv();
647
-            $view_details_btn .= '<br/>';
648
-        } else {
649
-            $view_details_btn .= $this->clearTicketSelector();
650
-            $view_details_btn .= '<br/>';
651
-            $view_details_btn .= $this->formClose();
652
-        }
653
-        return $view_details_btn;
654
-    }
655
-
656
-
657
-
658
-    /**
659
-     * @return string
660
-     */
661
-    public function ticketSelectorEndDiv()
662
-    {
663
-        return '<div class="clear"></div></div>';
664
-    }
665
-
666
-
667
-
668
-    /**
669
-     * @return string
670
-     */
671
-    public function clearTicketSelector()
672
-    {
673
-        // standard TS displayed, appears after a "Register Now" or "view Details" button
674
-        return '<div class="clear"></div>';
675
-    }
676
-
677
-
678
-
679
-    /**
680
-     * @access        public
681
-     * @return        string
682
-     */
683
-    public function formClose()
684
-    {
685
-        return '</form>';
686
-    }
271
+	}
272
+
273
+
274
+
275
+	/**
276
+	 * ticketSalesClosed
277
+	 * notice displayed if event ticket sales are turned off
278
+	 *
279
+	 * @return string
280
+	 * @throws \EE_Error
281
+	 */
282
+	protected function ticketSalesClosedMessage()
283
+	{
284
+		$sales_closed_msg = esc_html__(
285
+			'We\'re sorry, but ticket sales have been closed at this time. Please check back again later.',
286
+			'event_espresso'
287
+		);
288
+		if (current_user_can('edit_post', $this->event->ID())) {
289
+			$sales_closed_msg .= sprintf(
290
+				esc_html__(
291
+					'%sNote to Event Admin:%sThe "Maximum number of tickets allowed per order for this event" in the Event Registration Options has been set to "0". This effectively turns off ticket sales. %s(click to edit this event)%s',
292
+					'event_espresso'
293
+				),
294
+				'<div class="ee-attention" style="text-align: left;"><b>',
295
+				'</b><br />',
296
+				'<span class="edit-link"><a class="post-edit-link" href="'.get_edit_post_link($this->event->ID()).'">',
297
+				'</a></span></div>'
298
+			);
299
+		}
300
+		return '<p><span class="important-notice">' . $sales_closed_msg . '</span></p>';
301
+	}
302
+
303
+
304
+
305
+	/**
306
+	 * getTickets
307
+	 *
308
+	 * @return \EE_Base_Class[]|\EE_Ticket[]
309
+	 * @throws \EE_Error
310
+	 */
311
+	protected function getTickets()
312
+	{
313
+		$ticket_query_args = array(
314
+			array('Datetime.EVT_ID' => $this->event->ID()),
315
+			'order_by' => array(
316
+				'TKT_order'              => 'ASC',
317
+				'TKT_required'           => 'DESC',
318
+				'TKT_start_date'         => 'ASC',
319
+				'TKT_end_date'           => 'ASC',
320
+				'Datetime.DTT_EVT_start' => 'DESC',
321
+			),
322
+		);
323
+		if ( ! \EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector->show_expired_tickets) {
324
+			//use the correct applicable time query depending on what version of core is being run.
325
+			$current_time = method_exists('EEM_Datetime', 'current_time_for_query')
326
+				? time()
327
+				: current_time('timestamp');
328
+			$ticket_query_args[0]['TKT_end_date'] = array('>', $current_time);
329
+		}
330
+		return \EEM_Ticket::instance()->get_all($ticket_query_args);
331
+	}
332
+
333
+
334
+
335
+	/**
336
+	 * loadTicketSelector
337
+	 * begins to assemble template arguments
338
+	 * and decides whether to load a "simple" ticket selector, or the standard
339
+	 *
340
+	 * @param \EE_Ticket[] $tickets
341
+	 * @param array $template_args
342
+	 * @return string
343
+	 * @throws \EE_Error
344
+	 */
345
+	protected function loadTicketSelector(array $tickets, array $template_args)
346
+	{
347
+		$template_args['event'] = $this->event;
348
+		$template_args['EVT_ID'] = $this->event->ID();
349
+		$template_args['event_is_expired'] = $this->event->is_expired();
350
+		$template_args['max_atndz'] = $this->getMaxAttendees();
351
+		$template_args['date_format'] = $this->date_format;
352
+		$template_args['time_format'] = $this->time_format;
353
+		/**
354
+		 * Filters the anchor ID used when redirecting to the Ticket Selector if no quantity selected
355
+		 *
356
+		 * @since 4.9.13
357
+		 * @param     string  '#tkt-slctr-tbl-' . $EVT_ID The html ID to anchor to
358
+		 * @param int $EVT_ID The Event ID
359
+		 */
360
+		$template_args['anchor_id'] = apply_filters(
361
+			'FHEE__EE_Ticket_Selector__redirect_anchor_id',
362
+			'#tkt-slctr-tbl-' . $this->event->ID(),
363
+			$this->event->ID()
364
+		);
365
+		$template_args['tickets'] = $tickets;
366
+		$template_args['ticket_count'] = count($tickets);
367
+		$ticket_selector = $this->simpleTicketSelector( $tickets, $template_args);
368
+		return $ticket_selector instanceof TicketSelectorSimple
369
+			? $ticket_selector
370
+			: new TicketSelectorStandard(
371
+				$this->event,
372
+				$tickets,
373
+				$this->getMaxAttendees(),
374
+				$template_args,
375
+				$this->date_format,
376
+				$this->time_format
377
+			);
378
+	}
379
+
380
+
381
+
382
+	/**
383
+	 * simpleTicketSelector
384
+	 * there's one ticket, and max attendees is set to one,
385
+	 * so if the event is free, then this is a "simple" ticket selector
386
+	 * a.k.a. "Dude Where's my Ticket Selector?"
387
+	 *
388
+	 * @param \EE_Ticket[] $tickets
389
+	 * @param array  $template_args
390
+	 * @return string
391
+	 * @throws \EE_Error
392
+	 */
393
+	protected function simpleTicketSelector($tickets, array $template_args)
394
+	{
395
+		// if there is only ONE ticket with a max qty of ONE
396
+		if (count($tickets) > 1 || $this->getMaxAttendees() !== 1) {
397
+			return '';
398
+		}
399
+		/** @var \EE_Ticket $ticket */
400
+		$ticket = reset($tickets);
401
+		// if the ticket is free... then not much need for the ticket selector
402
+		if (
403
+			apply_filters(
404
+				'FHEE__ticket_selector_chart_template__hide_ticket_selector',
405
+				$ticket->is_free(),
406
+				$this->event->ID()
407
+			)
408
+		) {
409
+			return new TicketSelectorSimple(
410
+				$this->event,
411
+				$ticket,
412
+				$this->getMaxAttendees(),
413
+				$template_args
414
+			);
415
+		}
416
+		return '';
417
+	}
418
+
419
+
420
+
421
+	/**
422
+	 * externalEventRegistration
423
+	 *
424
+	 * @return string
425
+	 */
426
+	public function externalEventRegistration()
427
+	{
428
+		// if not we still need to trigger the display of the submit button
429
+		add_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true');
430
+		//display notice to admin that registration is external
431
+		return is_admin()
432
+			? esc_html__(
433
+				'Registration is at an external URL for this event.',
434
+				'event_espresso'
435
+			)
436
+			: '';
437
+	}
438
+
439
+
440
+
441
+	/**
442
+	 * formOpen
443
+	 *
444
+	 * @param        int    $ID
445
+	 * @param        string $external_url
446
+	 * @return        string
447
+	 */
448
+	public function formOpen( $ID = 0, $external_url = '' )
449
+	{
450
+		// if redirecting, we don't need any anything else
451
+		if ( $external_url ) {
452
+			$html = '<form method="GET" action="' . \EEH_URL::refactor_url($external_url) . '"';
453
+			// open link in new window ?
454
+			$html .= apply_filters(
455
+				'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__formOpen__external_url_target_blank',
456
+				false
457
+			)
458
+				? ' target="_blank"'
459
+				: '';
460
+			$html .= '>';
461
+			$query_args = \EEH_URL::get_query_string( $external_url );
462
+			foreach ( (array)$query_args as $query_arg => $value ) {
463
+				$html .= '<input type="hidden" name="' . $query_arg . '" value="' . $value . '">';
464
+			}
465
+			return $html;
466
+		}
467
+		// if there is no submit button, then don't start building a form
468
+		// because the "View Details" button will build its own form
469
+		if ( ! apply_filters( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false ) ) {
470
+			return '';
471
+		}
472
+		$checkout_url = \EEH_Event_View::event_link_url( $ID );
473
+		if ( ! $checkout_url ) {
474
+			\EE_Error::add_error(
475
+				esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ),
476
+				__FILE__,
477
+				__FUNCTION__,
478
+				__LINE__
479
+			);
480
+		}
481
+		// set no cache headers and constants
482
+		\EE_System::do_not_cache();
483
+		$extra_params = $this->iframe ? ' target="_blank"' : '';
484
+		$html = '<form method="POST" action="' . $checkout_url . '"' . $extra_params . '>';
485
+		$html .= wp_nonce_field( 'process_ticket_selections', 'process_ticket_selections_nonce_' . $ID, true, false );
486
+		$html .= '<input type="hidden" name="ee" value="process_ticket_selections">';
487
+		$html = apply_filters( 'FHEE__EE_Ticket_Selector__ticket_selector_form_open__html', $html, $this->event );
488
+		return $html;
489
+	}
490
+
491
+
492
+
493
+	/**
494
+	 * displaySubmitButton
495
+	 *
496
+	 * @param  string $external_url
497
+	 * @return string
498
+	 * @throws \EE_Error
499
+	 */
500
+	public function displaySubmitButton($external_url = '')
501
+	{
502
+		$html = '';
503
+		if ( ! is_admin()) {
504
+			// standard TS displayed with submit button, ie: "Register Now"
505
+			if (apply_filters('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false)) {
506
+				$html .= $this->displayRegisterNowButton();
507
+				$html .= empty($external_url)
508
+					? $this->ticketSelectorEndDiv()
509
+					: $this->clearTicketSelector();
510
+				$html .= '<br/>' . $this->formClose();
511
+			} else if ($this->getMaxAttendees() === 1) {
512
+				// its a "Dude Where's my Ticket Selector?" (DWMTS) type event (ie: $_max_atndz === 1)
513
+				if ($this->event->is_sold_out()) {
514
+					// then instead of a View Details or Submit button, just display a "Sold Out" message
515
+					$html .= apply_filters(
516
+						'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__sold_out_msg',
517
+						sprintf(
518
+							__(
519
+								'%1$s"%2$s" is currently sold out.%4$sPlease check back again later, as spots may become available.%3$s',
520
+								'event_espresso'
521
+							),
522
+							'<p class="no-ticket-selector-msg clear-float">',
523
+							$this->event->name(),
524
+							'</p>',
525
+							'<br />'
526
+						),
527
+						$this->event
528
+					);
529
+					if (
530
+					apply_filters(
531
+						'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button',
532
+						false,
533
+						$this->event
534
+					)
535
+					) {
536
+						$html .= $this->displayRegisterNowButton();
537
+					}
538
+					// sold out DWMTS event, no TS, no submit or view details button, but has additional content
539
+					$html .= $this->ticketSelectorEndDiv();
540
+				} else if (
541
+					apply_filters('FHEE__EE_Ticket_Selector__hide_ticket_selector', false)
542
+					&& ! is_single()
543
+				) {
544
+					// this is a "Dude Where's my Ticket Selector?" (DWMTS) type event,
545
+					// but no tickets are available, so display event's "View Details" button.
546
+					// it is being viewed via somewhere other than a single post
547
+					$html .= $this->displayViewDetailsButton(true);
548
+				}
549
+			} else if (is_archive()) {
550
+				// event list, no tickets available so display event's "View Details" button
551
+				$html .= $this->ticketSelectorEndDiv();
552
+				$html .= $this->displayViewDetailsButton();
553
+			} else {
554
+				if (
555
+				apply_filters(
556
+					'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button',
557
+					false,
558
+					$this->event
559
+				)
560
+				) {
561
+					$html .= $this->displayRegisterNowButton();
562
+				}
563
+				// no submit or view details button, and no additional content
564
+				$html .= $this->ticketSelectorEndDiv();
565
+			}
566
+			if ( ! $this->iframe && ! is_archive()) {
567
+				$html .= \EEH_Template::powered_by_event_espresso('', '', array('utm_content' => 'ticket_selector'));
568
+			}
569
+		}
570
+		return $html;
571
+	}
572
+
573
+
574
+
575
+	/**
576
+	 * @return string
577
+	 * @throws \EE_Error
578
+	 */
579
+	public function displayRegisterNowButton()
580
+	{
581
+		$btn_text = apply_filters(
582
+			'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__btn_text',
583
+			__('Register Now', 'event_espresso'),
584
+			$this->event
585
+		);
586
+		$external_url = $this->event->external_url();
587
+		$html = \EEH_HTML::div(
588
+			'', 'ticket-selector-submit-' . $this->event->ID() . '-btn-wrap', 'ticket-selector-submit-btn-wrap'
589
+		);
590
+		$html .= \EEH_HTML::span(
591
+			esc_html__('please select a datetime', 'event_espresso'),
592
+			'', 'ticket-selector-disabled-submit-btn-msg important-notice'
593
+		);
594
+		$html .= '<input id="ticket-selector-submit-' . $this->event->ID() . '-btn"';
595
+		$html .= ' class="ticket-selector-submit-btn ';
596
+		$html .= empty($external_url) ? 'ticket-selector-submit-ajax"' : '"';
597
+		$html .= ' type="submit" value="' . $btn_text . '" />';
598
+		$html .= \EEH_HTML::divx();
599
+		$html .= apply_filters(
600
+			'FHEE__EE_Ticket_Selector__after_ticket_selector_submit',
601
+			'',
602
+			$this->event
603
+		);
604
+		return $html;
605
+	}
606
+
607
+
608
+	/**
609
+	 * displayViewDetailsButton
610
+	 *
611
+	 * @param bool $DWMTS indicates a "Dude Where's my Ticket Selector?" (DWMTS) type event
612
+	 *                    (ie: $_max_atndz === 1) where there are no available tickets,
613
+	 *                    either because they are sold out, expired, or not yet on sale.
614
+	 *                    In this case, we need to close the form BEFORE adding any closing divs
615
+	 * @return string
616
+	 * @throws \EE_Error
617
+	 */
618
+	public function displayViewDetailsButton( $DWMTS = false )
619
+	{
620
+		if ( ! $this->event->get_permalink() ) {
621
+			\EE_Error::add_error(
622
+				esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ),
623
+				__FILE__, __FUNCTION__, __LINE__
624
+			);
625
+		}
626
+		$view_details_btn = '<form method="POST" action="';
627
+		$view_details_btn .= apply_filters(
628
+			'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_url',
629
+			$this->event->get_permalink(),
630
+			$this->event
631
+		);
632
+		$view_details_btn .= '">';
633
+		$btn_text = apply_filters(
634
+			'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_text',
635
+			esc_html__('View Details', 'event_espresso'),
636
+			$this->event
637
+		);
638
+		$view_details_btn .= '<input id="ticket-selector-submit-'
639
+							 . $this->event->ID()
640
+							 . '-btn" class="ticket-selector-submit-btn view-details-btn" type="submit" value="'
641
+							 . $btn_text
642
+							 . '" />';
643
+		$view_details_btn .= apply_filters( 'FHEE__EE_Ticket_Selector__after_view_details_btn', '', $this->event );
644
+		if ($DWMTS) {
645
+			$view_details_btn .= $this->formClose();
646
+			$view_details_btn .= $this->ticketSelectorEndDiv();
647
+			$view_details_btn .= '<br/>';
648
+		} else {
649
+			$view_details_btn .= $this->clearTicketSelector();
650
+			$view_details_btn .= '<br/>';
651
+			$view_details_btn .= $this->formClose();
652
+		}
653
+		return $view_details_btn;
654
+	}
655
+
656
+
657
+
658
+	/**
659
+	 * @return string
660
+	 */
661
+	public function ticketSelectorEndDiv()
662
+	{
663
+		return '<div class="clear"></div></div>';
664
+	}
665
+
666
+
667
+
668
+	/**
669
+	 * @return string
670
+	 */
671
+	public function clearTicketSelector()
672
+	{
673
+		// standard TS displayed, appears after a "Register Now" or "view Details" button
674
+		return '<div class="clear"></div>';
675
+	}
676
+
677
+
678
+
679
+	/**
680
+	 * @access        public
681
+	 * @return        string
682
+	 */
683
+	public function formClose()
684
+	{
685
+		return '</form>';
686
+	}
687 687
 
688 688
 
689 689
 
Please login to merge, or discard this patch.
core/libraries/rest_api/controllers/model/Read.php 2 patches
Indentation   +1177 added lines, -1177 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,1182 +27,1182 @@  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->_add_extra_fields_to_schema(
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
-     * Adds additional fields to the schema
125
-     * The REST API returns a GMT value field for each datetime field in the resource.  Thus the description about this
126
-     * needs to be added to the schema.
127
-     *
128
-     * @param \EEM_Base $model
129
-     * @param string    $schema
130
-     */
131
-    protected function _add_extra_fields_to_schema(\EEM_Base $model, $schema)
132
-    {
133
-        foreach ($this->get_model_version_info()->fields_on_model_in_this_version($model) as $field_name => $field) {
134
-            if ($field instanceof EE_Datetime_Field) {
135
-                $schema['properties'][$field_name . '_gmt'] = $field->getSchema();
136
-                //modify the description
137
-                $schema['properties'][$field_name . '_gmt']['description'] = sprintf(
138
-                    esc_html__('%s - the value for this field is in GMT.', 'event_espresso'),
139
-                    $field->get_nicename()
140
-                );
141
-            }
142
-        }
143
-        return $schema;
144
-    }
145
-
146
-
147
-
148
-
149
-    /**
150
-     * Used to figure out the route from the request when a `WP_REST_Request` object is not available
151
-     * @return string
152
-     */
153
-    protected function get_route_from_request() {
154
-        if (isset($GLOBALS['wp'])
155
-            && $GLOBALS['wp'] instanceof \WP
156
-            && isset($GLOBALS['wp']->query_vars['rest_route'] )
157
-        ) {
158
-            return $GLOBALS['wp']->query_vars['rest_route'];
159
-        } else {
160
-            return isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '/';
161
-        }
162
-    }
163
-
164
-
165
-
166
-    /**
167
-     * Gets a single entity related to the model indicated in the path and its id
168
-     *
169
-     * @param \WP_REST_Request $request
170
-     * @return \WP_REST_Response|\WP_Error
171
-     */
172
-    public static function handle_request_get_one(\WP_REST_Request $request)
173
-    {
174
-        $controller = new Read();
175
-        try {
176
-            $matches = $controller->parse_route(
177
-                $request->get_route(),
178
-                '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)~',
179
-                array('version', 'model', 'id'));
180
-            $controller->set_requested_version($matches['version']);
181
-            $model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']);
182
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) {
183
-                return $controller->send_response(
184
-                    new \WP_Error(
185
-                        'endpoint_parsing_error',
186
-                        sprintf(
187
-                            __('There is no model for endpoint %s. Please contact event espresso support',
188
-                                'event_espresso'),
189
-                            $model_name_singular
190
-                        )
191
-                    )
192
-                );
193
-            }
194
-            return $controller->send_response(
195
-                $controller->get_entity_from_model(
196
-                    $controller->get_model_version_info()->load_model($model_name_singular),
197
-                    $request
198
-                )
199
-            );
200
-        } catch (\Exception $e) {
201
-            return $controller->send_response($e);
202
-        }
203
-    }
204
-
205
-
206
-
207
-    /**
208
-     * Gets all the related entities (or if its a belongs-to relation just the one)
209
-     * to the item with the given id
210
-     *
211
-     * @param \WP_REST_Request $request
212
-     * @return \WP_REST_Response|\WP_Error
213
-     */
214
-    public static function handle_request_get_related(\WP_REST_Request $request)
215
-    {
216
-        $controller = new Read();
217
-        try {
218
-            $matches = $controller->parse_route(
219
-                $request->get_route(),
220
-                '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)/(.*)~',
221
-                array('version', 'model', 'id', 'related_model')
222
-            );
223
-            $controller->set_requested_version($matches['version']);
224
-            $main_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']);
225
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($main_model_name_singular)) {
226
-                return $controller->send_response(
227
-                    new \WP_Error(
228
-                        'endpoint_parsing_error',
229
-                        sprintf(
230
-                            __('There is no model for endpoint %s. Please contact event espresso support',
231
-                                'event_espresso'),
232
-                            $main_model_name_singular
233
-                        )
234
-                    )
235
-                );
236
-            }
237
-            $main_model = $controller->get_model_version_info()->load_model($main_model_name_singular);
238
-            //assume the related model name is plural and try to find the model's name
239
-            $related_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['related_model']);
240
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) {
241
-                //so the word didn't singularize well. Maybe that's just because it's a singular word?
242
-                $related_model_name_singular = \EEH_Inflector::humanize($matches['related_model']);
243
-            }
244
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) {
245
-                return $controller->send_response(
246
-                    new \WP_Error(
247
-                        'endpoint_parsing_error',
248
-                        sprintf(
249
-                            __('There is no model for endpoint %s. Please contact event espresso support',
250
-                                'event_espresso'),
251
-                            $related_model_name_singular
252
-                        )
253
-                    )
254
-                );
255
-            }
256
-            return $controller->send_response(
257
-                $controller->get_entities_from_relation(
258
-                    $request->get_param('id'),
259
-                    $main_model->related_settings_for($related_model_name_singular),
260
-                    $request
261
-                )
262
-            );
263
-        } catch (\Exception $e) {
264
-            return $controller->send_response($e);
265
-        }
266
-    }
267
-
268
-
269
-
270
-    /**
271
-     * Gets a collection for the given model and filters
272
-     *
273
-     * @param \EEM_Base        $model
274
-     * @param \WP_REST_Request $request
275
-     * @return array|\WP_Error
276
-     */
277
-    public function get_entities_from_model($model, $request)
278
-    {
279
-        $query_params = $this->create_model_query_params($model, $request->get_params());
280
-        if (! Capabilities::current_user_has_partial_access_to($model, $query_params['caps'])) {
281
-            $model_name_plural = \EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
282
-            return new \WP_Error(
283
-                sprintf('rest_%s_cannot_list', $model_name_plural),
284
-                sprintf(
285
-                    __('Sorry, you are not allowed to list %1$s. Missing permissions: %2$s', 'event_espresso'),
286
-                    $model_name_plural,
287
-                    Capabilities::get_missing_permissions_string($model, $query_params['caps'])
288
-                ),
289
-                array('status' => 403)
290
-            );
291
-        }
292
-        if (! $request->get_header('no_rest_headers')) {
293
-            $this->_set_headers_from_query_params($model, $query_params);
294
-        }
295
-        /** @type array $results */
296
-        $results = $model->get_all_wpdb_results($query_params);
297
-        $nice_results = array();
298
-        foreach ($results as $result) {
299
-            $nice_results[] = $this->create_entity_from_wpdb_result(
300
-                $model,
301
-                $result,
302
-                $request
303
-            );
304
-        }
305
-        return $nice_results;
306
-    }
307
-
308
-
309
-
310
-    /**
311
-     * @param array                   $primary_model_query_params query params for finding the item from which
312
-     *                                                            relations will be based
313
-     * @param \EE_Model_Relation_Base $relation
314
-     * @param \WP_REST_Request        $request
315
-     * @return \WP_Error|array
316
-     */
317
-    protected function _get_entities_from_relation($primary_model_query_params, $relation, $request)
318
-    {
319
-        $context = $this->validate_context($request->get_param('caps'));
320
-        $model = $relation->get_this_model();
321
-        $related_model = $relation->get_other_model();
322
-        if (! isset($primary_model_query_params[0])) {
323
-            $primary_model_query_params[0] = array();
324
-        }
325
-        //check if they can access the 1st model object
326
-        $primary_model_query_params = array(
327
-            0       => $primary_model_query_params[0],
328
-            'limit' => 1,
329
-        );
330
-        if ($model instanceof \EEM_Soft_Delete_Base) {
331
-            $primary_model_query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($primary_model_query_params);
332
-        }
333
-        $restricted_query_params = $primary_model_query_params;
334
-        $restricted_query_params['caps'] = $context;
335
-        $this->_set_debug_info('main model query params', $restricted_query_params);
336
-        $this->_set_debug_info('missing caps', Capabilities::get_missing_permissions_string($related_model, $context));
337
-        if (
338
-        ! (
339
-            Capabilities::current_user_has_partial_access_to($related_model, $context)
340
-            && $model->exists($restricted_query_params)
341
-        )
342
-        ) {
343
-            if ($relation instanceof \EE_Belongs_To_Relation) {
344
-                $related_model_name_maybe_plural = strtolower($related_model->get_this_model_name());
345
-            } else {
346
-                $related_model_name_maybe_plural = \EEH_Inflector::pluralize_and_lower($related_model->get_this_model_name());
347
-            }
348
-            return new \WP_Error(
349
-                sprintf('rest_%s_cannot_list', $related_model_name_maybe_plural),
350
-                sprintf(
351
-                    __('Sorry, you are not allowed to list %1$s related to %2$s. Missing permissions: %3$s',
352
-                        'event_espresso'),
353
-                    $related_model_name_maybe_plural,
354
-                    $relation->get_this_model()->get_this_model_name(),
355
-                    implode(
356
-                        ',',
357
-                        array_keys(
358
-                            Capabilities::get_missing_permissions($related_model, $context)
359
-                        )
360
-                    )
361
-                ),
362
-                array('status' => 403)
363
-            );
364
-        }
365
-        $query_params = $this->create_model_query_params($relation->get_other_model(), $request->get_params());
366
-        foreach ($primary_model_query_params[0] as $where_condition_key => $where_condition_value) {
367
-            $query_params[0][$relation->get_this_model()->get_this_model_name()
368
-                             . '.'
369
-                             . $where_condition_key] = $where_condition_value;
370
-        }
371
-        $query_params['default_where_conditions'] = 'none';
372
-        $query_params['caps'] = $context;
373
-        if (! $request->get_header('no_rest_headers')) {
374
-            $this->_set_headers_from_query_params($relation->get_other_model(), $query_params);
375
-        }
376
-        /** @type array $results */
377
-        $results = $relation->get_other_model()->get_all_wpdb_results($query_params);
378
-        $nice_results = array();
379
-        foreach ($results as $result) {
380
-            $nice_result = $this->create_entity_from_wpdb_result(
381
-                $relation->get_other_model(),
382
-                $result,
383
-                $request
384
-            );
385
-            if ($relation instanceof \EE_HABTM_Relation) {
386
-                //put the unusual stuff (properties from the HABTM relation) first, and make sure
387
-                //if there are conflicts we prefer the properties from the main model
388
-                $join_model_result = $this->create_entity_from_wpdb_result(
389
-                    $relation->get_join_model(),
390
-                    $result,
391
-                    $request
392
-                );
393
-                $joined_result = array_merge($nice_result, $join_model_result);
394
-                //but keep the meta stuff from the main model
395
-                if (isset($nice_result['meta'])) {
396
-                    $joined_result['meta'] = $nice_result['meta'];
397
-                }
398
-                $nice_result = $joined_result;
399
-            }
400
-            $nice_results[] = $nice_result;
401
-        }
402
-        if ($relation instanceof \EE_Belongs_To_Relation) {
403
-            return array_shift($nice_results);
404
-        } else {
405
-            return $nice_results;
406
-        }
407
-    }
408
-
409
-
410
-
411
-    /**
412
-     * Gets the collection for given relation object
413
-     * The same as Read::get_entities_from_model(), except if the relation
414
-     * is a HABTM relation, in which case it merges any non-foreign-key fields from
415
-     * the join-model-object into the results
416
-     *
417
-     * @param string                  $id the ID of the thing we are fetching related stuff from
418
-     * @param \EE_Model_Relation_Base $relation
419
-     * @param \WP_REST_Request        $request
420
-     * @return array|\WP_Error
421
-     * @throws \EE_Error
422
-     */
423
-    public function get_entities_from_relation($id, $relation, $request)
424
-    {
425
-        if (! $relation->get_this_model()->has_primary_key_field()) {
426
-            throw new \EE_Error(
427
-                sprintf(
428
-                    __('Read::get_entities_from_relation should only be called from a model with a primary key, it was called from %1$s',
429
-                        'event_espresso'),
430
-                    $relation->get_this_model()->get_this_model_name()
431
-                )
432
-            );
433
-        }
434
-        return $this->_get_entities_from_relation(
435
-            array(
436
-                array(
437
-                    $relation->get_this_model()->primary_key_name() => $id,
438
-                ),
439
-            ),
440
-            $relation,
441
-            $request
442
-        );
443
-    }
444
-
445
-
446
-
447
-    /**
448
-     * Sets the headers that are based on the model and query params,
449
-     * like the total records. This should only be called on the original request
450
-     * from the client, not on subsequent internal
451
-     *
452
-     * @param \EEM_Base $model
453
-     * @param array     $query_params
454
-     * @return void
455
-     */
456
-    protected function _set_headers_from_query_params($model, $query_params)
457
-    {
458
-        $this->_set_debug_info('model query params', $query_params);
459
-        $this->_set_debug_info('missing caps',
460
-            Capabilities::get_missing_permissions_string($model, $query_params['caps']));
461
-        //normally the limit to a 2-part array, where the 2nd item is the limit
462
-        if (! isset($query_params['limit'])) {
463
-            $query_params['limit'] = \EED_Core_Rest_Api::get_default_query_limit();
464
-        }
465
-        if (is_array($query_params['limit'])) {
466
-            $limit_parts = $query_params['limit'];
467
-        } else {
468
-            $limit_parts = explode(',', $query_params['limit']);
469
-            if (count($limit_parts) == 1) {
470
-                $limit_parts = array(0, $limit_parts[0]);
471
-            }
472
-        }
473
-        //remove the group by and having parts of the query, as those will
474
-        //make the sql query return an array of values, instead of just a single value
475
-        unset($query_params['group_by'], $query_params['having'], $query_params['limit']);
476
-        $count = $model->count($query_params, null, true);
477
-        $pages = $count / $limit_parts[1];
478
-        $this->_set_response_header('Total', $count, false);
479
-        $this->_set_response_header('PageSize', $limit_parts[1], false);
480
-        $this->_set_response_header('TotalPages', ceil($pages), false);
481
-    }
482
-
483
-
484
-
485
-    /**
486
-     * Changes database results into REST API entities
487
-     *
488
-     * @param \EEM_Base        $model
489
-     * @param array            $db_row     like results from $wpdb->get_results()
490
-     * @param \WP_REST_Request $rest_request
491
-     * @param string           $deprecated no longer used
492
-     * @return array ready for being converted into json for sending to client
493
-     */
494
-    public function create_entity_from_wpdb_result($model, $db_row, $rest_request, $deprecated = null)
495
-    {
496
-        if (! $rest_request instanceof \WP_REST_Request) {
497
-            //ok so this was called in the old style, where the 3rd arg was
498
-            //$include, and the 4th arg was $context
499
-            //now setup the request just to avoid fatal errors, although we won't be able
500
-            //to truly make use of it because it's kinda devoid of info
501
-            $rest_request = new \WP_REST_Request();
502
-            $rest_request->set_param('include', $rest_request);
503
-            $rest_request->set_param('caps', $deprecated);
504
-        }
505
-        if ($rest_request->get_param('caps') == null) {
506
-            $rest_request->set_param('caps', \EEM_Base::caps_read);
507
-        }
508
-        $entity_array = $this->_create_bare_entity_from_wpdb_results($model, $db_row);
509
-        $entity_array = $this->_add_extra_fields($model, $db_row, $entity_array);
510
-        $entity_array['_links'] = $this->_get_entity_links($model, $db_row, $entity_array);
511
-        $entity_array['_calculated_fields'] = $this->_get_entity_calculations($model, $db_row, $rest_request);
512
-        $entity_array = $this->_include_requested_models($model, $rest_request, $entity_array, $db_row);
513
-        $entity_array = apply_filters(
514
-            'FHEE__Read__create_entity_from_wpdb_results__entity_before_inaccessible_field_removal',
515
-            $entity_array,
516
-            $model,
517
-            $rest_request->get_param('caps'),
518
-            $rest_request,
519
-            $this
520
-        );
521
-        $result_without_inaccessible_fields = Capabilities::filter_out_inaccessible_entity_fields(
522
-            $entity_array,
523
-            $model,
524
-            $rest_request->get_param('caps'),
525
-            $this->get_model_version_info(),
526
-            $model->get_index_primary_key_string(
527
-                $model->deduce_fields_n_values_from_cols_n_values($db_row)
528
-            )
529
-        );
530
-        $this->_set_debug_info(
531
-            'inaccessible fields',
532
-            array_keys(array_diff_key($entity_array, $result_without_inaccessible_fields))
533
-        );
534
-        return apply_filters(
535
-            'FHEE__Read__create_entity_from_wpdb_results__entity_return',
536
-            $result_without_inaccessible_fields,
537
-            $model,
538
-            $rest_request->get_param('caps')
539
-        );
540
-    }
541
-
542
-
543
-
544
-    /**
545
-     * Creates a REST entity array (JSON object we're going to return in the response, but
546
-     * for now still a PHP array, but soon enough we'll call json_encode on it, don't worry),
547
-     * from $wpdb->get_row( $sql, ARRAY_A)
548
-     *
549
-     * @param \EEM_Base $model
550
-     * @param array     $db_row
551
-     * @return array entity mostly ready for converting to JSON and sending in the response
552
-     */
553
-    protected function _create_bare_entity_from_wpdb_results(\EEM_Base $model, $db_row)
554
-    {
555
-        $result = $model->deduce_fields_n_values_from_cols_n_values($db_row);
556
-        $result = array_intersect_key($result,
557
-            $this->get_model_version_info()->fields_on_model_in_this_version($model));
558
-        foreach ($result as $field_name => $raw_field_value) {
559
-            $field_obj = $model->field_settings_for($field_name);
560
-            $field_value = $field_obj->prepare_for_set_from_db($raw_field_value);
561
-            if ($this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_ignored())) {
562
-                unset($result[$field_name]);
563
-            } elseif (
564
-            $this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_rendered_format())
565
-            ) {
566
-                $result[$field_name] = array(
567
-                    'raw'      => $field_obj->prepare_for_get($field_value),
568
-                    'rendered' => $field_obj->prepare_for_pretty_echoing($field_value),
569
-                );
570
-            } elseif (
571
-            $this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_pretty_format())
572
-            ) {
573
-                $result[$field_name] = array(
574
-                    'raw'    => $field_obj->prepare_for_get($field_value),
575
-                    'pretty' => $field_obj->prepare_for_pretty_echoing($field_value),
576
-                );
577
-            } elseif ($field_obj instanceof \EE_Datetime_Field) {
578
-                if ($field_value instanceof \DateTime) {
579
-                    $timezone = $field_value->getTimezone();
580
-                    $field_value->setTimezone(new \DateTimeZone('UTC'));
581
-                    $result[$field_name . '_gmt'] = Model_Data_Translator::prepare_field_value_for_json(
582
-                        $field_obj,
583
-                        $field_value,
584
-                        $this->get_model_version_info()->requested_version()
585
-                    );
586
-                    $field_value->setTimezone($timezone);
587
-                    $result[$field_name] = Model_Data_Translator::prepare_field_value_for_json(
588
-                        $field_obj,
589
-                        $field_value,
590
-                        $this->get_model_version_info()->requested_version()
591
-                    );
592
-                }
593
-            } else {
594
-                $result[$field_name] = Model_Data_Translator::prepare_field_value_for_json(
595
-                    $field_obj,
596
-                    $field_obj->prepare_for_get($field_value),
597
-                    $this->get_model_version_info()->requested_version()
598
-                );
599
-            }
600
-        }
601
-        return $result;
602
-    }
603
-
604
-
605
-
606
-    /**
607
-     * Adds a few extra fields to the entity response
608
-     *
609
-     * @param \EEM_Base $model
610
-     * @param array     $db_row
611
-     * @param array     $entity_array
612
-     * @return array modified entity
613
-     */
614
-    protected function _add_extra_fields(\EEM_Base $model, $db_row, $entity_array)
615
-    {
616
-        if ($model instanceof \EEM_CPT_Base) {
617
-            $entity_array['link'] = get_permalink($db_row[$model->get_primary_key_field()->get_qualified_column()]);
618
-        }
619
-        return $entity_array;
620
-    }
621
-
622
-
623
-
624
-    /**
625
-     * Gets links we want to add to the response
626
-     *
627
-     * @global \WP_REST_Server $wp_rest_server
628
-     * @param \EEM_Base        $model
629
-     * @param array            $db_row
630
-     * @param array            $entity_array
631
-     * @return array the _links item in the entity
632
-     */
633
-    protected function _get_entity_links($model, $db_row, $entity_array)
634
-    {
635
-        //add basic links
636
-        $links = array();
637
-        if ($model->has_primary_key_field()) {
638
-            $links['self'] = array(
639
-                array(
640
-                    'href' => $this->get_versioned_link_to(
641
-                        \EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
642
-                        . '/'
643
-                        . $entity_array[$model->primary_key_name()]
644
-                    ),
645
-                ),
646
-            );
647
-        }
648
-        $links['collection'] = array(
649
-            array(
650
-                'href' => $this->get_versioned_link_to(
651
-                    \EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
652
-                ),
653
-            ),
654
-        );
655
-        //add links to related models
656
-        if ($model->has_primary_key_field()) {
657
-            foreach ($this->get_model_version_info()->relation_settings($model) as $relation_name => $relation_obj) {
658
-                $related_model_part = Read::get_related_entity_name($relation_name, $relation_obj);
659
-                $links[\EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part] = array(
660
-                    array(
661
-                        'href'   => $this->get_versioned_link_to(
662
-                            \EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
663
-                            . '/'
664
-                            . $entity_array[$model->primary_key_name()]
665
-                            . '/'
666
-                            . $related_model_part
667
-                        ),
668
-                        'single' => $relation_obj instanceof \EE_Belongs_To_Relation ? true : false,
669
-                    ),
670
-                );
671
-            }
672
-        }
673
-        return $links;
674
-    }
675
-
676
-
677
-
678
-    /**
679
-     * Adds the included models indicated in the request to the entity provided
680
-     *
681
-     * @param \EEM_Base        $model
682
-     * @param \WP_REST_Request $rest_request
683
-     * @param array            $entity_array
684
-     * @param array            $db_row
685
-     * @return array the modified entity
686
-     */
687
-    protected function _include_requested_models(
688
-        \EEM_Base $model,
689
-        \WP_REST_Request $rest_request,
690
-        $entity_array,
691
-        $db_row = array()
692
-    ) {
693
-        //if $db_row not included, hope the entity array has what we need
694
-        if (! $db_row) {
695
-            $db_row = $entity_array;
696
-        }
697
-        $includes_for_this_model = $this->explode_and_get_items_prefixed_with($rest_request->get_param('include'), '');
698
-        $includes_for_this_model = $this->_remove_model_names_from_array($includes_for_this_model);
699
-        //if they passed in * or didn't specify any includes, return everything
700
-        if (! in_array('*', $includes_for_this_model)
701
-            && ! empty($includes_for_this_model)
702
-        ) {
703
-            if ($model->has_primary_key_field()) {
704
-                //always include the primary key. ya just gotta know that at least
705
-                $includes_for_this_model[] = $model->primary_key_name();
706
-            }
707
-            if ($this->explode_and_get_items_prefixed_with($rest_request->get_param('calculate'), '')) {
708
-                $includes_for_this_model[] = '_calculated_fields';
709
-            }
710
-            $entity_array = array_intersect_key($entity_array, array_flip($includes_for_this_model));
711
-        }
712
-        $relation_settings = $this->get_model_version_info()->relation_settings($model);
713
-        foreach ($relation_settings as $relation_name => $relation_obj) {
714
-            $related_fields_to_include = $this->explode_and_get_items_prefixed_with(
715
-                $rest_request->get_param('include'),
716
-                $relation_name
717
-            );
718
-            $related_fields_to_calculate = $this->explode_and_get_items_prefixed_with(
719
-                $rest_request->get_param('calculate'),
720
-                $relation_name
721
-            );
722
-            //did they specify they wanted to include a related model, or
723
-            //specific fields from a related model?
724
-            //or did they specify to calculate a field from a related model?
725
-            if ($related_fields_to_include || $related_fields_to_calculate) {
726
-                //if so, we should include at least some part of the related model
727
-                $pretend_related_request = new \WP_REST_Request();
728
-                $pretend_related_request->set_query_params(
729
-                    array(
730
-                        'caps'      => $rest_request->get_param('caps'),
731
-                        'include'   => $related_fields_to_include,
732
-                        'calculate' => $related_fields_to_calculate,
733
-                    )
734
-                );
735
-                $pretend_related_request->add_header('no_rest_headers', true);
736
-                $primary_model_query_params = $model->alter_query_params_to_restrict_by_ID(
737
-                    $model->get_index_primary_key_string(
738
-                        $model->deduce_fields_n_values_from_cols_n_values($db_row)
739
-                    )
740
-                );
741
-                $related_results = $this->_get_entities_from_relation(
742
-                    $primary_model_query_params,
743
-                    $relation_obj,
744
-                    $pretend_related_request
745
-                );
746
-                $entity_array[Read::get_related_entity_name($relation_name, $relation_obj)] = $related_results
747
-                                                                                              instanceof
748
-                                                                                              \WP_Error
749
-                    ? null
750
-                    : $related_results;
751
-            }
752
-        }
753
-        return $entity_array;
754
-    }
755
-
756
-
757
-
758
-    /**
759
-     * Returns a new array with all the names of models removed. Eg
760
-     * array( 'Event', 'Datetime.*', 'foobar' ) would become array( 'Datetime.*', 'foobar' )
761
-     *
762
-     * @param array $arr
763
-     * @return array
764
-     */
765
-    private function _remove_model_names_from_array($arr)
766
-    {
767
-        return array_diff($arr, array_keys(\EE_Registry::instance()->non_abstract_db_models));
768
-    }
769
-
770
-
771
-
772
-    /**
773
-     * Gets the calculated fields for the response
774
-     *
775
-     * @param \EEM_Base        $model
776
-     * @param array            $wpdb_row
777
-     * @param \WP_REST_Request $rest_request
778
-     * @return \stdClass the _calculations item in the entity
779
-     */
780
-    protected function _get_entity_calculations($model, $wpdb_row, $rest_request)
781
-    {
782
-        $calculated_fields = $this->explode_and_get_items_prefixed_with(
783
-            $rest_request->get_param('calculate'),
784
-            ''
785
-        );
786
-        //note: setting calculate=* doesn't do anything
787
-        $calculated_fields_to_return = new \stdClass();
788
-        foreach ($calculated_fields as $field_to_calculate) {
789
-            try {
790
-                $calculated_fields_to_return->$field_to_calculate = Model_Data_Translator::prepare_field_value_for_json(
791
-                    null,
792
-                    $this->_fields_calculator->retrieve_calculated_field_value(
793
-                        $model,
794
-                        $field_to_calculate,
795
-                        $wpdb_row,
796
-                        $rest_request,
797
-                        $this
798
-                    ),
799
-                    $this->get_model_version_info()->requested_version()
800
-                );
801
-            } catch (Rest_Exception $e) {
802
-                //if we don't have permission to read it, just leave it out. but let devs know about the problem
803
-                $this->_set_response_header(
804
-                    'Notices-Field-Calculation-Errors['
805
-                    . $e->get_string_code()
806
-                    . ']['
807
-                    . $model->get_this_model_name()
808
-                    . ']['
809
-                    . $field_to_calculate
810
-                    . ']',
811
-                    $e->getMessage(),
812
-                    true
813
-                );
814
-            }
815
-        }
816
-        return $calculated_fields_to_return;
817
-    }
818
-
819
-
820
-
821
-    /**
822
-     * Gets the full URL to the resource, taking the requested version into account
823
-     *
824
-     * @param string $link_part_after_version_and_slash eg "events/10/datetimes"
825
-     * @return string url eg "http://mysite.com/wp-json/ee/v4.6/events/10/datetimes"
826
-     */
827
-    public function get_versioned_link_to($link_part_after_version_and_slash)
828
-    {
829
-        return rest_url(
830
-            \EED_Core_Rest_Api::ee_api_namespace
831
-            . $this->get_model_version_info()->requested_version()
832
-            . '/'
833
-            . $link_part_after_version_and_slash
834
-        );
835
-    }
836
-
837
-
838
-
839
-    /**
840
-     * Gets the correct lowercase name for the relation in the API according
841
-     * to the relation's type
842
-     *
843
-     * @param string                  $relation_name
844
-     * @param \EE_Model_Relation_Base $relation_obj
845
-     * @return string
846
-     */
847
-    public static function get_related_entity_name($relation_name, $relation_obj)
848
-    {
849
-        if ($relation_obj instanceof \EE_Belongs_To_Relation) {
850
-            return strtolower($relation_name);
851
-        } else {
852
-            return \EEH_Inflector::pluralize_and_lower($relation_name);
853
-        }
854
-    }
855
-
856
-
857
-
858
-    /**
859
-     * Gets the one model object with the specified id for the specified model
860
-     *
861
-     * @param \EEM_Base        $model
862
-     * @param \WP_REST_Request $request
863
-     * @return array|\WP_Error
864
-     */
865
-    public function get_entity_from_model($model, $request)
866
-    {
867
-        $query_params = array(array($model->primary_key_name() => $request->get_param('id')), 'limit' => 1);
868
-        if ($model instanceof \EEM_Soft_Delete_Base) {
869
-            $query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($query_params);
870
-        }
871
-        $restricted_query_params = $query_params;
872
-        $restricted_query_params['caps'] = $this->validate_context($request->get_param('caps'));
873
-        $this->_set_debug_info('model query params', $restricted_query_params);
874
-        $model_rows = $model->get_all_wpdb_results($restricted_query_params);
875
-        if (! empty ($model_rows)) {
876
-            return $this->create_entity_from_wpdb_result(
877
-                $model,
878
-                array_shift($model_rows),
879
-                $request);
880
-        } else {
881
-            //ok let's test to see if we WOULD have found it, had we not had restrictions from missing capabilities
882
-            $lowercase_model_name = strtolower($model->get_this_model_name());
883
-            $model_rows_found_sans_restrictions = $model->get_all_wpdb_results($query_params);
884
-            if (! empty($model_rows_found_sans_restrictions)) {
885
-                //you got shafted- it existed but we didn't want to tell you!
886
-                return new \WP_Error(
887
-                    'rest_user_cannot_read',
888
-                    sprintf(
889
-                        __('Sorry, you cannot read this %1$s. Missing permissions are: %2$s', 'event_espresso'),
890
-                        strtolower($model->get_this_model_name()),
891
-                        Capabilities::get_missing_permissions_string(
892
-                            $model,
893
-                            $this->validate_context($request->get_param('caps')))
894
-                    ),
895
-                    array('status' => 403)
896
-                );
897
-            } else {
898
-                //it's not you. It just doesn't exist
899
-                return new \WP_Error(
900
-                    sprintf('rest_%s_invalid_id', $lowercase_model_name),
901
-                    sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
902
-                    array('status' => 404)
903
-                );
904
-            }
905
-        }
906
-    }
907
-
908
-
909
-
910
-    /**
911
-     * If a context is provided which isn't valid, maybe it was added in a future
912
-     * version so just treat it as a default read
913
-     *
914
-     * @param string $context
915
-     * @return string array key of EEM_Base::cap_contexts_to_cap_action_map()
916
-     */
917
-    public function validate_context($context)
918
-    {
919
-        if (! $context) {
920
-            $context = \EEM_Base::caps_read;
921
-        }
922
-        $valid_contexts = \EEM_Base::valid_cap_contexts();
923
-        if (in_array($context, $valid_contexts)) {
924
-            return $context;
925
-        } else {
926
-            return \EEM_Base::caps_read;
927
-        }
928
-    }
929
-
930
-
931
-
932
-    /**
933
-     * Verifies the passed in value is an allowable default where conditions value.
934
-     *
935
-     * @param $default_query_params
936
-     * @return string
937
-     */
938
-    public function validate_default_query_params($default_query_params)
939
-    {
940
-        $valid_default_where_conditions_for_api_calls = array(
941
-            \EEM_Base::default_where_conditions_all,
942
-            \EEM_Base::default_where_conditions_minimum_all,
943
-            \EEM_Base::default_where_conditions_minimum_others,
944
-        );
945
-        if (! $default_query_params) {
946
-            $default_query_params = \EEM_Base::default_where_conditions_all;
947
-        }
948
-        if (
949
-        in_array(
950
-            $default_query_params,
951
-            $valid_default_where_conditions_for_api_calls,
952
-            true
953
-        )
954
-        ) {
955
-            return $default_query_params;
956
-        } else {
957
-            return \EEM_Base::default_where_conditions_all;
958
-        }
959
-    }
960
-
961
-
962
-
963
-    /**
964
-     * Translates API filter get parameter into $query_params array used by EEM_Base::get_all().
965
-     * Note: right now the query parameter keys for fields (and related fields)
966
-     * can be left as-is, but it's quite possible this will change someday.
967
-     * Also, this method's contents might be candidate for moving to Model_Data_Translator
968
-     *
969
-     * @param \EEM_Base $model
970
-     * @param array     $query_parameters from $_GET parameter @see Read:handle_request_get_all
971
-     * @return array like what EEM_Base::get_all() expects or FALSE to indicate
972
-     *                                    that absolutely no results should be returned
973
-     * @throws \EE_Error
974
-     */
975
-    public function create_model_query_params($model, $query_parameters)
976
-    {
977
-        $model_query_params = array();
978
-        if (isset($query_parameters['where'])) {
979
-            $model_query_params[0] = Model_Data_Translator::prepare_conditions_query_params_for_models(
980
-                $query_parameters['where'],
981
-                $model,
982
-                $this->get_model_version_info()->requested_version()
983
-            );
984
-        }
985
-        if (isset($query_parameters['order_by'])) {
986
-            $order_by = $query_parameters['order_by'];
987
-        } elseif (isset($query_parameters['orderby'])) {
988
-            $order_by = $query_parameters['orderby'];
989
-        } else {
990
-            $order_by = null;
991
-        }
992
-        if ($order_by !== null) {
993
-            if (is_array($order_by)) {
994
-                $order_by = Model_Data_Translator::prepare_field_names_in_array_keys_from_json($order_by);
995
-            } else {
996
-                //it's a single item
997
-                $order_by = Model_Data_Translator::prepare_field_name_from_json($order_by);
998
-            }
999
-            $model_query_params['order_by'] = $order_by;
1000
-        }
1001
-        if (isset($query_parameters['group_by'])) {
1002
-            $group_by = $query_parameters['group_by'];
1003
-        } elseif (isset($query_parameters['groupby'])) {
1004
-            $group_by = $query_parameters['groupby'];
1005
-        } else {
1006
-            $group_by = array_keys($model->get_combined_primary_key_fields());
1007
-        }
1008
-        //make sure they're all real names
1009
-        if (is_array($group_by)) {
1010
-            $group_by = Model_Data_Translator::prepare_field_names_from_json($group_by);
1011
-        }
1012
-        if ($group_by !== null) {
1013
-            $model_query_params['group_by'] = $group_by;
1014
-        }
1015
-        if (isset($query_parameters['having'])) {
1016
-            $model_query_params['having'] = Model_Data_Translator::prepare_conditions_query_params_for_models(
1017
-                $query_parameters['having'],
1018
-                $model,
1019
-                $this->get_model_version_info()->requested_version()
1020
-            );
1021
-        }
1022
-        if (isset($query_parameters['order'])) {
1023
-            $model_query_params['order'] = $query_parameters['order'];
1024
-        }
1025
-        if (isset($query_parameters['mine'])) {
1026
-            $model_query_params = $model->alter_query_params_to_only_include_mine($model_query_params);
1027
-        }
1028
-        if (isset($query_parameters['limit'])) {
1029
-            //limit should be either a string like '23' or '23,43', or an array with two items in it
1030
-            if (! is_array($query_parameters['limit'])) {
1031
-                $limit_array = explode(',', (string)$query_parameters['limit']);
1032
-            } else {
1033
-                $limit_array = $query_parameters['limit'];
1034
-            }
1035
-            $sanitized_limit = array();
1036
-            foreach ($limit_array as $key => $limit_part) {
1037
-                if ($this->_debug_mode && (! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1038
-                    throw new \EE_Error(
1039
-                        sprintf(
1040
-                            __('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.',
1041
-                                'event_espresso'),
1042
-                            wp_json_encode($query_parameters['limit'])
1043
-                        )
1044
-                    );
1045
-                }
1046
-                $sanitized_limit[] = (int)$limit_part;
1047
-            }
1048
-            $model_query_params['limit'] = implode(',', $sanitized_limit);
1049
-        } else {
1050
-            $model_query_params['limit'] = \EED_Core_Rest_Api::get_default_query_limit();
1051
-        }
1052
-        if (isset($query_parameters['caps'])) {
1053
-            $model_query_params['caps'] = $this->validate_context($query_parameters['caps']);
1054
-        } else {
1055
-            $model_query_params['caps'] = \EEM_Base::caps_read;
1056
-        }
1057
-        if (isset($query_parameters['default_where_conditions'])) {
1058
-            $model_query_params['default_where_conditions'] = $this->validate_default_query_params($query_parameters['default_where_conditions']);
1059
-        }
1060
-        return apply_filters('FHEE__Read__create_model_query_params', $model_query_params, $query_parameters, $model);
1061
-    }
1062
-
1063
-
1064
-
1065
-    /**
1066
-     * Changes the REST-style query params for use in the models
1067
-     *
1068
-     * @deprecated
1069
-     * @param \EEM_Base $model
1070
-     * @param array     $query_params sub-array from @see EEM_Base::get_all()
1071
-     * @return array
1072
-     */
1073
-    public function prepare_rest_query_params_key_for_models($model, $query_params)
1074
-    {
1075
-        $model_ready_query_params = array();
1076
-        foreach ($query_params as $key => $value) {
1077
-            if (is_array($value)) {
1078
-                $model_ready_query_params[$key] = $this->prepare_rest_query_params_key_for_models($model, $value);
1079
-            } else {
1080
-                $model_ready_query_params[$key] = $value;
1081
-            }
1082
-        }
1083
-        return $model_ready_query_params;
1084
-    }
1085
-
1086
-
1087
-
1088
-    /**
1089
-     * @deprecated
1090
-     * @param $model
1091
-     * @param $query_params
1092
-     * @return array
1093
-     */
1094
-    public function prepare_rest_query_params_values_for_models($model, $query_params)
1095
-    {
1096
-        $model_ready_query_params = array();
1097
-        foreach ($query_params as $key => $value) {
1098
-            if (is_array($value)) {
1099
-                $model_ready_query_params[$key] = $this->prepare_rest_query_params_values_for_models($model, $value);
1100
-            } else {
1101
-                $model_ready_query_params[$key] = $value;
1102
-            }
1103
-        }
1104
-        return $model_ready_query_params;
1105
-    }
1106
-
1107
-
1108
-
1109
-    /**
1110
-     * Explodes the string on commas, and only returns items with $prefix followed by a period.
1111
-     * If no prefix is specified, returns items with no period.
1112
-     *
1113
-     * @param string|array $string_to_explode eg "jibba,jabba, blah, blaabla" or array('jibba', 'jabba' )
1114
-     * @param string       $prefix            "Event" or "foobar"
1115
-     * @return array $string_to_exploded exploded on COMMAS, and if a prefix was specified
1116
-     *                                        we only return strings starting with that and a period; if no prefix was
1117
-     *                                        specified we return all items containing NO periods
1118
-     */
1119
-    public function explode_and_get_items_prefixed_with($string_to_explode, $prefix)
1120
-    {
1121
-        if (is_string($string_to_explode)) {
1122
-            $exploded_contents = explode(',', $string_to_explode);
1123
-        } else if (is_array($string_to_explode)) {
1124
-            $exploded_contents = $string_to_explode;
1125
-        } else {
1126
-            $exploded_contents = array();
1127
-        }
1128
-        //if the string was empty, we want an empty array
1129
-        $exploded_contents = array_filter($exploded_contents);
1130
-        $contents_with_prefix = array();
1131
-        foreach ($exploded_contents as $item) {
1132
-            $item = trim($item);
1133
-            //if no prefix was provided, so we look for items with no "." in them
1134
-            if (! $prefix) {
1135
-                //does this item have a period?
1136
-                if (strpos($item, '.') === false) {
1137
-                    //if not, then its what we're looking for
1138
-                    $contents_with_prefix[] = $item;
1139
-                }
1140
-            } else if (strpos($item, $prefix . '.') === 0) {
1141
-                //this item has the prefix and a period, grab it
1142
-                $contents_with_prefix[] = substr(
1143
-                    $item,
1144
-                    strpos($item, $prefix . '.') + strlen($prefix . '.')
1145
-                );
1146
-            } else if ($item === $prefix) {
1147
-                //this item is JUST the prefix
1148
-                //so let's grab everything after, which is a blank string
1149
-                $contents_with_prefix[] = '';
1150
-            }
1151
-        }
1152
-        return $contents_with_prefix;
1153
-    }
1154
-
1155
-
1156
-
1157
-    /**
1158
-     * @deprecated since 4.8.36.rc.001 You should instead use Read::explode_and_get_items_prefixed_with.
1159
-     * Deprecated because its return values were really quite confusing- sometimes it returned
1160
-     * an empty array (when the include string was blank or '*') or sometimes it returned
1161
-     * array('*') (when you provided a model and a model of that kind was found).
1162
-     * Parses the $include_string so we fetch all the field names relating to THIS model
1163
-     * (ie have NO period in them), or for the provided model (ie start with the model
1164
-     * name and then a period).
1165
-     * @param string $include_string @see Read:handle_request_get_all
1166
-     * @param string $model_name
1167
-     * @return array of fields for this model. If $model_name is provided, then
1168
-     *                               the fields for that model, with the model's name removed from each.
1169
-     *                               If $include_string was blank or '*' returns an empty array
1170
-     */
1171
-    public function extract_includes_for_this_model($include_string, $model_name = null)
1172
-    {
1173
-        if (is_array($include_string)) {
1174
-            $include_string = implode(',', $include_string);
1175
-        }
1176
-        if ($include_string === '*' || $include_string === '') {
1177
-            return array();
1178
-        }
1179
-        $includes = explode(',', $include_string);
1180
-        $extracted_fields_to_include = array();
1181
-        if ($model_name) {
1182
-            foreach ($includes as $field_to_include) {
1183
-                $field_to_include = trim($field_to_include);
1184
-                if (strpos($field_to_include, $model_name . '.') === 0) {
1185
-                    //found the model name at the exact start
1186
-                    $field_sans_model_name = str_replace($model_name . '.', '', $field_to_include);
1187
-                    $extracted_fields_to_include[] = $field_sans_model_name;
1188
-                } elseif ($field_to_include == $model_name) {
1189
-                    $extracted_fields_to_include[] = '*';
1190
-                }
1191
-            }
1192
-        } else {
1193
-            //look for ones with no period
1194
-            foreach ($includes as $field_to_include) {
1195
-                $field_to_include = trim($field_to_include);
1196
-                if (
1197
-                    strpos($field_to_include, '.') === false
1198
-                    && ! $this->get_model_version_info()->is_model_name_in_this_version($field_to_include)
1199
-                ) {
1200
-                    $extracted_fields_to_include[] = $field_to_include;
1201
-                }
1202
-            }
1203
-        }
1204
-        return $extracted_fields_to_include;
1205
-    }
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->_add_extra_fields_to_schema(
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
+	 * Adds additional fields to the schema
125
+	 * The REST API returns a GMT value field for each datetime field in the resource.  Thus the description about this
126
+	 * needs to be added to the schema.
127
+	 *
128
+	 * @param \EEM_Base $model
129
+	 * @param string    $schema
130
+	 */
131
+	protected function _add_extra_fields_to_schema(\EEM_Base $model, $schema)
132
+	{
133
+		foreach ($this->get_model_version_info()->fields_on_model_in_this_version($model) as $field_name => $field) {
134
+			if ($field instanceof EE_Datetime_Field) {
135
+				$schema['properties'][$field_name . '_gmt'] = $field->getSchema();
136
+				//modify the description
137
+				$schema['properties'][$field_name . '_gmt']['description'] = sprintf(
138
+					esc_html__('%s - the value for this field is in GMT.', 'event_espresso'),
139
+					$field->get_nicename()
140
+				);
141
+			}
142
+		}
143
+		return $schema;
144
+	}
145
+
146
+
147
+
148
+
149
+	/**
150
+	 * Used to figure out the route from the request when a `WP_REST_Request` object is not available
151
+	 * @return string
152
+	 */
153
+	protected function get_route_from_request() {
154
+		if (isset($GLOBALS['wp'])
155
+			&& $GLOBALS['wp'] instanceof \WP
156
+			&& isset($GLOBALS['wp']->query_vars['rest_route'] )
157
+		) {
158
+			return $GLOBALS['wp']->query_vars['rest_route'];
159
+		} else {
160
+			return isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '/';
161
+		}
162
+	}
163
+
164
+
165
+
166
+	/**
167
+	 * Gets a single entity related to the model indicated in the path and its id
168
+	 *
169
+	 * @param \WP_REST_Request $request
170
+	 * @return \WP_REST_Response|\WP_Error
171
+	 */
172
+	public static function handle_request_get_one(\WP_REST_Request $request)
173
+	{
174
+		$controller = new Read();
175
+		try {
176
+			$matches = $controller->parse_route(
177
+				$request->get_route(),
178
+				'~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)~',
179
+				array('version', 'model', 'id'));
180
+			$controller->set_requested_version($matches['version']);
181
+			$model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']);
182
+			if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) {
183
+				return $controller->send_response(
184
+					new \WP_Error(
185
+						'endpoint_parsing_error',
186
+						sprintf(
187
+							__('There is no model for endpoint %s. Please contact event espresso support',
188
+								'event_espresso'),
189
+							$model_name_singular
190
+						)
191
+					)
192
+				);
193
+			}
194
+			return $controller->send_response(
195
+				$controller->get_entity_from_model(
196
+					$controller->get_model_version_info()->load_model($model_name_singular),
197
+					$request
198
+				)
199
+			);
200
+		} catch (\Exception $e) {
201
+			return $controller->send_response($e);
202
+		}
203
+	}
204
+
205
+
206
+
207
+	/**
208
+	 * Gets all the related entities (or if its a belongs-to relation just the one)
209
+	 * to the item with the given id
210
+	 *
211
+	 * @param \WP_REST_Request $request
212
+	 * @return \WP_REST_Response|\WP_Error
213
+	 */
214
+	public static function handle_request_get_related(\WP_REST_Request $request)
215
+	{
216
+		$controller = new Read();
217
+		try {
218
+			$matches = $controller->parse_route(
219
+				$request->get_route(),
220
+				'~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)/(.*)~',
221
+				array('version', 'model', 'id', 'related_model')
222
+			);
223
+			$controller->set_requested_version($matches['version']);
224
+			$main_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']);
225
+			if (! $controller->get_model_version_info()->is_model_name_in_this_version($main_model_name_singular)) {
226
+				return $controller->send_response(
227
+					new \WP_Error(
228
+						'endpoint_parsing_error',
229
+						sprintf(
230
+							__('There is no model for endpoint %s. Please contact event espresso support',
231
+								'event_espresso'),
232
+							$main_model_name_singular
233
+						)
234
+					)
235
+				);
236
+			}
237
+			$main_model = $controller->get_model_version_info()->load_model($main_model_name_singular);
238
+			//assume the related model name is plural and try to find the model's name
239
+			$related_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['related_model']);
240
+			if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) {
241
+				//so the word didn't singularize well. Maybe that's just because it's a singular word?
242
+				$related_model_name_singular = \EEH_Inflector::humanize($matches['related_model']);
243
+			}
244
+			if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) {
245
+				return $controller->send_response(
246
+					new \WP_Error(
247
+						'endpoint_parsing_error',
248
+						sprintf(
249
+							__('There is no model for endpoint %s. Please contact event espresso support',
250
+								'event_espresso'),
251
+							$related_model_name_singular
252
+						)
253
+					)
254
+				);
255
+			}
256
+			return $controller->send_response(
257
+				$controller->get_entities_from_relation(
258
+					$request->get_param('id'),
259
+					$main_model->related_settings_for($related_model_name_singular),
260
+					$request
261
+				)
262
+			);
263
+		} catch (\Exception $e) {
264
+			return $controller->send_response($e);
265
+		}
266
+	}
267
+
268
+
269
+
270
+	/**
271
+	 * Gets a collection for the given model and filters
272
+	 *
273
+	 * @param \EEM_Base        $model
274
+	 * @param \WP_REST_Request $request
275
+	 * @return array|\WP_Error
276
+	 */
277
+	public function get_entities_from_model($model, $request)
278
+	{
279
+		$query_params = $this->create_model_query_params($model, $request->get_params());
280
+		if (! Capabilities::current_user_has_partial_access_to($model, $query_params['caps'])) {
281
+			$model_name_plural = \EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
282
+			return new \WP_Error(
283
+				sprintf('rest_%s_cannot_list', $model_name_plural),
284
+				sprintf(
285
+					__('Sorry, you are not allowed to list %1$s. Missing permissions: %2$s', 'event_espresso'),
286
+					$model_name_plural,
287
+					Capabilities::get_missing_permissions_string($model, $query_params['caps'])
288
+				),
289
+				array('status' => 403)
290
+			);
291
+		}
292
+		if (! $request->get_header('no_rest_headers')) {
293
+			$this->_set_headers_from_query_params($model, $query_params);
294
+		}
295
+		/** @type array $results */
296
+		$results = $model->get_all_wpdb_results($query_params);
297
+		$nice_results = array();
298
+		foreach ($results as $result) {
299
+			$nice_results[] = $this->create_entity_from_wpdb_result(
300
+				$model,
301
+				$result,
302
+				$request
303
+			);
304
+		}
305
+		return $nice_results;
306
+	}
307
+
308
+
309
+
310
+	/**
311
+	 * @param array                   $primary_model_query_params query params for finding the item from which
312
+	 *                                                            relations will be based
313
+	 * @param \EE_Model_Relation_Base $relation
314
+	 * @param \WP_REST_Request        $request
315
+	 * @return \WP_Error|array
316
+	 */
317
+	protected function _get_entities_from_relation($primary_model_query_params, $relation, $request)
318
+	{
319
+		$context = $this->validate_context($request->get_param('caps'));
320
+		$model = $relation->get_this_model();
321
+		$related_model = $relation->get_other_model();
322
+		if (! isset($primary_model_query_params[0])) {
323
+			$primary_model_query_params[0] = array();
324
+		}
325
+		//check if they can access the 1st model object
326
+		$primary_model_query_params = array(
327
+			0       => $primary_model_query_params[0],
328
+			'limit' => 1,
329
+		);
330
+		if ($model instanceof \EEM_Soft_Delete_Base) {
331
+			$primary_model_query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($primary_model_query_params);
332
+		}
333
+		$restricted_query_params = $primary_model_query_params;
334
+		$restricted_query_params['caps'] = $context;
335
+		$this->_set_debug_info('main model query params', $restricted_query_params);
336
+		$this->_set_debug_info('missing caps', Capabilities::get_missing_permissions_string($related_model, $context));
337
+		if (
338
+		! (
339
+			Capabilities::current_user_has_partial_access_to($related_model, $context)
340
+			&& $model->exists($restricted_query_params)
341
+		)
342
+		) {
343
+			if ($relation instanceof \EE_Belongs_To_Relation) {
344
+				$related_model_name_maybe_plural = strtolower($related_model->get_this_model_name());
345
+			} else {
346
+				$related_model_name_maybe_plural = \EEH_Inflector::pluralize_and_lower($related_model->get_this_model_name());
347
+			}
348
+			return new \WP_Error(
349
+				sprintf('rest_%s_cannot_list', $related_model_name_maybe_plural),
350
+				sprintf(
351
+					__('Sorry, you are not allowed to list %1$s related to %2$s. Missing permissions: %3$s',
352
+						'event_espresso'),
353
+					$related_model_name_maybe_plural,
354
+					$relation->get_this_model()->get_this_model_name(),
355
+					implode(
356
+						',',
357
+						array_keys(
358
+							Capabilities::get_missing_permissions($related_model, $context)
359
+						)
360
+					)
361
+				),
362
+				array('status' => 403)
363
+			);
364
+		}
365
+		$query_params = $this->create_model_query_params($relation->get_other_model(), $request->get_params());
366
+		foreach ($primary_model_query_params[0] as $where_condition_key => $where_condition_value) {
367
+			$query_params[0][$relation->get_this_model()->get_this_model_name()
368
+							 . '.'
369
+							 . $where_condition_key] = $where_condition_value;
370
+		}
371
+		$query_params['default_where_conditions'] = 'none';
372
+		$query_params['caps'] = $context;
373
+		if (! $request->get_header('no_rest_headers')) {
374
+			$this->_set_headers_from_query_params($relation->get_other_model(), $query_params);
375
+		}
376
+		/** @type array $results */
377
+		$results = $relation->get_other_model()->get_all_wpdb_results($query_params);
378
+		$nice_results = array();
379
+		foreach ($results as $result) {
380
+			$nice_result = $this->create_entity_from_wpdb_result(
381
+				$relation->get_other_model(),
382
+				$result,
383
+				$request
384
+			);
385
+			if ($relation instanceof \EE_HABTM_Relation) {
386
+				//put the unusual stuff (properties from the HABTM relation) first, and make sure
387
+				//if there are conflicts we prefer the properties from the main model
388
+				$join_model_result = $this->create_entity_from_wpdb_result(
389
+					$relation->get_join_model(),
390
+					$result,
391
+					$request
392
+				);
393
+				$joined_result = array_merge($nice_result, $join_model_result);
394
+				//but keep the meta stuff from the main model
395
+				if (isset($nice_result['meta'])) {
396
+					$joined_result['meta'] = $nice_result['meta'];
397
+				}
398
+				$nice_result = $joined_result;
399
+			}
400
+			$nice_results[] = $nice_result;
401
+		}
402
+		if ($relation instanceof \EE_Belongs_To_Relation) {
403
+			return array_shift($nice_results);
404
+		} else {
405
+			return $nice_results;
406
+		}
407
+	}
408
+
409
+
410
+
411
+	/**
412
+	 * Gets the collection for given relation object
413
+	 * The same as Read::get_entities_from_model(), except if the relation
414
+	 * is a HABTM relation, in which case it merges any non-foreign-key fields from
415
+	 * the join-model-object into the results
416
+	 *
417
+	 * @param string                  $id the ID of the thing we are fetching related stuff from
418
+	 * @param \EE_Model_Relation_Base $relation
419
+	 * @param \WP_REST_Request        $request
420
+	 * @return array|\WP_Error
421
+	 * @throws \EE_Error
422
+	 */
423
+	public function get_entities_from_relation($id, $relation, $request)
424
+	{
425
+		if (! $relation->get_this_model()->has_primary_key_field()) {
426
+			throw new \EE_Error(
427
+				sprintf(
428
+					__('Read::get_entities_from_relation should only be called from a model with a primary key, it was called from %1$s',
429
+						'event_espresso'),
430
+					$relation->get_this_model()->get_this_model_name()
431
+				)
432
+			);
433
+		}
434
+		return $this->_get_entities_from_relation(
435
+			array(
436
+				array(
437
+					$relation->get_this_model()->primary_key_name() => $id,
438
+				),
439
+			),
440
+			$relation,
441
+			$request
442
+		);
443
+	}
444
+
445
+
446
+
447
+	/**
448
+	 * Sets the headers that are based on the model and query params,
449
+	 * like the total records. This should only be called on the original request
450
+	 * from the client, not on subsequent internal
451
+	 *
452
+	 * @param \EEM_Base $model
453
+	 * @param array     $query_params
454
+	 * @return void
455
+	 */
456
+	protected function _set_headers_from_query_params($model, $query_params)
457
+	{
458
+		$this->_set_debug_info('model query params', $query_params);
459
+		$this->_set_debug_info('missing caps',
460
+			Capabilities::get_missing_permissions_string($model, $query_params['caps']));
461
+		//normally the limit to a 2-part array, where the 2nd item is the limit
462
+		if (! isset($query_params['limit'])) {
463
+			$query_params['limit'] = \EED_Core_Rest_Api::get_default_query_limit();
464
+		}
465
+		if (is_array($query_params['limit'])) {
466
+			$limit_parts = $query_params['limit'];
467
+		} else {
468
+			$limit_parts = explode(',', $query_params['limit']);
469
+			if (count($limit_parts) == 1) {
470
+				$limit_parts = array(0, $limit_parts[0]);
471
+			}
472
+		}
473
+		//remove the group by and having parts of the query, as those will
474
+		//make the sql query return an array of values, instead of just a single value
475
+		unset($query_params['group_by'], $query_params['having'], $query_params['limit']);
476
+		$count = $model->count($query_params, null, true);
477
+		$pages = $count / $limit_parts[1];
478
+		$this->_set_response_header('Total', $count, false);
479
+		$this->_set_response_header('PageSize', $limit_parts[1], false);
480
+		$this->_set_response_header('TotalPages', ceil($pages), false);
481
+	}
482
+
483
+
484
+
485
+	/**
486
+	 * Changes database results into REST API entities
487
+	 *
488
+	 * @param \EEM_Base        $model
489
+	 * @param array            $db_row     like results from $wpdb->get_results()
490
+	 * @param \WP_REST_Request $rest_request
491
+	 * @param string           $deprecated no longer used
492
+	 * @return array ready for being converted into json for sending to client
493
+	 */
494
+	public function create_entity_from_wpdb_result($model, $db_row, $rest_request, $deprecated = null)
495
+	{
496
+		if (! $rest_request instanceof \WP_REST_Request) {
497
+			//ok so this was called in the old style, where the 3rd arg was
498
+			//$include, and the 4th arg was $context
499
+			//now setup the request just to avoid fatal errors, although we won't be able
500
+			//to truly make use of it because it's kinda devoid of info
501
+			$rest_request = new \WP_REST_Request();
502
+			$rest_request->set_param('include', $rest_request);
503
+			$rest_request->set_param('caps', $deprecated);
504
+		}
505
+		if ($rest_request->get_param('caps') == null) {
506
+			$rest_request->set_param('caps', \EEM_Base::caps_read);
507
+		}
508
+		$entity_array = $this->_create_bare_entity_from_wpdb_results($model, $db_row);
509
+		$entity_array = $this->_add_extra_fields($model, $db_row, $entity_array);
510
+		$entity_array['_links'] = $this->_get_entity_links($model, $db_row, $entity_array);
511
+		$entity_array['_calculated_fields'] = $this->_get_entity_calculations($model, $db_row, $rest_request);
512
+		$entity_array = $this->_include_requested_models($model, $rest_request, $entity_array, $db_row);
513
+		$entity_array = apply_filters(
514
+			'FHEE__Read__create_entity_from_wpdb_results__entity_before_inaccessible_field_removal',
515
+			$entity_array,
516
+			$model,
517
+			$rest_request->get_param('caps'),
518
+			$rest_request,
519
+			$this
520
+		);
521
+		$result_without_inaccessible_fields = Capabilities::filter_out_inaccessible_entity_fields(
522
+			$entity_array,
523
+			$model,
524
+			$rest_request->get_param('caps'),
525
+			$this->get_model_version_info(),
526
+			$model->get_index_primary_key_string(
527
+				$model->deduce_fields_n_values_from_cols_n_values($db_row)
528
+			)
529
+		);
530
+		$this->_set_debug_info(
531
+			'inaccessible fields',
532
+			array_keys(array_diff_key($entity_array, $result_without_inaccessible_fields))
533
+		);
534
+		return apply_filters(
535
+			'FHEE__Read__create_entity_from_wpdb_results__entity_return',
536
+			$result_without_inaccessible_fields,
537
+			$model,
538
+			$rest_request->get_param('caps')
539
+		);
540
+	}
541
+
542
+
543
+
544
+	/**
545
+	 * Creates a REST entity array (JSON object we're going to return in the response, but
546
+	 * for now still a PHP array, but soon enough we'll call json_encode on it, don't worry),
547
+	 * from $wpdb->get_row( $sql, ARRAY_A)
548
+	 *
549
+	 * @param \EEM_Base $model
550
+	 * @param array     $db_row
551
+	 * @return array entity mostly ready for converting to JSON and sending in the response
552
+	 */
553
+	protected function _create_bare_entity_from_wpdb_results(\EEM_Base $model, $db_row)
554
+	{
555
+		$result = $model->deduce_fields_n_values_from_cols_n_values($db_row);
556
+		$result = array_intersect_key($result,
557
+			$this->get_model_version_info()->fields_on_model_in_this_version($model));
558
+		foreach ($result as $field_name => $raw_field_value) {
559
+			$field_obj = $model->field_settings_for($field_name);
560
+			$field_value = $field_obj->prepare_for_set_from_db($raw_field_value);
561
+			if ($this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_ignored())) {
562
+				unset($result[$field_name]);
563
+			} elseif (
564
+			$this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_rendered_format())
565
+			) {
566
+				$result[$field_name] = array(
567
+					'raw'      => $field_obj->prepare_for_get($field_value),
568
+					'rendered' => $field_obj->prepare_for_pretty_echoing($field_value),
569
+				);
570
+			} elseif (
571
+			$this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_pretty_format())
572
+			) {
573
+				$result[$field_name] = array(
574
+					'raw'    => $field_obj->prepare_for_get($field_value),
575
+					'pretty' => $field_obj->prepare_for_pretty_echoing($field_value),
576
+				);
577
+			} elseif ($field_obj instanceof \EE_Datetime_Field) {
578
+				if ($field_value instanceof \DateTime) {
579
+					$timezone = $field_value->getTimezone();
580
+					$field_value->setTimezone(new \DateTimeZone('UTC'));
581
+					$result[$field_name . '_gmt'] = Model_Data_Translator::prepare_field_value_for_json(
582
+						$field_obj,
583
+						$field_value,
584
+						$this->get_model_version_info()->requested_version()
585
+					);
586
+					$field_value->setTimezone($timezone);
587
+					$result[$field_name] = Model_Data_Translator::prepare_field_value_for_json(
588
+						$field_obj,
589
+						$field_value,
590
+						$this->get_model_version_info()->requested_version()
591
+					);
592
+				}
593
+			} else {
594
+				$result[$field_name] = Model_Data_Translator::prepare_field_value_for_json(
595
+					$field_obj,
596
+					$field_obj->prepare_for_get($field_value),
597
+					$this->get_model_version_info()->requested_version()
598
+				);
599
+			}
600
+		}
601
+		return $result;
602
+	}
603
+
604
+
605
+
606
+	/**
607
+	 * Adds a few extra fields to the entity response
608
+	 *
609
+	 * @param \EEM_Base $model
610
+	 * @param array     $db_row
611
+	 * @param array     $entity_array
612
+	 * @return array modified entity
613
+	 */
614
+	protected function _add_extra_fields(\EEM_Base $model, $db_row, $entity_array)
615
+	{
616
+		if ($model instanceof \EEM_CPT_Base) {
617
+			$entity_array['link'] = get_permalink($db_row[$model->get_primary_key_field()->get_qualified_column()]);
618
+		}
619
+		return $entity_array;
620
+	}
621
+
622
+
623
+
624
+	/**
625
+	 * Gets links we want to add to the response
626
+	 *
627
+	 * @global \WP_REST_Server $wp_rest_server
628
+	 * @param \EEM_Base        $model
629
+	 * @param array            $db_row
630
+	 * @param array            $entity_array
631
+	 * @return array the _links item in the entity
632
+	 */
633
+	protected function _get_entity_links($model, $db_row, $entity_array)
634
+	{
635
+		//add basic links
636
+		$links = array();
637
+		if ($model->has_primary_key_field()) {
638
+			$links['self'] = array(
639
+				array(
640
+					'href' => $this->get_versioned_link_to(
641
+						\EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
642
+						. '/'
643
+						. $entity_array[$model->primary_key_name()]
644
+					),
645
+				),
646
+			);
647
+		}
648
+		$links['collection'] = array(
649
+			array(
650
+				'href' => $this->get_versioned_link_to(
651
+					\EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
652
+				),
653
+			),
654
+		);
655
+		//add links to related models
656
+		if ($model->has_primary_key_field()) {
657
+			foreach ($this->get_model_version_info()->relation_settings($model) as $relation_name => $relation_obj) {
658
+				$related_model_part = Read::get_related_entity_name($relation_name, $relation_obj);
659
+				$links[\EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part] = array(
660
+					array(
661
+						'href'   => $this->get_versioned_link_to(
662
+							\EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
663
+							. '/'
664
+							. $entity_array[$model->primary_key_name()]
665
+							. '/'
666
+							. $related_model_part
667
+						),
668
+						'single' => $relation_obj instanceof \EE_Belongs_To_Relation ? true : false,
669
+					),
670
+				);
671
+			}
672
+		}
673
+		return $links;
674
+	}
675
+
676
+
677
+
678
+	/**
679
+	 * Adds the included models indicated in the request to the entity provided
680
+	 *
681
+	 * @param \EEM_Base        $model
682
+	 * @param \WP_REST_Request $rest_request
683
+	 * @param array            $entity_array
684
+	 * @param array            $db_row
685
+	 * @return array the modified entity
686
+	 */
687
+	protected function _include_requested_models(
688
+		\EEM_Base $model,
689
+		\WP_REST_Request $rest_request,
690
+		$entity_array,
691
+		$db_row = array()
692
+	) {
693
+		//if $db_row not included, hope the entity array has what we need
694
+		if (! $db_row) {
695
+			$db_row = $entity_array;
696
+		}
697
+		$includes_for_this_model = $this->explode_and_get_items_prefixed_with($rest_request->get_param('include'), '');
698
+		$includes_for_this_model = $this->_remove_model_names_from_array($includes_for_this_model);
699
+		//if they passed in * or didn't specify any includes, return everything
700
+		if (! in_array('*', $includes_for_this_model)
701
+			&& ! empty($includes_for_this_model)
702
+		) {
703
+			if ($model->has_primary_key_field()) {
704
+				//always include the primary key. ya just gotta know that at least
705
+				$includes_for_this_model[] = $model->primary_key_name();
706
+			}
707
+			if ($this->explode_and_get_items_prefixed_with($rest_request->get_param('calculate'), '')) {
708
+				$includes_for_this_model[] = '_calculated_fields';
709
+			}
710
+			$entity_array = array_intersect_key($entity_array, array_flip($includes_for_this_model));
711
+		}
712
+		$relation_settings = $this->get_model_version_info()->relation_settings($model);
713
+		foreach ($relation_settings as $relation_name => $relation_obj) {
714
+			$related_fields_to_include = $this->explode_and_get_items_prefixed_with(
715
+				$rest_request->get_param('include'),
716
+				$relation_name
717
+			);
718
+			$related_fields_to_calculate = $this->explode_and_get_items_prefixed_with(
719
+				$rest_request->get_param('calculate'),
720
+				$relation_name
721
+			);
722
+			//did they specify they wanted to include a related model, or
723
+			//specific fields from a related model?
724
+			//or did they specify to calculate a field from a related model?
725
+			if ($related_fields_to_include || $related_fields_to_calculate) {
726
+				//if so, we should include at least some part of the related model
727
+				$pretend_related_request = new \WP_REST_Request();
728
+				$pretend_related_request->set_query_params(
729
+					array(
730
+						'caps'      => $rest_request->get_param('caps'),
731
+						'include'   => $related_fields_to_include,
732
+						'calculate' => $related_fields_to_calculate,
733
+					)
734
+				);
735
+				$pretend_related_request->add_header('no_rest_headers', true);
736
+				$primary_model_query_params = $model->alter_query_params_to_restrict_by_ID(
737
+					$model->get_index_primary_key_string(
738
+						$model->deduce_fields_n_values_from_cols_n_values($db_row)
739
+					)
740
+				);
741
+				$related_results = $this->_get_entities_from_relation(
742
+					$primary_model_query_params,
743
+					$relation_obj,
744
+					$pretend_related_request
745
+				);
746
+				$entity_array[Read::get_related_entity_name($relation_name, $relation_obj)] = $related_results
747
+																							  instanceof
748
+																							  \WP_Error
749
+					? null
750
+					: $related_results;
751
+			}
752
+		}
753
+		return $entity_array;
754
+	}
755
+
756
+
757
+
758
+	/**
759
+	 * Returns a new array with all the names of models removed. Eg
760
+	 * array( 'Event', 'Datetime.*', 'foobar' ) would become array( 'Datetime.*', 'foobar' )
761
+	 *
762
+	 * @param array $arr
763
+	 * @return array
764
+	 */
765
+	private function _remove_model_names_from_array($arr)
766
+	{
767
+		return array_diff($arr, array_keys(\EE_Registry::instance()->non_abstract_db_models));
768
+	}
769
+
770
+
771
+
772
+	/**
773
+	 * Gets the calculated fields for the response
774
+	 *
775
+	 * @param \EEM_Base        $model
776
+	 * @param array            $wpdb_row
777
+	 * @param \WP_REST_Request $rest_request
778
+	 * @return \stdClass the _calculations item in the entity
779
+	 */
780
+	protected function _get_entity_calculations($model, $wpdb_row, $rest_request)
781
+	{
782
+		$calculated_fields = $this->explode_and_get_items_prefixed_with(
783
+			$rest_request->get_param('calculate'),
784
+			''
785
+		);
786
+		//note: setting calculate=* doesn't do anything
787
+		$calculated_fields_to_return = new \stdClass();
788
+		foreach ($calculated_fields as $field_to_calculate) {
789
+			try {
790
+				$calculated_fields_to_return->$field_to_calculate = Model_Data_Translator::prepare_field_value_for_json(
791
+					null,
792
+					$this->_fields_calculator->retrieve_calculated_field_value(
793
+						$model,
794
+						$field_to_calculate,
795
+						$wpdb_row,
796
+						$rest_request,
797
+						$this
798
+					),
799
+					$this->get_model_version_info()->requested_version()
800
+				);
801
+			} catch (Rest_Exception $e) {
802
+				//if we don't have permission to read it, just leave it out. but let devs know about the problem
803
+				$this->_set_response_header(
804
+					'Notices-Field-Calculation-Errors['
805
+					. $e->get_string_code()
806
+					. ']['
807
+					. $model->get_this_model_name()
808
+					. ']['
809
+					. $field_to_calculate
810
+					. ']',
811
+					$e->getMessage(),
812
+					true
813
+				);
814
+			}
815
+		}
816
+		return $calculated_fields_to_return;
817
+	}
818
+
819
+
820
+
821
+	/**
822
+	 * Gets the full URL to the resource, taking the requested version into account
823
+	 *
824
+	 * @param string $link_part_after_version_and_slash eg "events/10/datetimes"
825
+	 * @return string url eg "http://mysite.com/wp-json/ee/v4.6/events/10/datetimes"
826
+	 */
827
+	public function get_versioned_link_to($link_part_after_version_and_slash)
828
+	{
829
+		return rest_url(
830
+			\EED_Core_Rest_Api::ee_api_namespace
831
+			. $this->get_model_version_info()->requested_version()
832
+			. '/'
833
+			. $link_part_after_version_and_slash
834
+		);
835
+	}
836
+
837
+
838
+
839
+	/**
840
+	 * Gets the correct lowercase name for the relation in the API according
841
+	 * to the relation's type
842
+	 *
843
+	 * @param string                  $relation_name
844
+	 * @param \EE_Model_Relation_Base $relation_obj
845
+	 * @return string
846
+	 */
847
+	public static function get_related_entity_name($relation_name, $relation_obj)
848
+	{
849
+		if ($relation_obj instanceof \EE_Belongs_To_Relation) {
850
+			return strtolower($relation_name);
851
+		} else {
852
+			return \EEH_Inflector::pluralize_and_lower($relation_name);
853
+		}
854
+	}
855
+
856
+
857
+
858
+	/**
859
+	 * Gets the one model object with the specified id for the specified model
860
+	 *
861
+	 * @param \EEM_Base        $model
862
+	 * @param \WP_REST_Request $request
863
+	 * @return array|\WP_Error
864
+	 */
865
+	public function get_entity_from_model($model, $request)
866
+	{
867
+		$query_params = array(array($model->primary_key_name() => $request->get_param('id')), 'limit' => 1);
868
+		if ($model instanceof \EEM_Soft_Delete_Base) {
869
+			$query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($query_params);
870
+		}
871
+		$restricted_query_params = $query_params;
872
+		$restricted_query_params['caps'] = $this->validate_context($request->get_param('caps'));
873
+		$this->_set_debug_info('model query params', $restricted_query_params);
874
+		$model_rows = $model->get_all_wpdb_results($restricted_query_params);
875
+		if (! empty ($model_rows)) {
876
+			return $this->create_entity_from_wpdb_result(
877
+				$model,
878
+				array_shift($model_rows),
879
+				$request);
880
+		} else {
881
+			//ok let's test to see if we WOULD have found it, had we not had restrictions from missing capabilities
882
+			$lowercase_model_name = strtolower($model->get_this_model_name());
883
+			$model_rows_found_sans_restrictions = $model->get_all_wpdb_results($query_params);
884
+			if (! empty($model_rows_found_sans_restrictions)) {
885
+				//you got shafted- it existed but we didn't want to tell you!
886
+				return new \WP_Error(
887
+					'rest_user_cannot_read',
888
+					sprintf(
889
+						__('Sorry, you cannot read this %1$s. Missing permissions are: %2$s', 'event_espresso'),
890
+						strtolower($model->get_this_model_name()),
891
+						Capabilities::get_missing_permissions_string(
892
+							$model,
893
+							$this->validate_context($request->get_param('caps')))
894
+					),
895
+					array('status' => 403)
896
+				);
897
+			} else {
898
+				//it's not you. It just doesn't exist
899
+				return new \WP_Error(
900
+					sprintf('rest_%s_invalid_id', $lowercase_model_name),
901
+					sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
902
+					array('status' => 404)
903
+				);
904
+			}
905
+		}
906
+	}
907
+
908
+
909
+
910
+	/**
911
+	 * If a context is provided which isn't valid, maybe it was added in a future
912
+	 * version so just treat it as a default read
913
+	 *
914
+	 * @param string $context
915
+	 * @return string array key of EEM_Base::cap_contexts_to_cap_action_map()
916
+	 */
917
+	public function validate_context($context)
918
+	{
919
+		if (! $context) {
920
+			$context = \EEM_Base::caps_read;
921
+		}
922
+		$valid_contexts = \EEM_Base::valid_cap_contexts();
923
+		if (in_array($context, $valid_contexts)) {
924
+			return $context;
925
+		} else {
926
+			return \EEM_Base::caps_read;
927
+		}
928
+	}
929
+
930
+
931
+
932
+	/**
933
+	 * Verifies the passed in value is an allowable default where conditions value.
934
+	 *
935
+	 * @param $default_query_params
936
+	 * @return string
937
+	 */
938
+	public function validate_default_query_params($default_query_params)
939
+	{
940
+		$valid_default_where_conditions_for_api_calls = array(
941
+			\EEM_Base::default_where_conditions_all,
942
+			\EEM_Base::default_where_conditions_minimum_all,
943
+			\EEM_Base::default_where_conditions_minimum_others,
944
+		);
945
+		if (! $default_query_params) {
946
+			$default_query_params = \EEM_Base::default_where_conditions_all;
947
+		}
948
+		if (
949
+		in_array(
950
+			$default_query_params,
951
+			$valid_default_where_conditions_for_api_calls,
952
+			true
953
+		)
954
+		) {
955
+			return $default_query_params;
956
+		} else {
957
+			return \EEM_Base::default_where_conditions_all;
958
+		}
959
+	}
960
+
961
+
962
+
963
+	/**
964
+	 * Translates API filter get parameter into $query_params array used by EEM_Base::get_all().
965
+	 * Note: right now the query parameter keys for fields (and related fields)
966
+	 * can be left as-is, but it's quite possible this will change someday.
967
+	 * Also, this method's contents might be candidate for moving to Model_Data_Translator
968
+	 *
969
+	 * @param \EEM_Base $model
970
+	 * @param array     $query_parameters from $_GET parameter @see Read:handle_request_get_all
971
+	 * @return array like what EEM_Base::get_all() expects or FALSE to indicate
972
+	 *                                    that absolutely no results should be returned
973
+	 * @throws \EE_Error
974
+	 */
975
+	public function create_model_query_params($model, $query_parameters)
976
+	{
977
+		$model_query_params = array();
978
+		if (isset($query_parameters['where'])) {
979
+			$model_query_params[0] = Model_Data_Translator::prepare_conditions_query_params_for_models(
980
+				$query_parameters['where'],
981
+				$model,
982
+				$this->get_model_version_info()->requested_version()
983
+			);
984
+		}
985
+		if (isset($query_parameters['order_by'])) {
986
+			$order_by = $query_parameters['order_by'];
987
+		} elseif (isset($query_parameters['orderby'])) {
988
+			$order_by = $query_parameters['orderby'];
989
+		} else {
990
+			$order_by = null;
991
+		}
992
+		if ($order_by !== null) {
993
+			if (is_array($order_by)) {
994
+				$order_by = Model_Data_Translator::prepare_field_names_in_array_keys_from_json($order_by);
995
+			} else {
996
+				//it's a single item
997
+				$order_by = Model_Data_Translator::prepare_field_name_from_json($order_by);
998
+			}
999
+			$model_query_params['order_by'] = $order_by;
1000
+		}
1001
+		if (isset($query_parameters['group_by'])) {
1002
+			$group_by = $query_parameters['group_by'];
1003
+		} elseif (isset($query_parameters['groupby'])) {
1004
+			$group_by = $query_parameters['groupby'];
1005
+		} else {
1006
+			$group_by = array_keys($model->get_combined_primary_key_fields());
1007
+		}
1008
+		//make sure they're all real names
1009
+		if (is_array($group_by)) {
1010
+			$group_by = Model_Data_Translator::prepare_field_names_from_json($group_by);
1011
+		}
1012
+		if ($group_by !== null) {
1013
+			$model_query_params['group_by'] = $group_by;
1014
+		}
1015
+		if (isset($query_parameters['having'])) {
1016
+			$model_query_params['having'] = Model_Data_Translator::prepare_conditions_query_params_for_models(
1017
+				$query_parameters['having'],
1018
+				$model,
1019
+				$this->get_model_version_info()->requested_version()
1020
+			);
1021
+		}
1022
+		if (isset($query_parameters['order'])) {
1023
+			$model_query_params['order'] = $query_parameters['order'];
1024
+		}
1025
+		if (isset($query_parameters['mine'])) {
1026
+			$model_query_params = $model->alter_query_params_to_only_include_mine($model_query_params);
1027
+		}
1028
+		if (isset($query_parameters['limit'])) {
1029
+			//limit should be either a string like '23' or '23,43', or an array with two items in it
1030
+			if (! is_array($query_parameters['limit'])) {
1031
+				$limit_array = explode(',', (string)$query_parameters['limit']);
1032
+			} else {
1033
+				$limit_array = $query_parameters['limit'];
1034
+			}
1035
+			$sanitized_limit = array();
1036
+			foreach ($limit_array as $key => $limit_part) {
1037
+				if ($this->_debug_mode && (! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1038
+					throw new \EE_Error(
1039
+						sprintf(
1040
+							__('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.',
1041
+								'event_espresso'),
1042
+							wp_json_encode($query_parameters['limit'])
1043
+						)
1044
+					);
1045
+				}
1046
+				$sanitized_limit[] = (int)$limit_part;
1047
+			}
1048
+			$model_query_params['limit'] = implode(',', $sanitized_limit);
1049
+		} else {
1050
+			$model_query_params['limit'] = \EED_Core_Rest_Api::get_default_query_limit();
1051
+		}
1052
+		if (isset($query_parameters['caps'])) {
1053
+			$model_query_params['caps'] = $this->validate_context($query_parameters['caps']);
1054
+		} else {
1055
+			$model_query_params['caps'] = \EEM_Base::caps_read;
1056
+		}
1057
+		if (isset($query_parameters['default_where_conditions'])) {
1058
+			$model_query_params['default_where_conditions'] = $this->validate_default_query_params($query_parameters['default_where_conditions']);
1059
+		}
1060
+		return apply_filters('FHEE__Read__create_model_query_params', $model_query_params, $query_parameters, $model);
1061
+	}
1062
+
1063
+
1064
+
1065
+	/**
1066
+	 * Changes the REST-style query params for use in the models
1067
+	 *
1068
+	 * @deprecated
1069
+	 * @param \EEM_Base $model
1070
+	 * @param array     $query_params sub-array from @see EEM_Base::get_all()
1071
+	 * @return array
1072
+	 */
1073
+	public function prepare_rest_query_params_key_for_models($model, $query_params)
1074
+	{
1075
+		$model_ready_query_params = array();
1076
+		foreach ($query_params as $key => $value) {
1077
+			if (is_array($value)) {
1078
+				$model_ready_query_params[$key] = $this->prepare_rest_query_params_key_for_models($model, $value);
1079
+			} else {
1080
+				$model_ready_query_params[$key] = $value;
1081
+			}
1082
+		}
1083
+		return $model_ready_query_params;
1084
+	}
1085
+
1086
+
1087
+
1088
+	/**
1089
+	 * @deprecated
1090
+	 * @param $model
1091
+	 * @param $query_params
1092
+	 * @return array
1093
+	 */
1094
+	public function prepare_rest_query_params_values_for_models($model, $query_params)
1095
+	{
1096
+		$model_ready_query_params = array();
1097
+		foreach ($query_params as $key => $value) {
1098
+			if (is_array($value)) {
1099
+				$model_ready_query_params[$key] = $this->prepare_rest_query_params_values_for_models($model, $value);
1100
+			} else {
1101
+				$model_ready_query_params[$key] = $value;
1102
+			}
1103
+		}
1104
+		return $model_ready_query_params;
1105
+	}
1106
+
1107
+
1108
+
1109
+	/**
1110
+	 * Explodes the string on commas, and only returns items with $prefix followed by a period.
1111
+	 * If no prefix is specified, returns items with no period.
1112
+	 *
1113
+	 * @param string|array $string_to_explode eg "jibba,jabba, blah, blaabla" or array('jibba', 'jabba' )
1114
+	 * @param string       $prefix            "Event" or "foobar"
1115
+	 * @return array $string_to_exploded exploded on COMMAS, and if a prefix was specified
1116
+	 *                                        we only return strings starting with that and a period; if no prefix was
1117
+	 *                                        specified we return all items containing NO periods
1118
+	 */
1119
+	public function explode_and_get_items_prefixed_with($string_to_explode, $prefix)
1120
+	{
1121
+		if (is_string($string_to_explode)) {
1122
+			$exploded_contents = explode(',', $string_to_explode);
1123
+		} else if (is_array($string_to_explode)) {
1124
+			$exploded_contents = $string_to_explode;
1125
+		} else {
1126
+			$exploded_contents = array();
1127
+		}
1128
+		//if the string was empty, we want an empty array
1129
+		$exploded_contents = array_filter($exploded_contents);
1130
+		$contents_with_prefix = array();
1131
+		foreach ($exploded_contents as $item) {
1132
+			$item = trim($item);
1133
+			//if no prefix was provided, so we look for items with no "." in them
1134
+			if (! $prefix) {
1135
+				//does this item have a period?
1136
+				if (strpos($item, '.') === false) {
1137
+					//if not, then its what we're looking for
1138
+					$contents_with_prefix[] = $item;
1139
+				}
1140
+			} else if (strpos($item, $prefix . '.') === 0) {
1141
+				//this item has the prefix and a period, grab it
1142
+				$contents_with_prefix[] = substr(
1143
+					$item,
1144
+					strpos($item, $prefix . '.') + strlen($prefix . '.')
1145
+				);
1146
+			} else if ($item === $prefix) {
1147
+				//this item is JUST the prefix
1148
+				//so let's grab everything after, which is a blank string
1149
+				$contents_with_prefix[] = '';
1150
+			}
1151
+		}
1152
+		return $contents_with_prefix;
1153
+	}
1154
+
1155
+
1156
+
1157
+	/**
1158
+	 * @deprecated since 4.8.36.rc.001 You should instead use Read::explode_and_get_items_prefixed_with.
1159
+	 * Deprecated because its return values were really quite confusing- sometimes it returned
1160
+	 * an empty array (when the include string was blank or '*') or sometimes it returned
1161
+	 * array('*') (when you provided a model and a model of that kind was found).
1162
+	 * Parses the $include_string so we fetch all the field names relating to THIS model
1163
+	 * (ie have NO period in them), or for the provided model (ie start with the model
1164
+	 * name and then a period).
1165
+	 * @param string $include_string @see Read:handle_request_get_all
1166
+	 * @param string $model_name
1167
+	 * @return array of fields for this model. If $model_name is provided, then
1168
+	 *                               the fields for that model, with the model's name removed from each.
1169
+	 *                               If $include_string was blank or '*' returns an empty array
1170
+	 */
1171
+	public function extract_includes_for_this_model($include_string, $model_name = null)
1172
+	{
1173
+		if (is_array($include_string)) {
1174
+			$include_string = implode(',', $include_string);
1175
+		}
1176
+		if ($include_string === '*' || $include_string === '') {
1177
+			return array();
1178
+		}
1179
+		$includes = explode(',', $include_string);
1180
+		$extracted_fields_to_include = array();
1181
+		if ($model_name) {
1182
+			foreach ($includes as $field_to_include) {
1183
+				$field_to_include = trim($field_to_include);
1184
+				if (strpos($field_to_include, $model_name . '.') === 0) {
1185
+					//found the model name at the exact start
1186
+					$field_sans_model_name = str_replace($model_name . '.', '', $field_to_include);
1187
+					$extracted_fields_to_include[] = $field_sans_model_name;
1188
+				} elseif ($field_to_include == $model_name) {
1189
+					$extracted_fields_to_include[] = '*';
1190
+				}
1191
+			}
1192
+		} else {
1193
+			//look for ones with no period
1194
+			foreach ($includes as $field_to_include) {
1195
+				$field_to_include = trim($field_to_include);
1196
+				if (
1197
+					strpos($field_to_include, '.') === false
1198
+					&& ! $this->get_model_version_info()->is_model_name_in_this_version($field_to_include)
1199
+				) {
1200
+					$extracted_fields_to_include[] = $field_to_include;
1201
+				}
1202
+			}
1203
+		}
1204
+		return $extracted_fields_to_include;
1205
+	}
1206 1206
 }
1207 1207
 
1208 1208
 
Please login to merge, or discard this patch.
Spacing   +37 added lines, -37 removed lines patch added patch discarded remove patch
@@ -8,7 +8,7 @@  discard block
 block discarded – undo
8 8
 use EventEspresso\core\entities\models\JsonModelSchema;
9 9
 use EE_Datetime_Field;
10 10
 
11
-if (! defined('EVENT_ESPRESSO_VERSION')) {
11
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
12 12
     exit('No direct script access allowed');
13 13
 }
14 14
 
@@ -57,12 +57,12 @@  discard block
 block discarded – undo
57 57
         try {
58 58
             $matches = $controller->parse_route(
59 59
                 $request->get_route(),
60
-                '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)~',
60
+                '~'.\EED_Core_Rest_Api::ee_api_namespace_for_regex.'(.*)~',
61 61
                 array('version', 'model')
62 62
             );
63 63
             $controller->set_requested_version($matches['version']);
64 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)) {
65
+            if ( ! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) {
66 66
                 return $controller->send_response(
67 67
                     new \WP_Error(
68 68
                         'endpoint_parsing_error',
@@ -98,7 +98,7 @@  discard block
 block discarded – undo
98 98
         $controller = new Read();
99 99
         try {
100 100
             $controller->set_requested_version($version);
101
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name)) {
101
+            if ( ! $controller->get_model_version_info()->is_model_name_in_this_version($model_name)) {
102 102
                 return array();
103 103
             }
104 104
             //get the model for this version
@@ -132,9 +132,9 @@  discard block
 block discarded – undo
132 132
     {
133 133
         foreach ($this->get_model_version_info()->fields_on_model_in_this_version($model) as $field_name => $field) {
134 134
             if ($field instanceof EE_Datetime_Field) {
135
-                $schema['properties'][$field_name . '_gmt'] = $field->getSchema();
135
+                $schema['properties'][$field_name.'_gmt'] = $field->getSchema();
136 136
                 //modify the description
137
-                $schema['properties'][$field_name . '_gmt']['description'] = sprintf(
137
+                $schema['properties'][$field_name.'_gmt']['description'] = sprintf(
138 138
                     esc_html__('%s - the value for this field is in GMT.', 'event_espresso'),
139 139
                     $field->get_nicename()
140 140
                 );
@@ -153,7 +153,7 @@  discard block
 block discarded – undo
153 153
     protected function get_route_from_request() {
154 154
         if (isset($GLOBALS['wp'])
155 155
             && $GLOBALS['wp'] instanceof \WP
156
-            && isset($GLOBALS['wp']->query_vars['rest_route'] )
156
+            && isset($GLOBALS['wp']->query_vars['rest_route'])
157 157
         ) {
158 158
             return $GLOBALS['wp']->query_vars['rest_route'];
159 159
         } else {
@@ -175,11 +175,11 @@  discard block
 block discarded – undo
175 175
         try {
176 176
             $matches = $controller->parse_route(
177 177
                 $request->get_route(),
178
-                '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)~',
178
+                '~'.\EED_Core_Rest_Api::ee_api_namespace_for_regex.'(.*)/(.*)~',
179 179
                 array('version', 'model', 'id'));
180 180
             $controller->set_requested_version($matches['version']);
181 181
             $model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']);
182
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) {
182
+            if ( ! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) {
183 183
                 return $controller->send_response(
184 184
                     new \WP_Error(
185 185
                         'endpoint_parsing_error',
@@ -217,12 +217,12 @@  discard block
 block discarded – undo
217 217
         try {
218 218
             $matches = $controller->parse_route(
219 219
                 $request->get_route(),
220
-                '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)/(.*)~',
220
+                '~'.\EED_Core_Rest_Api::ee_api_namespace_for_regex.'(.*)/(.*)/(.*)~',
221 221
                 array('version', 'model', 'id', 'related_model')
222 222
             );
223 223
             $controller->set_requested_version($matches['version']);
224 224
             $main_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']);
225
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($main_model_name_singular)) {
225
+            if ( ! $controller->get_model_version_info()->is_model_name_in_this_version($main_model_name_singular)) {
226 226
                 return $controller->send_response(
227 227
                     new \WP_Error(
228 228
                         'endpoint_parsing_error',
@@ -237,11 +237,11 @@  discard block
 block discarded – undo
237 237
             $main_model = $controller->get_model_version_info()->load_model($main_model_name_singular);
238 238
             //assume the related model name is plural and try to find the model's name
239 239
             $related_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['related_model']);
240
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) {
240
+            if ( ! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) {
241 241
                 //so the word didn't singularize well. Maybe that's just because it's a singular word?
242 242
                 $related_model_name_singular = \EEH_Inflector::humanize($matches['related_model']);
243 243
             }
244
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) {
244
+            if ( ! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) {
245 245
                 return $controller->send_response(
246 246
                     new \WP_Error(
247 247
                         'endpoint_parsing_error',
@@ -277,7 +277,7 @@  discard block
 block discarded – undo
277 277
     public function get_entities_from_model($model, $request)
278 278
     {
279 279
         $query_params = $this->create_model_query_params($model, $request->get_params());
280
-        if (! Capabilities::current_user_has_partial_access_to($model, $query_params['caps'])) {
280
+        if ( ! Capabilities::current_user_has_partial_access_to($model, $query_params['caps'])) {
281 281
             $model_name_plural = \EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
282 282
             return new \WP_Error(
283 283
                 sprintf('rest_%s_cannot_list', $model_name_plural),
@@ -289,7 +289,7 @@  discard block
 block discarded – undo
289 289
                 array('status' => 403)
290 290
             );
291 291
         }
292
-        if (! $request->get_header('no_rest_headers')) {
292
+        if ( ! $request->get_header('no_rest_headers')) {
293 293
             $this->_set_headers_from_query_params($model, $query_params);
294 294
         }
295 295
         /** @type array $results */
@@ -319,7 +319,7 @@  discard block
 block discarded – undo
319 319
         $context = $this->validate_context($request->get_param('caps'));
320 320
         $model = $relation->get_this_model();
321 321
         $related_model = $relation->get_other_model();
322
-        if (! isset($primary_model_query_params[0])) {
322
+        if ( ! isset($primary_model_query_params[0])) {
323 323
             $primary_model_query_params[0] = array();
324 324
         }
325 325
         //check if they can access the 1st model object
@@ -370,7 +370,7 @@  discard block
 block discarded – undo
370 370
         }
371 371
         $query_params['default_where_conditions'] = 'none';
372 372
         $query_params['caps'] = $context;
373
-        if (! $request->get_header('no_rest_headers')) {
373
+        if ( ! $request->get_header('no_rest_headers')) {
374 374
             $this->_set_headers_from_query_params($relation->get_other_model(), $query_params);
375 375
         }
376 376
         /** @type array $results */
@@ -422,7 +422,7 @@  discard block
 block discarded – undo
422 422
      */
423 423
     public function get_entities_from_relation($id, $relation, $request)
424 424
     {
425
-        if (! $relation->get_this_model()->has_primary_key_field()) {
425
+        if ( ! $relation->get_this_model()->has_primary_key_field()) {
426 426
             throw new \EE_Error(
427 427
                 sprintf(
428 428
                     __('Read::get_entities_from_relation should only be called from a model with a primary key, it was called from %1$s',
@@ -459,7 +459,7 @@  discard block
 block discarded – undo
459 459
         $this->_set_debug_info('missing caps',
460 460
             Capabilities::get_missing_permissions_string($model, $query_params['caps']));
461 461
         //normally the limit to a 2-part array, where the 2nd item is the limit
462
-        if (! isset($query_params['limit'])) {
462
+        if ( ! isset($query_params['limit'])) {
463 463
             $query_params['limit'] = \EED_Core_Rest_Api::get_default_query_limit();
464 464
         }
465 465
         if (is_array($query_params['limit'])) {
@@ -493,7 +493,7 @@  discard block
 block discarded – undo
493 493
      */
494 494
     public function create_entity_from_wpdb_result($model, $db_row, $rest_request, $deprecated = null)
495 495
     {
496
-        if (! $rest_request instanceof \WP_REST_Request) {
496
+        if ( ! $rest_request instanceof \WP_REST_Request) {
497 497
             //ok so this was called in the old style, where the 3rd arg was
498 498
             //$include, and the 4th arg was $context
499 499
             //now setup the request just to avoid fatal errors, although we won't be able
@@ -578,7 +578,7 @@  discard block
 block discarded – undo
578 578
                 if ($field_value instanceof \DateTime) {
579 579
                     $timezone = $field_value->getTimezone();
580 580
                     $field_value->setTimezone(new \DateTimeZone('UTC'));
581
-                    $result[$field_name . '_gmt'] = Model_Data_Translator::prepare_field_value_for_json(
581
+                    $result[$field_name.'_gmt'] = Model_Data_Translator::prepare_field_value_for_json(
582 582
                         $field_obj,
583 583
                         $field_value,
584 584
                         $this->get_model_version_info()->requested_version()
@@ -656,7 +656,7 @@  discard block
 block discarded – undo
656 656
         if ($model->has_primary_key_field()) {
657 657
             foreach ($this->get_model_version_info()->relation_settings($model) as $relation_name => $relation_obj) {
658 658
                 $related_model_part = Read::get_related_entity_name($relation_name, $relation_obj);
659
-                $links[\EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part] = array(
659
+                $links[\EED_Core_Rest_Api::ee_api_link_namespace.$related_model_part] = array(
660 660
                     array(
661 661
                         'href'   => $this->get_versioned_link_to(
662 662
                             \EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
@@ -691,13 +691,13 @@  discard block
 block discarded – undo
691 691
         $db_row = array()
692 692
     ) {
693 693
         //if $db_row not included, hope the entity array has what we need
694
-        if (! $db_row) {
694
+        if ( ! $db_row) {
695 695
             $db_row = $entity_array;
696 696
         }
697 697
         $includes_for_this_model = $this->explode_and_get_items_prefixed_with($rest_request->get_param('include'), '');
698 698
         $includes_for_this_model = $this->_remove_model_names_from_array($includes_for_this_model);
699 699
         //if they passed in * or didn't specify any includes, return everything
700
-        if (! in_array('*', $includes_for_this_model)
700
+        if ( ! in_array('*', $includes_for_this_model)
701 701
             && ! empty($includes_for_this_model)
702 702
         ) {
703 703
             if ($model->has_primary_key_field()) {
@@ -872,7 +872,7 @@  discard block
 block discarded – undo
872 872
         $restricted_query_params['caps'] = $this->validate_context($request->get_param('caps'));
873 873
         $this->_set_debug_info('model query params', $restricted_query_params);
874 874
         $model_rows = $model->get_all_wpdb_results($restricted_query_params);
875
-        if (! empty ($model_rows)) {
875
+        if ( ! empty ($model_rows)) {
876 876
             return $this->create_entity_from_wpdb_result(
877 877
                 $model,
878 878
                 array_shift($model_rows),
@@ -881,7 +881,7 @@  discard block
 block discarded – undo
881 881
             //ok let's test to see if we WOULD have found it, had we not had restrictions from missing capabilities
882 882
             $lowercase_model_name = strtolower($model->get_this_model_name());
883 883
             $model_rows_found_sans_restrictions = $model->get_all_wpdb_results($query_params);
884
-            if (! empty($model_rows_found_sans_restrictions)) {
884
+            if ( ! empty($model_rows_found_sans_restrictions)) {
885 885
                 //you got shafted- it existed but we didn't want to tell you!
886 886
                 return new \WP_Error(
887 887
                     'rest_user_cannot_read',
@@ -916,7 +916,7 @@  discard block
 block discarded – undo
916 916
      */
917 917
     public function validate_context($context)
918 918
     {
919
-        if (! $context) {
919
+        if ( ! $context) {
920 920
             $context = \EEM_Base::caps_read;
921 921
         }
922 922
         $valid_contexts = \EEM_Base::valid_cap_contexts();
@@ -942,7 +942,7 @@  discard block
 block discarded – undo
942 942
             \EEM_Base::default_where_conditions_minimum_all,
943 943
             \EEM_Base::default_where_conditions_minimum_others,
944 944
         );
945
-        if (! $default_query_params) {
945
+        if ( ! $default_query_params) {
946 946
             $default_query_params = \EEM_Base::default_where_conditions_all;
947 947
         }
948 948
         if (
@@ -1027,14 +1027,14 @@  discard block
 block discarded – undo
1027 1027
         }
1028 1028
         if (isset($query_parameters['limit'])) {
1029 1029
             //limit should be either a string like '23' or '23,43', or an array with two items in it
1030
-            if (! is_array($query_parameters['limit'])) {
1031
-                $limit_array = explode(',', (string)$query_parameters['limit']);
1030
+            if ( ! is_array($query_parameters['limit'])) {
1031
+                $limit_array = explode(',', (string) $query_parameters['limit']);
1032 1032
             } else {
1033 1033
                 $limit_array = $query_parameters['limit'];
1034 1034
             }
1035 1035
             $sanitized_limit = array();
1036 1036
             foreach ($limit_array as $key => $limit_part) {
1037
-                if ($this->_debug_mode && (! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1037
+                if ($this->_debug_mode && ( ! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1038 1038
                     throw new \EE_Error(
1039 1039
                         sprintf(
1040 1040
                             __('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.',
@@ -1043,7 +1043,7 @@  discard block
 block discarded – undo
1043 1043
                         )
1044 1044
                     );
1045 1045
                 }
1046
-                $sanitized_limit[] = (int)$limit_part;
1046
+                $sanitized_limit[] = (int) $limit_part;
1047 1047
             }
1048 1048
             $model_query_params['limit'] = implode(',', $sanitized_limit);
1049 1049
         } else {
@@ -1131,17 +1131,17 @@  discard block
 block discarded – undo
1131 1131
         foreach ($exploded_contents as $item) {
1132 1132
             $item = trim($item);
1133 1133
             //if no prefix was provided, so we look for items with no "." in them
1134
-            if (! $prefix) {
1134
+            if ( ! $prefix) {
1135 1135
                 //does this item have a period?
1136 1136
                 if (strpos($item, '.') === false) {
1137 1137
                     //if not, then its what we're looking for
1138 1138
                     $contents_with_prefix[] = $item;
1139 1139
                 }
1140
-            } else if (strpos($item, $prefix . '.') === 0) {
1140
+            } else if (strpos($item, $prefix.'.') === 0) {
1141 1141
                 //this item has the prefix and a period, grab it
1142 1142
                 $contents_with_prefix[] = substr(
1143 1143
                     $item,
1144
-                    strpos($item, $prefix . '.') + strlen($prefix . '.')
1144
+                    strpos($item, $prefix.'.') + strlen($prefix.'.')
1145 1145
                 );
1146 1146
             } else if ($item === $prefix) {
1147 1147
                 //this item is JUST the prefix
@@ -1181,9 +1181,9 @@  discard block
 block discarded – undo
1181 1181
         if ($model_name) {
1182 1182
             foreach ($includes as $field_to_include) {
1183 1183
                 $field_to_include = trim($field_to_include);
1184
-                if (strpos($field_to_include, $model_name . '.') === 0) {
1184
+                if (strpos($field_to_include, $model_name.'.') === 0) {
1185 1185
                     //found the model name at the exact start
1186
-                    $field_sans_model_name = str_replace($model_name . '.', '', $field_to_include);
1186
+                    $field_sans_model_name = str_replace($model_name.'.', '', $field_to_include);
1187 1187
                     $extracted_fields_to_include[] = $field_sans_model_name;
1188 1188
                 } elseif ($field_to_include == $model_name) {
1189 1189
                     $extracted_fields_to_include[] = '*';
Please login to merge, or discard this patch.
admin_pages/registration_form/Registration_Form_Admin_Page.core.php 2 patches
Indentation   +624 added lines, -624 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
 /**
@@ -28,580 +28,580 @@  discard block
 block discarded – undo
28 28
 class Registration_Form_Admin_Page extends EE_Admin_Page
29 29
 {
30 30
 
31
-    /**
32
-     * _question
33
-     * holds the specific question object for the question details screen
34
-     *
35
-     * @var EE_Question $_question
36
-     */
37
-    protected $_question;
38
-
39
-    /**
40
-     * _question_group
41
-     * holds the specific question group object for the question group details screen
42
-     *
43
-     * @var EE_Question_Group $_question_group
44
-     */
45
-    protected $_question_group;
46
-
47
-    /**
48
-     *_question_model EEM_Question model instance (for queries)
49
-     *
50
-     * @var EEM_Question $_question_model ;
51
-     */
52
-    protected $_question_model;
53
-
54
-    /**
55
-     * _question_group_model EEM_Question_group instance (for queries)
56
-     *
57
-     * @var EEM_Question_Group $_question_group_model
58
-     */
59
-    protected $_question_group_model;
60
-
61
-
62
-    /**
63
-     * @Constructor
64
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
65
-     * @access public
66
-     */
67
-    public function __construct($routing = true)
68
-    {
69
-        require_once(EE_MODELS . 'EEM_Question.model.php');
70
-        require_once(EE_MODELS . 'EEM_Question_Group.model.php');
71
-        $this->_question_model       = EEM_Question::instance();
72
-        $this->_question_group_model = EEM_Question_Group::instance();
73
-        parent::__construct($routing);
74
-    }
75
-
76
-
77
-    protected function _init_page_props()
78
-    {
79
-        $this->page_slug        = REGISTRATION_FORM_PG_SLUG;
80
-        $this->page_label       = esc_html__('Registration Form', 'event_espresso');
81
-        $this->_admin_base_url  = REGISTRATION_FORM_ADMIN_URL;
82
-        $this->_admin_base_path = REGISTRATION_FORM_ADMIN;
83
-    }
84
-
85
-
86
-    protected function _ajax_hooks()
87
-    {
88
-    }
89
-
90
-
91
-    protected function _define_page_props()
92
-    {
93
-        $this->_admin_page_title = esc_html__('Registration Form', 'event_espresso');
94
-        $this->_labels           = array(
95
-            'buttons' => array(
96
-                'edit_question' => esc_html__('Edit Question', 'event_espresso'),
97
-            ),
98
-        );
99
-    }
100
-
101
-
102
-    /**
103
-     *_set_page_routes
104
-     */
105
-    protected function _set_page_routes()
106
-    {
107
-        $qst_id             = ! empty($this->_req_data['QST_ID']) ? $this->_req_data['QST_ID'] : 0;
108
-        $this->_page_routes = array(
109
-            'default' => array(
110
-                'func'       => '_questions_overview_list_table',
111
-                'capability' => 'ee_read_questions',
112
-            ),
113
-
114
-            'edit_question' => array(
115
-                'func'       => '_edit_question',
116
-                'capability' => 'ee_edit_question',
117
-                'obj_id'     => $qst_id,
118
-                'args'       => array('edit'),
119
-            ),
120
-
121
-            'question_groups' => array(
122
-                'func'       => '_questions_groups_preview',
123
-                'capability' => 'ee_read_question_groups',
124
-            ),
125
-
126
-            'update_question' => array(
127
-                'func'       => '_insert_or_update_question',
128
-                'args'       => array('new_question' => false),
129
-                'capability' => 'ee_edit_question',
130
-                'obj_id'     => $qst_id,
131
-                'noheader'   => true,
132
-            ),
133
-        );
134
-    }
135
-
136
-
137
-    protected function _set_page_config()
138
-    {
139
-        $this->_page_config = array(
140
-            'default' => array(
141
-                'nav'           => array(
142
-                    'label' => esc_html__('Questions', 'event_espresso'),
143
-                    'order' => 10,
144
-                ),
145
-                'list_table'    => 'Registration_Form_Questions_Admin_List_Table',
146
-                'metaboxes'     => $this->_default_espresso_metaboxes,
147
-                'help_tabs'     => array(
148
-                    'registration_form_questions_overview_help_tab'                           => array(
149
-                        'title'    => esc_html__('Questions Overview', 'event_espresso'),
150
-                        'filename' => 'registration_form_questions_overview',
151
-                    ),
152
-                    'registration_form_questions_overview_table_column_headings_help_tab'     => array(
153
-                        'title'    => esc_html__('Questions Overview Table Column Headings', 'event_espresso'),
154
-                        'filename' => 'registration_form_questions_overview_table_column_headings',
155
-                    ),
156
-                    'registration_form_questions_overview_views_bulk_actions_search_help_tab' => array(
157
-                        'title'    => esc_html__('Question Overview Views & Bulk Actions & Search', 'event_espresso'),
158
-                        'filename' => 'registration_form_questions_overview_views_bulk_actions_search',
159
-                    ),
160
-                ),
161
-                'help_tour'     => array('Registration_Form_Questions_Overview_Help_Tour'),
162
-                'require_nonce' => false,
163
-                'qtips'         => array(
164
-                    'EE_Registration_Form_Tips',
165
-                )/**/
166
-            ),
167
-
168
-            'question_groups' => array(
169
-                'nav'           => array(
170
-                    'label' => esc_html__('Question Groups', 'event_espresso'),
171
-                    'order' => 20,
172
-                ),
173
-                'metaboxes'     => $this->_default_espresso_metaboxes,
174
-                'help_tabs'     => array(
175
-                    'registration_form_question_groups_help_tab' => array(
176
-                        'title'    => esc_html__('Question Groups', 'event_espresso'),
177
-                        'filename' => 'registration_form_question_groups',
178
-                    ),
179
-                ),
180
-                'help_tour'     => array('Registration_Form_Question_Groups_Help_Tour'),
181
-                'require_nonce' => false,
182
-            ),
183
-
184
-            'edit_question' => array(
185
-                'nav'           => array(
186
-                    'label'      => esc_html__('Edit Question', 'event_espresso'),
187
-                    'order'      => 15,
188
-                    'persistent' => false,
189
-                    'url'        => isset($this->_req_data['question_id']) ? add_query_arg(array('question_id' => $this->_req_data['question_id']),
190
-                        $this->_current_page_view_url) : $this->_admin_base_url,
191
-                ),
192
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
193
-                'help_tabs'     => array(
194
-                    'registration_form_edit_question_group_help_tab' => array(
195
-                        'title'    => esc_html__('Edit Question', 'event_espresso'),
196
-                        'filename' => 'registration_form_edit_question',
197
-                    ),
198
-                ),
199
-                'help_tour'     => array('Registration_Form_Edit_Question_Help_Tour'),
200
-                'require_nonce' => false,
201
-            ),
202
-        );
203
-    }
204
-
205
-
206
-    protected function _add_screen_options()
207
-    {
208
-        //todo
209
-    }
210
-
211
-    protected function _add_screen_options_default()
212
-    {
213
-        $page_title              = $this->_admin_page_title;
214
-        $this->_admin_page_title = esc_html__('Questions', 'event_espresso');
215
-        $this->_per_page_screen_option();
216
-        $this->_admin_page_title = $page_title;
217
-    }
218
-
219
-    protected function _add_screen_options_question_groups()
220
-    {
221
-        $page_title              = $this->_admin_page_title;
222
-        $this->_admin_page_title = esc_html__('Question Groups', 'event_espresso');
223
-        $this->_per_page_screen_option();
224
-        $this->_admin_page_title = $page_title;
225
-    }
226
-
227
-    //none of the below group are currently used for Event Categories
228
-    protected function _add_feature_pointers()
229
-    {
230
-    }
231
-
232
-    public function load_scripts_styles()
233
-    {
234
-        wp_register_style('espresso_registration',
235
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css', array(), EVENT_ESPRESSO_VERSION);
236
-        wp_enqueue_style('espresso_registration');
237
-    }
238
-
239
-    public function admin_init()
240
-    {
241
-    }
242
-
243
-    public function admin_notices()
244
-    {
245
-    }
246
-
247
-    public function admin_footer_scripts()
248
-    {
249
-    }
250
-
251
-
252
-    public function load_scripts_styles_default()
253
-    {
254
-    }
255
-
256
-
257
-    public function load_scripts_styles_add_question()
258
-    {
259
-        $this->load_scripts_styles_forms();
260
-        wp_register_script('espresso_registration_form_single',
261
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
262
-            EVENT_ESPRESSO_VERSION, true);
263
-        wp_enqueue_script('espresso_registration_form_single');
264
-    }
265
-
266
-    public function load_scripts_styles_edit_question()
267
-    {
268
-        $this->load_scripts_styles_forms();
269
-        wp_register_script('espresso_registration_form_single',
270
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
271
-            EVENT_ESPRESSO_VERSION, true);
272
-        wp_enqueue_script('espresso_registration_form_single');
273
-    }
274
-
275
-
276
-    public function recaptcha_info_help_tab()
277
-    {
278
-        $template = REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php';
279
-        EEH_Template::display_template($template, array());
280
-    }
281
-
282
-
283
-    public function load_scripts_styles_forms()
284
-    {
285
-        //styles
286
-        wp_enqueue_style('espresso-ui-theme');
287
-        //scripts
288
-        wp_enqueue_script('ee_admin_js');
289
-    }
290
-
291
-
292
-    protected function _set_list_table_views_default()
293
-    {
294
-        $this->_views = array(
295
-            'all' => array(
296
-                'slug'  => 'all',
297
-                'label' => esc_html__('View All Questions', 'event_espresso'),
298
-                'count' => 0,
31
+	/**
32
+	 * _question
33
+	 * holds the specific question object for the question details screen
34
+	 *
35
+	 * @var EE_Question $_question
36
+	 */
37
+	protected $_question;
38
+
39
+	/**
40
+	 * _question_group
41
+	 * holds the specific question group object for the question group details screen
42
+	 *
43
+	 * @var EE_Question_Group $_question_group
44
+	 */
45
+	protected $_question_group;
46
+
47
+	/**
48
+	 *_question_model EEM_Question model instance (for queries)
49
+	 *
50
+	 * @var EEM_Question $_question_model ;
51
+	 */
52
+	protected $_question_model;
53
+
54
+	/**
55
+	 * _question_group_model EEM_Question_group instance (for queries)
56
+	 *
57
+	 * @var EEM_Question_Group $_question_group_model
58
+	 */
59
+	protected $_question_group_model;
60
+
61
+
62
+	/**
63
+	 * @Constructor
64
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
65
+	 * @access public
66
+	 */
67
+	public function __construct($routing = true)
68
+	{
69
+		require_once(EE_MODELS . 'EEM_Question.model.php');
70
+		require_once(EE_MODELS . 'EEM_Question_Group.model.php');
71
+		$this->_question_model       = EEM_Question::instance();
72
+		$this->_question_group_model = EEM_Question_Group::instance();
73
+		parent::__construct($routing);
74
+	}
75
+
76
+
77
+	protected function _init_page_props()
78
+	{
79
+		$this->page_slug        = REGISTRATION_FORM_PG_SLUG;
80
+		$this->page_label       = esc_html__('Registration Form', 'event_espresso');
81
+		$this->_admin_base_url  = REGISTRATION_FORM_ADMIN_URL;
82
+		$this->_admin_base_path = REGISTRATION_FORM_ADMIN;
83
+	}
84
+
85
+
86
+	protected function _ajax_hooks()
87
+	{
88
+	}
89
+
90
+
91
+	protected function _define_page_props()
92
+	{
93
+		$this->_admin_page_title = esc_html__('Registration Form', 'event_espresso');
94
+		$this->_labels           = array(
95
+			'buttons' => array(
96
+				'edit_question' => esc_html__('Edit Question', 'event_espresso'),
97
+			),
98
+		);
99
+	}
100
+
101
+
102
+	/**
103
+	 *_set_page_routes
104
+	 */
105
+	protected function _set_page_routes()
106
+	{
107
+		$qst_id             = ! empty($this->_req_data['QST_ID']) ? $this->_req_data['QST_ID'] : 0;
108
+		$this->_page_routes = array(
109
+			'default' => array(
110
+				'func'       => '_questions_overview_list_table',
111
+				'capability' => 'ee_read_questions',
112
+			),
113
+
114
+			'edit_question' => array(
115
+				'func'       => '_edit_question',
116
+				'capability' => 'ee_edit_question',
117
+				'obj_id'     => $qst_id,
118
+				'args'       => array('edit'),
119
+			),
120
+
121
+			'question_groups' => array(
122
+				'func'       => '_questions_groups_preview',
123
+				'capability' => 'ee_read_question_groups',
124
+			),
125
+
126
+			'update_question' => array(
127
+				'func'       => '_insert_or_update_question',
128
+				'args'       => array('new_question' => false),
129
+				'capability' => 'ee_edit_question',
130
+				'obj_id'     => $qst_id,
131
+				'noheader'   => true,
132
+			),
133
+		);
134
+	}
135
+
136
+
137
+	protected function _set_page_config()
138
+	{
139
+		$this->_page_config = array(
140
+			'default' => array(
141
+				'nav'           => array(
142
+					'label' => esc_html__('Questions', 'event_espresso'),
143
+					'order' => 10,
144
+				),
145
+				'list_table'    => 'Registration_Form_Questions_Admin_List_Table',
146
+				'metaboxes'     => $this->_default_espresso_metaboxes,
147
+				'help_tabs'     => array(
148
+					'registration_form_questions_overview_help_tab'                           => array(
149
+						'title'    => esc_html__('Questions Overview', 'event_espresso'),
150
+						'filename' => 'registration_form_questions_overview',
151
+					),
152
+					'registration_form_questions_overview_table_column_headings_help_tab'     => array(
153
+						'title'    => esc_html__('Questions Overview Table Column Headings', 'event_espresso'),
154
+						'filename' => 'registration_form_questions_overview_table_column_headings',
155
+					),
156
+					'registration_form_questions_overview_views_bulk_actions_search_help_tab' => array(
157
+						'title'    => esc_html__('Question Overview Views & Bulk Actions & Search', 'event_espresso'),
158
+						'filename' => 'registration_form_questions_overview_views_bulk_actions_search',
159
+					),
160
+				),
161
+				'help_tour'     => array('Registration_Form_Questions_Overview_Help_Tour'),
162
+				'require_nonce' => false,
163
+				'qtips'         => array(
164
+					'EE_Registration_Form_Tips',
165
+				)/**/
166
+			),
167
+
168
+			'question_groups' => array(
169
+				'nav'           => array(
170
+					'label' => esc_html__('Question Groups', 'event_espresso'),
171
+					'order' => 20,
172
+				),
173
+				'metaboxes'     => $this->_default_espresso_metaboxes,
174
+				'help_tabs'     => array(
175
+					'registration_form_question_groups_help_tab' => array(
176
+						'title'    => esc_html__('Question Groups', 'event_espresso'),
177
+						'filename' => 'registration_form_question_groups',
178
+					),
179
+				),
180
+				'help_tour'     => array('Registration_Form_Question_Groups_Help_Tour'),
181
+				'require_nonce' => false,
182
+			),
183
+
184
+			'edit_question' => array(
185
+				'nav'           => array(
186
+					'label'      => esc_html__('Edit Question', 'event_espresso'),
187
+					'order'      => 15,
188
+					'persistent' => false,
189
+					'url'        => isset($this->_req_data['question_id']) ? add_query_arg(array('question_id' => $this->_req_data['question_id']),
190
+						$this->_current_page_view_url) : $this->_admin_base_url,
191
+				),
192
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
193
+				'help_tabs'     => array(
194
+					'registration_form_edit_question_group_help_tab' => array(
195
+						'title'    => esc_html__('Edit Question', 'event_espresso'),
196
+						'filename' => 'registration_form_edit_question',
197
+					),
198
+				),
199
+				'help_tour'     => array('Registration_Form_Edit_Question_Help_Tour'),
200
+				'require_nonce' => false,
201
+			),
202
+		);
203
+	}
204
+
205
+
206
+	protected function _add_screen_options()
207
+	{
208
+		//todo
209
+	}
210
+
211
+	protected function _add_screen_options_default()
212
+	{
213
+		$page_title              = $this->_admin_page_title;
214
+		$this->_admin_page_title = esc_html__('Questions', 'event_espresso');
215
+		$this->_per_page_screen_option();
216
+		$this->_admin_page_title = $page_title;
217
+	}
218
+
219
+	protected function _add_screen_options_question_groups()
220
+	{
221
+		$page_title              = $this->_admin_page_title;
222
+		$this->_admin_page_title = esc_html__('Question Groups', 'event_espresso');
223
+		$this->_per_page_screen_option();
224
+		$this->_admin_page_title = $page_title;
225
+	}
226
+
227
+	//none of the below group are currently used for Event Categories
228
+	protected function _add_feature_pointers()
229
+	{
230
+	}
231
+
232
+	public function load_scripts_styles()
233
+	{
234
+		wp_register_style('espresso_registration',
235
+			REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css', array(), EVENT_ESPRESSO_VERSION);
236
+		wp_enqueue_style('espresso_registration');
237
+	}
238
+
239
+	public function admin_init()
240
+	{
241
+	}
242
+
243
+	public function admin_notices()
244
+	{
245
+	}
246
+
247
+	public function admin_footer_scripts()
248
+	{
249
+	}
250
+
251
+
252
+	public function load_scripts_styles_default()
253
+	{
254
+	}
255
+
256
+
257
+	public function load_scripts_styles_add_question()
258
+	{
259
+		$this->load_scripts_styles_forms();
260
+		wp_register_script('espresso_registration_form_single',
261
+			REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
262
+			EVENT_ESPRESSO_VERSION, true);
263
+		wp_enqueue_script('espresso_registration_form_single');
264
+	}
265
+
266
+	public function load_scripts_styles_edit_question()
267
+	{
268
+		$this->load_scripts_styles_forms();
269
+		wp_register_script('espresso_registration_form_single',
270
+			REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
271
+			EVENT_ESPRESSO_VERSION, true);
272
+		wp_enqueue_script('espresso_registration_form_single');
273
+	}
274
+
275
+
276
+	public function recaptcha_info_help_tab()
277
+	{
278
+		$template = REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php';
279
+		EEH_Template::display_template($template, array());
280
+	}
281
+
282
+
283
+	public function load_scripts_styles_forms()
284
+	{
285
+		//styles
286
+		wp_enqueue_style('espresso-ui-theme');
287
+		//scripts
288
+		wp_enqueue_script('ee_admin_js');
289
+	}
290
+
291
+
292
+	protected function _set_list_table_views_default()
293
+	{
294
+		$this->_views = array(
295
+			'all' => array(
296
+				'slug'  => 'all',
297
+				'label' => esc_html__('View All Questions', 'event_espresso'),
298
+				'count' => 0,
299 299
 //				'bulk_action' => array(
300 300
 //					'trash_questions' => esc_html__('Trash', 'event_espresso'),
301 301
 //					)
302
-            ),
303
-        );
304
-
305
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_questions',
306
-            'espresso_registration_form_trash_questions')
307
-        ) {
308
-            $this->_views['trash'] = array(
309
-                'slug'  => 'trash',
310
-                'label' => esc_html__('Trash', 'event_espresso'),
311
-                'count' => 0,
302
+			),
303
+		);
304
+
305
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_questions',
306
+			'espresso_registration_form_trash_questions')
307
+		) {
308
+			$this->_views['trash'] = array(
309
+				'slug'  => 'trash',
310
+				'label' => esc_html__('Trash', 'event_espresso'),
311
+				'count' => 0,
312 312
 //				'bulk_action' => array(
313 313
 //					'delete_questions' => esc_html__('Delete Permanently', 'event_espresso'),
314 314
 //					'restore_questions' => esc_html__('Restore', 'event_espresso'),
315
-            );
316
-        }
317
-    }
318
-
319
-    /**
320
-     * This just previews the question groups tab that comes in caffeinated.
321
-     *
322
-     * @return string html
323
-     */
324
-    protected function _questions_groups_preview()
325
-    {
326
-        $this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
327
-        $this->_template_args['preview_img']  = '<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="' . esc_attr__('Preview Question Groups Overview List Table screenshot',
328
-                'event_espresso') . '" />';
329
-        $this->_template_args['preview_text'] = '<strong>' . esc_html__('Question Groups 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 Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
330
-                'event_espresso') . '</strong>';
331
-        $this->display_admin_caf_preview_page('question_groups_tab');
332
-    }
333
-
334
-
335
-    /**
336
-     * Extracts the question field's values from the POST request to update or insert them
337
-     *
338
-     * @param \EEM_Base $model
339
-     * @return array where each key is the name of a model's field/db column, and each value is its value.
340
-     */
341
-    protected function _set_column_values_for(EEM_Base $model)
342
-    {
343
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
344
-        $set_column_values = array();
345
-
346
-        //some initial checks for proper values.
347
-        //if QST_admin_only, then no matter what QST_required is we disable.
348
-        if (! empty($this->_req_data['QST_admin_only'])) {
349
-            $this->_req_data['QST_required'] = 0;
350
-        }
351
-        foreach ($model->field_settings() as $fieldName => $settings) {
352
-            // basically if QSG_identifier is empty or not set
353
-            if ($fieldName === 'QSG_identifier' && (isset($this->_req_data['QSG_identifier']) && empty($this->_req_data['QSG_identifier']))) {
354
-                $QSG_name                      = isset($this->_req_data['QSG_name']) ? $this->_req_data['QSG_name'] : '';
355
-                $set_column_values[$fieldName] = sanitize_title($QSG_name) . '-' . uniqid('', true);
315
+			);
316
+		}
317
+	}
318
+
319
+	/**
320
+	 * This just previews the question groups tab that comes in caffeinated.
321
+	 *
322
+	 * @return string html
323
+	 */
324
+	protected function _questions_groups_preview()
325
+	{
326
+		$this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
327
+		$this->_template_args['preview_img']  = '<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="' . esc_attr__('Preview Question Groups Overview List Table screenshot',
328
+				'event_espresso') . '" />';
329
+		$this->_template_args['preview_text'] = '<strong>' . esc_html__('Question Groups 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 Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
330
+				'event_espresso') . '</strong>';
331
+		$this->display_admin_caf_preview_page('question_groups_tab');
332
+	}
333
+
334
+
335
+	/**
336
+	 * Extracts the question field's values from the POST request to update or insert them
337
+	 *
338
+	 * @param \EEM_Base $model
339
+	 * @return array where each key is the name of a model's field/db column, and each value is its value.
340
+	 */
341
+	protected function _set_column_values_for(EEM_Base $model)
342
+	{
343
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
344
+		$set_column_values = array();
345
+
346
+		//some initial checks for proper values.
347
+		//if QST_admin_only, then no matter what QST_required is we disable.
348
+		if (! empty($this->_req_data['QST_admin_only'])) {
349
+			$this->_req_data['QST_required'] = 0;
350
+		}
351
+		foreach ($model->field_settings() as $fieldName => $settings) {
352
+			// basically if QSG_identifier is empty or not set
353
+			if ($fieldName === 'QSG_identifier' && (isset($this->_req_data['QSG_identifier']) && empty($this->_req_data['QSG_identifier']))) {
354
+				$QSG_name                      = isset($this->_req_data['QSG_name']) ? $this->_req_data['QSG_name'] : '';
355
+				$set_column_values[$fieldName] = sanitize_title($QSG_name) . '-' . uniqid('', true);
356 356
 //				dd($set_column_values);
357
-            } //if the admin label is blank, use a slug version of the question text
358
-            else if ($fieldName === 'QST_admin_label' && (isset($this->_req_data['QST_admin_label']) && empty($this->_req_data['QST_admin_label']))) {
359
-                $QST_text                      = isset($this->_req_data['QST_display_text']) ? $this->_req_data['QST_display_text'] : '';
360
-                $set_column_values[$fieldName] = sanitize_title(wp_trim_words($QST_text, 10));
361
-            } else if ($fieldName === 'QST_admin_only' && (! isset($this->_req_data['QST_admin_only']))) {
362
-                $set_column_values[$fieldName] = 0;
363
-            } else if ($fieldName === 'QST_max') {
364
-                $qst_system = EEM_Question::instance()->get_var(
365
-                    array(
366
-                        array(
367
-                            'QST_ID' => isset($this->_req_data['QST_ID']) ? $this->_req_data['QST_ID'] : 0,
368
-                        ),
369
-                    ),
370
-                    'QST_system');
371
-                $max_max    = EEM_Question::instance()->absolute_max_for_system_question($qst_system);
372
-                if (empty($this->_req_data['QST_max']) ||
373
-                    $this->_req_data['QST_max'] > $max_max
374
-                ) {
375
-                    $set_column_values[$fieldName] = $max_max;
376
-                }
377
-            }
378
-
379
-
380
-            //only add a property to the array if it's not null (otherwise the model should just use the default value)
381
-            if (
382
-                ! isset($set_column_values[$fieldName]) &&
383
-                isset($this->_req_data[$fieldName])
384
-            ) {
385
-                $set_column_values[$fieldName] = $this->_req_data[$fieldName];
386
-            }
387
-
388
-        }
389
-        return $set_column_values;//validation fo this data to be performed by the model before insertion.
390
-    }
391
-
392
-
393
-    /**
394
-     *_questions_overview_list_table
395
-     */
396
-    protected function _questions_overview_list_table()
397
-    {
398
-        $this->_search_btn_label = esc_html__('Questions', 'event_espresso');
399
-        $this->display_admin_list_table_page_with_sidebar();
400
-    }
401
-
402
-
403
-    /**
404
-     * _edit_question
405
-     */
406
-    protected function _edit_question()
407
-    {
408
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
409
-        $ID = isset($this->_req_data['QST_ID']) && ! empty($this->_req_data['QST_ID']) ? absint($this->_req_data['QST_ID']) : false;
410
-
411
-        switch ($this->_req_action) {
412
-            case 'add_question' :
413
-                $this->_admin_page_title = esc_html__('Add Question', 'event_espresso');
414
-                break;
415
-            case 'edit_question' :
416
-                $this->_admin_page_title = esc_html__('Edit Question', 'event_espresso');
417
-                break;
418
-            default :
419
-                $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
420
-        }
421
-
422
-        // add PRC_ID to title if editing
423
-        $this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
424
-        if ($ID) {
425
-            $question                 = $this->_question_model->get_one_by_ID($ID);
426
-            $additional_hidden_fields = array('QST_ID' => array('type' => 'hidden', 'value' => $ID));
427
-            $this->_set_add_edit_form_tags('update_question', $additional_hidden_fields);
428
-        } else {
429
-            $question = EE_Question::new_instance();
430
-            $question->set_order_to_latest();
431
-            $this->_set_add_edit_form_tags('insert_question');
432
-        }
433
-        $question_types                                     = $question->has_answers() ? $this->_question_model->question_types_in_same_category($question->type()) : $this->_question_model->allowed_question_types();
434
-        $this->_template_args['QST_ID']                     = $ID;
435
-        $this->_template_args['question']                   = $question;
436
-        $this->_template_args['question_types']             = $question_types;
437
-        $this->_template_args['max_max']                    = EEM_Question::instance()->absolute_max_for_system_question($question->system_ID());
438
-        $this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
439
-        $this->_set_publish_post_box_vars('id', $ID);
440
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
441
-            $this->_template_args, true);
442
-
443
-        // the details template wrapper
444
-        $this->display_admin_page_with_sidebar();
445
-    }
446
-
447
-
448
-    /**
449
-     * @return string
450
-     */
451
-    protected function _get_question_type_descriptions()
452
-    {
453
-        EE_Registry::instance()->load_helper('HTML');
454
-        $descriptions               = '';
455
-        $question_type_descriptions = EEM_Question::instance()->question_descriptions();
456
-        foreach ($question_type_descriptions as $type => $question_type_description) {
457
-            if ($type == 'HTML_TEXTAREA') {
458
-                $html = new EE_Simple_HTML_Validation_Strategy();
459
-                $question_type_description .= sprintf(
460
-                    esc_html__('%1$s(allowed tags: %2$s)', 'event_espresso'),
461
-                    '<br/>',
462
-                    $html->get_list_of_allowed_tags()
463
-                );
464
-            }
465
-            $descriptions .= EEH_HTML::p(
466
-                $question_type_description,
467
-                'question_type_description-' . $type,
468
-                'question_type_description description',
469
-                'display:none;'
470
-            );
471
-        }
472
-        return $descriptions;
473
-    }
474
-
475
-
476
-    /**
477
-     * @param bool|true $new_question
478
-     * @throws \EE_Error
479
-     */
480
-    protected function _insert_or_update_question($new_question = true)
481
-    {
482
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
483
-        $set_column_values = $this->_set_column_values_for($this->_question_model);
484
-        if ($new_question) {
485
-            $ID          = $this->_question_model->insert($set_column_values);
486
-            $success     = $ID ? true : false;
487
-            $action_desc = 'added';
488
-        } else {
489
-            $ID     = absint($this->_req_data['QST_ID']);
490
-            $pk     = $this->_question_model->primary_key_name();
491
-            $wheres = array($pk => $ID);
492
-            unset($set_column_values[$pk]);
493
-            $success     = $this->_question_model->update($set_column_values, array($wheres));
494
-            $action_desc = 'updated';
495
-        }
496
-
497
-        if ($ID) {
498
-            //save the related options
499
-            //trash removed options, save old ones
500
-            //get list of all options
501
-            /** @type EE_Question $question */
502
-            $question = $this->_question_model->get_one_by_ID($ID);
503
-            $options  = $question->options();
504
-            if (! empty($options)) {
505
-                foreach ($options as $option_ID => $option) {
506
-                    $option_req_index = $this->_get_option_req_data_index($option_ID);
507
-                    if ($option_req_index !== false) {
508
-                        $option->save($this->_req_data['question_options'][$option_req_index]);
509
-                    } else {
510
-                        //not found, remove it
511
-                        $option->delete();
512
-                    }
513
-                }
514
-            }
515
-            //save new related options
516
-            foreach ($this->_req_data['question_options'] as $index => $option_req_data) {
517
-                if (empty($option_req_data['QSO_ID']) && ((isset($option_req_data['QSO_value']) && $option_req_data['QSO_value'] !== '') || ! empty($option_req_data['QSO_desc']))) {//no ID! save it!
518
-                    if (! isset($option_req_data['QSO_value']) || $option_req_data['QSO_value'] === '') {
519
-                        $option_req_data['QSO_value'] = $option_req_data['QSO_desc'];
520
-                    }
521
-                    $new_option = EE_Question_Option::new_instance(array(
522
-                        'QSO_value' => $option_req_data['QSO_value'],
523
-                        'QSO_desc'  => $option_req_data['QSO_desc'],
524
-                        'QSO_order' => $option_req_data['QSO_order'],
525
-                        'QST_ID'    => $question->ID(),
526
-                    ));
527
-                    $new_option->save();
528
-                }
529
-            }
530
-        }
531
-        $query_args = array('action' => 'edit_question', 'QST_ID' => $ID);
532
-        if ($success !== false) {
533
-            $msg = $new_question ? sprintf(esc_html__('The %s has been created', 'event_espresso'),
534
-                $this->_question_model->item_name()) : sprintf(esc_html__('The %s has been updated', 'event_espresso'),
535
-                $this->_question_model->item_name());
536
-            EE_Error::add_success($msg);
537
-        }
538
-
539
-        $this->_redirect_after_action(false, '', $action_desc, $query_args, true);
540
-    }
541
-
542
-
543
-    /**
544
-     * Upon saving a question, there should be an array of 'question_options'. This array is index numerically, but not
545
-     * by ID
546
-     * (this is done because new question options don't have an ID, but we may want to add multiple simultaneously).
547
-     * So, this function gets the index in that request data array called question_options. Returns FALSE if not found.
548
-     *
549
-     * @param int $ID of the question option to find
550
-     * @return int index in question_options array if successful, FALSE if unsuccessful
551
-     */
552
-    protected function _get_option_req_data_index($ID)
553
-    {
554
-        $req_data_for_question_options = $this->_req_data['question_options'];
555
-        foreach ($req_data_for_question_options as $num => $option_data) {
556
-            if (array_key_exists('QSO_ID', $option_data) && (int)$option_data['QSO_ID'] === $ID) {
557
-                return $num;
558
-            }
559
-        }
560
-        return false;
561
-    }
562
-
563
-
564
-
565
-
566
-    /***********/
567
-    /* QUERIES */
568
-    /**
569
-     * For internal use in getting all the query parameters
570
-     * (because it's pretty well the same between question, question groups,
571
-     * and for both when searching for trashed and untrashed ones)
572
-     *
573
-     * @param EEM_Base $model either EEM_Question or EEM_Question_Group
574
-     * @param int      $per_page
575
-     * @param int      $current_page
576
-     * @return array lik EEM_Base::get_all's $query_params parameter
577
-     */
578
-    protected function get_query_params($model, $per_page = 10, $current_page = 10)
579
-    {
580
-        $query_params             = array();
581
-        $offset                   = ($current_page - 1) * $per_page;
582
-        $query_params['limit']    = array($offset, $per_page);
583
-        $order                    = (isset($this->_req_data['order']) && ! empty($this->_req_data['order'])) ? $this->_req_data['order'] : 'ASC';
584
-        $orderby_field            = $model instanceof EEM_Question ? 'QST_ID' : 'QSG_order';
585
-        $field_to_order_by        = empty($this->_req_data['orderby']) ? $orderby_field : $this->_req_data['orderby'];
586
-        $query_params['order_by'] = array($field_to_order_by => $order);
587
-        $search_string            = array_key_exists('s', $this->_req_data) ? $this->_req_data['s'] : null;
588
-        if (! empty($search_string)) {
589
-            if ($model instanceof EEM_Question_Group) {
590
-                $query_params[0] = array(
591
-                    'OR' => array(
592
-                        'QSG_name' => array('LIKE', "%$search_string%"),
593
-                        'QSG_desc' => array('LIKE', "%$search_string%"),
594
-                    ),
595
-                );
596
-            } else {
597
-                $query_params[0] = array(
598
-                    'QST_display_text' => array('LIKE', "%$search_string%"),
599
-                );
600
-            }
601
-        }
602
-
603
-        //capability checks (just leaving this commented out for reference because it illustrates some complicated query params that could be useful when fully implemented)
604
-        /*if ( $model instanceof EEM_Question_Group ) {
357
+			} //if the admin label is blank, use a slug version of the question text
358
+			else if ($fieldName === 'QST_admin_label' && (isset($this->_req_data['QST_admin_label']) && empty($this->_req_data['QST_admin_label']))) {
359
+				$QST_text                      = isset($this->_req_data['QST_display_text']) ? $this->_req_data['QST_display_text'] : '';
360
+				$set_column_values[$fieldName] = sanitize_title(wp_trim_words($QST_text, 10));
361
+			} else if ($fieldName === 'QST_admin_only' && (! isset($this->_req_data['QST_admin_only']))) {
362
+				$set_column_values[$fieldName] = 0;
363
+			} else if ($fieldName === 'QST_max') {
364
+				$qst_system = EEM_Question::instance()->get_var(
365
+					array(
366
+						array(
367
+							'QST_ID' => isset($this->_req_data['QST_ID']) ? $this->_req_data['QST_ID'] : 0,
368
+						),
369
+					),
370
+					'QST_system');
371
+				$max_max    = EEM_Question::instance()->absolute_max_for_system_question($qst_system);
372
+				if (empty($this->_req_data['QST_max']) ||
373
+					$this->_req_data['QST_max'] > $max_max
374
+				) {
375
+					$set_column_values[$fieldName] = $max_max;
376
+				}
377
+			}
378
+
379
+
380
+			//only add a property to the array if it's not null (otherwise the model should just use the default value)
381
+			if (
382
+				! isset($set_column_values[$fieldName]) &&
383
+				isset($this->_req_data[$fieldName])
384
+			) {
385
+				$set_column_values[$fieldName] = $this->_req_data[$fieldName];
386
+			}
387
+
388
+		}
389
+		return $set_column_values;//validation fo this data to be performed by the model before insertion.
390
+	}
391
+
392
+
393
+	/**
394
+	 *_questions_overview_list_table
395
+	 */
396
+	protected function _questions_overview_list_table()
397
+	{
398
+		$this->_search_btn_label = esc_html__('Questions', 'event_espresso');
399
+		$this->display_admin_list_table_page_with_sidebar();
400
+	}
401
+
402
+
403
+	/**
404
+	 * _edit_question
405
+	 */
406
+	protected function _edit_question()
407
+	{
408
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
409
+		$ID = isset($this->_req_data['QST_ID']) && ! empty($this->_req_data['QST_ID']) ? absint($this->_req_data['QST_ID']) : false;
410
+
411
+		switch ($this->_req_action) {
412
+			case 'add_question' :
413
+				$this->_admin_page_title = esc_html__('Add Question', 'event_espresso');
414
+				break;
415
+			case 'edit_question' :
416
+				$this->_admin_page_title = esc_html__('Edit Question', 'event_espresso');
417
+				break;
418
+			default :
419
+				$this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
420
+		}
421
+
422
+		// add PRC_ID to title if editing
423
+		$this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
424
+		if ($ID) {
425
+			$question                 = $this->_question_model->get_one_by_ID($ID);
426
+			$additional_hidden_fields = array('QST_ID' => array('type' => 'hidden', 'value' => $ID));
427
+			$this->_set_add_edit_form_tags('update_question', $additional_hidden_fields);
428
+		} else {
429
+			$question = EE_Question::new_instance();
430
+			$question->set_order_to_latest();
431
+			$this->_set_add_edit_form_tags('insert_question');
432
+		}
433
+		$question_types                                     = $question->has_answers() ? $this->_question_model->question_types_in_same_category($question->type()) : $this->_question_model->allowed_question_types();
434
+		$this->_template_args['QST_ID']                     = $ID;
435
+		$this->_template_args['question']                   = $question;
436
+		$this->_template_args['question_types']             = $question_types;
437
+		$this->_template_args['max_max']                    = EEM_Question::instance()->absolute_max_for_system_question($question->system_ID());
438
+		$this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
439
+		$this->_set_publish_post_box_vars('id', $ID);
440
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
441
+			$this->_template_args, true);
442
+
443
+		// the details template wrapper
444
+		$this->display_admin_page_with_sidebar();
445
+	}
446
+
447
+
448
+	/**
449
+	 * @return string
450
+	 */
451
+	protected function _get_question_type_descriptions()
452
+	{
453
+		EE_Registry::instance()->load_helper('HTML');
454
+		$descriptions               = '';
455
+		$question_type_descriptions = EEM_Question::instance()->question_descriptions();
456
+		foreach ($question_type_descriptions as $type => $question_type_description) {
457
+			if ($type == 'HTML_TEXTAREA') {
458
+				$html = new EE_Simple_HTML_Validation_Strategy();
459
+				$question_type_description .= sprintf(
460
+					esc_html__('%1$s(allowed tags: %2$s)', 'event_espresso'),
461
+					'<br/>',
462
+					$html->get_list_of_allowed_tags()
463
+				);
464
+			}
465
+			$descriptions .= EEH_HTML::p(
466
+				$question_type_description,
467
+				'question_type_description-' . $type,
468
+				'question_type_description description',
469
+				'display:none;'
470
+			);
471
+		}
472
+		return $descriptions;
473
+	}
474
+
475
+
476
+	/**
477
+	 * @param bool|true $new_question
478
+	 * @throws \EE_Error
479
+	 */
480
+	protected function _insert_or_update_question($new_question = true)
481
+	{
482
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
483
+		$set_column_values = $this->_set_column_values_for($this->_question_model);
484
+		if ($new_question) {
485
+			$ID          = $this->_question_model->insert($set_column_values);
486
+			$success     = $ID ? true : false;
487
+			$action_desc = 'added';
488
+		} else {
489
+			$ID     = absint($this->_req_data['QST_ID']);
490
+			$pk     = $this->_question_model->primary_key_name();
491
+			$wheres = array($pk => $ID);
492
+			unset($set_column_values[$pk]);
493
+			$success     = $this->_question_model->update($set_column_values, array($wheres));
494
+			$action_desc = 'updated';
495
+		}
496
+
497
+		if ($ID) {
498
+			//save the related options
499
+			//trash removed options, save old ones
500
+			//get list of all options
501
+			/** @type EE_Question $question */
502
+			$question = $this->_question_model->get_one_by_ID($ID);
503
+			$options  = $question->options();
504
+			if (! empty($options)) {
505
+				foreach ($options as $option_ID => $option) {
506
+					$option_req_index = $this->_get_option_req_data_index($option_ID);
507
+					if ($option_req_index !== false) {
508
+						$option->save($this->_req_data['question_options'][$option_req_index]);
509
+					} else {
510
+						//not found, remove it
511
+						$option->delete();
512
+					}
513
+				}
514
+			}
515
+			//save new related options
516
+			foreach ($this->_req_data['question_options'] as $index => $option_req_data) {
517
+				if (empty($option_req_data['QSO_ID']) && ((isset($option_req_data['QSO_value']) && $option_req_data['QSO_value'] !== '') || ! empty($option_req_data['QSO_desc']))) {//no ID! save it!
518
+					if (! isset($option_req_data['QSO_value']) || $option_req_data['QSO_value'] === '') {
519
+						$option_req_data['QSO_value'] = $option_req_data['QSO_desc'];
520
+					}
521
+					$new_option = EE_Question_Option::new_instance(array(
522
+						'QSO_value' => $option_req_data['QSO_value'],
523
+						'QSO_desc'  => $option_req_data['QSO_desc'],
524
+						'QSO_order' => $option_req_data['QSO_order'],
525
+						'QST_ID'    => $question->ID(),
526
+					));
527
+					$new_option->save();
528
+				}
529
+			}
530
+		}
531
+		$query_args = array('action' => 'edit_question', 'QST_ID' => $ID);
532
+		if ($success !== false) {
533
+			$msg = $new_question ? sprintf(esc_html__('The %s has been created', 'event_espresso'),
534
+				$this->_question_model->item_name()) : sprintf(esc_html__('The %s has been updated', 'event_espresso'),
535
+				$this->_question_model->item_name());
536
+			EE_Error::add_success($msg);
537
+		}
538
+
539
+		$this->_redirect_after_action(false, '', $action_desc, $query_args, true);
540
+	}
541
+
542
+
543
+	/**
544
+	 * Upon saving a question, there should be an array of 'question_options'. This array is index numerically, but not
545
+	 * by ID
546
+	 * (this is done because new question options don't have an ID, but we may want to add multiple simultaneously).
547
+	 * So, this function gets the index in that request data array called question_options. Returns FALSE if not found.
548
+	 *
549
+	 * @param int $ID of the question option to find
550
+	 * @return int index in question_options array if successful, FALSE if unsuccessful
551
+	 */
552
+	protected function _get_option_req_data_index($ID)
553
+	{
554
+		$req_data_for_question_options = $this->_req_data['question_options'];
555
+		foreach ($req_data_for_question_options as $num => $option_data) {
556
+			if (array_key_exists('QSO_ID', $option_data) && (int)$option_data['QSO_ID'] === $ID) {
557
+				return $num;
558
+			}
559
+		}
560
+		return false;
561
+	}
562
+
563
+
564
+
565
+
566
+	/***********/
567
+	/* QUERIES */
568
+	/**
569
+	 * For internal use in getting all the query parameters
570
+	 * (because it's pretty well the same between question, question groups,
571
+	 * and for both when searching for trashed and untrashed ones)
572
+	 *
573
+	 * @param EEM_Base $model either EEM_Question or EEM_Question_Group
574
+	 * @param int      $per_page
575
+	 * @param int      $current_page
576
+	 * @return array lik EEM_Base::get_all's $query_params parameter
577
+	 */
578
+	protected function get_query_params($model, $per_page = 10, $current_page = 10)
579
+	{
580
+		$query_params             = array();
581
+		$offset                   = ($current_page - 1) * $per_page;
582
+		$query_params['limit']    = array($offset, $per_page);
583
+		$order                    = (isset($this->_req_data['order']) && ! empty($this->_req_data['order'])) ? $this->_req_data['order'] : 'ASC';
584
+		$orderby_field            = $model instanceof EEM_Question ? 'QST_ID' : 'QSG_order';
585
+		$field_to_order_by        = empty($this->_req_data['orderby']) ? $orderby_field : $this->_req_data['orderby'];
586
+		$query_params['order_by'] = array($field_to_order_by => $order);
587
+		$search_string            = array_key_exists('s', $this->_req_data) ? $this->_req_data['s'] : null;
588
+		if (! empty($search_string)) {
589
+			if ($model instanceof EEM_Question_Group) {
590
+				$query_params[0] = array(
591
+					'OR' => array(
592
+						'QSG_name' => array('LIKE', "%$search_string%"),
593
+						'QSG_desc' => array('LIKE', "%$search_string%"),
594
+					),
595
+				);
596
+			} else {
597
+				$query_params[0] = array(
598
+					'QST_display_text' => array('LIKE', "%$search_string%"),
599
+				);
600
+			}
601
+		}
602
+
603
+		//capability checks (just leaving this commented out for reference because it illustrates some complicated query params that could be useful when fully implemented)
604
+		/*if ( $model instanceof EEM_Question_Group ) {
605 605
             if ( ! EE_Registry::instance()->CAP->current_user_can( 'edit_others_question_groups', 'espresso_registration_form_edit_question_group' ) ) {
606 606
                 $query_params[0] = array(
607 607
                     'AND' => array(
@@ -631,62 +631,62 @@  discard block
 block discarded – undo
631 631
             }
632 632
         }/**/
633 633
 
634
-        return $query_params;
635
-
636
-    }
637
-
638
-
639
-    /**
640
-     * @param int        $per_page
641
-     * @param int        $current_page
642
-     * @param bool|false $count
643
-     * @return \EE_Soft_Delete_Base_Class[]|int
644
-     */
645
-    public function get_questions($per_page = 10, $current_page = 1, $count = false)
646
-    {
647
-        $QST          = EEM_Question::instance();
648
-        $query_params = $this->get_query_params($QST, $per_page, $current_page);
649
-        if ($count) {
650
-            $where   = isset($query_params[0]) ? array($query_params[0]) : array();
651
-            $results = $QST->count($where);
652
-        } else {
653
-            $results = $QST->get_all($query_params);
654
-        }
655
-        return $results;
656
-
657
-    }
658
-
659
-
660
-    /**
661
-     * @param            $per_page
662
-     * @param int        $current_page
663
-     * @param bool|false $count
664
-     * @return \EE_Soft_Delete_Base_Class[]|int
665
-     */
666
-    public function get_trashed_questions($per_page, $current_page = 1, $count = false)
667
-    {
668
-        $query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
669
-        $where        = isset($query_params[0]) ? array($query_params[0]) : array();
670
-        $questions    = $count ? EEM_Question::instance()->count_deleted($where) : EEM_Question::instance()->get_all_deleted($query_params);
671
-        return $questions;
672
-    }
673
-
674
-
675
-    /**
676
-     * @param            $per_page
677
-     * @param int        $current_page
678
-     * @param bool|false $count
679
-     * @return \EE_Soft_Delete_Base_Class[]
680
-     */
681
-    public function get_question_groups($per_page, $current_page = 1, $count = false)
682
-    {
683
-        /** @type EEM_Question_Group $questionGroupModel */
684
-        $questionGroupModel = EEM_Question_Group::instance();
685
-        //note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
686
-        return $questionGroupModel->get_all(
687
-            $this->get_query_params($questionGroupModel, $per_page, $current_page)
688
-        );
689
-    }
634
+		return $query_params;
635
+
636
+	}
637
+
638
+
639
+	/**
640
+	 * @param int        $per_page
641
+	 * @param int        $current_page
642
+	 * @param bool|false $count
643
+	 * @return \EE_Soft_Delete_Base_Class[]|int
644
+	 */
645
+	public function get_questions($per_page = 10, $current_page = 1, $count = false)
646
+	{
647
+		$QST          = EEM_Question::instance();
648
+		$query_params = $this->get_query_params($QST, $per_page, $current_page);
649
+		if ($count) {
650
+			$where   = isset($query_params[0]) ? array($query_params[0]) : array();
651
+			$results = $QST->count($where);
652
+		} else {
653
+			$results = $QST->get_all($query_params);
654
+		}
655
+		return $results;
656
+
657
+	}
658
+
659
+
660
+	/**
661
+	 * @param            $per_page
662
+	 * @param int        $current_page
663
+	 * @param bool|false $count
664
+	 * @return \EE_Soft_Delete_Base_Class[]|int
665
+	 */
666
+	public function get_trashed_questions($per_page, $current_page = 1, $count = false)
667
+	{
668
+		$query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
669
+		$where        = isset($query_params[0]) ? array($query_params[0]) : array();
670
+		$questions    = $count ? EEM_Question::instance()->count_deleted($where) : EEM_Question::instance()->get_all_deleted($query_params);
671
+		return $questions;
672
+	}
673
+
674
+
675
+	/**
676
+	 * @param            $per_page
677
+	 * @param int        $current_page
678
+	 * @param bool|false $count
679
+	 * @return \EE_Soft_Delete_Base_Class[]
680
+	 */
681
+	public function get_question_groups($per_page, $current_page = 1, $count = false)
682
+	{
683
+		/** @type EEM_Question_Group $questionGroupModel */
684
+		$questionGroupModel = EEM_Question_Group::instance();
685
+		//note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
686
+		return $questionGroupModel->get_all(
687
+			$this->get_query_params($questionGroupModel, $per_page, $current_page)
688
+		);
689
+	}
690 690
 
691 691
 
692 692
 } //ends Registration_Form_Admin_Page class
Please login to merge, or discard this patch.
Spacing   +23 added lines, -23 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
 
@@ -66,8 +66,8 @@  discard block
 block discarded – undo
66 66
      */
67 67
     public function __construct($routing = true)
68 68
     {
69
-        require_once(EE_MODELS . 'EEM_Question.model.php');
70
-        require_once(EE_MODELS . 'EEM_Question_Group.model.php');
69
+        require_once(EE_MODELS.'EEM_Question.model.php');
70
+        require_once(EE_MODELS.'EEM_Question_Group.model.php');
71 71
         $this->_question_model       = EEM_Question::instance();
72 72
         $this->_question_group_model = EEM_Question_Group::instance();
73 73
         parent::__construct($routing);
@@ -232,7 +232,7 @@  discard block
 block discarded – undo
232 232
     public function load_scripts_styles()
233 233
     {
234 234
         wp_register_style('espresso_registration',
235
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css', array(), EVENT_ESPRESSO_VERSION);
235
+            REGISTRATION_FORM_ASSETS_URL.'espresso_registration_form_admin.css', array(), EVENT_ESPRESSO_VERSION);
236 236
         wp_enqueue_style('espresso_registration');
237 237
     }
238 238
 
@@ -258,7 +258,7 @@  discard block
 block discarded – undo
258 258
     {
259 259
         $this->load_scripts_styles_forms();
260 260
         wp_register_script('espresso_registration_form_single',
261
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
261
+            REGISTRATION_FORM_ASSETS_URL.'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
262 262
             EVENT_ESPRESSO_VERSION, true);
263 263
         wp_enqueue_script('espresso_registration_form_single');
264 264
     }
@@ -267,7 +267,7 @@  discard block
 block discarded – undo
267 267
     {
268 268
         $this->load_scripts_styles_forms();
269 269
         wp_register_script('espresso_registration_form_single',
270
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
270
+            REGISTRATION_FORM_ASSETS_URL.'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
271 271
             EVENT_ESPRESSO_VERSION, true);
272 272
         wp_enqueue_script('espresso_registration_form_single');
273 273
     }
@@ -275,7 +275,7 @@  discard block
 block discarded – undo
275 275
 
276 276
     public function recaptcha_info_help_tab()
277 277
     {
278
-        $template = REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php';
278
+        $template = REGISTRATION_FORM_TEMPLATE_PATH.'recaptcha_info_help_tab.template.php';
279 279
         EEH_Template::display_template($template, array());
280 280
     }
281 281
 
@@ -324,10 +324,10 @@  discard block
 block discarded – undo
324 324
     protected function _questions_groups_preview()
325 325
     {
326 326
         $this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
327
-        $this->_template_args['preview_img']  = '<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="' . esc_attr__('Preview Question Groups Overview List Table screenshot',
328
-                'event_espresso') . '" />';
329
-        $this->_template_args['preview_text'] = '<strong>' . esc_html__('Question Groups 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 Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
330
-                'event_espresso') . '</strong>';
327
+        $this->_template_args['preview_img']  = '<img src="'.REGISTRATION_FORM_ASSETS_URL.'caf_reg_form_preview.jpg" alt="'.esc_attr__('Preview Question Groups Overview List Table screenshot',
328
+                'event_espresso').'" />';
329
+        $this->_template_args['preview_text'] = '<strong>'.esc_html__('Question Groups 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 Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
330
+                'event_espresso').'</strong>';
331 331
         $this->display_admin_caf_preview_page('question_groups_tab');
332 332
     }
333 333
 
@@ -345,20 +345,20 @@  discard block
 block discarded – undo
345 345
 
346 346
         //some initial checks for proper values.
347 347
         //if QST_admin_only, then no matter what QST_required is we disable.
348
-        if (! empty($this->_req_data['QST_admin_only'])) {
348
+        if ( ! empty($this->_req_data['QST_admin_only'])) {
349 349
             $this->_req_data['QST_required'] = 0;
350 350
         }
351 351
         foreach ($model->field_settings() as $fieldName => $settings) {
352 352
             // basically if QSG_identifier is empty or not set
353 353
             if ($fieldName === 'QSG_identifier' && (isset($this->_req_data['QSG_identifier']) && empty($this->_req_data['QSG_identifier']))) {
354 354
                 $QSG_name                      = isset($this->_req_data['QSG_name']) ? $this->_req_data['QSG_name'] : '';
355
-                $set_column_values[$fieldName] = sanitize_title($QSG_name) . '-' . uniqid('', true);
355
+                $set_column_values[$fieldName] = sanitize_title($QSG_name).'-'.uniqid('', true);
356 356
 //				dd($set_column_values);
357 357
             } //if the admin label is blank, use a slug version of the question text
358 358
             else if ($fieldName === 'QST_admin_label' && (isset($this->_req_data['QST_admin_label']) && empty($this->_req_data['QST_admin_label']))) {
359 359
                 $QST_text                      = isset($this->_req_data['QST_display_text']) ? $this->_req_data['QST_display_text'] : '';
360 360
                 $set_column_values[$fieldName] = sanitize_title(wp_trim_words($QST_text, 10));
361
-            } else if ($fieldName === 'QST_admin_only' && (! isset($this->_req_data['QST_admin_only']))) {
361
+            } else if ($fieldName === 'QST_admin_only' && ( ! isset($this->_req_data['QST_admin_only']))) {
362 362
                 $set_column_values[$fieldName] = 0;
363 363
             } else if ($fieldName === 'QST_max') {
364 364
                 $qst_system = EEM_Question::instance()->get_var(
@@ -368,7 +368,7 @@  discard block
 block discarded – undo
368 368
                         ),
369 369
                     ),
370 370
                     'QST_system');
371
-                $max_max    = EEM_Question::instance()->absolute_max_for_system_question($qst_system);
371
+                $max_max = EEM_Question::instance()->absolute_max_for_system_question($qst_system);
372 372
                 if (empty($this->_req_data['QST_max']) ||
373 373
                     $this->_req_data['QST_max'] > $max_max
374 374
                 ) {
@@ -386,7 +386,7 @@  discard block
 block discarded – undo
386 386
             }
387 387
 
388 388
         }
389
-        return $set_column_values;//validation fo this data to be performed by the model before insertion.
389
+        return $set_column_values; //validation fo this data to be performed by the model before insertion.
390 390
     }
391 391
 
392 392
 
@@ -420,7 +420,7 @@  discard block
 block discarded – undo
420 420
         }
421 421
 
422 422
         // add PRC_ID to title if editing
423
-        $this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
423
+        $this->_admin_page_title = $ID ? $this->_admin_page_title.' # '.$ID : $this->_admin_page_title;
424 424
         if ($ID) {
425 425
             $question                 = $this->_question_model->get_one_by_ID($ID);
426 426
             $additional_hidden_fields = array('QST_ID' => array('type' => 'hidden', 'value' => $ID));
@@ -437,7 +437,7 @@  discard block
 block discarded – undo
437 437
         $this->_template_args['max_max']                    = EEM_Question::instance()->absolute_max_for_system_question($question->system_ID());
438 438
         $this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
439 439
         $this->_set_publish_post_box_vars('id', $ID);
440
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
440
+        $this->_template_args['admin_page_content'] = EEH_Template::display_template(REGISTRATION_FORM_TEMPLATE_PATH.'questions_main_meta_box.template.php',
441 441
             $this->_template_args, true);
442 442
 
443 443
         // the details template wrapper
@@ -464,7 +464,7 @@  discard block
 block discarded – undo
464 464
             }
465 465
             $descriptions .= EEH_HTML::p(
466 466
                 $question_type_description,
467
-                'question_type_description-' . $type,
467
+                'question_type_description-'.$type,
468 468
                 'question_type_description description',
469 469
                 'display:none;'
470 470
             );
@@ -501,7 +501,7 @@  discard block
 block discarded – undo
501 501
             /** @type EE_Question $question */
502 502
             $question = $this->_question_model->get_one_by_ID($ID);
503 503
             $options  = $question->options();
504
-            if (! empty($options)) {
504
+            if ( ! empty($options)) {
505 505
                 foreach ($options as $option_ID => $option) {
506 506
                     $option_req_index = $this->_get_option_req_data_index($option_ID);
507 507
                     if ($option_req_index !== false) {
@@ -515,7 +515,7 @@  discard block
 block discarded – undo
515 515
             //save new related options
516 516
             foreach ($this->_req_data['question_options'] as $index => $option_req_data) {
517 517
                 if (empty($option_req_data['QSO_ID']) && ((isset($option_req_data['QSO_value']) && $option_req_data['QSO_value'] !== '') || ! empty($option_req_data['QSO_desc']))) {//no ID! save it!
518
-                    if (! isset($option_req_data['QSO_value']) || $option_req_data['QSO_value'] === '') {
518
+                    if ( ! isset($option_req_data['QSO_value']) || $option_req_data['QSO_value'] === '') {
519 519
                         $option_req_data['QSO_value'] = $option_req_data['QSO_desc'];
520 520
                     }
521 521
                     $new_option = EE_Question_Option::new_instance(array(
@@ -553,7 +553,7 @@  discard block
 block discarded – undo
553 553
     {
554 554
         $req_data_for_question_options = $this->_req_data['question_options'];
555 555
         foreach ($req_data_for_question_options as $num => $option_data) {
556
-            if (array_key_exists('QSO_ID', $option_data) && (int)$option_data['QSO_ID'] === $ID) {
556
+            if (array_key_exists('QSO_ID', $option_data) && (int) $option_data['QSO_ID'] === $ID) {
557 557
                 return $num;
558 558
             }
559 559
         }
@@ -585,7 +585,7 @@  discard block
 block discarded – undo
585 585
         $field_to_order_by        = empty($this->_req_data['orderby']) ? $orderby_field : $this->_req_data['orderby'];
586 586
         $query_params['order_by'] = array($field_to_order_by => $order);
587 587
         $search_string            = array_key_exists('s', $this->_req_data) ? $this->_req_data['s'] : null;
588
-        if (! empty($search_string)) {
588
+        if ( ! empty($search_string)) {
589 589
             if ($model instanceof EEM_Question_Group) {
590 590
                 $query_params[0] = array(
591 591
                     'OR' => array(
Please login to merge, or discard this patch.
admin_pages/messages/Messages_Admin_Page.core.php 2 patches
Spacing   +119 added lines, -119 removed lines patch added patch discarded remove patch
@@ -87,7 +87,7 @@  discard block
 block discarded – undo
87 87
         $this->_admin_base_url  = EE_MSG_ADMIN_URL;
88 88
         $this->_admin_base_path = EE_MSG_ADMIN;
89 89
         
90
-        $this->_activate_state = isset($this->_req_data['activate_state']) ? (array)$this->_req_data['activate_state'] : array();
90
+        $this->_activate_state = isset($this->_req_data['activate_state']) ? (array) $this->_req_data['activate_state'] : array();
91 91
         
92 92
         $this->_active_messenger = isset($this->_req_data['messenger']) ? $this->_req_data['messenger'] : null;
93 93
         $this->_load_message_resource_manager();
@@ -219,7 +219,7 @@  discard block
 block discarded – undo
219 219
             array('none_selected' => __('Show All Messengers', 'event_espresso')),
220 220
             $messenger_options
221 221
         );
222
-        $input             = new EE_Select_Input(
222
+        $input = new EE_Select_Input(
223 223
             $messenger_options,
224 224
             array(
225 225
                 'html_name'  => 'ee_messenger_filter_by',
@@ -257,7 +257,7 @@  discard block
 block discarded – undo
257 257
             array('none_selected' => __('Show All Message Types', 'event_espresso')),
258 258
             $message_type_options
259 259
         );
260
-        $input                = new EE_Select_Input(
260
+        $input = new EE_Select_Input(
261 261
             $message_type_options,
262 262
             array(
263 263
                 'html_name'  => 'ee_message_type_filter_by',
@@ -295,7 +295,7 @@  discard block
 block discarded – undo
295 295
             array('none_selected' => __('Show all Contexts', 'event_espresso')),
296 296
             $context_options
297 297
         );
298
-        $input           = new EE_Select_Input(
298
+        $input = new EE_Select_Input(
299 299
             $context_options,
300 300
             array(
301 301
                 'html_name'  => 'ee_context_filter_by',
@@ -676,47 +676,47 @@  discard block
 block discarded – undo
676 676
     
677 677
     public function messages_help_tab()
678 678
     {
679
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
679
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_messages_help_tab.template.php');
680 680
     }
681 681
     
682 682
     
683 683
     public function messengers_help_tab()
684 684
     {
685
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
685
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_messenger_help_tab.template.php');
686 686
     }
687 687
     
688 688
     
689 689
     public function message_types_help_tab()
690 690
     {
691
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
691
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_message_type_help_tab.template.php');
692 692
     }
693 693
     
694 694
     
695 695
     public function messages_overview_help_tab()
696 696
     {
697
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
697
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_overview_help_tab.template.php');
698 698
     }
699 699
     
700 700
     
701 701
     public function message_templates_help_tab()
702 702
     {
703
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
703
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_message_templates_help_tab.template.php');
704 704
     }
705 705
     
706 706
     
707 707
     public function edit_message_template_help_tab()
708 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',
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 720
             $args);
721 721
     }
722 722
     
@@ -725,37 +725,37 @@  discard block
 block discarded – undo
725 725
     {
726 726
         $this->_set_shortcodes();
727 727
         $args['shortcodes'] = $this->_shortcodes;
728
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
728
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_messages_shortcodes_help_tab.template.php',
729 729
             $args);
730 730
     }
731 731
     
732 732
     
733 733
     public function preview_message_help_tab()
734 734
     {
735
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
735
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_preview_help_tab.template.php');
736 736
     }
737 737
     
738 738
     
739 739
     public function settings_help_tab()
740 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') . '" />';
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 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 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);
747
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_messages_settings_help_tab.template.php', $args);
748 748
     }
749 749
     
750 750
     
751 751
     public function load_scripts_styles()
752 752
     {
753
-        wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
753
+        wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL.'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
754 754
         wp_enqueue_style('espresso_ee_msg');
755 755
         
756
-        wp_register_script('ee-messages-settings', EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
756
+        wp_register_script('ee-messages-settings', EE_MSG_ASSETS_URL.'ee-messages-settings.js',
757 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',
758
+        wp_register_script('ee-msg-list-table-js', EE_MSG_ASSETS_URL.'ee_message_admin_list_table.js',
759 759
             array('ee-dialog'), EVENT_ESPRESSO_VERSION);
760 760
     }
761 761
     
@@ -787,7 +787,7 @@  discard block
 block discarded – undo
787 787
         
788 788
         $this->_set_shortcodes();
789 789
         
790
-        EE_Registry::$i18n_js_strings['confirm_default_reset']        = sprintf(
790
+        EE_Registry::$i18n_js_strings['confirm_default_reset'] = sprintf(
791 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 792
                 'event_espresso'),
793 793
             $this->_message_template_group->messenger_obj()->label['singular'],
@@ -796,7 +796,7 @@  discard block
 block discarded – undo
796 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 797
             'event_espresso');
798 798
         
799
-        wp_register_script('ee_msgs_edit_js', EE_MSG_ASSETS_URL . 'ee_message_editor.js', array('jquery'),
799
+        wp_register_script('ee_msgs_edit_js', EE_MSG_ASSETS_URL.'ee_message_editor.js', array('jquery'),
800 800
             EVENT_ESPRESSO_VERSION);
801 801
         
802 802
         wp_enqueue_script('ee_admin_js');
@@ -827,7 +827,7 @@  discard block
 block discarded – undo
827 827
     
828 828
     public function load_scripts_styles_settings()
829 829
     {
830
-        wp_register_style('ee-message-settings', EE_MSG_ASSETS_URL . 'ee_message_settings.css', array(),
830
+        wp_register_style('ee-message-settings', EE_MSG_ASSETS_URL.'ee_message_settings.css', array(),
831 831
             EVENT_ESPRESSO_VERSION);
832 832
         wp_enqueue_style('ee-text-links');
833 833
         wp_enqueue_style('ee-message-settings');
@@ -893,7 +893,7 @@  discard block
 block discarded – undo
893 893
             }
894 894
             $status_bulk_actions = $common_bulk_actions;
895 895
             //unset bulk actions not applying to status
896
-            if (! empty($status_bulk_actions)) {
896
+            if ( ! empty($status_bulk_actions)) {
897 897
                 switch ($status) {
898 898
                     case EEM_Message::status_idle:
899 899
                     case EEM_Message::status_resend:
@@ -918,7 +918,7 @@  discard block
 block discarded – undo
918 918
             }
919 919
 
920 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 ) {
921
+            if ($status === EEM_Message::status_messenger_executing) {
922 922
                 continue;
923 923
             }
924 924
             
@@ -944,7 +944,7 @@  discard block
 block discarded – undo
944 944
         $this->_search_btn_label                   = __('Message Activity', 'event_espresso');
945 945
         $this->_template_args['per_column']        = 6;
946 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>';
947
+        $this->_template_args['before_list_table'] = '<h3>'.EEM_Message::instance()->get_pretty_label_for_results().'</h3>';
948 948
         $this->display_admin_list_table_page_with_no_sidebar();
949 949
     }
950 950
     
@@ -968,37 +968,37 @@  discard block
 block discarded – undo
968 968
         /** @type array $status_items status legend setup */
969 969
         $status_items = array(
970 970
             'sent_status'       => array(
971
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_sent,
971
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_sent,
972 972
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence')
973 973
             ),
974 974
             'idle_status'       => array(
975
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_idle,
975
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_idle,
976 976
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence')
977 977
             ),
978 978
             'failed_status'     => array(
979
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_failed,
979
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_failed,
980 980
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence')
981 981
             ),
982 982
             'messenger_executing_status' => array(
983
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_messenger_executing,
983
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_messenger_executing,
984 984
                 'desc' => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence')
985 985
             ),
986 986
             'resend_status'     => array(
987
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_resend,
987
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_resend,
988 988
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence')
989 989
             ),
990 990
             'incomplete_status' => array(
991
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_incomplete,
991
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_incomplete,
992 992
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence')
993 993
             ),
994 994
             'retry_status'      => array(
995
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_retry,
995
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_retry,
996 996
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence')
997 997
             )
998 998
         );
999 999
         if (EEM_Message::debug()) {
1000 1000
             $status_items['debug_only_status'] = array(
1001
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_debug_only,
1001
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_debug_only,
1002 1002
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence')
1003 1003
             );
1004 1004
         }
@@ -1010,10 +1010,10 @@  discard block
 block discarded – undo
1010 1010
     protected function _custom_mtps_preview()
1011 1011
     {
1012 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>';
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 1017
         $this->display_admin_caf_preview_page('custom_message_types', false);
1018 1018
     }
1019 1019
     
@@ -1261,7 +1261,7 @@  discard block
 block discarded – undo
1261 1261
                             //let's verify if we need this extra field via the shortcodes parameter.
1262 1262
                             $continue = false;
1263 1263
                             if (isset($extra_array['shortcodes_required'])) {
1264
-                                foreach ((array)$extra_array['shortcodes_required'] as $shortcode) {
1264
+                                foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1265 1265
                                     if ( ! array_key_exists($shortcode, $this->_shortcodes)) {
1266 1266
                                         $continue = true;
1267 1267
                                     }
@@ -1271,9 +1271,9 @@  discard block
 block discarded – undo
1271 1271
                                 }
1272 1272
                             }
1273 1273
                             
1274
-                            $field_id                                = $reference_field . '-' . $extra_field . '-content';
1274
+                            $field_id                                = $reference_field.'-'.$extra_field.'-content';
1275 1275
                             $template_form_fields[$field_id]         = $extra_array;
1276
-                            $template_form_fields[$field_id]['name'] = 'MTP_template_fields[' . $reference_field . '][content][' . $extra_field . ']';
1276
+                            $template_form_fields[$field_id]['name'] = 'MTP_template_fields['.$reference_field.'][content]['.$extra_field.']';
1277 1277
                             $css_class                               = isset($extra_array['css_class']) ? $extra_array['css_class'] : '';
1278 1278
                             
1279 1279
                             $template_form_fields[$field_id]['css_class'] = ! empty($v_fields)
@@ -1283,7 +1283,7 @@  discard block
 block discarded – undo
1283 1283
                                                                                 is_array($validators[$extra_field])
1284 1284
                                                                                 && isset($validators[$extra_field]['msg'])
1285 1285
                                                                             )
1286
-                                ? 'validate-error ' . $css_class
1286
+                                ? 'validate-error '.$css_class
1287 1287
                                 : $css_class;
1288 1288
                             
1289 1289
                             $template_form_fields[$field_id]['value'] = ! empty($message_templates) && isset($content[$extra_field])
@@ -1311,11 +1311,11 @@  discard block
 block discarded – undo
1311 1311
                                 
1312 1312
                             }/**/
1313 1313
                         }
1314
-                        $templatefield_MTP_id          = $reference_field . '-MTP_ID';
1315
-                        $templatefield_templatename_id = $reference_field . '-name';
1314
+                        $templatefield_MTP_id          = $reference_field.'-MTP_ID';
1315
+                        $templatefield_templatename_id = $reference_field.'-name';
1316 1316
                         
1317 1317
                         $template_form_fields[$templatefield_MTP_id] = array(
1318
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1318
+                            'name'       => 'MTP_template_fields['.$reference_field.'][MTP_ID]',
1319 1319
                             'label'      => null,
1320 1320
                             'input'      => 'hidden',
1321 1321
                             'type'       => 'int',
@@ -1328,7 +1328,7 @@  discard block
 block discarded – undo
1328 1328
                         );
1329 1329
                         
1330 1330
                         $template_form_fields[$templatefield_templatename_id] = array(
1331
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1331
+                            'name'       => 'MTP_template_fields['.$reference_field.'][name]',
1332 1332
                             'label'      => null,
1333 1333
                             'input'      => 'hidden',
1334 1334
                             'type'       => 'string',
@@ -1342,9 +1342,9 @@  discard block
 block discarded – undo
1342 1342
                     }
1343 1343
                     continue; //skip the next stuff, we got the necessary fields here for this dataset.
1344 1344
                 } else {
1345
-                    $field_id                                 = $template_field . '-content';
1345
+                    $field_id                                 = $template_field.'-content';
1346 1346
                     $template_form_fields[$field_id]          = $field_setup_array;
1347
-                    $template_form_fields[$field_id]['name']  = 'MTP_template_fields[' . $template_field . '][content]';
1347
+                    $template_form_fields[$field_id]['name']  = 'MTP_template_fields['.$template_field.'][content]';
1348 1348
                     $message_template                         = isset($message_templates[$context][$template_field])
1349 1349
                         ? $message_templates[$context][$template_field]
1350 1350
                         : null;
@@ -1365,7 +1365,7 @@  discard block
 block discarded – undo
1365 1365
                     $template_form_fields[$field_id]['css_class'] = ! empty($v_fields)
1366 1366
                                                                     && in_array($template_field, $v_fields)
1367 1367
                                                                     && isset($validators[$template_field]['msg'])
1368
-                        ? 'validate-error ' . $css_class
1368
+                        ? 'validate-error '.$css_class
1369 1369
                         : $css_class;
1370 1370
                     
1371 1371
                     //shortcode selector
@@ -1376,12 +1376,12 @@  discard block
 block discarded – undo
1376 1376
                 
1377 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 1382
                 //foreach template field there are actually two form fields created
1383 1383
                 $template_form_fields[$templatefield_MTP_id] = array(
1384
-                    'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1384
+                    'name'       => 'MTP_template_fields['.$template_field.'][MTP_ID]',
1385 1385
                     'label'      => null,
1386 1386
                     'input'      => 'hidden',
1387 1387
                     'type'       => 'int',
@@ -1394,7 +1394,7 @@  discard block
 block discarded – undo
1394 1394
                 );
1395 1395
                 
1396 1396
                 $template_form_fields[$templatefield_field_templatename_id] = array(
1397
-                    'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1397
+                    'name'       => 'MTP_template_fields['.$template_field.'][name]',
1398 1398
                     'label'      => null,
1399 1399
                     'input'      => 'hidden',
1400 1400
                     'type'       => 'string',
@@ -1512,7 +1512,7 @@  discard block
 block discarded – undo
1512 1512
                 'format'     => '%d',
1513 1513
                 'db-col'     => 'MTP_deleted'
1514 1514
             );
1515
-            $sidebar_form_fields['ee-msg-author']  = array(
1515
+            $sidebar_form_fields['ee-msg-author'] = array(
1516 1516
                 'name'       => 'MTP_user_id',
1517 1517
                 'label'      => __('Author', 'event_espresso'),
1518 1518
                 'input'      => 'hidden',
@@ -1531,17 +1531,17 @@  discard block
 block discarded – undo
1531 1531
                 'value' => $action
1532 1532
             );
1533 1533
             
1534
-            $sidebar_form_fields['ee-msg-id']        = array(
1534
+            $sidebar_form_fields['ee-msg-id'] = array(
1535 1535
                 'name'  => 'id',
1536 1536
                 'input' => 'hidden',
1537 1537
                 'type'  => 'int',
1538 1538
                 'value' => $GRP_ID
1539 1539
             );
1540 1540
             $sidebar_form_fields['ee-msg-evt-nonce'] = array(
1541
-                'name'  => $action . '_nonce',
1541
+                'name'  => $action.'_nonce',
1542 1542
                 'input' => 'hidden',
1543 1543
                 'type'  => 'string',
1544
-                'value' => wp_create_nonce($action . '_nonce')
1544
+                'value' => wp_create_nonce($action.'_nonce')
1545 1545
             );
1546 1546
             
1547 1547
             if (isset($this->_req_data['template_switch']) && $this->_req_data['template_switch']) {
@@ -1573,7 +1573,7 @@  discard block
 block discarded – undo
1573 1573
         );
1574 1574
         
1575 1575
         //add preview button
1576
-        $preview_url    = parent::add_query_args_and_nonce(
1576
+        $preview_url = parent::add_query_args_and_nonce(
1577 1577
             array(
1578 1578
                 'message_type' => $message_template_group->message_type(),
1579 1579
                 'messenger'    => $message_template_group->messenger(),
@@ -1583,8 +1583,8 @@  discard block
 block discarded – undo
1583 1583
             ),
1584 1584
             $this->_admin_base_url
1585 1585
         );
1586
-        $preview_button = '<a href="' . $preview_url . '" class="button-secondary messages-preview-button">' . __('Preview',
1587
-                'event_espresso') . '</a>';
1586
+        $preview_button = '<a href="'.$preview_url.'" class="button-secondary messages-preview-button">'.__('Preview',
1587
+                'event_espresso').'</a>';
1588 1588
         
1589 1589
         
1590 1590
         //setup context switcher
@@ -1612,8 +1612,8 @@  discard block
 block discarded – undo
1612 1612
         $this->_template_args['after_admin_page_content'] = $this->_add_form_element_after();
1613 1613
         
1614 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';
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 1617
         
1618 1618
         //send along EE_Message_Template_Group object for further template use.
1619 1619
         $this->_template_args['MTP'] = $message_template_group;
@@ -1648,7 +1648,7 @@  discard block
 block discarded – undo
1648 1648
     
1649 1649
     public function _add_form_element_before()
1650 1650
     {
1651
-        return '<form method="post" action="' . $this->_template_args["edit_message_template_form_url"] . '" id="ee-msg-edit-frm">';
1651
+        return '<form method="post" action="'.$this->_template_args["edit_message_template_form_url"].'" id="ee-msg-edit-frm">';
1652 1652
     }
1653 1653
     
1654 1654
     public function _add_form_element_after()
@@ -1843,14 +1843,14 @@  discard block
 block discarded – undo
1843 1843
         }
1844 1844
         
1845 1845
         //let's add a button to go back to the edit view
1846
-        $query_args             = array(
1846
+        $query_args = array(
1847 1847
             'id'      => $this->_req_data['GRP_ID'],
1848 1848
             'context' => $this->_req_data['context'],
1849 1849
             'action'  => 'edit_message_template'
1850 1850
         );
1851 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>';
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 1854
         $message_types          = $this->get_installed_message_types();
1855 1855
         $active_messenger       = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
1856 1856
         $active_messenger_label = $active_messenger instanceof EE_messenger
@@ -1864,7 +1864,7 @@  discard block
 block discarded – undo
1864 1864
         );
1865 1865
         //setup display of preview.
1866 1866
         $this->_admin_page_title                    = $preview_title;
1867
-        $this->_template_args['admin_page_content'] = $preview_button . '<br />' . stripslashes($preview);
1867
+        $this->_template_args['admin_page_content'] = $preview_button.'<br />'.stripslashes($preview);
1868 1868
         $this->_template_args['data']['force_json'] = true;
1869 1869
         
1870 1870
         return '';
@@ -1946,7 +1946,7 @@  discard block
 block discarded – undo
1946 1946
         }
1947 1947
         
1948 1948
         //setup variation select values for the currently selected template.
1949
-        $variations               = $this->_message_template_group->get_template_pack()->get_variations(
1949
+        $variations = $this->_message_template_group->get_template_pack()->get_variations(
1950 1950
             $this->_message_template_group->messenger(),
1951 1951
             $this->_message_template_group->message_type()
1952 1952
         );
@@ -1960,12 +1960,12 @@  discard block
 block discarded – undo
1960 1960
         
1961 1961
         $template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
1962 1962
         
1963
-        $template_args['template_packs_selector']        = EEH_Form_Fields::select_input(
1963
+        $template_args['template_packs_selector'] = EEH_Form_Fields::select_input(
1964 1964
             'MTP_template_pack',
1965 1965
             $tp_select_values,
1966 1966
             $this->_message_template_group->get_template_pack_name()
1967 1967
         );
1968
-        $template_args['variations_selector']            = EEH_Form_Fields::select_input(
1968
+        $template_args['variations_selector'] = EEH_Form_Fields::select_input(
1969 1969
             'MTP_template_variation',
1970 1970
             $variations_select_values,
1971 1971
             $this->_message_template_group->get_template_pack_variation()
@@ -1975,7 +1975,7 @@  discard block
 block discarded – undo
1975 1975
         $template_args['template_pack_description']      = $template_pack_labels->template_pack_description;
1976 1976
         $template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
1977 1977
         
1978
-        $template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
1978
+        $template = EE_MSG_TEMPLATE_PATH.'template_pack_and_variations_metabox.template.php';
1979 1979
         
1980 1980
         EEH_Template::display_template($template, $template_args);
1981 1981
     }
@@ -2004,7 +2004,7 @@  discard block
 block discarded – undo
2004 2004
         if ( ! empty($fields)) {
2005 2005
             //yup there be fields
2006 2006
             foreach ($fields as $field => $config) {
2007
-                $field_id = $this->_message_template_group->messenger() . '_' . $field;
2007
+                $field_id = $this->_message_template_group->messenger().'_'.$field;
2008 2008
                 $existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2009 2009
                 $default  = isset($config['default']) ? $config['default'] : '';
2010 2010
                 $default  = isset($config['value']) ? $config['value'] : $default;
@@ -2019,7 +2019,7 @@  discard block
 block discarded – undo
2019 2019
                     : $fix;
2020 2020
                 
2021 2021
                 $template_form_fields[$field_id] = array(
2022
-                    'name'       => 'test_settings_fld[' . $field . ']',
2022
+                    'name'       => 'test_settings_fld['.$field.']',
2023 2023
                     'label'      => $config['label'],
2024 2024
                     'input'      => $config['input'],
2025 2025
                     'type'       => $config['type'],
@@ -2049,7 +2049,7 @@  discard block
 block discarded – undo
2049 2049
         }
2050 2050
         
2051 2051
         //and button
2052
-        $test_settings_html .= '<p>' . __('Need to reset this message type and start over?', 'event_espresso') . '</p>';
2052
+        $test_settings_html .= '<p>'.__('Need to reset this message type and start over?', 'event_espresso').'</p>';
2053 2053
         $test_settings_html .= '<div class="publishing-action alignright resetbutton">';
2054 2054
         $test_settings_html .= $this->get_action_link_or_button(
2055 2055
             'reset_to_default',
@@ -2080,7 +2080,7 @@  discard block
 block discarded – undo
2080 2080
             'linked_input_id' => $linked_input_id
2081 2081
         );
2082 2082
         
2083
-        return EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2083
+        return EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'shortcode_selector_skeleton.template.php',
2084 2084
             $template_args, true);
2085 2085
     }
2086 2086
     
@@ -2098,7 +2098,7 @@  discard block
 block discarded – undo
2098 2098
         //$messenger = $this->_message_template_group->messenger_obj();
2099 2099
         //now let's set the content depending on the status of the shortcodes array
2100 2100
         if (empty($shortcodes)) {
2101
-            $content = '<p>' . __('There are no valid shortcodes available', 'event_espresso') . '</p>';
2101
+            $content = '<p>'.__('There are no valid shortcodes available', 'event_espresso').'</p>';
2102 2102
             echo $content;
2103 2103
         } else {
2104 2104
             //$alt = 0;
@@ -2215,7 +2215,7 @@  discard block
 block discarded – undo
2215 2215
                     <?php
2216 2216
                 }
2217 2217
                 //setup nonce_url
2218
-                wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2218
+                wp_nonce_field($args['action'].'_nonce', $args['action'].'_nonce', false);
2219 2219
                 ?>
2220 2220
                 <select name="context">
2221 2221
                     <?php
@@ -2313,7 +2313,7 @@  discard block
 block discarded – undo
2313 2313
             : '';
2314 2314
         $context      = ucwords(str_replace('_', ' ', $context_slug));
2315 2315
         
2316
-        $item_desc = $messenger_label && $message_type_label ? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' ' : '';
2316
+        $item_desc = $messenger_label && $message_type_label ? $messenger_label.' '.$message_type_label.' '.$context.' ' : '';
2317 2317
         $item_desc .= 'Message Template';
2318 2318
         $query_args  = array();
2319 2319
         $edit_array  = array();
@@ -2682,8 +2682,8 @@  discard block
 block discarded – undo
2682 2682
      */
2683 2683
     protected function _learn_more_about_message_templates_link()
2684 2684
     {
2685
-        return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >' . __('learn more about how message templates works',
2686
-            'event_espresso') . '</a>';
2685
+        return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >'.__('learn more about how message templates works',
2686
+            'event_espresso').'</a>';
2687 2687
     }
2688 2688
     
2689 2689
     
@@ -2759,10 +2759,10 @@  discard block
 block discarded – undo
2759 2759
                 
2760 2760
                 $this->_m_mt_settings['message_type_tabs'][$messenger->name][$a_or_i][$message_type->name] = array(
2761 2761
                     'label'    => ucwords($message_type->label['singular']),
2762
-                    'class'    => 'message-type-' . $a_or_i,
2763
-                    'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
2764
-                    'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
2765
-                    'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
2762
+                    'class'    => 'message-type-'.$a_or_i,
2763
+                    'slug_id'  => $message_type->name.'-messagetype-'.$messenger->name,
2764
+                    'mt_nonce' => wp_create_nonce($message_type->name.'_nonce'),
2765
+                    'href'     => 'espresso_'.$message_type->name.'_message_type_settings',
2766 2766
                     'title'    => $a_or_i == 'active'
2767 2767
                         ? __('Drag this message type to the Inactive window to deactivate', 'event_espresso')
2768 2768
                         : __('Drag this message type to the messenger to activate', 'event_espresso'),
@@ -2798,9 +2798,9 @@  discard block
 block discarded – undo
2798 2798
             $existing_settings = $message_type->get_existing_admin_settings($messenger->name);
2799 2799
             
2800 2800
             foreach ($fields as $fldname => $fldprops) {
2801
-                $field_id                       = $messenger->name . '-' . $message_type->name . '-' . $fldname;
2801
+                $field_id                       = $messenger->name.'-'.$message_type->name.'-'.$fldname;
2802 2802
                 $template_form_field[$field_id] = array(
2803
-                    'name'       => 'message_type_settings[' . $fldname . ']',
2803
+                    'name'       => 'message_type_settings['.$fldname.']',
2804 2804
                     'label'      => $fldprops['label'],
2805 2805
                     'input'      => $fldprops['field_type'],
2806 2806
                     'type'       => $fldprops['value_type'],
@@ -2841,7 +2841,7 @@  discard block
 block discarded – undo
2841 2841
         $settings_template_args['show_form']     = empty($settings_template_args['template_form_fields']) ? ' hidden' : '';
2842 2842
         
2843 2843
         
2844
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
2844
+        $template = EE_MSG_TEMPLATE_PATH.'ee_msg_mt_settings_content.template.php';
2845 2845
         $content  = EEH_Template::display_template($template, $settings_template_args, true);
2846 2846
         
2847 2847
         return $content;
@@ -2871,11 +2871,11 @@  discard block
 block discarded – undo
2871 2871
                 $active_mt_tabs                         = isset($this->_m_mt_settings['message_type_tabs'][$messenger]['active'])
2872 2872
                     ? $this->_m_mt_settings['message_type_tabs'][$messenger]['active']
2873 2873
                     : '';
2874
-                $m_boxes[$messenger . '_a_box']         = sprintf(
2874
+                $m_boxes[$messenger.'_a_box']         = sprintf(
2875 2875
                     __('%s Settings', 'event_espresso'),
2876 2876
                     $tab_array['label']
2877 2877
                 );
2878
-                $m_template_args[$messenger . '_a_box'] = array(
2878
+                $m_template_args[$messenger.'_a_box'] = array(
2879 2879
                     'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
2880 2880
                     'inactive_message_types' => isset($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
2881 2881
                         ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
@@ -2889,8 +2889,8 @@  discard block
 block discarded – undo
2889 2889
                 // message type meta boxes
2890 2890
                 // (which is really just the inactive container for each messenger
2891 2891
                 // showing inactive message types for that messenger)
2892
-                $mt_boxes[$messenger . '_i_box']         = __('Inactive Message Types', 'event_espresso');
2893
-                $mt_template_args[$messenger . '_i_box'] = array(
2892
+                $mt_boxes[$messenger.'_i_box']         = __('Inactive Message Types', 'event_espresso');
2893
+                $mt_template_args[$messenger.'_i_box'] = array(
2894 2894
                     'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
2895 2895
                     'inactive_message_types' => isset($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
2896 2896
                         ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
@@ -2906,14 +2906,14 @@  discard block
 block discarded – undo
2906 2906
         
2907 2907
         
2908 2908
         //register messenger metaboxes
2909
-        $m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
2909
+        $m_template_path = EE_MSG_TEMPLATE_PATH.'ee_msg_details_messenger_mt_meta_box.template.php';
2910 2910
         foreach ($m_boxes as $box => $label) {
2911 2911
             $callback_args = array('template_path' => $m_template_path, 'template_args' => $m_template_args[$box]);
2912 2912
             $msgr          = str_replace('_a_box', '', $box);
2913 2913
             add_meta_box(
2914
-                'espresso_' . $msgr . '_settings',
2914
+                'espresso_'.$msgr.'_settings',
2915 2915
                 $label,
2916
-                function ($post, $metabox) {
2916
+                function($post, $metabox) {
2917 2917
                     echo EEH_Template::display_template($metabox["args"]["template_path"],
2918 2918
                         $metabox["args"]["template_args"], true);
2919 2919
                 },
@@ -2925,17 +2925,17 @@  discard block
 block discarded – undo
2925 2925
         }
2926 2926
         
2927 2927
         //register message type metaboxes
2928
-        $mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
2928
+        $mt_template_path = EE_MSG_TEMPLATE_PATH.'ee_msg_details_messenger_meta_box.template.php';
2929 2929
         foreach ($mt_boxes as $box => $label) {
2930 2930
             $callback_args = array(
2931 2931
                 'template_path' => $mt_template_path,
2932 2932
                 'template_args' => $mt_template_args[$box]
2933 2933
             );
2934
-            $mt            = str_replace('_i_box', '', $box);
2934
+            $mt = str_replace('_i_box', '', $box);
2935 2935
             add_meta_box(
2936
-                'espresso_' . $mt . '_inactive_mts',
2936
+                'espresso_'.$mt.'_inactive_mts',
2937 2937
                 $label,
2938
-                function ($post, $metabox) {
2938
+                function($post, $metabox) {
2939 2939
                     echo EEH_Template::display_template($metabox["args"]["template_path"],
2940 2940
                         $metabox["args"]["template_args"], true);
2941 2941
                 },
@@ -3037,7 +3037,7 @@  discard block
 block discarded – undo
3037 3037
             if ($form->is_valid()) {
3038 3038
                 $valid_data = $form->valid_data();
3039 3039
                 foreach ($valid_data as $property => $value) {
3040
-                    $setter = 'set_' . $property;
3040
+                    $setter = 'set_'.$property;
3041 3041
                     if (method_exists($network_config, $setter)) {
3042 3042
                         $network_config->{$setter}($value);
3043 3043
                     } else if (
@@ -3066,8 +3066,8 @@  discard block
 block discarded – undo
3066 3066
      */
3067 3067
     protected function _get_mt_tabs($tab_array)
3068 3068
     {
3069
-        $tab_array = (array)$tab_array;
3070
-        $template  = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3069
+        $tab_array = (array) $tab_array;
3070
+        $template  = EE_MSG_TEMPLATE_PATH.'ee_msg_details_mt_settings_tab_item.template.php';
3071 3071
         $tabs      = '';
3072 3072
         
3073 3073
         foreach ($tab_array as $tab) {
@@ -3100,9 +3100,9 @@  discard block
 block discarded – undo
3100 3100
             $existing_settings = $messenger->get_existing_admin_settings();
3101 3101
             
3102 3102
             foreach ($fields as $fldname => $fldprops) {
3103
-                $field_id                       = $messenger->name . '-' . $fldname;
3103
+                $field_id                       = $messenger->name.'-'.$fldname;
3104 3104
                 $template_form_field[$field_id] = array(
3105
-                    'name'       => 'messenger_settings[' . $field_id . ']',
3105
+                    'name'       => 'messenger_settings['.$field_id.']',
3106 3106
                     'label'      => $fldprops['label'],
3107 3107
                     'input'      => $fldprops['field_type'],
3108 3108
                     'type'       => $fldprops['value_type'],
@@ -3137,7 +3137,7 @@  discard block
 block discarded – undo
3137 3137
         //make sure any active message types that are existing are included in the hidden fields
3138 3138
         if (isset($this->_m_mt_settings['message_type_tabs'][$messenger->name]['active'])) {
3139 3139
             foreach ($this->_m_mt_settings['message_type_tabs'][$messenger->name]['active'] as $mt => $values) {
3140
-                $settings_template_args['hidden_fields']['messenger_settings[message_types][' . $mt . ']'] = array(
3140
+                $settings_template_args['hidden_fields']['messenger_settings[message_types]['.$mt.']'] = array(
3141 3141
                     'type'  => 'hidden',
3142 3142
                     'value' => $mt
3143 3143
                 );
@@ -3147,7 +3147,7 @@  discard block
 block discarded – undo
3147 3147
             $settings_template_args['hidden_fields'],
3148 3148
             'array'
3149 3149
         );
3150
-        $active                                  = $this->_message_resource_manager->is_messenger_active($messenger->name);
3150
+        $active = $this->_message_resource_manager->is_messenger_active($messenger->name);
3151 3151
         
3152 3152
         $settings_template_args['messenger']           = $messenger->name;
3153 3153
         $settings_template_args['description']         = $messenger->description;
@@ -3164,9 +3164,9 @@  discard block
 block discarded – undo
3164 3164
         
3165 3165
         
3166 3166
         $settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3167
-        $settings_template_args['nonce']         = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3167
+        $settings_template_args['nonce']         = wp_create_nonce('activate_'.$messenger->name.'_toggle_nonce');
3168 3168
         $settings_template_args['on_off_status'] = $active ? true : false;
3169
-        $template                                = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3169
+        $template                                = EE_MSG_TEMPLATE_PATH.'ee_msg_m_settings_content.template.php';
3170 3170
         $content                                 = EEH_Template::display_template($template, $settings_template_args,
3171 3171
             true);
3172 3172
         
@@ -3194,7 +3194,7 @@  discard block
 block discarded – undo
3194 3194
         
3195 3195
         //do a nonce check here since we're not arriving via a normal route
3196 3196
         $nonce     = isset($this->_req_data['activate_nonce']) ? sanitize_text_field($this->_req_data['activate_nonce']) : '';
3197
-        $nonce_ref = 'activate_' . $this->_req_data['messenger'] . '_toggle_nonce';
3197
+        $nonce_ref = 'activate_'.$this->_req_data['messenger'].'_toggle_nonce';
3198 3198
         
3199 3199
         $this->_verify_nonce($nonce, $nonce_ref);
3200 3200
         
@@ -3296,7 +3296,7 @@  discard block
 block discarded – undo
3296 3296
         
3297 3297
         //do a nonce check here since we're not arriving via a normal route
3298 3298
         $nonce     = isset($this->_req_data['mt_nonce']) ? sanitize_text_field($this->_req_data['mt_nonce']) : '';
3299
-        $nonce_ref = $this->_req_data['message_type'] . '_nonce';
3299
+        $nonce_ref = $this->_req_data['message_type'].'_nonce';
3300 3300
         
3301 3301
         $this->_verify_nonce($nonce, $nonce_ref);
3302 3302
         
Please login to merge, or discard this patch.
Indentation   +3620 added lines, -3620 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,1560 +2236,1560 @@  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  => __("On the same request", "event_espresso"),
3010
-                                false => __("On a separate request", "event_espresso")
3011
-                            ),
3012
-                            array(
3013
-                                'default'         => $network_config->do_messages_on_same_request,
3014
-                                'html_label_text' => __('Generate and send all messages:', 'event_espresso'),
3015
-                                'html_help_text'  => __('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
-                        'update_settings'             => new EE_Submit_Input(
3020
-                            array(
3021
-                                'default'         => __('Update', 'event_espresso'),
3022
-                                'html_label_text' => '&nbsp'
3023
-                            )
3024
-                        )
3025
-                    )
3026
-                )
3027
-            )
3028
-        );
3029
-    }
3030
-    
3031
-    
3032
-    /**
3033
-     * This handles updating the global settings set on the admin page.
3034
-     * @throws \EE_Error
3035
-     */
3036
-    protected function _update_global_settings()
3037
-    {
3038
-        /** @var EE_Network_Core_Config $network_config */
3039
-        $network_config = EE_Registry::instance()->NET_CFG->core;
3040
-        $form           = $this->_generate_global_settings_form();
3041
-        if ($form->was_submitted()) {
3042
-            $form->receive_form_submission();
3043
-            if ($form->is_valid()) {
3044
-                $valid_data = $form->valid_data();
3045
-                foreach ($valid_data as $property => $value) {
3046
-                    $setter = 'set_' . $property;
3047
-                    if (method_exists($network_config, $setter)) {
3048
-                        $network_config->{$setter}($value);
3049
-                    } else if (
3050
-                        property_exists($network_config, $property)
3051
-                        && $network_config->{$property} !== $value
3052
-                    ) {
3053
-                        $network_config->{$property} = $value;
3054
-                    }
3055
-                }
3056
-                //only update if the form submission was valid!
3057
-                EE_Registry::instance()->NET_CFG->update_config(true, false);
3058
-                EE_Error::overwrite_success();
3059
-                EE_Error::add_success(__('Global message settings were updated', 'event_espresso'));
3060
-            }
3061
-        }
3062
-        $this->_redirect_after_action(0, '', '', array('action' => 'settings'), true);
3063
-    }
3064
-    
3065
-    
3066
-    /**
3067
-     * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3068
-     *
3069
-     * @param  array $tab_array This is an array of message type tab details used to generate the tabs
3070
-     *
3071
-     * @return string            html formatted tabs
3072
-     */
3073
-    protected function _get_mt_tabs($tab_array)
3074
-    {
3075
-        $tab_array = (array)$tab_array;
3076
-        $template  = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3077
-        $tabs      = '';
3078
-        
3079
-        foreach ($tab_array as $tab) {
3080
-            $tabs .= EEH_Template::display_template($template, $tab, true);
3081
-        }
3082
-        
3083
-        return $tabs;
3084
-    }
3085
-    
3086
-    
3087
-    /**
3088
-     * This prepares the content of the messenger meta box admin settings
3089
-     *
3090
-     * @param  EE_messenger $messenger The messenger we're setting up content for
3091
-     *
3092
-     * @return string            html formatted content
3093
-     */
3094
-    protected function _get_messenger_box_content(EE_messenger $messenger)
3095
-    {
3096
-        
3097
-        $fields                                         = $messenger->get_admin_settings_fields();
3098
-        $settings_template_args['template_form_fields'] = '';
3099
-        
3100
-        //is $messenger active?
3101
-        $settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3102
-        
3103
-        
3104
-        if ( ! empty($fields)) {
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  => __("On the same request", "event_espresso"),
3010
+								false => __("On a separate request", "event_espresso")
3011
+							),
3012
+							array(
3013
+								'default'         => $network_config->do_messages_on_same_request,
3014
+								'html_label_text' => __('Generate and send all messages:', 'event_espresso'),
3015
+								'html_help_text'  => __('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
+						'update_settings'             => new EE_Submit_Input(
3020
+							array(
3021
+								'default'         => __('Update', 'event_espresso'),
3022
+								'html_label_text' => '&nbsp'
3023
+							)
3024
+						)
3025
+					)
3026
+				)
3027
+			)
3028
+		);
3029
+	}
3030
+    
3031
+    
3032
+	/**
3033
+	 * This handles updating the global settings set on the admin page.
3034
+	 * @throws \EE_Error
3035
+	 */
3036
+	protected function _update_global_settings()
3037
+	{
3038
+		/** @var EE_Network_Core_Config $network_config */
3039
+		$network_config = EE_Registry::instance()->NET_CFG->core;
3040
+		$form           = $this->_generate_global_settings_form();
3041
+		if ($form->was_submitted()) {
3042
+			$form->receive_form_submission();
3043
+			if ($form->is_valid()) {
3044
+				$valid_data = $form->valid_data();
3045
+				foreach ($valid_data as $property => $value) {
3046
+					$setter = 'set_' . $property;
3047
+					if (method_exists($network_config, $setter)) {
3048
+						$network_config->{$setter}($value);
3049
+					} else if (
3050
+						property_exists($network_config, $property)
3051
+						&& $network_config->{$property} !== $value
3052
+					) {
3053
+						$network_config->{$property} = $value;
3054
+					}
3055
+				}
3056
+				//only update if the form submission was valid!
3057
+				EE_Registry::instance()->NET_CFG->update_config(true, false);
3058
+				EE_Error::overwrite_success();
3059
+				EE_Error::add_success(__('Global message settings were updated', 'event_espresso'));
3060
+			}
3061
+		}
3062
+		$this->_redirect_after_action(0, '', '', array('action' => 'settings'), true);
3063
+	}
3064
+    
3065
+    
3066
+	/**
3067
+	 * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3068
+	 *
3069
+	 * @param  array $tab_array This is an array of message type tab details used to generate the tabs
3070
+	 *
3071
+	 * @return string            html formatted tabs
3072
+	 */
3073
+	protected function _get_mt_tabs($tab_array)
3074
+	{
3075
+		$tab_array = (array)$tab_array;
3076
+		$template  = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3077
+		$tabs      = '';
3078
+        
3079
+		foreach ($tab_array as $tab) {
3080
+			$tabs .= EEH_Template::display_template($template, $tab, true);
3081
+		}
3082
+        
3083
+		return $tabs;
3084
+	}
3085
+    
3086
+    
3087
+	/**
3088
+	 * This prepares the content of the messenger meta box admin settings
3089
+	 *
3090
+	 * @param  EE_messenger $messenger The messenger we're setting up content for
3091
+	 *
3092
+	 * @return string            html formatted content
3093
+	 */
3094
+	protected function _get_messenger_box_content(EE_messenger $messenger)
3095
+	{
3096
+        
3097
+		$fields                                         = $messenger->get_admin_settings_fields();
3098
+		$settings_template_args['template_form_fields'] = '';
3099
+        
3100
+		//is $messenger active?
3101
+		$settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3102
+        
3103
+        
3104
+		if ( ! empty($fields)) {
3105 3105
             
3106
-            $existing_settings = $messenger->get_existing_admin_settings();
3106
+			$existing_settings = $messenger->get_existing_admin_settings();
3107 3107
             
3108
-            foreach ($fields as $fldname => $fldprops) {
3109
-                $field_id                       = $messenger->name . '-' . $fldname;
3110
-                $template_form_field[$field_id] = array(
3111
-                    'name'       => 'messenger_settings[' . $field_id . ']',
3112
-                    'label'      => $fldprops['label'],
3113
-                    'input'      => $fldprops['field_type'],
3114
-                    'type'       => $fldprops['value_type'],
3115
-                    'required'   => $fldprops['required'],
3116
-                    'validation' => $fldprops['validation'],
3117
-                    'value'      => isset($existing_settings[$field_id])
3118
-                        ? $existing_settings[$field_id]
3119
-                        : $fldprops['default'],
3120
-                    'css_class'  => '',
3121
-                    'format'     => $fldprops['format']
3122
-                );
3123
-            }
3108
+			foreach ($fields as $fldname => $fldprops) {
3109
+				$field_id                       = $messenger->name . '-' . $fldname;
3110
+				$template_form_field[$field_id] = array(
3111
+					'name'       => 'messenger_settings[' . $field_id . ']',
3112
+					'label'      => $fldprops['label'],
3113
+					'input'      => $fldprops['field_type'],
3114
+					'type'       => $fldprops['value_type'],
3115
+					'required'   => $fldprops['required'],
3116
+					'validation' => $fldprops['validation'],
3117
+					'value'      => isset($existing_settings[$field_id])
3118
+						? $existing_settings[$field_id]
3119
+						: $fldprops['default'],
3120
+					'css_class'  => '',
3121
+					'format'     => $fldprops['format']
3122
+				);
3123
+			}
3124 3124
             
3125 3125
             
3126
-            $settings_template_args['template_form_fields'] = ! empty($template_form_field)
3127
-                ? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3128
-                : '';
3129
-        }
3130
-        
3131
-        //we also need some hidden fields
3132
-        $settings_template_args['hidden_fields'] = array(
3133
-            'messenger_settings[messenger]' => array(
3134
-                'type'  => 'hidden',
3135
-                'value' => $messenger->name
3136
-            ),
3137
-            'type'                          => array(
3138
-                'type'  => 'hidden',
3139
-                'value' => 'messenger'
3140
-            )
3141
-        );
3142
-        
3143
-        //make sure any active message types that are existing are included in the hidden fields
3144
-        if (isset($this->_m_mt_settings['message_type_tabs'][$messenger->name]['active'])) {
3145
-            foreach ($this->_m_mt_settings['message_type_tabs'][$messenger->name]['active'] as $mt => $values) {
3146
-                $settings_template_args['hidden_fields']['messenger_settings[message_types][' . $mt . ']'] = array(
3147
-                    'type'  => 'hidden',
3148
-                    'value' => $mt
3149
-                );
3150
-            }
3151
-        }
3152
-        $settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3153
-            $settings_template_args['hidden_fields'],
3154
-            'array'
3155
-        );
3156
-        $active                                  = $this->_message_resource_manager->is_messenger_active($messenger->name);
3157
-        
3158
-        $settings_template_args['messenger']           = $messenger->name;
3159
-        $settings_template_args['description']         = $messenger->description;
3160
-        $settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3161
-        
3162
-        
3163
-        $settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active($messenger->name)
3164
-            ? $settings_template_args['show_hide_edit_form']
3165
-            : ' hidden';
3166
-        
3167
-        $settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3168
-            ? ' hidden'
3169
-            : $settings_template_args['show_hide_edit_form'];
3170
-        
3171
-        
3172
-        $settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3173
-        $settings_template_args['nonce']         = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3174
-        $settings_template_args['on_off_status'] = $active ? true : false;
3175
-        $template                                = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3176
-        $content                                 = EEH_Template::display_template($template, $settings_template_args,
3177
-            true);
3178
-        
3179
-        return $content;
3180
-    }
3181
-    
3182
-    
3183
-    /**
3184
-     * used by ajax on the messages settings page to activate|deactivate the messenger
3185
-     */
3186
-    public function activate_messenger_toggle()
3187
-    {
3188
-        $success = true;
3189
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
3190
-        //let's check that we have required data
3191
-        if ( ! isset($this->_req_data['messenger'])) {
3192
-            EE_Error::add_error(
3193
-                __('Messenger name needed to toggle activation. None given', 'event_espresso'),
3194
-                __FILE__,
3195
-                __FUNCTION__,
3196
-                __LINE__
3197
-            );
3198
-            $success = false;
3199
-        }
3200
-        
3201
-        //do a nonce check here since we're not arriving via a normal route
3202
-        $nonce     = isset($this->_req_data['activate_nonce']) ? sanitize_text_field($this->_req_data['activate_nonce']) : '';
3203
-        $nonce_ref = 'activate_' . $this->_req_data['messenger'] . '_toggle_nonce';
3204
-        
3205
-        $this->_verify_nonce($nonce, $nonce_ref);
3206
-        
3207
-        
3208
-        if ( ! isset($this->_req_data['status'])) {
3209
-            EE_Error::add_error(
3210
-                __(
3211
-                    'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3212
-                    'event_espresso'
3213
-                ),
3214
-                __FILE__,
3215
-                __FUNCTION__,
3216
-                __LINE__
3217
-            );
3218
-            $success = false;
3219
-        }
3220
-        
3221
-        //do check to verify we have a valid status.
3222
-        $status = $this->_req_data['status'];
3223
-        
3224
-        if ($status != 'off' && $status != 'on') {
3225
-            EE_Error::add_error(
3226
-                sprintf(
3227
-                    __('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
3228
-                    $this->_req_data['status']
3229
-                ),
3230
-                __FILE__,
3231
-                __FUNCTION__,
3232
-                __LINE__
3233
-            );
3234
-            $success = false;
3235
-        }
3236
-        
3237
-        if ($success) {
3238
-            //made it here?  Stop dawdling then!!
3239
-            $success = $status == 'off'
3240
-                ? $this->_deactivate_messenger($this->_req_data['messenger'])
3241
-                : $this->_activate_messenger($this->_req_data['messenger']);
3242
-        }
3243
-        
3244
-        $this->_template_args['success'] = $success;
3245
-        
3246
-        //no special instructions so let's just do the json return (which should automatically do all the special stuff).
3247
-        $this->_return_json();
3248
-        
3249
-    }
3250
-    
3251
-    
3252
-    /**
3253
-     * used by ajax from the messages settings page to activate|deactivate a message type
3254
-     *
3255
-     */
3256
-    public function activate_mt_toggle()
3257
-    {
3258
-        $success = true;
3259
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
3260
-        
3261
-        //let's make sure we have the necessary data
3262
-        if ( ! isset($this->_req_data['message_type'])) {
3263
-            EE_Error::add_error(
3264
-                __('Message Type name needed to toggle activation. None given', 'event_espresso'),
3265
-                __FILE__, __FUNCTION__, __LINE__
3266
-            );
3267
-            $success = false;
3268
-        }
3269
-        
3270
-        if ( ! isset($this->_req_data['messenger'])) {
3271
-            EE_Error::add_error(
3272
-                __('Messenger name needed to toggle activation. None given', 'event_espresso'),
3273
-                __FILE__, __FUNCTION__, __LINE__
3274
-            );
3275
-            $success = false;
3276
-        }
3277
-        
3278
-        if ( ! isset($this->_req_data['status'])) {
3279
-            EE_Error::add_error(
3280
-                __('Messenger status needed to know whether activation or deactivation is happening. No status is given',
3281
-                    'event_espresso'),
3282
-                __FILE__, __FUNCTION__, __LINE__
3283
-            );
3284
-            $success = false;
3285
-        }
3286
-        
3287
-        
3288
-        //do check to verify we have a valid status.
3289
-        $status = $this->_req_data['status'];
3290
-        
3291
-        if ($status != 'activate' && $status != 'deactivate') {
3292
-            EE_Error::add_error(
3293
-                sprintf(
3294
-                    __('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
3295
-                    $this->_req_data['status']
3296
-                ),
3297
-                __FILE__, __FUNCTION__, __LINE__
3298
-            );
3299
-            $success = false;
3300
-        }
3301
-        
3302
-        
3303
-        //do a nonce check here since we're not arriving via a normal route
3304
-        $nonce     = isset($this->_req_data['mt_nonce']) ? sanitize_text_field($this->_req_data['mt_nonce']) : '';
3305
-        $nonce_ref = $this->_req_data['message_type'] . '_nonce';
3306
-        
3307
-        $this->_verify_nonce($nonce, $nonce_ref);
3308
-        
3309
-        if ($success) {
3310
-            //made it here? um, what are you waiting for then?
3311
-            $success = $status == 'deactivate'
3312
-                ? $this->_deactivate_message_type_for_messenger($this->_req_data['messenger'],
3313
-                    $this->_req_data['message_type'])
3314
-                : $this->_activate_message_type_for_messenger($this->_req_data['messenger'],
3315
-                    $this->_req_data['message_type']);
3316
-        }
3317
-        
3318
-        $this->_template_args['success'] = $success;
3319
-        $this->_return_json();
3320
-    }
3321
-    
3322
-    
3323
-    /**
3324
-     * Takes care of processing activating a messenger and preparing the appropriate response.
3325
-     *
3326
-     * @param string $messenger_name The name of the messenger being activated
3327
-     *
3328
-     * @return bool
3329
-     */
3330
-    protected function _activate_messenger($messenger_name)
3331
-    {
3332
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
3333
-        $active_messenger          = $this->_message_resource_manager->get_messenger($messenger_name);
3334
-        $message_types_to_activate = $active_messenger instanceof EE_Messenger ? $active_messenger->get_default_message_types() : array();
3335
-        
3336
-        //ensure is active
3337
-        $this->_message_resource_manager->activate_messenger($messenger_name, $message_types_to_activate);
3338
-        
3339
-        //set response_data for reload
3340
-        foreach ($message_types_to_activate as $message_type_name) {
3341
-            /** @var EE_message_type $message_type */
3342
-            $message_type = $this->_message_resource_manager->get_message_type($message_type_name);
3343
-            if ($this->_message_resource_manager->is_message_type_active_for_messenger($messenger_name,
3344
-                    $message_type_name)
3345
-                && $message_type instanceof EE_message_type
3346
-            ) {
3347
-                $this->_template_args['data']['active_mts'][] = $message_type_name;
3348
-                if ($message_type->get_admin_settings_fields()) {
3349
-                    $this->_template_args['data']['mt_reload'][] = $message_type_name;
3350
-                }
3351
-            }
3352
-        }
3353
-        
3354
-        //add success message for activating messenger
3355
-        return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
3356
-        
3357
-    }
3358
-    
3359
-    
3360
-    /**
3361
-     * Takes care of processing deactivating a messenger and preparing the appropriate response.
3362
-     *
3363
-     * @param string $messenger_name The name of the messenger being activated
3364
-     *
3365
-     * @return bool
3366
-     */
3367
-    protected function _deactivate_messenger($messenger_name)
3368
-    {
3369
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
3370
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
3371
-        $this->_message_resource_manager->deactivate_messenger($messenger_name);
3372
-        
3373
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
3374
-    }
3375
-    
3376
-    
3377
-    /**
3378
-     * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
3379
-     *
3380
-     * @param string $messenger_name    The name of the messenger the message type is being activated for.
3381
-     * @param string $message_type_name The name of the message type being activated for the messenger
3382
-     *
3383
-     * @return bool
3384
-     */
3385
-    protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
3386
-    {
3387
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
3388
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
3389
-        /** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
3390
-        $message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
3391
-        
3392
-        //ensure is active
3393
-        $this->_message_resource_manager->activate_messenger($messenger_name, $message_type_name);
3394
-        
3395
-        //set response for load
3396
-        if ($this->_message_resource_manager->is_message_type_active_for_messenger($messenger_name,
3397
-            $message_type_name)
3398
-        ) {
3399
-            $this->_template_args['data']['active_mts'][] = $message_type_name;
3400
-            if ($message_type_to_activate->get_admin_settings_fields()) {
3401
-                $this->_template_args['data']['mt_reload'][] = $message_type_name;
3402
-            }
3403
-        }
3404
-        
3405
-        return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger,
3406
-            $message_type_to_activate);
3407
-    }
3408
-    
3409
-    
3410
-    /**
3411
-     * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
3412
-     *
3413
-     * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
3414
-     * @param string $message_type_name The name of the message type being deactivated for the messenger
3415
-     *
3416
-     * @return bool
3417
-     */
3418
-    protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
3419
-    {
3420
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
3421
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
3422
-        /** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
3423
-        $message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
3424
-        $this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
3425
-        
3426
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger,
3427
-            $message_type_to_deactivate);
3428
-    }
3429
-    
3430
-    
3431
-    /**
3432
-     * This just initializes the defaults for activating messenger and message type responses.
3433
-     */
3434
-    protected function _prep_default_response_for_messenger_or_message_type_toggle()
3435
-    {
3436
-        $this->_template_args['data']['active_mts'] = array();
3437
-        $this->_template_args['data']['mt_reload']  = array();
3438
-    }
3439
-    
3440
-    
3441
-    /**
3442
-     * Setup appropriate response for activating a messenger and/or message types
3443
-     *
3444
-     * @param EE_messenger         $messenger
3445
-     * @param EE_message_type|null $message_type
3446
-     *
3447
-     * @return bool
3448
-     * @throws EE_Error
3449
-     */
3450
-    protected function _setup_response_message_for_activating_messenger_with_message_types(
3451
-        $messenger,
3452
-        EE_Message_Type $message_type = null
3453
-    ) {
3454
-        //if $messenger isn't a valid messenger object then get out.
3455
-        if ( ! $messenger instanceof EE_Messenger) {
3456
-            EE_Error::add_error(
3457
-                __('The messenger being activated is not a valid messenger', 'event_espresso'),
3458
-                __FILE__,
3459
-                __FUNCTION__,
3460
-                __LINE__
3461
-            );
3126
+			$settings_template_args['template_form_fields'] = ! empty($template_form_field)
3127
+				? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3128
+				: '';
3129
+		}
3130
+        
3131
+		//we also need some hidden fields
3132
+		$settings_template_args['hidden_fields'] = array(
3133
+			'messenger_settings[messenger]' => array(
3134
+				'type'  => 'hidden',
3135
+				'value' => $messenger->name
3136
+			),
3137
+			'type'                          => array(
3138
+				'type'  => 'hidden',
3139
+				'value' => 'messenger'
3140
+			)
3141
+		);
3142
+        
3143
+		//make sure any active message types that are existing are included in the hidden fields
3144
+		if (isset($this->_m_mt_settings['message_type_tabs'][$messenger->name]['active'])) {
3145
+			foreach ($this->_m_mt_settings['message_type_tabs'][$messenger->name]['active'] as $mt => $values) {
3146
+				$settings_template_args['hidden_fields']['messenger_settings[message_types][' . $mt . ']'] = array(
3147
+					'type'  => 'hidden',
3148
+					'value' => $mt
3149
+				);
3150
+			}
3151
+		}
3152
+		$settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3153
+			$settings_template_args['hidden_fields'],
3154
+			'array'
3155
+		);
3156
+		$active                                  = $this->_message_resource_manager->is_messenger_active($messenger->name);
3157
+        
3158
+		$settings_template_args['messenger']           = $messenger->name;
3159
+		$settings_template_args['description']         = $messenger->description;
3160
+		$settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3161
+        
3162
+        
3163
+		$settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active($messenger->name)
3164
+			? $settings_template_args['show_hide_edit_form']
3165
+			: ' hidden';
3166
+        
3167
+		$settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3168
+			? ' hidden'
3169
+			: $settings_template_args['show_hide_edit_form'];
3170
+        
3171
+        
3172
+		$settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3173
+		$settings_template_args['nonce']         = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3174
+		$settings_template_args['on_off_status'] = $active ? true : false;
3175
+		$template                                = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3176
+		$content                                 = EEH_Template::display_template($template, $settings_template_args,
3177
+			true);
3178
+        
3179
+		return $content;
3180
+	}
3181
+    
3182
+    
3183
+	/**
3184
+	 * used by ajax on the messages settings page to activate|deactivate the messenger
3185
+	 */
3186
+	public function activate_messenger_toggle()
3187
+	{
3188
+		$success = true;
3189
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
3190
+		//let's check that we have required data
3191
+		if ( ! isset($this->_req_data['messenger'])) {
3192
+			EE_Error::add_error(
3193
+				__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3194
+				__FILE__,
3195
+				__FUNCTION__,
3196
+				__LINE__
3197
+			);
3198
+			$success = false;
3199
+		}
3200
+        
3201
+		//do a nonce check here since we're not arriving via a normal route
3202
+		$nonce     = isset($this->_req_data['activate_nonce']) ? sanitize_text_field($this->_req_data['activate_nonce']) : '';
3203
+		$nonce_ref = 'activate_' . $this->_req_data['messenger'] . '_toggle_nonce';
3204
+        
3205
+		$this->_verify_nonce($nonce, $nonce_ref);
3206
+        
3207
+        
3208
+		if ( ! isset($this->_req_data['status'])) {
3209
+			EE_Error::add_error(
3210
+				__(
3211
+					'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3212
+					'event_espresso'
3213
+				),
3214
+				__FILE__,
3215
+				__FUNCTION__,
3216
+				__LINE__
3217
+			);
3218
+			$success = false;
3219
+		}
3220
+        
3221
+		//do check to verify we have a valid status.
3222
+		$status = $this->_req_data['status'];
3223
+        
3224
+		if ($status != 'off' && $status != 'on') {
3225
+			EE_Error::add_error(
3226
+				sprintf(
3227
+					__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
3228
+					$this->_req_data['status']
3229
+				),
3230
+				__FILE__,
3231
+				__FUNCTION__,
3232
+				__LINE__
3233
+			);
3234
+			$success = false;
3235
+		}
3236
+        
3237
+		if ($success) {
3238
+			//made it here?  Stop dawdling then!!
3239
+			$success = $status == 'off'
3240
+				? $this->_deactivate_messenger($this->_req_data['messenger'])
3241
+				: $this->_activate_messenger($this->_req_data['messenger']);
3242
+		}
3243
+        
3244
+		$this->_template_args['success'] = $success;
3245
+        
3246
+		//no special instructions so let's just do the json return (which should automatically do all the special stuff).
3247
+		$this->_return_json();
3248
+        
3249
+	}
3250
+    
3251
+    
3252
+	/**
3253
+	 * used by ajax from the messages settings page to activate|deactivate a message type
3254
+	 *
3255
+	 */
3256
+	public function activate_mt_toggle()
3257
+	{
3258
+		$success = true;
3259
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
3260
+        
3261
+		//let's make sure we have the necessary data
3262
+		if ( ! isset($this->_req_data['message_type'])) {
3263
+			EE_Error::add_error(
3264
+				__('Message Type name needed to toggle activation. None given', 'event_espresso'),
3265
+				__FILE__, __FUNCTION__, __LINE__
3266
+			);
3267
+			$success = false;
3268
+		}
3269
+        
3270
+		if ( ! isset($this->_req_data['messenger'])) {
3271
+			EE_Error::add_error(
3272
+				__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3273
+				__FILE__, __FUNCTION__, __LINE__
3274
+			);
3275
+			$success = false;
3276
+		}
3277
+        
3278
+		if ( ! isset($this->_req_data['status'])) {
3279
+			EE_Error::add_error(
3280
+				__('Messenger status needed to know whether activation or deactivation is happening. No status is given',
3281
+					'event_espresso'),
3282
+				__FILE__, __FUNCTION__, __LINE__
3283
+			);
3284
+			$success = false;
3285
+		}
3286
+        
3287
+        
3288
+		//do check to verify we have a valid status.
3289
+		$status = $this->_req_data['status'];
3290
+        
3291
+		if ($status != 'activate' && $status != 'deactivate') {
3292
+			EE_Error::add_error(
3293
+				sprintf(
3294
+					__('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
3295
+					$this->_req_data['status']
3296
+				),
3297
+				__FILE__, __FUNCTION__, __LINE__
3298
+			);
3299
+			$success = false;
3300
+		}
3301
+        
3302
+        
3303
+		//do a nonce check here since we're not arriving via a normal route
3304
+		$nonce     = isset($this->_req_data['mt_nonce']) ? sanitize_text_field($this->_req_data['mt_nonce']) : '';
3305
+		$nonce_ref = $this->_req_data['message_type'] . '_nonce';
3306
+        
3307
+		$this->_verify_nonce($nonce, $nonce_ref);
3308
+        
3309
+		if ($success) {
3310
+			//made it here? um, what are you waiting for then?
3311
+			$success = $status == 'deactivate'
3312
+				? $this->_deactivate_message_type_for_messenger($this->_req_data['messenger'],
3313
+					$this->_req_data['message_type'])
3314
+				: $this->_activate_message_type_for_messenger($this->_req_data['messenger'],
3315
+					$this->_req_data['message_type']);
3316
+		}
3317
+        
3318
+		$this->_template_args['success'] = $success;
3319
+		$this->_return_json();
3320
+	}
3321
+    
3322
+    
3323
+	/**
3324
+	 * Takes care of processing activating a messenger and preparing the appropriate response.
3325
+	 *
3326
+	 * @param string $messenger_name The name of the messenger being activated
3327
+	 *
3328
+	 * @return bool
3329
+	 */
3330
+	protected function _activate_messenger($messenger_name)
3331
+	{
3332
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
3333
+		$active_messenger          = $this->_message_resource_manager->get_messenger($messenger_name);
3334
+		$message_types_to_activate = $active_messenger instanceof EE_Messenger ? $active_messenger->get_default_message_types() : array();
3335
+        
3336
+		//ensure is active
3337
+		$this->_message_resource_manager->activate_messenger($messenger_name, $message_types_to_activate);
3338
+        
3339
+		//set response_data for reload
3340
+		foreach ($message_types_to_activate as $message_type_name) {
3341
+			/** @var EE_message_type $message_type */
3342
+			$message_type = $this->_message_resource_manager->get_message_type($message_type_name);
3343
+			if ($this->_message_resource_manager->is_message_type_active_for_messenger($messenger_name,
3344
+					$message_type_name)
3345
+				&& $message_type instanceof EE_message_type
3346
+			) {
3347
+				$this->_template_args['data']['active_mts'][] = $message_type_name;
3348
+				if ($message_type->get_admin_settings_fields()) {
3349
+					$this->_template_args['data']['mt_reload'][] = $message_type_name;
3350
+				}
3351
+			}
3352
+		}
3353
+        
3354
+		//add success message for activating messenger
3355
+		return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
3356
+        
3357
+	}
3358
+    
3359
+    
3360
+	/**
3361
+	 * Takes care of processing deactivating a messenger and preparing the appropriate response.
3362
+	 *
3363
+	 * @param string $messenger_name The name of the messenger being activated
3364
+	 *
3365
+	 * @return bool
3366
+	 */
3367
+	protected function _deactivate_messenger($messenger_name)
3368
+	{
3369
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
3370
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
3371
+		$this->_message_resource_manager->deactivate_messenger($messenger_name);
3372
+        
3373
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
3374
+	}
3375
+    
3376
+    
3377
+	/**
3378
+	 * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
3379
+	 *
3380
+	 * @param string $messenger_name    The name of the messenger the message type is being activated for.
3381
+	 * @param string $message_type_name The name of the message type being activated for the messenger
3382
+	 *
3383
+	 * @return bool
3384
+	 */
3385
+	protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
3386
+	{
3387
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
3388
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
3389
+		/** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
3390
+		$message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
3391
+        
3392
+		//ensure is active
3393
+		$this->_message_resource_manager->activate_messenger($messenger_name, $message_type_name);
3394
+        
3395
+		//set response for load
3396
+		if ($this->_message_resource_manager->is_message_type_active_for_messenger($messenger_name,
3397
+			$message_type_name)
3398
+		) {
3399
+			$this->_template_args['data']['active_mts'][] = $message_type_name;
3400
+			if ($message_type_to_activate->get_admin_settings_fields()) {
3401
+				$this->_template_args['data']['mt_reload'][] = $message_type_name;
3402
+			}
3403
+		}
3404
+        
3405
+		return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger,
3406
+			$message_type_to_activate);
3407
+	}
3408
+    
3409
+    
3410
+	/**
3411
+	 * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
3412
+	 *
3413
+	 * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
3414
+	 * @param string $message_type_name The name of the message type being deactivated for the messenger
3415
+	 *
3416
+	 * @return bool
3417
+	 */
3418
+	protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
3419
+	{
3420
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
3421
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
3422
+		/** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
3423
+		$message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
3424
+		$this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
3425
+        
3426
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger,
3427
+			$message_type_to_deactivate);
3428
+	}
3429
+    
3430
+    
3431
+	/**
3432
+	 * This just initializes the defaults for activating messenger and message type responses.
3433
+	 */
3434
+	protected function _prep_default_response_for_messenger_or_message_type_toggle()
3435
+	{
3436
+		$this->_template_args['data']['active_mts'] = array();
3437
+		$this->_template_args['data']['mt_reload']  = array();
3438
+	}
3439
+    
3440
+    
3441
+	/**
3442
+	 * Setup appropriate response for activating a messenger and/or message types
3443
+	 *
3444
+	 * @param EE_messenger         $messenger
3445
+	 * @param EE_message_type|null $message_type
3446
+	 *
3447
+	 * @return bool
3448
+	 * @throws EE_Error
3449
+	 */
3450
+	protected function _setup_response_message_for_activating_messenger_with_message_types(
3451
+		$messenger,
3452
+		EE_Message_Type $message_type = null
3453
+	) {
3454
+		//if $messenger isn't a valid messenger object then get out.
3455
+		if ( ! $messenger instanceof EE_Messenger) {
3456
+			EE_Error::add_error(
3457
+				__('The messenger being activated is not a valid messenger', 'event_espresso'),
3458
+				__FILE__,
3459
+				__FUNCTION__,
3460
+				__LINE__
3461
+			);
3462 3462
             
3463
-            return false;
3464
-        }
3465
-        //activated
3466
-        if ($this->_template_args['data']['active_mts']) {
3467
-            EE_Error::overwrite_success();
3468
-            //activated a message type with the messenger
3469
-            if ($message_type instanceof EE_message_type) {
3470
-                EE_Error::add_success(
3471
-                    sprintf(
3472
-                        __('%s message type has been successfully activated with the %s messenger', 'event_espresso'),
3473
-                        ucwords($message_type->label['singular']),
3474
-                        ucwords($messenger->label['singular'])
3475
-                    )
3476
-                );
3463
+			return false;
3464
+		}
3465
+		//activated
3466
+		if ($this->_template_args['data']['active_mts']) {
3467
+			EE_Error::overwrite_success();
3468
+			//activated a message type with the messenger
3469
+			if ($message_type instanceof EE_message_type) {
3470
+				EE_Error::add_success(
3471
+					sprintf(
3472
+						__('%s message type has been successfully activated with the %s messenger', 'event_espresso'),
3473
+						ucwords($message_type->label['singular']),
3474
+						ucwords($messenger->label['singular'])
3475
+					)
3476
+				);
3477 3477
                 
3478
-                //if message type was invoice then let's make sure we activate the invoice payment method.
3479
-                if ($message_type->name == 'invoice') {
3480
-                    EE_Registry::instance()->load_lib('Payment_Method_Manager');
3481
-                    $pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
3482
-                    if ($pm instanceof EE_Payment_Method) {
3483
-                        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.',
3484
-                            'event_espresso'));
3485
-                    }
3486
-                }
3487
-                //just toggles the entire messenger
3488
-            } else {
3489
-                EE_Error::add_success(
3490
-                    sprintf(
3491
-                        __('%s messenger has been successfully activated', 'event_espresso'),
3492
-                        ucwords($messenger->label['singular'])
3493
-                    )
3494
-                );
3495
-            }
3478
+				//if message type was invoice then let's make sure we activate the invoice payment method.
3479
+				if ($message_type->name == 'invoice') {
3480
+					EE_Registry::instance()->load_lib('Payment_Method_Manager');
3481
+					$pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
3482
+					if ($pm instanceof EE_Payment_Method) {
3483
+						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.',
3484
+							'event_espresso'));
3485
+					}
3486
+				}
3487
+				//just toggles the entire messenger
3488
+			} else {
3489
+				EE_Error::add_success(
3490
+					sprintf(
3491
+						__('%s messenger has been successfully activated', 'event_espresso'),
3492
+						ucwords($messenger->label['singular'])
3493
+					)
3494
+				);
3495
+			}
3496 3496
             
3497
-            return true;
3497
+			return true;
3498 3498
             
3499
-            //possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
3500
-            //message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
3501
-            //in which case we just give a success message for the messenger being successfully activated.
3502
-        } else {
3503
-            if ( ! $messenger->get_default_message_types()) {
3504
-                //messenger doesn't have any default message types so still a success.
3505
-                EE_Error::add_success(
3506
-                    sprintf(
3507
-                        __('%s messenger was successfully activated.', 'event_espresso'),
3508
-                        ucwords($messenger->label['singular'])
3509
-                    )
3510
-                );
3499
+			//possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
3500
+			//message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
3501
+			//in which case we just give a success message for the messenger being successfully activated.
3502
+		} else {
3503
+			if ( ! $messenger->get_default_message_types()) {
3504
+				//messenger doesn't have any default message types so still a success.
3505
+				EE_Error::add_success(
3506
+					sprintf(
3507
+						__('%s messenger was successfully activated.', 'event_espresso'),
3508
+						ucwords($messenger->label['singular'])
3509
+					)
3510
+				);
3511 3511
                 
3512
-                return true;
3513
-            } else {
3514
-                EE_Error::add_error(
3515
-                    $message_type instanceof EE_message_type
3516
-                        ? sprintf(
3517
-                        __('%s message type was not successfully activated with the %s messenger', 'event_espresso'),
3518
-                        ucwords($message_type->label['singular']),
3519
-                        ucwords($messenger->label['singular'])
3520
-                    )
3521
-                        : sprintf(
3522
-                        __('%s messenger was not successfully activated', 'event_espresso'),
3523
-                        ucwords($messenger->label['singular'])
3524
-                    ),
3525
-                    __FILE__,
3526
-                    __FUNCTION__,
3527
-                    __LINE__
3528
-                );
3512
+				return true;
3513
+			} else {
3514
+				EE_Error::add_error(
3515
+					$message_type instanceof EE_message_type
3516
+						? sprintf(
3517
+						__('%s message type was not successfully activated with the %s messenger', 'event_espresso'),
3518
+						ucwords($message_type->label['singular']),
3519
+						ucwords($messenger->label['singular'])
3520
+					)
3521
+						: sprintf(
3522
+						__('%s messenger was not successfully activated', 'event_espresso'),
3523
+						ucwords($messenger->label['singular'])
3524
+					),
3525
+					__FILE__,
3526
+					__FUNCTION__,
3527
+					__LINE__
3528
+				);
3529 3529
                 
3530
-                return false;
3531
-            }
3532
-        }
3533
-    }
3534
-    
3535
-    
3536
-    /**
3537
-     * This sets up the appropriate response for deactivating a messenger and/or message type.
3538
-     *
3539
-     * @param EE_messenger         $messenger
3540
-     * @param EE_message_type|null $message_type
3541
-     *
3542
-     * @return bool
3543
-     */
3544
-    protected function _setup_response_message_for_deactivating_messenger_with_message_types(
3545
-        $messenger,
3546
-        EE_message_type $message_type = null
3547
-    ) {
3548
-        EE_Error::overwrite_success();
3549
-        
3550
-        //if $messenger isn't a valid messenger object then get out.
3551
-        if ( ! $messenger instanceof EE_Messenger) {
3552
-            EE_Error::add_error(
3553
-                __('The messenger being deactivated is not a valid messenger', 'event_espresso'),
3554
-                __FILE__,
3555
-                __FUNCTION__,
3556
-                __LINE__
3557
-            );
3530
+				return false;
3531
+			}
3532
+		}
3533
+	}
3534
+    
3535
+    
3536
+	/**
3537
+	 * This sets up the appropriate response for deactivating a messenger and/or message type.
3538
+	 *
3539
+	 * @param EE_messenger         $messenger
3540
+	 * @param EE_message_type|null $message_type
3541
+	 *
3542
+	 * @return bool
3543
+	 */
3544
+	protected function _setup_response_message_for_deactivating_messenger_with_message_types(
3545
+		$messenger,
3546
+		EE_message_type $message_type = null
3547
+	) {
3548
+		EE_Error::overwrite_success();
3549
+        
3550
+		//if $messenger isn't a valid messenger object then get out.
3551
+		if ( ! $messenger instanceof EE_Messenger) {
3552
+			EE_Error::add_error(
3553
+				__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
3554
+				__FILE__,
3555
+				__FUNCTION__,
3556
+				__LINE__
3557
+			);
3558 3558
             
3559
-            return false;
3560
-        }
3561
-        
3562
-        if ($message_type instanceof EE_message_type) {
3563
-            $message_type_name = $message_type->name;
3564
-            EE_Error::add_success(
3565
-                sprintf(
3566
-                    __('%s message type has been successfully deactivated for the %s messenger.', 'event_espresso'),
3567
-                    ucwords($message_type->label['singular']),
3568
-                    ucwords($messenger->label['singular'])
3569
-                )
3570
-            );
3571
-        } else {
3572
-            $message_type_name = '';
3573
-            EE_Error::add_success(
3574
-                sprintf(
3575
-                    __('%s messenger has been successfully deactivated.', 'event_espresso'),
3576
-                    ucwords($messenger->label['singular'])
3577
-                )
3578
-            );
3579
-        }
3580
-        
3581
-        //if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
3582
-        if ($messenger->name == 'html' || $message_type_name == 'invoice') {
3583
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
3584
-            $count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
3585
-            if ($count_updated > 0) {
3586
-                $msg = $message_type_name == 'invoice'
3587
-                    ? __('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.',
3588
-                        'event_espresso')
3589
-                    : __('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.',
3590
-                        'event_espresso');
3591
-                EE_Error::add_attention($msg);
3592
-            }
3593
-        }
3594
-        
3595
-        return true;
3596
-    }
3597
-    
3598
-    
3599
-    /**
3600
-     * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
3601
-     */
3602
-    public function update_mt_form()
3603
-    {
3604
-        if ( ! isset($this->_req_data['messenger']) || ! isset($this->_req_data['message_type'])) {
3605
-            EE_Error::add_error(__('Require message type or messenger to send an updated form'), __FILE__, __FUNCTION__,
3606
-                __LINE__);
3607
-            $this->_return_json();
3608
-        }
3609
-        
3610
-        $message_types = $this->get_installed_message_types();
3611
-        
3612
-        $message_type = $message_types[$this->_req_data['message_type']];
3613
-        $messenger    = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
3614
-        
3615
-        $content                         = $this->_message_type_settings_content($message_type, $messenger, true);
3616
-        $this->_template_args['success'] = true;
3617
-        $this->_template_args['content'] = $content;
3618
-        $this->_return_json();
3619
-    }
3620
-    
3621
-    
3622
-    /**
3623
-     * this handles saving the settings for a messenger or message type
3624
-     *
3625
-     */
3626
-    public function save_settings()
3627
-    {
3628
-        if ( ! isset($this->_req_data['type'])) {
3629
-            EE_Error::add_error(__('Cannot save settings because type is unknown (messenger settings or messsage type settings?)',
3630
-                'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
3631
-            $this->_template_args['error'] = true;
3632
-            $this->_return_json();
3633
-        }
3634
-        
3635
-        
3636
-        if ($this->_req_data['type'] == 'messenger') {
3637
-            $settings  = $this->_req_data['messenger_settings']; //this should be an array.
3638
-            $messenger = $settings['messenger'];
3639
-            //let's setup the settings data
3640
-            foreach ($settings as $key => $value) {
3641
-                switch ($key) {
3642
-                    case 'messenger' :
3643
-                        unset($settings['messenger']);
3644
-                        break;
3645
-                    case 'message_types' :
3646
-                        unset($settings['message_types']);
3647
-                        break;
3648
-                    default :
3649
-                        $settings[$key] = $value;
3650
-                        break;
3651
-                }
3652
-            }
3653
-            $this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
3654
-        } else if ($this->_req_data['type'] == 'message_type') {
3655
-            $settings     = $this->_req_data['message_type_settings'];
3656
-            $messenger    = $settings['messenger'];
3657
-            $message_type = $settings['message_type'];
3559
+			return false;
3560
+		}
3561
+        
3562
+		if ($message_type instanceof EE_message_type) {
3563
+			$message_type_name = $message_type->name;
3564
+			EE_Error::add_success(
3565
+				sprintf(
3566
+					__('%s message type has been successfully deactivated for the %s messenger.', 'event_espresso'),
3567
+					ucwords($message_type->label['singular']),
3568
+					ucwords($messenger->label['singular'])
3569
+				)
3570
+			);
3571
+		} else {
3572
+			$message_type_name = '';
3573
+			EE_Error::add_success(
3574
+				sprintf(
3575
+					__('%s messenger has been successfully deactivated.', 'event_espresso'),
3576
+					ucwords($messenger->label['singular'])
3577
+				)
3578
+			);
3579
+		}
3580
+        
3581
+		//if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
3582
+		if ($messenger->name == 'html' || $message_type_name == 'invoice') {
3583
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
3584
+			$count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
3585
+			if ($count_updated > 0) {
3586
+				$msg = $message_type_name == 'invoice'
3587
+					? __('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.',
3588
+						'event_espresso')
3589
+					: __('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.',
3590
+						'event_espresso');
3591
+				EE_Error::add_attention($msg);
3592
+			}
3593
+		}
3594
+        
3595
+		return true;
3596
+	}
3597
+    
3598
+    
3599
+	/**
3600
+	 * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
3601
+	 */
3602
+	public function update_mt_form()
3603
+	{
3604
+		if ( ! isset($this->_req_data['messenger']) || ! isset($this->_req_data['message_type'])) {
3605
+			EE_Error::add_error(__('Require message type or messenger to send an updated form'), __FILE__, __FUNCTION__,
3606
+				__LINE__);
3607
+			$this->_return_json();
3608
+		}
3609
+        
3610
+		$message_types = $this->get_installed_message_types();
3611
+        
3612
+		$message_type = $message_types[$this->_req_data['message_type']];
3613
+		$messenger    = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
3614
+        
3615
+		$content                         = $this->_message_type_settings_content($message_type, $messenger, true);
3616
+		$this->_template_args['success'] = true;
3617
+		$this->_template_args['content'] = $content;
3618
+		$this->_return_json();
3619
+	}
3620
+    
3621
+    
3622
+	/**
3623
+	 * this handles saving the settings for a messenger or message type
3624
+	 *
3625
+	 */
3626
+	public function save_settings()
3627
+	{
3628
+		if ( ! isset($this->_req_data['type'])) {
3629
+			EE_Error::add_error(__('Cannot save settings because type is unknown (messenger settings or messsage type settings?)',
3630
+				'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
3631
+			$this->_template_args['error'] = true;
3632
+			$this->_return_json();
3633
+		}
3634
+        
3635
+        
3636
+		if ($this->_req_data['type'] == 'messenger') {
3637
+			$settings  = $this->_req_data['messenger_settings']; //this should be an array.
3638
+			$messenger = $settings['messenger'];
3639
+			//let's setup the settings data
3640
+			foreach ($settings as $key => $value) {
3641
+				switch ($key) {
3642
+					case 'messenger' :
3643
+						unset($settings['messenger']);
3644
+						break;
3645
+					case 'message_types' :
3646
+						unset($settings['message_types']);
3647
+						break;
3648
+					default :
3649
+						$settings[$key] = $value;
3650
+						break;
3651
+				}
3652
+			}
3653
+			$this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
3654
+		} else if ($this->_req_data['type'] == 'message_type') {
3655
+			$settings     = $this->_req_data['message_type_settings'];
3656
+			$messenger    = $settings['messenger'];
3657
+			$message_type = $settings['message_type'];
3658 3658
             
3659
-            foreach ($settings as $key => $value) {
3660
-                switch ($key) {
3661
-                    case 'messenger' :
3662
-                        unset($settings['messenger']);
3663
-                        break;
3664
-                    case 'message_type' :
3665
-                        unset($settings['message_type']);
3666
-                        break;
3667
-                    default :
3668
-                        $settings[$key] = $value;
3669
-                        break;
3670
-                }
3671
-            }
3659
+			foreach ($settings as $key => $value) {
3660
+				switch ($key) {
3661
+					case 'messenger' :
3662
+						unset($settings['messenger']);
3663
+						break;
3664
+					case 'message_type' :
3665
+						unset($settings['message_type']);
3666
+						break;
3667
+					default :
3668
+						$settings[$key] = $value;
3669
+						break;
3670
+				}
3671
+			}
3672 3672
             
3673
-            $this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
3674
-        }
3675
-        
3676
-        //okay we should have the data all setup.  Now we just update!
3677
-        $success = $this->_message_resource_manager->update_active_messengers_option();
3678
-        
3679
-        if ($success) {
3680
-            EE_Error::add_success(__('Settings updated', 'event_espresso'));
3681
-        } else {
3682
-            EE_Error::add_error(__('Settings did not get updated', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
3683
-        }
3684
-        
3685
-        $this->_template_args['success'] = $success;
3686
-        $this->_return_json();
3687
-    }
3688
-    
3689
-    
3690
-    
3691
-    
3692
-    /**  EE MESSAGE PROCESSING ACTIONS **/
3693
-    
3694
-    
3695
-    /**
3696
-     * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
3697
-     * However, this does not send immediately, it just queues for sending.
3698
-     *
3699
-     * @since 4.9.0
3700
-     */
3701
-    protected function _generate_now()
3702
-    {
3703
-        $msg_ids = $this->_get_msg_ids_from_request();
3704
-        EED_Messages::generate_now($msg_ids);
3705
-        $this->_redirect_after_action(false, '', '', array(), true);
3706
-    }
3707
-    
3708
-    
3709
-    /**
3710
-     * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
3711
-     * are EEM_Message::status_resend or EEM_Message::status_idle
3712
-     *
3713
-     * @since 4.9.0
3714
-     *
3715
-     */
3716
-    protected function _generate_and_send_now()
3717
-    {
3718
-        $this->_generate_now();
3719
-        $this->_send_now();
3720
-        $this->_redirect_after_action(false, '', '', array(), true);
3721
-    }
3722
-    
3723
-    
3724
-    /**
3725
-     * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
3726
-     *
3727
-     * @since 4.9.0
3728
-     */
3729
-    protected function _queue_for_resending()
3730
-    {
3731
-        $msg_ids = $this->_get_msg_ids_from_request();
3732
-        EED_Messages::queue_for_resending($msg_ids);
3733
-        $this->_redirect_after_action(false, '', '', array(), true);
3734
-    }
3735
-    
3736
-    
3737
-    /**
3738
-     *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
3739
-     *
3740
-     * @since 4.9.0
3741
-     */
3742
-    protected function _send_now()
3743
-    {
3744
-        $msg_ids = $this->_get_msg_ids_from_request();
3745
-        EED_Messages::send_now($msg_ids);
3746
-        $this->_redirect_after_action(false, '', '', array(), true);
3747
-    }
3748
-    
3749
-    
3750
-    /**
3751
-     * Deletes EE_messages for IDs in the request.
3752
-     *
3753
-     * @since 4.9.0
3754
-     */
3755
-    protected function _delete_ee_messages()
3756
-    {
3757
-        $msg_ids       = $this->_get_msg_ids_from_request();
3758
-        $deleted_count = 0;
3759
-        foreach ($msg_ids as $msg_id) {
3760
-            if (EEM_Message::instance()->delete_by_ID($msg_id)) {
3761
-                $deleted_count++;
3762
-            }
3763
-        }
3764
-        if ($deleted_count) {
3765
-            $this->_redirect_after_action(
3766
-                true,
3767
-                _n('message', 'messages', $deleted_count, 'event_espresso'),
3768
-                __('deleted', 'event_espresso')
3769
-            );
3770
-        } else {
3771
-            EE_Error::add_error(
3772
-                _n('The message was not deleted.', 'The messages were not deleted', count($msg_ids), 'event_espresso'),
3773
-                __FILE__, __FUNCTION__, __LINE__
3774
-            );
3775
-            $this->_redirect_after_action(false, '', '', array(), true);
3776
-        }
3777
-    }
3778
-    
3779
-    
3780
-    /**
3781
-     *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
3782
-     * @since 4.9.0
3783
-     * @return array
3784
-     */
3785
-    protected function _get_msg_ids_from_request()
3786
-    {
3787
-        if ( ! isset($this->_req_data['MSG_ID'])) {
3788
-            return array();
3789
-        }
3790
-        
3791
-        return is_array($this->_req_data['MSG_ID']) ? array_keys($this->_req_data['MSG_ID']) : array($this->_req_data['MSG_ID']);
3792
-    }
3673
+			$this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
3674
+		}
3675
+        
3676
+		//okay we should have the data all setup.  Now we just update!
3677
+		$success = $this->_message_resource_manager->update_active_messengers_option();
3678
+        
3679
+		if ($success) {
3680
+			EE_Error::add_success(__('Settings updated', 'event_espresso'));
3681
+		} else {
3682
+			EE_Error::add_error(__('Settings did not get updated', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
3683
+		}
3684
+        
3685
+		$this->_template_args['success'] = $success;
3686
+		$this->_return_json();
3687
+	}
3688
+    
3689
+    
3690
+    
3691
+    
3692
+	/**  EE MESSAGE PROCESSING ACTIONS **/
3693
+    
3694
+    
3695
+	/**
3696
+	 * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
3697
+	 * However, this does not send immediately, it just queues for sending.
3698
+	 *
3699
+	 * @since 4.9.0
3700
+	 */
3701
+	protected function _generate_now()
3702
+	{
3703
+		$msg_ids = $this->_get_msg_ids_from_request();
3704
+		EED_Messages::generate_now($msg_ids);
3705
+		$this->_redirect_after_action(false, '', '', array(), true);
3706
+	}
3707
+    
3708
+    
3709
+	/**
3710
+	 * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
3711
+	 * are EEM_Message::status_resend or EEM_Message::status_idle
3712
+	 *
3713
+	 * @since 4.9.0
3714
+	 *
3715
+	 */
3716
+	protected function _generate_and_send_now()
3717
+	{
3718
+		$this->_generate_now();
3719
+		$this->_send_now();
3720
+		$this->_redirect_after_action(false, '', '', array(), true);
3721
+	}
3722
+    
3723
+    
3724
+	/**
3725
+	 * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
3726
+	 *
3727
+	 * @since 4.9.0
3728
+	 */
3729
+	protected function _queue_for_resending()
3730
+	{
3731
+		$msg_ids = $this->_get_msg_ids_from_request();
3732
+		EED_Messages::queue_for_resending($msg_ids);
3733
+		$this->_redirect_after_action(false, '', '', array(), true);
3734
+	}
3735
+    
3736
+    
3737
+	/**
3738
+	 *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
3739
+	 *
3740
+	 * @since 4.9.0
3741
+	 */
3742
+	protected function _send_now()
3743
+	{
3744
+		$msg_ids = $this->_get_msg_ids_from_request();
3745
+		EED_Messages::send_now($msg_ids);
3746
+		$this->_redirect_after_action(false, '', '', array(), true);
3747
+	}
3748
+    
3749
+    
3750
+	/**
3751
+	 * Deletes EE_messages for IDs in the request.
3752
+	 *
3753
+	 * @since 4.9.0
3754
+	 */
3755
+	protected function _delete_ee_messages()
3756
+	{
3757
+		$msg_ids       = $this->_get_msg_ids_from_request();
3758
+		$deleted_count = 0;
3759
+		foreach ($msg_ids as $msg_id) {
3760
+			if (EEM_Message::instance()->delete_by_ID($msg_id)) {
3761
+				$deleted_count++;
3762
+			}
3763
+		}
3764
+		if ($deleted_count) {
3765
+			$this->_redirect_after_action(
3766
+				true,
3767
+				_n('message', 'messages', $deleted_count, 'event_espresso'),
3768
+				__('deleted', 'event_espresso')
3769
+			);
3770
+		} else {
3771
+			EE_Error::add_error(
3772
+				_n('The message was not deleted.', 'The messages were not deleted', count($msg_ids), 'event_espresso'),
3773
+				__FILE__, __FUNCTION__, __LINE__
3774
+			);
3775
+			$this->_redirect_after_action(false, '', '', array(), true);
3776
+		}
3777
+	}
3778
+    
3779
+    
3780
+	/**
3781
+	 *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
3782
+	 * @since 4.9.0
3783
+	 * @return array
3784
+	 */
3785
+	protected function _get_msg_ids_from_request()
3786
+	{
3787
+		if ( ! isset($this->_req_data['MSG_ID'])) {
3788
+			return array();
3789
+		}
3790
+        
3791
+		return is_array($this->_req_data['MSG_ID']) ? array_keys($this->_req_data['MSG_ID']) : array($this->_req_data['MSG_ID']);
3792
+	}
3793 3793
     
3794 3794
     
3795 3795
 }
Please login to merge, or discard this patch.
core/helpers/EEH_Template.helper.php 3 patches
Indentation   +928 added lines, -928 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
  * Event Espresso
@@ -16,35 +16,35 @@  discard block
 block discarded – undo
16 16
 
17 17
 
18 18
 if ( ! function_exists('espresso_get_template_part')) {
19
-    /**
20
-     * espresso_get_template_part
21
-     * basically a copy of the WordPress get_template_part() function but uses EEH_Template::locate_template() instead, and doesn't add base versions of files
22
-     * so not a very useful function at all except that it adds familiarity PLUS filtering based off of the entire template part name
23
-     *
24
-     * @param string $slug The slug name for the generic template.
25
-     * @param string $name The name of the specialised template.
26
-     * @return string        the html output for the formatted money value
27
-     */
28
-    function espresso_get_template_part($slug = null, $name = null)
29
-    {
30
-        EEH_Template::get_template_part($slug, $name);
31
-    }
19
+	/**
20
+	 * espresso_get_template_part
21
+	 * basically a copy of the WordPress get_template_part() function but uses EEH_Template::locate_template() instead, and doesn't add base versions of files
22
+	 * so not a very useful function at all except that it adds familiarity PLUS filtering based off of the entire template part name
23
+	 *
24
+	 * @param string $slug The slug name for the generic template.
25
+	 * @param string $name The name of the specialised template.
26
+	 * @return string        the html output for the formatted money value
27
+	 */
28
+	function espresso_get_template_part($slug = null, $name = null)
29
+	{
30
+		EEH_Template::get_template_part($slug, $name);
31
+	}
32 32
 }
33 33
 
34 34
 
35 35
 if ( ! function_exists('espresso_get_object_css_class')) {
36
-    /**
37
-     * espresso_get_object_css_class - attempts to generate a css class based on the type of EE object passed
38
-     *
39
-     * @param EE_Base_Class $object the EE object the css class is being generated for
40
-     * @param  string       $prefix added to the beginning of the generated class
41
-     * @param  string       $suffix added to the end of the generated class
42
-     * @return string
43
-     */
44
-    function espresso_get_object_css_class($object = null, $prefix = '', $suffix = '')
45
-    {
46
-        return EEH_Template::get_object_css_class($object, $prefix, $suffix);
47
-    }
36
+	/**
37
+	 * espresso_get_object_css_class - attempts to generate a css class based on the type of EE object passed
38
+	 *
39
+	 * @param EE_Base_Class $object the EE object the css class is being generated for
40
+	 * @param  string       $prefix added to the beginning of the generated class
41
+	 * @param  string       $suffix added to the end of the generated class
42
+	 * @return string
43
+	 */
44
+	function espresso_get_object_css_class($object = null, $prefix = '', $suffix = '')
45
+	{
46
+		return EEH_Template::get_object_css_class($object, $prefix, $suffix);
47
+	}
48 48
 }
49 49
 
50 50
 
@@ -59,648 +59,648 @@  discard block
 block discarded – undo
59 59
 class EEH_Template
60 60
 {
61 61
 
62
-    private static $_espresso_themes = array();
63
-
64
-
65
-    /**
66
-     *    is_espresso_theme - returns TRUE or FALSE on whether the currently active WP theme is an espresso theme
67
-     *
68
-     * @return boolean
69
-     */
70
-    public static function is_espresso_theme()
71
-    {
72
-        return wp_get_theme()->get('TextDomain') == 'event_espresso' ? true : false;
73
-    }
74
-
75
-    /**
76
-     *    load_espresso_theme_functions - if current theme is an espresso theme, or uses ee theme template parts, then
77
-     *    load it's functions.php file ( if not already loaded )
78
-     *
79
-     * @return void
80
-     */
81
-    public static function load_espresso_theme_functions()
82
-    {
83
-        if ( ! defined('EE_THEME_FUNCTIONS_LOADED')) {
84
-            if (is_readable(EE_PUBLIC . EE_Config::get_current_theme() . DS . 'functions.php')) {
85
-                require_once(EE_PUBLIC . EE_Config::get_current_theme() . DS . 'functions.php');
86
-            }
87
-        }
88
-    }
89
-
90
-
91
-    /**
92
-     *    get_espresso_themes - returns an array of Espresso Child themes located in the /templates/ directory
93
-     *
94
-     * @return array
95
-     */
96
-    public static function get_espresso_themes()
97
-    {
98
-        if (empty(EEH_Template::$_espresso_themes)) {
99
-            $espresso_themes = glob(EE_PUBLIC . '*', GLOB_ONLYDIR);
100
-            if (empty($espresso_themes)) {
101
-                return array();
102
-            }
103
-            if (($key = array_search('global_assets', $espresso_themes)) !== false) {
104
-                unset($espresso_themes[$key]);
105
-            }
106
-            EEH_Template::$_espresso_themes = array();
107
-            foreach ($espresso_themes as $espresso_theme) {
108
-                EEH_Template::$_espresso_themes[basename($espresso_theme)] = $espresso_theme;
109
-            }
110
-        }
111
-        return EEH_Template::$_espresso_themes;
112
-    }
113
-
114
-
115
-    /**
116
-     * EEH_Template::get_template_part
117
-     * basically a copy of the WordPress get_template_part() function but uses EEH_Template::locate_template() instead,
118
-     * and doesn't add base versions of files so not a very useful function at all except that it adds familiarity PLUS
119
-     * filtering based off of the entire template part name
120
-     *
121
-     * @param string $slug The slug name for the generic template.
122
-     * @param string $name The name of the specialised template.
123
-     * @param array  $template_args
124
-     * @param bool   $return_string
125
-     * @return string        the html output for the formatted money value
126
-     */
127
-    public static function get_template_part(
128
-        $slug = null,
129
-        $name = null,
130
-        $template_args = array(),
131
-        $return_string = false
132
-    ) {
133
-        do_action("get_template_part_{$slug}-{$name}", $slug, $name);
134
-        $templates = array();
135
-        $name      = (string)$name;
136
-        if ($name != '') {
137
-            $templates[] = "{$slug}-{$name}.php";
138
-        }
139
-        // allow template parts to be turned off via something like: add_filter( 'FHEE__content_espresso_events_tickets_template__display_datetimes', '__return_false' );
140
-        if (apply_filters("FHEE__EEH_Template__get_template_part__display__{$slug}_{$name}", true)) {
141
-            EEH_Template::locate_template($templates, $template_args, true, $return_string);
142
-        }
143
-    }
144
-
145
-
146
-    /**
147
-     *    locate_template
148
-     *    locate a template file by looking in the following places, in the following order:
149
-     *        <server path up to>/wp-content/themes/<current active WordPress theme>/
150
-     *        <assumed full absolute server path>
151
-     *        <server path up to>/wp-content/uploads/espresso/templates/<current EE theme>/
152
-     *        <server path up to>/wp-content/uploads/espresso/templates/
153
-     *        <server path up to>/wp-content/plugins/<EE4 folder>/public/<current EE theme>/
154
-     *        <server path up to>/wp-content/plugins/<EE4 folder>/core/templates/<current EE theme>/
155
-     *        <server path up to>/wp-content/plugins/<EE4 folder>/
156
-     *    as soon as the template is found in one of these locations, it will be returned or loaded
157
-     *        Example:
158
-     *          You are using the WordPress Twenty Sixteen theme,
159
-     *        and you want to customize the "some-event.template.php" template,
160
-     *          which is located in the "/relative/path/to/" folder relative to the main EE plugin folder.
161
-     *          Assuming WP is installed on your server in the "/home/public_html/" folder,
162
-     *        EEH_Template::locate_template() will look at the following paths in order until the template is found:
163
-     *        /home/public_html/wp-content/themes/twentysixteen/some-event.template.php
164
-     *        /relative/path/to/some-event.template.php
165
-     *        /home/public_html/wp-content/uploads/espresso/templates/Espresso_Arabica_2014/relative/path/to/some-event.template.php
166
-     *        /home/public_html/wp-content/uploads/espresso/templates/relative/path/to/some-event.template.php
167
-     *        /home/public_html/wp-content/plugins/event-espresso-core-reg/public/Espresso_Arabica_2014/relative/path/to/some-event.template.php
168
-     *        /home/public_html/wp-content/plugins/event-espresso-core-reg/core/templates/Espresso_Arabica_2014/relative/path/to/some-event.template.php
169
-     *        /home/public_html/wp-content/plugins/event-espresso-core-reg/relative/path/to/some-event.template.php
170
-     *          Had you passed an absolute path to your template that was in some other location,
171
-     *        ie: "/absolute/path/to/some-event.template.php"
172
-     *          then the search would have been :
173
-     *        /home/public_html/wp-content/themes/twentysixteen/some-event.template.php
174
-     *        /absolute/path/to/some-event.template.php
175
-     *          and stopped there upon finding it in the second location
176
-     *
177
-     * @param array|string $templates       array of template file names including extension (or just a single string)
178
-     * @param  array       $template_args   an array of arguments to be extracted for use in the template
179
-     * @param  boolean     $load            whether to pass the located template path on to the
180
-     *                                      EEH_Template::display_template() method or simply return it
181
-     * @param  boolean     $return_string   whether to send output immediately to screen, or capture and return as a
182
-     *                                      string
183
-     * @param boolean      $check_if_custom If TRUE, this flags this method to return boolean for whether this will
184
-     *                                      generate a custom template or not. Used in places where you don't actually
185
-     *                                      load the template, you just want to know if there's a custom version of it.
186
-     * @return mixed
187
-     */
188
-    public static function locate_template(
189
-        $templates = array(),
190
-        $template_args = array(),
191
-        $load = true,
192
-        $return_string = true,
193
-        $check_if_custom = false
194
-    ) {
195
-        // first use WP locate_template to check for template in the current theme folder
196
-        $template_path = locate_template($templates);
197
-
198
-        if ($check_if_custom && ! empty($template_path)) {
199
-            return true;
200
-        }
201
-
202
-        // not in the theme
203
-        if (empty($template_path)) {
204
-            // not even a template to look for ?
205
-            if (empty($templates)) {
206
-                // get post_type
207
-                $post_type = EE_Registry::instance()->REQ->get('post_type');
208
-                // get array of EE Custom Post Types
209
-                $EE_CPTs = EE_Register_CPTs::get_CPTs();
210
-                // build template name based on request
211
-                if (isset($EE_CPTs[$post_type])) {
212
-                    $archive_or_single = is_archive() ? 'archive' : '';
213
-                    $archive_or_single = is_single() ? 'single' : $archive_or_single;
214
-                    $templates         = $archive_or_single . '-' . $post_type . '.php';
215
-                }
216
-            }
217
-            // currently active EE template theme
218
-            $current_theme = EE_Config::get_current_theme();
219
-
220
-            // array of paths to folders that may contain templates
221
-            $template_folder_paths = array(
222
-                // first check the /wp-content/uploads/espresso/templates/(current EE theme)/  folder for an EE theme template file
223
-                EVENT_ESPRESSO_TEMPLATE_DIR . $current_theme,
224
-                // then in the root of the /wp-content/uploads/espresso/templates/ folder
225
-                EVENT_ESPRESSO_TEMPLATE_DIR,
226
-            );
227
-
228
-            //add core plugin folders for checking only if we're not $check_if_custom
229
-            if ( ! $check_if_custom) {
230
-                $core_paths            = array(
231
-                    // in the  /wp-content/plugins/(EE4 folder)/public/(current EE theme)/ folder within the plugin
232
-                    EE_PUBLIC . $current_theme,
233
-                    // in the  /wp-content/plugins/(EE4 folder)/core/templates/(current EE theme)/ folder within the plugin
234
-                    EE_TEMPLATES . $current_theme,
235
-                    // or maybe relative from the plugin root: /wp-content/plugins/(EE4 folder)/
236
-                    EE_PLUGIN_DIR_PATH,
237
-                );
238
-                $template_folder_paths = array_merge($template_folder_paths, $core_paths);
239
-            }
240
-
241
-            // now filter that array
242
-            $template_folder_paths = apply_filters('FHEE__EEH_Template__locate_template__template_folder_paths',
243
-                $template_folder_paths);
244
-            $templates             = is_array($templates) ? $templates : array($templates);
245
-            $template_folder_paths = is_array($template_folder_paths) ? $template_folder_paths : array($template_folder_paths);
246
-            // array to hold all possible template paths
247
-            $full_template_paths = array();
248
-
249
-            // loop through $templates
250
-            foreach ($templates as $template) {
251
-                // normalize directory separators
252
-                $template                      = EEH_File::standardise_directory_separators($template);
253
-                $file_name                     = basename($template);
254
-                $template_path_minus_file_name = substr($template, 0, (strlen($file_name) * -1));
255
-                // while looping through all template folder paths
256
-                foreach ($template_folder_paths as $template_folder_path) {
257
-                    // normalize directory separators
258
-                    $template_folder_path = EEH_File::standardise_directory_separators($template_folder_path);
259
-                    // determine if any common base path exists between the two paths
260
-                    $common_base_path = EEH_Template::_find_common_base_path(
261
-                        array($template_folder_path, $template_path_minus_file_name)
262
-                    );
263
-                    if ($common_base_path !== '') {
264
-                        // both paths have a common base, so just tack the filename onto our search path
265
-                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $file_name;
266
-                    } else {
267
-                        // no common base path, so let's just concatenate
268
-                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $template;
269
-                    }
270
-                    // build up our template locations array by adding our resolved paths
271
-                    $full_template_paths[] = $resolved_path;
272
-                }
273
-                // if $template is an absolute path, then we'll tack it onto the start of our array so that it gets searched first
274
-                array_unshift($full_template_paths, $template);
275
-                // path to the directory of the current theme: /wp-content/themes/(current WP theme)/
276
-                array_unshift($full_template_paths, get_stylesheet_directory() . DS . $file_name);
277
-            }
278
-            // filter final array of full template paths
279
-            $full_template_paths = apply_filters('FHEE__EEH_Template__locate_template__full_template_paths',
280
-                $full_template_paths, $file_name);
281
-            // now loop through our final array of template location paths and check each location
282
-            foreach ((array)$full_template_paths as $full_template_path) {
283
-                if (is_readable($full_template_path)) {
284
-                    $template_path = str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, $full_template_path);
285
-                    // hook that can be used to display the full template path that will be used
286
-                    do_action('AHEE__EEH_Template__locate_template__full_template_path', $template_path);
287
-                    break;
288
-                }
289
-            }
290
-        }
291
-        // if we got it and you want to see it...
292
-        if ($template_path && $load && ! $check_if_custom) {
293
-            if ($return_string) {
294
-                return EEH_Template::display_template($template_path, $template_args, true);
295
-            } else {
296
-                EEH_Template::display_template($template_path, $template_args, false);
297
-            }
298
-        }
299
-        return $check_if_custom && ! empty($template_path) ? true : $template_path;
300
-    }
301
-
302
-
303
-    /**
304
-     * _find_common_base_path
305
-     * given two paths, this determines if there is a common base path between the two
306
-     *
307
-     * @param array $paths
308
-     * @return string
309
-     */
310
-    protected static function _find_common_base_path($paths)
311
-    {
312
-        $last_offset      = 0;
313
-        $common_base_path = '';
314
-        while (($index = strpos($paths[0], DS, $last_offset)) !== false) {
315
-            $dir_length = $index - $last_offset + 1;
316
-            $directory  = substr($paths[0], $last_offset, $dir_length);
317
-            foreach ($paths as $path) {
318
-                if (substr($path, $last_offset, $dir_length) != $directory) {
319
-                    return $common_base_path;
320
-                }
321
-            }
322
-            $common_base_path .= $directory;
323
-            $last_offset = $index + 1;
324
-        }
325
-        return substr($common_base_path, 0, -1);
326
-    }
327
-
328
-
329
-    /**
330
-     * load and display a template
331
-     *
332
-     * @param bool|string $template_path server path to the file to be loaded, including file name and extension
333
-     * @param  array      $template_args an array of arguments to be extracted for use in the template
334
-     * @param  boolean    $return_string whether to send output immediately to screen, or capture and return as a string
335
-     * @param bool        $throw_exceptions if set to true, will throw an exception if the template is either
336
-     *                                      not found or is not readable
337
-     * @return mixed string
338
-     * @throws \DomainException
339
-     */
62
+	private static $_espresso_themes = array();
63
+
64
+
65
+	/**
66
+	 *    is_espresso_theme - returns TRUE or FALSE on whether the currently active WP theme is an espresso theme
67
+	 *
68
+	 * @return boolean
69
+	 */
70
+	public static function is_espresso_theme()
71
+	{
72
+		return wp_get_theme()->get('TextDomain') == 'event_espresso' ? true : false;
73
+	}
74
+
75
+	/**
76
+	 *    load_espresso_theme_functions - if current theme is an espresso theme, or uses ee theme template parts, then
77
+	 *    load it's functions.php file ( if not already loaded )
78
+	 *
79
+	 * @return void
80
+	 */
81
+	public static function load_espresso_theme_functions()
82
+	{
83
+		if ( ! defined('EE_THEME_FUNCTIONS_LOADED')) {
84
+			if (is_readable(EE_PUBLIC . EE_Config::get_current_theme() . DS . 'functions.php')) {
85
+				require_once(EE_PUBLIC . EE_Config::get_current_theme() . DS . 'functions.php');
86
+			}
87
+		}
88
+	}
89
+
90
+
91
+	/**
92
+	 *    get_espresso_themes - returns an array of Espresso Child themes located in the /templates/ directory
93
+	 *
94
+	 * @return array
95
+	 */
96
+	public static function get_espresso_themes()
97
+	{
98
+		if (empty(EEH_Template::$_espresso_themes)) {
99
+			$espresso_themes = glob(EE_PUBLIC . '*', GLOB_ONLYDIR);
100
+			if (empty($espresso_themes)) {
101
+				return array();
102
+			}
103
+			if (($key = array_search('global_assets', $espresso_themes)) !== false) {
104
+				unset($espresso_themes[$key]);
105
+			}
106
+			EEH_Template::$_espresso_themes = array();
107
+			foreach ($espresso_themes as $espresso_theme) {
108
+				EEH_Template::$_espresso_themes[basename($espresso_theme)] = $espresso_theme;
109
+			}
110
+		}
111
+		return EEH_Template::$_espresso_themes;
112
+	}
113
+
114
+
115
+	/**
116
+	 * EEH_Template::get_template_part
117
+	 * basically a copy of the WordPress get_template_part() function but uses EEH_Template::locate_template() instead,
118
+	 * and doesn't add base versions of files so not a very useful function at all except that it adds familiarity PLUS
119
+	 * filtering based off of the entire template part name
120
+	 *
121
+	 * @param string $slug The slug name for the generic template.
122
+	 * @param string $name The name of the specialised template.
123
+	 * @param array  $template_args
124
+	 * @param bool   $return_string
125
+	 * @return string        the html output for the formatted money value
126
+	 */
127
+	public static function get_template_part(
128
+		$slug = null,
129
+		$name = null,
130
+		$template_args = array(),
131
+		$return_string = false
132
+	) {
133
+		do_action("get_template_part_{$slug}-{$name}", $slug, $name);
134
+		$templates = array();
135
+		$name      = (string)$name;
136
+		if ($name != '') {
137
+			$templates[] = "{$slug}-{$name}.php";
138
+		}
139
+		// allow template parts to be turned off via something like: add_filter( 'FHEE__content_espresso_events_tickets_template__display_datetimes', '__return_false' );
140
+		if (apply_filters("FHEE__EEH_Template__get_template_part__display__{$slug}_{$name}", true)) {
141
+			EEH_Template::locate_template($templates, $template_args, true, $return_string);
142
+		}
143
+	}
144
+
145
+
146
+	/**
147
+	 *    locate_template
148
+	 *    locate a template file by looking in the following places, in the following order:
149
+	 *        <server path up to>/wp-content/themes/<current active WordPress theme>/
150
+	 *        <assumed full absolute server path>
151
+	 *        <server path up to>/wp-content/uploads/espresso/templates/<current EE theme>/
152
+	 *        <server path up to>/wp-content/uploads/espresso/templates/
153
+	 *        <server path up to>/wp-content/plugins/<EE4 folder>/public/<current EE theme>/
154
+	 *        <server path up to>/wp-content/plugins/<EE4 folder>/core/templates/<current EE theme>/
155
+	 *        <server path up to>/wp-content/plugins/<EE4 folder>/
156
+	 *    as soon as the template is found in one of these locations, it will be returned or loaded
157
+	 *        Example:
158
+	 *          You are using the WordPress Twenty Sixteen theme,
159
+	 *        and you want to customize the "some-event.template.php" template,
160
+	 *          which is located in the "/relative/path/to/" folder relative to the main EE plugin folder.
161
+	 *          Assuming WP is installed on your server in the "/home/public_html/" folder,
162
+	 *        EEH_Template::locate_template() will look at the following paths in order until the template is found:
163
+	 *        /home/public_html/wp-content/themes/twentysixteen/some-event.template.php
164
+	 *        /relative/path/to/some-event.template.php
165
+	 *        /home/public_html/wp-content/uploads/espresso/templates/Espresso_Arabica_2014/relative/path/to/some-event.template.php
166
+	 *        /home/public_html/wp-content/uploads/espresso/templates/relative/path/to/some-event.template.php
167
+	 *        /home/public_html/wp-content/plugins/event-espresso-core-reg/public/Espresso_Arabica_2014/relative/path/to/some-event.template.php
168
+	 *        /home/public_html/wp-content/plugins/event-espresso-core-reg/core/templates/Espresso_Arabica_2014/relative/path/to/some-event.template.php
169
+	 *        /home/public_html/wp-content/plugins/event-espresso-core-reg/relative/path/to/some-event.template.php
170
+	 *          Had you passed an absolute path to your template that was in some other location,
171
+	 *        ie: "/absolute/path/to/some-event.template.php"
172
+	 *          then the search would have been :
173
+	 *        /home/public_html/wp-content/themes/twentysixteen/some-event.template.php
174
+	 *        /absolute/path/to/some-event.template.php
175
+	 *          and stopped there upon finding it in the second location
176
+	 *
177
+	 * @param array|string $templates       array of template file names including extension (or just a single string)
178
+	 * @param  array       $template_args   an array of arguments to be extracted for use in the template
179
+	 * @param  boolean     $load            whether to pass the located template path on to the
180
+	 *                                      EEH_Template::display_template() method or simply return it
181
+	 * @param  boolean     $return_string   whether to send output immediately to screen, or capture and return as a
182
+	 *                                      string
183
+	 * @param boolean      $check_if_custom If TRUE, this flags this method to return boolean for whether this will
184
+	 *                                      generate a custom template or not. Used in places where you don't actually
185
+	 *                                      load the template, you just want to know if there's a custom version of it.
186
+	 * @return mixed
187
+	 */
188
+	public static function locate_template(
189
+		$templates = array(),
190
+		$template_args = array(),
191
+		$load = true,
192
+		$return_string = true,
193
+		$check_if_custom = false
194
+	) {
195
+		// first use WP locate_template to check for template in the current theme folder
196
+		$template_path = locate_template($templates);
197
+
198
+		if ($check_if_custom && ! empty($template_path)) {
199
+			return true;
200
+		}
201
+
202
+		// not in the theme
203
+		if (empty($template_path)) {
204
+			// not even a template to look for ?
205
+			if (empty($templates)) {
206
+				// get post_type
207
+				$post_type = EE_Registry::instance()->REQ->get('post_type');
208
+				// get array of EE Custom Post Types
209
+				$EE_CPTs = EE_Register_CPTs::get_CPTs();
210
+				// build template name based on request
211
+				if (isset($EE_CPTs[$post_type])) {
212
+					$archive_or_single = is_archive() ? 'archive' : '';
213
+					$archive_or_single = is_single() ? 'single' : $archive_or_single;
214
+					$templates         = $archive_or_single . '-' . $post_type . '.php';
215
+				}
216
+			}
217
+			// currently active EE template theme
218
+			$current_theme = EE_Config::get_current_theme();
219
+
220
+			// array of paths to folders that may contain templates
221
+			$template_folder_paths = array(
222
+				// first check the /wp-content/uploads/espresso/templates/(current EE theme)/  folder for an EE theme template file
223
+				EVENT_ESPRESSO_TEMPLATE_DIR . $current_theme,
224
+				// then in the root of the /wp-content/uploads/espresso/templates/ folder
225
+				EVENT_ESPRESSO_TEMPLATE_DIR,
226
+			);
227
+
228
+			//add core plugin folders for checking only if we're not $check_if_custom
229
+			if ( ! $check_if_custom) {
230
+				$core_paths            = array(
231
+					// in the  /wp-content/plugins/(EE4 folder)/public/(current EE theme)/ folder within the plugin
232
+					EE_PUBLIC . $current_theme,
233
+					// in the  /wp-content/plugins/(EE4 folder)/core/templates/(current EE theme)/ folder within the plugin
234
+					EE_TEMPLATES . $current_theme,
235
+					// or maybe relative from the plugin root: /wp-content/plugins/(EE4 folder)/
236
+					EE_PLUGIN_DIR_PATH,
237
+				);
238
+				$template_folder_paths = array_merge($template_folder_paths, $core_paths);
239
+			}
240
+
241
+			// now filter that array
242
+			$template_folder_paths = apply_filters('FHEE__EEH_Template__locate_template__template_folder_paths',
243
+				$template_folder_paths);
244
+			$templates             = is_array($templates) ? $templates : array($templates);
245
+			$template_folder_paths = is_array($template_folder_paths) ? $template_folder_paths : array($template_folder_paths);
246
+			// array to hold all possible template paths
247
+			$full_template_paths = array();
248
+
249
+			// loop through $templates
250
+			foreach ($templates as $template) {
251
+				// normalize directory separators
252
+				$template                      = EEH_File::standardise_directory_separators($template);
253
+				$file_name                     = basename($template);
254
+				$template_path_minus_file_name = substr($template, 0, (strlen($file_name) * -1));
255
+				// while looping through all template folder paths
256
+				foreach ($template_folder_paths as $template_folder_path) {
257
+					// normalize directory separators
258
+					$template_folder_path = EEH_File::standardise_directory_separators($template_folder_path);
259
+					// determine if any common base path exists between the two paths
260
+					$common_base_path = EEH_Template::_find_common_base_path(
261
+						array($template_folder_path, $template_path_minus_file_name)
262
+					);
263
+					if ($common_base_path !== '') {
264
+						// both paths have a common base, so just tack the filename onto our search path
265
+						$resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $file_name;
266
+					} else {
267
+						// no common base path, so let's just concatenate
268
+						$resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $template;
269
+					}
270
+					// build up our template locations array by adding our resolved paths
271
+					$full_template_paths[] = $resolved_path;
272
+				}
273
+				// if $template is an absolute path, then we'll tack it onto the start of our array so that it gets searched first
274
+				array_unshift($full_template_paths, $template);
275
+				// path to the directory of the current theme: /wp-content/themes/(current WP theme)/
276
+				array_unshift($full_template_paths, get_stylesheet_directory() . DS . $file_name);
277
+			}
278
+			// filter final array of full template paths
279
+			$full_template_paths = apply_filters('FHEE__EEH_Template__locate_template__full_template_paths',
280
+				$full_template_paths, $file_name);
281
+			// now loop through our final array of template location paths and check each location
282
+			foreach ((array)$full_template_paths as $full_template_path) {
283
+				if (is_readable($full_template_path)) {
284
+					$template_path = str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, $full_template_path);
285
+					// hook that can be used to display the full template path that will be used
286
+					do_action('AHEE__EEH_Template__locate_template__full_template_path', $template_path);
287
+					break;
288
+				}
289
+			}
290
+		}
291
+		// if we got it and you want to see it...
292
+		if ($template_path && $load && ! $check_if_custom) {
293
+			if ($return_string) {
294
+				return EEH_Template::display_template($template_path, $template_args, true);
295
+			} else {
296
+				EEH_Template::display_template($template_path, $template_args, false);
297
+			}
298
+		}
299
+		return $check_if_custom && ! empty($template_path) ? true : $template_path;
300
+	}
301
+
302
+
303
+	/**
304
+	 * _find_common_base_path
305
+	 * given two paths, this determines if there is a common base path between the two
306
+	 *
307
+	 * @param array $paths
308
+	 * @return string
309
+	 */
310
+	protected static function _find_common_base_path($paths)
311
+	{
312
+		$last_offset      = 0;
313
+		$common_base_path = '';
314
+		while (($index = strpos($paths[0], DS, $last_offset)) !== false) {
315
+			$dir_length = $index - $last_offset + 1;
316
+			$directory  = substr($paths[0], $last_offset, $dir_length);
317
+			foreach ($paths as $path) {
318
+				if (substr($path, $last_offset, $dir_length) != $directory) {
319
+					return $common_base_path;
320
+				}
321
+			}
322
+			$common_base_path .= $directory;
323
+			$last_offset = $index + 1;
324
+		}
325
+		return substr($common_base_path, 0, -1);
326
+	}
327
+
328
+
329
+	/**
330
+	 * load and display a template
331
+	 *
332
+	 * @param bool|string $template_path server path to the file to be loaded, including file name and extension
333
+	 * @param  array      $template_args an array of arguments to be extracted for use in the template
334
+	 * @param  boolean    $return_string whether to send output immediately to screen, or capture and return as a string
335
+	 * @param bool        $throw_exceptions if set to true, will throw an exception if the template is either
336
+	 *                                      not found or is not readable
337
+	 * @return mixed string
338
+	 * @throws \DomainException
339
+	 */
340 340
 	public static function display_template(
341
-        $template_path    = false,
342
-        $template_args    = array(),
343
-        $return_string    = false,
344
-        $throw_exceptions = false
345
-    ) {
346
-
347
-        /**
348
-         * These two filters are intended for last minute changes to templates being loaded and/or template arg
349
-         * modifications.  NOTE... modifying these things can cause breakage as most templates running through
350
-         * the display_template method are templates we DON'T want modified (usually because of js
351
-         * dependencies etc).  So unless you know what you are doing, do NOT filter templates or template args
352
-         * using this.
353
-         *
354
-         * @since 4.6.0
355
-         */
356
-        $template_path = (string) apply_filters('FHEE__EEH_Template__display_template__template_path', $template_path);
357
-        $template_args = (array) apply_filters('FHEE__EEH_Template__display_template__template_args', $template_args);
358
-
359
-        // you gimme nuttin - YOU GET NUTTIN !!
360
-        if ( ! $template_path || ! is_readable($template_path)) {
361
-            return '';
362
-        }
363
-        // if $template_args are not in an array, then make it so
364
-        if ( ! is_array($template_args) && ! is_object($template_args)) {
365
-            $template_args = array($template_args);
366
-        }
367
-        extract( $template_args, EXTR_SKIP );
368
-        // ignore whether template is accessible ?
369
-        if ( $throw_exceptions && ! is_readable( $template_path ) ) {
370
-            throw new \DomainException(
371
-                    esc_html__(
372
-                            'Invalid, unreadable, or missing file.',
373
-                            'event_espresso'
374
-                    )
375
-            );
376
-        }
377
-
378
-
379
-        if ($return_string) {
380
-            // because we want to return a string, we are going to capture the output
381
-            ob_start();
382
-            include($template_path);
383
-            return ob_get_clean();
384
-        } else {
385
-            include($template_path);
386
-        }
387
-        return '';
388
-    }
389
-
390
-
391
-    /**
392
-     * get_object_css_class - attempts to generate a css class based on the type of EE object passed
393
-     *
394
-     * @param EE_Base_Class $object the EE object the css class is being generated for
395
-     * @param  string       $prefix added to the beginning of the generated class
396
-     * @param  string       $suffix added to the end of the generated class
397
-     * @return string
398
-     */
399
-    public static function get_object_css_class($object = null, $prefix = '', $suffix = '')
400
-    {
401
-        // in the beginning...
402
-        $prefix = ! empty($prefix) ? rtrim($prefix, '-') . '-' : '';
403
-        // da muddle
404
-        $class = '';
405
-        // the end
406
-        $suffix = ! empty($suffix) ? '-' . ltrim($suffix, '-') : '';
407
-        // is the passed object an EE object ?
408
-        if ($object instanceof EE_Base_Class) {
409
-            // grab the exact type of object
410
-            $obj_class = get_class($object);
411
-            // depending on the type of object...
412
-            switch ($obj_class) {
413
-                // no specifics just yet...
414
-                default :
415
-                    $class = strtolower(str_replace('_', '-', $obj_class));
416
-                    $class .= method_exists($obj_class, 'name') ? '-' . sanitize_title($object->name()) : '';
417
-
418
-            }
419
-        }
420
-        return $prefix . $class . $suffix;
421
-    }
422
-
423
-
424
-
425
-    /**
426
-     * EEH_Template::format_currency
427
-     * This helper takes a raw float value and formats it according to the default config country currency settings, or
428
-     * the country currency settings from the supplied country ISO code
429
-     *
430
-     * @param  float   $amount       raw money value
431
-     * @param  boolean $return_raw   whether to return the formatted float value only with no currency sign or code
432
-     * @param  boolean $display_code whether to display the country code (USD). Default = TRUE
433
-     * @param string   $CNT_ISO      2 letter ISO code for a country
434
-     * @param string   $cur_code_span_class
435
-     * @return string        the html output for the formatted money value
436
-     * @throws \EE_Error
437
-     */
438
-    public static function format_currency(
439
-        $amount = null,
440
-        $return_raw = false,
441
-        $display_code = true,
442
-        $CNT_ISO = '',
443
-        $cur_code_span_class = 'currency-code'
444
-    ) {
445
-        // ensure amount was received
446
-        if ($amount === null) {
447
-            $msg = __('In order to format currency, an amount needs to be passed.', 'event_espresso');
448
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
449
-            return '';
450
-        }
451
-        //ensure amount is float
452
-        $amount  = apply_filters('FHEE__EEH_Template__format_currency__raw_amount', (float)$amount);
453
-        $CNT_ISO = apply_filters('FHEE__EEH_Template__format_currency__CNT_ISO', $CNT_ISO, $amount);
454
-        // filter raw amount (allows 0.00 to be changed to "free" for example)
455
-        $amount_formatted = apply_filters('FHEE__EEH_Template__format_currency__amount', $amount, $return_raw);
456
-        // still a number or was amount converted to a string like "free" ?
457
-        if (is_float($amount_formatted)) {
458
-            // was a country ISO code passed ? if so generate currency config object for that country
459
-            $mny = $CNT_ISO !== '' ? new EE_Currency_Config($CNT_ISO) : null;
460
-            // verify results
461
-            if ( ! $mny instanceof EE_Currency_Config) {
462
-                // set default config country currency settings
463
-                $mny = EE_Registry::instance()->CFG->currency instanceof EE_Currency_Config
464
-                    ? EE_Registry::instance()->CFG->currency
465
-                    : new EE_Currency_Config();
466
-            }
467
-            // format float
468
-            $amount_formatted = number_format($amount, $mny->dec_plc, $mny->dec_mrk, $mny->thsnds);
469
-            // add formatting ?
470
-            if ( ! $return_raw) {
471
-                // add currency sign
472
-                if ($mny->sign_b4) {
473
-                    if ($amount >= 0) {
474
-                        $amount_formatted = $mny->sign . $amount_formatted;
475
-                    } else {
476
-                        $amount_formatted = '-' . $mny->sign . str_replace('-', '', $amount_formatted);
477
-                    }
478
-
479
-                } else {
480
-                    $amount_formatted = $amount_formatted . $mny->sign;
481
-                }
482
-
483
-                // filter to allow global setting of display_code
484
-                $display_code = apply_filters('FHEE__EEH_Template__format_currency__display_code', $display_code);
485
-
486
-                // add currency code ?
487
-                $amount_formatted = $display_code ? $amount_formatted . ' <span class="' . $cur_code_span_class . '">(' . $mny->code . ')</span>' : $amount_formatted;
488
-            }
489
-            // filter results
490
-            $amount_formatted = apply_filters('FHEE__EEH_Template__format_currency__amount_formatted',
491
-                $amount_formatted, $mny, $return_raw);
492
-        }
493
-        // clean up vars
494
-        unset($mny);
495
-        // return formatted currency amount
496
-        return $amount_formatted;
497
-    }
498
-
499
-
500
-    /**
501
-     * This function is used for outputting the localized label for a given status id in the schema requested (and
502
-     * possibly plural).  The intended use of this function is only for cases where wanting a label outside of a
503
-     * related status model or model object (i.e. in documentation etc.)
504
-     *
505
-     * @param  string  $status_id Status ID matching a registered status in the esp_status table.  If there is no
506
-     *                            match, then 'Unknown' will be returned.
507
-     * @param  boolean $plural    Whether to return plural or not
508
-     * @param  string  $schema    'UPPER', 'lower', or 'Sentence'
509
-     * @return string             The localized label for the status id.
510
-     */
511
-    public static function pretty_status($status_id, $plural = false, $schema = 'upper')
512
-    {
513
-        /** @type EEM_Status $EEM_Status */
514
-        $EEM_Status = EE_Registry::instance()->load_model('Status');
515
-        $status     = $EEM_Status->localized_status(array($status_id => __('unknown', 'event_espresso')), $plural,
516
-            $schema);
517
-        return $status[$status_id];
518
-    }
519
-
520
-
521
-    /**
522
-     * This helper just returns a button or link for the given parameters
523
-     *
524
-     * @param  string $url   the url for the link
525
-     * @param  string $label What is the label you want displayed for the button
526
-     * @param  string $class what class is used for the button (defaults to 'button-primary')
527
-     * @param string  $icon
528
-     * @param string  $title
529
-     * @return string the html output for the button
530
-     */
531
-    public static function get_button_or_link($url, $label, $class = 'button-primary', $icon = '', $title = '')
532
-    {
533
-        $icon_html = '';
534
-        if ( ! empty($icon)) {
535
-            $dashicons = preg_split("(ee-icon |dashicons )", $icon);
536
-            $dashicons = array_filter($dashicons);
537
-            $count     = count($dashicons);
538
-            $icon_html .= $count > 1 ? '<span class="ee-composite-dashicon">' : '';
539
-            foreach ($dashicons as $dashicon) {
540
-                $type = strpos($dashicon, 'ee-icon') !== false ? 'ee-icon ' : 'dashicons ';
541
-                $icon_html .= '<span class="' . $type . $dashicon . '"></span>';
542
-            }
543
-            $icon_html .= $count > 1 ? '</span>' : '';
544
-        }
545
-        $label  = ! empty($icon) ? $icon_html . $label : $label;
546
-        $button = '<a id="' . sanitize_title_with_dashes($label) . '" href="' . $url . '" class="' . $class . '" title="' . $title . '">' . $label . '</a>';
547
-        return $button;
548
-    }
549
-
550
-
551
-    /**
552
-     * This returns a generated link that will load the related help tab on admin pages.
553
-     *
554
-     * @param  string     $help_tab_id the id for the connected help tab
555
-     * @param bool|string $page        The page identifier for the page the help tab is on
556
-     * @param bool|string $action      The action (route) for the admin page the help tab is on.
557
-     * @param bool|string $icon_style  (optional) include css class for the style you want to use for the help icon.
558
-     * @param bool|string $help_text   (optional) send help text you want to use for the link if default not to be used
559
-     * @return string              generated link
560
-     */
561
-    public static function get_help_tab_link(
562
-        $help_tab_id,
563
-        $page = false,
564
-        $action = false,
565
-        $icon_style = false,
566
-        $help_text = false
567
-    ) {
568
-
569
-        if ( ! $page) {
570
-            $page = isset($_REQUEST['page']) && ! empty($_REQUEST['page']) ? sanitize_key($_REQUEST['page']) : $page;
571
-        }
572
-
573
-        if ( ! $action) {
574
-            $action = isset($_REQUEST['action']) && ! empty($_REQUEST['action']) ? sanitize_key($_REQUEST['action']) : $action;
575
-        }
576
-
577
-        $action = empty($action) ? 'default' : $action;
578
-
579
-
580
-        $help_tab_lnk = $page . '-' . $action . '-' . $help_tab_id;
581
-        $icon         = ! $icon_style ? ' dashicons-editor-help' : $icon_style;
582
-        $help_text    = ! $help_text ? '' : $help_text;
583
-        return '<a id="' . $help_tab_lnk . '" class="ee-clickable dashicons espresso-help-tab-lnk ee-icon-size-22' . $icon . '" title="' . esc_attr__('Click to open the \'Help\' tab for more information about this feature.',
584
-                'event_espresso') . '" > ' . $help_text . ' </a>';
585
-    }
586
-
587
-
588
-    /**
589
-     * This helper generates the html structure for the jquery joyride plugin with the given params.
590
-     *
591
-     * @link http://zurb.com/playground/jquery-joyride-feature-tour-plugin
592
-     * @see  EE_Admin_Page->_stop_callback() for the construct expected for the $stops param.
593
-     * @param EE_Help_Tour
594
-     * @return string         html
595
-     */
596
-    public static function help_tour_stops_generator(EE_Help_Tour $tour)
597
-    {
598
-        $id    = $tour->get_slug();
599
-        $stops = $tour->get_stops();
600
-
601
-        $content = '<ol style="display:none" id="' . $id . '">';
602
-
603
-        foreach ($stops as $stop) {
604
-            $data_id    = ! empty($stop['id']) ? ' data-id="' . $stop['id'] . '"' : '';
605
-            $data_class = empty($data_id) && ! empty($stop['class']) ? ' data-class="' . $stop['class'] . '"' : '';
606
-
607
-            //if container is set to modal then let's make sure we set the options accordingly
608
-            if (empty($data_id) && empty($data_class)) {
609
-                $stop['options']['modal']  = true;
610
-                $stop['options']['expose'] = true;
611
-            }
612
-
613
-            $custom_class  = ! empty($stop['custom_class']) ? ' class="' . $stop['custom_class'] . '"' : '';
614
-            $button_text   = ! empty($stop['button_text']) ? ' data-button="' . $stop['button_text'] . '"' : '';
615
-            $inner_content = isset($stop['content']) ? $stop['content'] : '';
616
-
617
-            //options
618
-            if (isset($stop['options']) && is_array($stop['options'])) {
619
-                $options = ' data-options="';
620
-                foreach ($stop['options'] as $option => $value) {
621
-                    $options .= $option . ':' . $value . ';';
622
-                }
623
-                $options .= '"';
624
-            } else {
625
-                $options = '';
626
-            }
627
-
628
-            //let's put all together
629
-            $content .= '<li' . $data_id . $data_class . $custom_class . $button_text . $options . '>' . $inner_content . '</li>';
630
-        }
631
-
632
-        $content .= '</ol>';
633
-        return $content;
634
-    }
635
-
636
-
637
-    /**
638
-     * This is a helper method to generate a status legend for a given status array.
639
-     * Note this will only work if the incoming statuses have a key in the EEM_Status->localized_status() methods
640
-     * status_array.
641
-     *
642
-     * @param  array  $status_array  array of statuses that will make up the legend. In format:
643
-     *                               array(
644
-     *                               'status_item' => 'status_name'
645
-     *                               )
646
-     * @param  string $active_status This is used to indicate what the active status is IF that is to be highlighted in
647
-     *                               the legend.
648
-     * @throws EE_Error
649
-     * @return string               html structure for status.
650
-     */
651
-    public static function status_legend($status_array, $active_status = '')
652
-    {
653
-        if ( ! is_array($status_array)) {
654
-            throw new EE_Error(esc_html__('The EEH_Template::status_legend helper required the incoming status_array argument to be an array!',
655
-                'event_espresso'));
656
-        }
657
-
658
-        $setup_array = array();
659
-        foreach ($status_array as $item => $status) {
660
-            $setup_array[$item] = array(
661
-                'class'  => 'ee-status-legend ee-status-legend-' . $status,
662
-                'desc'   => EEH_Template::pretty_status($status, false, 'sentence'),
663
-                'status' => $status,
664
-            );
665
-        }
666
-
667
-        $content = '<div class="ee-list-table-legend-container">' . "\n";
668
-        $content .= '<h4 class="status-legend-title">' . esc_html__('Status Legend', 'event_espresso') . '</h4>' . "\n";
669
-        $content .= '<dl class="ee-list-table-legend">' . "\n\t";
670
-        foreach ($setup_array as $item => $details) {
671
-            $active_class = $active_status == $details['status'] ? ' class="ee-is-active-status"' : '';
672
-            $content .= '<dt id="ee-legend-item-tooltip-' . $item . '"' . $active_class . '>' . "\n\t\t";
673
-            $content .= '<span class="' . $details['class'] . '"></span>' . "\n\t\t";
674
-            $content .= '<span class="ee-legend-description">' . $details['desc'] . '</span>' . "\n\t";
675
-            $content .= '</dt>' . "\n";
676
-        }
677
-        $content .= '</dl>' . "\n";
678
-        $content .= '</div>' . "\n";
679
-        return $content;
680
-    }
681
-
682
-
683
-    /**
684
-     * Gets HTML for laying out a deeply-nested array (and objects) in a format
685
-     * that's nice for presenting in the wp admin
686
-     *
687
-     * @param mixed $data
688
-     * @return string
689
-     */
690
-    public static function layout_array_as_table($data)
691
-    {
692
-        if (is_object($data) || $data instanceof __PHP_Incomplete_Class) {
693
-            $data = (array)$data;
694
-        }
695
-        ob_start();
696
-        if (is_array($data)) {
697
-            if (EEH_Array::is_associative_array($data)) {
698
-                ?>
341
+		$template_path    = false,
342
+		$template_args    = array(),
343
+		$return_string    = false,
344
+		$throw_exceptions = false
345
+	) {
346
+
347
+		/**
348
+		 * These two filters are intended for last minute changes to templates being loaded and/or template arg
349
+		 * modifications.  NOTE... modifying these things can cause breakage as most templates running through
350
+		 * the display_template method are templates we DON'T want modified (usually because of js
351
+		 * dependencies etc).  So unless you know what you are doing, do NOT filter templates or template args
352
+		 * using this.
353
+		 *
354
+		 * @since 4.6.0
355
+		 */
356
+		$template_path = (string) apply_filters('FHEE__EEH_Template__display_template__template_path', $template_path);
357
+		$template_args = (array) apply_filters('FHEE__EEH_Template__display_template__template_args', $template_args);
358
+
359
+		// you gimme nuttin - YOU GET NUTTIN !!
360
+		if ( ! $template_path || ! is_readable($template_path)) {
361
+			return '';
362
+		}
363
+		// if $template_args are not in an array, then make it so
364
+		if ( ! is_array($template_args) && ! is_object($template_args)) {
365
+			$template_args = array($template_args);
366
+		}
367
+		extract( $template_args, EXTR_SKIP );
368
+		// ignore whether template is accessible ?
369
+		if ( $throw_exceptions && ! is_readable( $template_path ) ) {
370
+			throw new \DomainException(
371
+					esc_html__(
372
+							'Invalid, unreadable, or missing file.',
373
+							'event_espresso'
374
+					)
375
+			);
376
+		}
377
+
378
+
379
+		if ($return_string) {
380
+			// because we want to return a string, we are going to capture the output
381
+			ob_start();
382
+			include($template_path);
383
+			return ob_get_clean();
384
+		} else {
385
+			include($template_path);
386
+		}
387
+		return '';
388
+	}
389
+
390
+
391
+	/**
392
+	 * get_object_css_class - attempts to generate a css class based on the type of EE object passed
393
+	 *
394
+	 * @param EE_Base_Class $object the EE object the css class is being generated for
395
+	 * @param  string       $prefix added to the beginning of the generated class
396
+	 * @param  string       $suffix added to the end of the generated class
397
+	 * @return string
398
+	 */
399
+	public static function get_object_css_class($object = null, $prefix = '', $suffix = '')
400
+	{
401
+		// in the beginning...
402
+		$prefix = ! empty($prefix) ? rtrim($prefix, '-') . '-' : '';
403
+		// da muddle
404
+		$class = '';
405
+		// the end
406
+		$suffix = ! empty($suffix) ? '-' . ltrim($suffix, '-') : '';
407
+		// is the passed object an EE object ?
408
+		if ($object instanceof EE_Base_Class) {
409
+			// grab the exact type of object
410
+			$obj_class = get_class($object);
411
+			// depending on the type of object...
412
+			switch ($obj_class) {
413
+				// no specifics just yet...
414
+				default :
415
+					$class = strtolower(str_replace('_', '-', $obj_class));
416
+					$class .= method_exists($obj_class, 'name') ? '-' . sanitize_title($object->name()) : '';
417
+
418
+			}
419
+		}
420
+		return $prefix . $class . $suffix;
421
+	}
422
+
423
+
424
+
425
+	/**
426
+	 * EEH_Template::format_currency
427
+	 * This helper takes a raw float value and formats it according to the default config country currency settings, or
428
+	 * the country currency settings from the supplied country ISO code
429
+	 *
430
+	 * @param  float   $amount       raw money value
431
+	 * @param  boolean $return_raw   whether to return the formatted float value only with no currency sign or code
432
+	 * @param  boolean $display_code whether to display the country code (USD). Default = TRUE
433
+	 * @param string   $CNT_ISO      2 letter ISO code for a country
434
+	 * @param string   $cur_code_span_class
435
+	 * @return string        the html output for the formatted money value
436
+	 * @throws \EE_Error
437
+	 */
438
+	public static function format_currency(
439
+		$amount = null,
440
+		$return_raw = false,
441
+		$display_code = true,
442
+		$CNT_ISO = '',
443
+		$cur_code_span_class = 'currency-code'
444
+	) {
445
+		// ensure amount was received
446
+		if ($amount === null) {
447
+			$msg = __('In order to format currency, an amount needs to be passed.', 'event_espresso');
448
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
449
+			return '';
450
+		}
451
+		//ensure amount is float
452
+		$amount  = apply_filters('FHEE__EEH_Template__format_currency__raw_amount', (float)$amount);
453
+		$CNT_ISO = apply_filters('FHEE__EEH_Template__format_currency__CNT_ISO', $CNT_ISO, $amount);
454
+		// filter raw amount (allows 0.00 to be changed to "free" for example)
455
+		$amount_formatted = apply_filters('FHEE__EEH_Template__format_currency__amount', $amount, $return_raw);
456
+		// still a number or was amount converted to a string like "free" ?
457
+		if (is_float($amount_formatted)) {
458
+			// was a country ISO code passed ? if so generate currency config object for that country
459
+			$mny = $CNT_ISO !== '' ? new EE_Currency_Config($CNT_ISO) : null;
460
+			// verify results
461
+			if ( ! $mny instanceof EE_Currency_Config) {
462
+				// set default config country currency settings
463
+				$mny = EE_Registry::instance()->CFG->currency instanceof EE_Currency_Config
464
+					? EE_Registry::instance()->CFG->currency
465
+					: new EE_Currency_Config();
466
+			}
467
+			// format float
468
+			$amount_formatted = number_format($amount, $mny->dec_plc, $mny->dec_mrk, $mny->thsnds);
469
+			// add formatting ?
470
+			if ( ! $return_raw) {
471
+				// add currency sign
472
+				if ($mny->sign_b4) {
473
+					if ($amount >= 0) {
474
+						$amount_formatted = $mny->sign . $amount_formatted;
475
+					} else {
476
+						$amount_formatted = '-' . $mny->sign . str_replace('-', '', $amount_formatted);
477
+					}
478
+
479
+				} else {
480
+					$amount_formatted = $amount_formatted . $mny->sign;
481
+				}
482
+
483
+				// filter to allow global setting of display_code
484
+				$display_code = apply_filters('FHEE__EEH_Template__format_currency__display_code', $display_code);
485
+
486
+				// add currency code ?
487
+				$amount_formatted = $display_code ? $amount_formatted . ' <span class="' . $cur_code_span_class . '">(' . $mny->code . ')</span>' : $amount_formatted;
488
+			}
489
+			// filter results
490
+			$amount_formatted = apply_filters('FHEE__EEH_Template__format_currency__amount_formatted',
491
+				$amount_formatted, $mny, $return_raw);
492
+		}
493
+		// clean up vars
494
+		unset($mny);
495
+		// return formatted currency amount
496
+		return $amount_formatted;
497
+	}
498
+
499
+
500
+	/**
501
+	 * This function is used for outputting the localized label for a given status id in the schema requested (and
502
+	 * possibly plural).  The intended use of this function is only for cases where wanting a label outside of a
503
+	 * related status model or model object (i.e. in documentation etc.)
504
+	 *
505
+	 * @param  string  $status_id Status ID matching a registered status in the esp_status table.  If there is no
506
+	 *                            match, then 'Unknown' will be returned.
507
+	 * @param  boolean $plural    Whether to return plural or not
508
+	 * @param  string  $schema    'UPPER', 'lower', or 'Sentence'
509
+	 * @return string             The localized label for the status id.
510
+	 */
511
+	public static function pretty_status($status_id, $plural = false, $schema = 'upper')
512
+	{
513
+		/** @type EEM_Status $EEM_Status */
514
+		$EEM_Status = EE_Registry::instance()->load_model('Status');
515
+		$status     = $EEM_Status->localized_status(array($status_id => __('unknown', 'event_espresso')), $plural,
516
+			$schema);
517
+		return $status[$status_id];
518
+	}
519
+
520
+
521
+	/**
522
+	 * This helper just returns a button or link for the given parameters
523
+	 *
524
+	 * @param  string $url   the url for the link
525
+	 * @param  string $label What is the label you want displayed for the button
526
+	 * @param  string $class what class is used for the button (defaults to 'button-primary')
527
+	 * @param string  $icon
528
+	 * @param string  $title
529
+	 * @return string the html output for the button
530
+	 */
531
+	public static function get_button_or_link($url, $label, $class = 'button-primary', $icon = '', $title = '')
532
+	{
533
+		$icon_html = '';
534
+		if ( ! empty($icon)) {
535
+			$dashicons = preg_split("(ee-icon |dashicons )", $icon);
536
+			$dashicons = array_filter($dashicons);
537
+			$count     = count($dashicons);
538
+			$icon_html .= $count > 1 ? '<span class="ee-composite-dashicon">' : '';
539
+			foreach ($dashicons as $dashicon) {
540
+				$type = strpos($dashicon, 'ee-icon') !== false ? 'ee-icon ' : 'dashicons ';
541
+				$icon_html .= '<span class="' . $type . $dashicon . '"></span>';
542
+			}
543
+			$icon_html .= $count > 1 ? '</span>' : '';
544
+		}
545
+		$label  = ! empty($icon) ? $icon_html . $label : $label;
546
+		$button = '<a id="' . sanitize_title_with_dashes($label) . '" href="' . $url . '" class="' . $class . '" title="' . $title . '">' . $label . '</a>';
547
+		return $button;
548
+	}
549
+
550
+
551
+	/**
552
+	 * This returns a generated link that will load the related help tab on admin pages.
553
+	 *
554
+	 * @param  string     $help_tab_id the id for the connected help tab
555
+	 * @param bool|string $page        The page identifier for the page the help tab is on
556
+	 * @param bool|string $action      The action (route) for the admin page the help tab is on.
557
+	 * @param bool|string $icon_style  (optional) include css class for the style you want to use for the help icon.
558
+	 * @param bool|string $help_text   (optional) send help text you want to use for the link if default not to be used
559
+	 * @return string              generated link
560
+	 */
561
+	public static function get_help_tab_link(
562
+		$help_tab_id,
563
+		$page = false,
564
+		$action = false,
565
+		$icon_style = false,
566
+		$help_text = false
567
+	) {
568
+
569
+		if ( ! $page) {
570
+			$page = isset($_REQUEST['page']) && ! empty($_REQUEST['page']) ? sanitize_key($_REQUEST['page']) : $page;
571
+		}
572
+
573
+		if ( ! $action) {
574
+			$action = isset($_REQUEST['action']) && ! empty($_REQUEST['action']) ? sanitize_key($_REQUEST['action']) : $action;
575
+		}
576
+
577
+		$action = empty($action) ? 'default' : $action;
578
+
579
+
580
+		$help_tab_lnk = $page . '-' . $action . '-' . $help_tab_id;
581
+		$icon         = ! $icon_style ? ' dashicons-editor-help' : $icon_style;
582
+		$help_text    = ! $help_text ? '' : $help_text;
583
+		return '<a id="' . $help_tab_lnk . '" class="ee-clickable dashicons espresso-help-tab-lnk ee-icon-size-22' . $icon . '" title="' . esc_attr__('Click to open the \'Help\' tab for more information about this feature.',
584
+				'event_espresso') . '" > ' . $help_text . ' </a>';
585
+	}
586
+
587
+
588
+	/**
589
+	 * This helper generates the html structure for the jquery joyride plugin with the given params.
590
+	 *
591
+	 * @link http://zurb.com/playground/jquery-joyride-feature-tour-plugin
592
+	 * @see  EE_Admin_Page->_stop_callback() for the construct expected for the $stops param.
593
+	 * @param EE_Help_Tour
594
+	 * @return string         html
595
+	 */
596
+	public static function help_tour_stops_generator(EE_Help_Tour $tour)
597
+	{
598
+		$id    = $tour->get_slug();
599
+		$stops = $tour->get_stops();
600
+
601
+		$content = '<ol style="display:none" id="' . $id . '">';
602
+
603
+		foreach ($stops as $stop) {
604
+			$data_id    = ! empty($stop['id']) ? ' data-id="' . $stop['id'] . '"' : '';
605
+			$data_class = empty($data_id) && ! empty($stop['class']) ? ' data-class="' . $stop['class'] . '"' : '';
606
+
607
+			//if container is set to modal then let's make sure we set the options accordingly
608
+			if (empty($data_id) && empty($data_class)) {
609
+				$stop['options']['modal']  = true;
610
+				$stop['options']['expose'] = true;
611
+			}
612
+
613
+			$custom_class  = ! empty($stop['custom_class']) ? ' class="' . $stop['custom_class'] . '"' : '';
614
+			$button_text   = ! empty($stop['button_text']) ? ' data-button="' . $stop['button_text'] . '"' : '';
615
+			$inner_content = isset($stop['content']) ? $stop['content'] : '';
616
+
617
+			//options
618
+			if (isset($stop['options']) && is_array($stop['options'])) {
619
+				$options = ' data-options="';
620
+				foreach ($stop['options'] as $option => $value) {
621
+					$options .= $option . ':' . $value . ';';
622
+				}
623
+				$options .= '"';
624
+			} else {
625
+				$options = '';
626
+			}
627
+
628
+			//let's put all together
629
+			$content .= '<li' . $data_id . $data_class . $custom_class . $button_text . $options . '>' . $inner_content . '</li>';
630
+		}
631
+
632
+		$content .= '</ol>';
633
+		return $content;
634
+	}
635
+
636
+
637
+	/**
638
+	 * This is a helper method to generate a status legend for a given status array.
639
+	 * Note this will only work if the incoming statuses have a key in the EEM_Status->localized_status() methods
640
+	 * status_array.
641
+	 *
642
+	 * @param  array  $status_array  array of statuses that will make up the legend. In format:
643
+	 *                               array(
644
+	 *                               'status_item' => 'status_name'
645
+	 *                               )
646
+	 * @param  string $active_status This is used to indicate what the active status is IF that is to be highlighted in
647
+	 *                               the legend.
648
+	 * @throws EE_Error
649
+	 * @return string               html structure for status.
650
+	 */
651
+	public static function status_legend($status_array, $active_status = '')
652
+	{
653
+		if ( ! is_array($status_array)) {
654
+			throw new EE_Error(esc_html__('The EEH_Template::status_legend helper required the incoming status_array argument to be an array!',
655
+				'event_espresso'));
656
+		}
657
+
658
+		$setup_array = array();
659
+		foreach ($status_array as $item => $status) {
660
+			$setup_array[$item] = array(
661
+				'class'  => 'ee-status-legend ee-status-legend-' . $status,
662
+				'desc'   => EEH_Template::pretty_status($status, false, 'sentence'),
663
+				'status' => $status,
664
+			);
665
+		}
666
+
667
+		$content = '<div class="ee-list-table-legend-container">' . "\n";
668
+		$content .= '<h4 class="status-legend-title">' . esc_html__('Status Legend', 'event_espresso') . '</h4>' . "\n";
669
+		$content .= '<dl class="ee-list-table-legend">' . "\n\t";
670
+		foreach ($setup_array as $item => $details) {
671
+			$active_class = $active_status == $details['status'] ? ' class="ee-is-active-status"' : '';
672
+			$content .= '<dt id="ee-legend-item-tooltip-' . $item . '"' . $active_class . '>' . "\n\t\t";
673
+			$content .= '<span class="' . $details['class'] . '"></span>' . "\n\t\t";
674
+			$content .= '<span class="ee-legend-description">' . $details['desc'] . '</span>' . "\n\t";
675
+			$content .= '</dt>' . "\n";
676
+		}
677
+		$content .= '</dl>' . "\n";
678
+		$content .= '</div>' . "\n";
679
+		return $content;
680
+	}
681
+
682
+
683
+	/**
684
+	 * Gets HTML for laying out a deeply-nested array (and objects) in a format
685
+	 * that's nice for presenting in the wp admin
686
+	 *
687
+	 * @param mixed $data
688
+	 * @return string
689
+	 */
690
+	public static function layout_array_as_table($data)
691
+	{
692
+		if (is_object($data) || $data instanceof __PHP_Incomplete_Class) {
693
+			$data = (array)$data;
694
+		}
695
+		ob_start();
696
+		if (is_array($data)) {
697
+			if (EEH_Array::is_associative_array($data)) {
698
+				?>
699 699
                 <table class="widefat">
700 700
                     <tbody>
701 701
                     <?php
702
-                    foreach ($data as $data_key => $data_values) {
703
-                        ?>
702
+					foreach ($data as $data_key => $data_values) {
703
+						?>
704 704
                         <tr>
705 705
                             <td>
706 706
                                 <?php echo $data_key; ?>
@@ -710,248 +710,248 @@  discard block
 block discarded – undo
710 710
                             </td>
711 711
                         </tr>
712 712
                         <?php
713
-                    } ?>
713
+					} ?>
714 714
                     </tbody>
715 715
                 </table>
716 716
                 <?php
717
-            } else {
718
-                ?>
717
+			} else {
718
+				?>
719 719
                 <ul>
720 720
                     <?php
721
-                    foreach ($data as $datum) {
722
-                        echo "<li>";
723
-                        echo self::layout_array_as_table($datum);
724
-                        echo "</li>";
725
-                    } ?>
721
+					foreach ($data as $datum) {
722
+						echo "<li>";
723
+						echo self::layout_array_as_table($datum);
724
+						echo "</li>";
725
+					} ?>
726 726
                 </ul>
727 727
                 <?php
728
-            }
729
-        } else {
730
-            //simple value
731
-            echo esc_html($data);
732
-        }
733
-        return ob_get_clean();
734
-    }
735
-
736
-
737
-    /**
738
-     * wrapper for self::get_paging_html() that simply echos the generated paging html
739
-     *
740
-     * @since 4.4.0
741
-     * @see   self:get_paging_html() for argument docs.
742
-     * @param        $total_items
743
-     * @param        $current
744
-     * @param        $per_page
745
-     * @param        $url
746
-     * @param bool   $show_num_field
747
-     * @param string $paged_arg_name
748
-     * @param array  $items_label
749
-     * @return string
750
-     */
751
-    public static function paging_html(
752
-        $total_items,
753
-        $current,
754
-        $per_page,
755
-        $url,
756
-        $show_num_field = true,
757
-        $paged_arg_name = 'paged',
758
-        $items_label = array()
759
-    ) {
760
-        echo self::get_paging_html($total_items, $current, $per_page, $url, $show_num_field, $paged_arg_name,
761
-            $items_label);
762
-    }
763
-
764
-
765
-    /**
766
-     * A method for generating paging similar to WP_List_Table
767
-     *
768
-     * @since    4.4.0
769
-     * @see      wp-admin/includes/class-wp-list-table.php WP_List_Table::pagination()
770
-     * @param  integer $total_items     How many total items there are to page.
771
-     * @param  integer $current         What the current page is.
772
-     * @param  integer $per_page        How many items per page.
773
-     * @param  string  $url             What the base url for page links is.
774
-     * @param  boolean $show_num_field  Whether to show the input for changing page number.
775
-     * @param  string  $paged_arg_name  The name of the key for the paged query argument.
776
-     * @param  array   $items_label     An array of singular/plural values for the items label:
777
-     *                                  array(
778
-     *                                  'single' => 'item',
779
-     *                                  'plural' => 'items'
780
-     *                                  )
781
-     * @return  string
782
-     */
783
-    public static function get_paging_html(
784
-        $total_items,
785
-        $current,
786
-        $per_page,
787
-        $url,
788
-        $show_num_field = true,
789
-        $paged_arg_name = 'paged',
790
-        $items_label = array()
791
-    ) {
792
-        $page_links     = array();
793
-        $disable_first  = $disable_last = '';
794
-        $total_items    = (int)$total_items;
795
-        $per_page       = (int)$per_page;
796
-        $current        = (int)$current;
797
-        $paged_arg_name = empty($paged_arg_name) ? 'paged' : sanitize_key($paged_arg_name);
798
-
799
-        //filter items_label
800
-        $items_label = apply_filters(
801
-            'FHEE__EEH_Template__get_paging_html__items_label',
802
-            $items_label
803
-        );
804
-
805
-        if (empty($items_label)
806
-            || ! is_array($items_label)
807
-            || ! isset($items_label['single'])
808
-            || ! isset($items_label['plural'])
809
-        ) {
810
-            $items_label = array(
811
-                'single' => __('1 item', 'event_espresso'),
812
-                'plural' => __('%s items', 'event_espresso'),
813
-            );
814
-        } else {
815
-            $items_label = array(
816
-                'single' => '1 ' . esc_html($items_label['single']),
817
-                'plural' => '%s ' . esc_html($items_label['plural']),
818
-            );
819
-        }
820
-
821
-        $total_pages = ceil($total_items / $per_page);
822
-
823
-        if ($total_pages <= 1) {
824
-            return '';
825
-        }
826
-
827
-        $item_label = $total_items > 1 ? sprintf($items_label['plural'], $total_items) : $items_label['single'];
828
-
829
-        $output = '<span class="displaying-num">' . $item_label . '</span>';
830
-
831
-        if ($current === 1) {
832
-            $disable_first = ' disabled';
833
-        }
834
-        if ($current == $total_pages) {
835
-            $disable_last = ' disabled';
836
-        }
837
-
838
-        $page_links[] = sprintf("<a class='%s' title='%s' href='%s'>%s</a>",
839
-            'first-page' . $disable_first,
840
-            esc_attr__('Go to the first page'),
841
-            esc_url(remove_query_arg($paged_arg_name, $url)),
842
-            '&laquo;'
843
-        );
844
-
845
-        $page_links[] = sprintf(
846
-            '<a class="%s" title="%s" href="%s">%s</a>',
847
-            'prev-page' . $disable_first,
848
-            esc_attr__('Go to the previous page'),
849
-            esc_url(add_query_arg($paged_arg_name, max(1, $current - 1), $url)),
850
-            '&lsaquo;'
851
-        );
852
-
853
-        if ( ! $show_num_field) {
854
-            $html_current_page = $current;
855
-        } else {
856
-            $html_current_page = sprintf("<input class='current-page' title='%s' type='text' name=$paged_arg_name value='%s' size='%d' />",
857
-                esc_attr__('Current page'),
858
-                $current,
859
-                strlen($total_pages)
860
-            );
861
-        }
862
-
863
-        $html_total_pages = sprintf(
864
-            '<span class="total-pages">%s</span>',
865
-            number_format_i18n($total_pages)
866
-        );
867
-        $page_links[]     = sprintf(
868
-            _x('%3$s%1$s of %2$s%4$s', 'paging'),
869
-            $html_current_page,
870
-            $html_total_pages,
871
-            '<span class="paging-input">',
872
-            '</span>'
873
-        );
874
-
875
-        $page_links[] = sprintf(
876
-            '<a class="%s" title="%s" href="%s">%s</a>',
877
-            'next-page' . $disable_last,
878
-            esc_attr__('Go to the next page'),
879
-            esc_url(add_query_arg($paged_arg_name, min($total_pages, $current + 1), $url)),
880
-            '&rsaquo;'
881
-        );
882
-
883
-        $page_links[] = sprintf(
884
-            '<a class="%s" title="%s" href="%s">%s</a>',
885
-            'last-page' . $disable_last,
886
-            esc_attr__('Go to the last page'),
887
-            esc_url(add_query_arg($paged_arg_name, $total_pages, $url)),
888
-            '&raquo;'
889
-        );
890
-
891
-        $output .= "\n" . '<span class="pagination-links">' . join("\n", $page_links) . '</span>';
892
-        // set page class
893
-        if ($total_pages) {
894
-            $page_class = $total_pages < 2 ? ' one-page' : '';
895
-        } else {
896
-            $page_class = ' no-pages';
897
-        }
898
-
899
-        return '<div class="tablenav"><div class="tablenav-pages' . $page_class . '">' . $output . '</div></div>';
900
-    }
901
-
902
-
903
-    /**
904
-     * @param string $wrap_class
905
-     * @param string $wrap_id
906
-     * @return string
907
-     */
908
-    public static function powered_by_event_espresso($wrap_class = '', $wrap_id = '', array $query_args = array())
909
-    {
910
-        $admin = is_admin() && ! (defined('DOING_AJAX') && DOING_AJAX);
911
-        if (
912
-            ! $admin &&
913
-            ! apply_filters(
914
-                'FHEE__EEH_Template__powered_by_event_espresso__show_reg_footer',
915
-                EE_Registry::instance()->CFG->admin->show_reg_footer
916
-            )
917
-        ) {
918
-            return '';
919
-        }
920
-        $tag        = $admin ? 'span' : 'div';
921
-        $attributes = ! empty($wrap_id) ? " id=\"{$wrap_id}\"" : '';
922
-        $wrap_class = $admin ? "{$wrap_class} float-left" : $wrap_class;
923
-        $attributes .= ! empty($wrap_class)
924
-            ? " class=\"{$wrap_class} powered-by-event-espresso-credit\""
925
-            : ' class="powered-by-event-espresso-credit"';
926
-        $query_args = array_merge(
927
-            array(
928
-                'ap_id'        => EE_Registry::instance()->CFG->admin->affiliate_id(),
929
-                'utm_source'   => 'powered_by_event_espresso',
930
-                'utm_medium'   => 'link',
931
-                'utm_campaign' => 'powered_by',
932
-            ),
933
-            $query_args
934
-        );
935
-        $powered_by = apply_filters('FHEE__EEH_Template__powered_by_event_espresso_text',
936
-            $admin ? 'Event Espresso - ' . EVENT_ESPRESSO_VERSION : 'Event Espresso');
937
-        $url        = add_query_arg($query_args, 'https://eventespresso.com/');
938
-        $url        = apply_filters('FHEE__EEH_Template__powered_by_event_espresso__url', $url);
939
-        return (string)apply_filters(
940
-            'FHEE__EEH_Template__powered_by_event_espresso__html',
941
-            sprintf(
942
-                esc_html_x(
943
-                    '%3$s%1$sOnline event registration and ticketing powered by %2$s%3$s',
944
-                    'Online event registration and ticketing powered by [link to eventespresso.com]',
945
-                    'event_espresso'
946
-                ),
947
-                "<{$tag}{$attributes}>",
948
-                "<a href=\"{$url}\" target=\"_blank\" rel=\"nofollow\">{$powered_by}</a></{$tag}>",
949
-                $admin ? '' : '<br />'
950
-            ),
951
-            $wrap_class,
952
-            $wrap_id
953
-        );
954
-    }
728
+			}
729
+		} else {
730
+			//simple value
731
+			echo esc_html($data);
732
+		}
733
+		return ob_get_clean();
734
+	}
735
+
736
+
737
+	/**
738
+	 * wrapper for self::get_paging_html() that simply echos the generated paging html
739
+	 *
740
+	 * @since 4.4.0
741
+	 * @see   self:get_paging_html() for argument docs.
742
+	 * @param        $total_items
743
+	 * @param        $current
744
+	 * @param        $per_page
745
+	 * @param        $url
746
+	 * @param bool   $show_num_field
747
+	 * @param string $paged_arg_name
748
+	 * @param array  $items_label
749
+	 * @return string
750
+	 */
751
+	public static function paging_html(
752
+		$total_items,
753
+		$current,
754
+		$per_page,
755
+		$url,
756
+		$show_num_field = true,
757
+		$paged_arg_name = 'paged',
758
+		$items_label = array()
759
+	) {
760
+		echo self::get_paging_html($total_items, $current, $per_page, $url, $show_num_field, $paged_arg_name,
761
+			$items_label);
762
+	}
763
+
764
+
765
+	/**
766
+	 * A method for generating paging similar to WP_List_Table
767
+	 *
768
+	 * @since    4.4.0
769
+	 * @see      wp-admin/includes/class-wp-list-table.php WP_List_Table::pagination()
770
+	 * @param  integer $total_items     How many total items there are to page.
771
+	 * @param  integer $current         What the current page is.
772
+	 * @param  integer $per_page        How many items per page.
773
+	 * @param  string  $url             What the base url for page links is.
774
+	 * @param  boolean $show_num_field  Whether to show the input for changing page number.
775
+	 * @param  string  $paged_arg_name  The name of the key for the paged query argument.
776
+	 * @param  array   $items_label     An array of singular/plural values for the items label:
777
+	 *                                  array(
778
+	 *                                  'single' => 'item',
779
+	 *                                  'plural' => 'items'
780
+	 *                                  )
781
+	 * @return  string
782
+	 */
783
+	public static function get_paging_html(
784
+		$total_items,
785
+		$current,
786
+		$per_page,
787
+		$url,
788
+		$show_num_field = true,
789
+		$paged_arg_name = 'paged',
790
+		$items_label = array()
791
+	) {
792
+		$page_links     = array();
793
+		$disable_first  = $disable_last = '';
794
+		$total_items    = (int)$total_items;
795
+		$per_page       = (int)$per_page;
796
+		$current        = (int)$current;
797
+		$paged_arg_name = empty($paged_arg_name) ? 'paged' : sanitize_key($paged_arg_name);
798
+
799
+		//filter items_label
800
+		$items_label = apply_filters(
801
+			'FHEE__EEH_Template__get_paging_html__items_label',
802
+			$items_label
803
+		);
804
+
805
+		if (empty($items_label)
806
+			|| ! is_array($items_label)
807
+			|| ! isset($items_label['single'])
808
+			|| ! isset($items_label['plural'])
809
+		) {
810
+			$items_label = array(
811
+				'single' => __('1 item', 'event_espresso'),
812
+				'plural' => __('%s items', 'event_espresso'),
813
+			);
814
+		} else {
815
+			$items_label = array(
816
+				'single' => '1 ' . esc_html($items_label['single']),
817
+				'plural' => '%s ' . esc_html($items_label['plural']),
818
+			);
819
+		}
820
+
821
+		$total_pages = ceil($total_items / $per_page);
822
+
823
+		if ($total_pages <= 1) {
824
+			return '';
825
+		}
826
+
827
+		$item_label = $total_items > 1 ? sprintf($items_label['plural'], $total_items) : $items_label['single'];
828
+
829
+		$output = '<span class="displaying-num">' . $item_label . '</span>';
830
+
831
+		if ($current === 1) {
832
+			$disable_first = ' disabled';
833
+		}
834
+		if ($current == $total_pages) {
835
+			$disable_last = ' disabled';
836
+		}
837
+
838
+		$page_links[] = sprintf("<a class='%s' title='%s' href='%s'>%s</a>",
839
+			'first-page' . $disable_first,
840
+			esc_attr__('Go to the first page'),
841
+			esc_url(remove_query_arg($paged_arg_name, $url)),
842
+			'&laquo;'
843
+		);
844
+
845
+		$page_links[] = sprintf(
846
+			'<a class="%s" title="%s" href="%s">%s</a>',
847
+			'prev-page' . $disable_first,
848
+			esc_attr__('Go to the previous page'),
849
+			esc_url(add_query_arg($paged_arg_name, max(1, $current - 1), $url)),
850
+			'&lsaquo;'
851
+		);
852
+
853
+		if ( ! $show_num_field) {
854
+			$html_current_page = $current;
855
+		} else {
856
+			$html_current_page = sprintf("<input class='current-page' title='%s' type='text' name=$paged_arg_name value='%s' size='%d' />",
857
+				esc_attr__('Current page'),
858
+				$current,
859
+				strlen($total_pages)
860
+			);
861
+		}
862
+
863
+		$html_total_pages = sprintf(
864
+			'<span class="total-pages">%s</span>',
865
+			number_format_i18n($total_pages)
866
+		);
867
+		$page_links[]     = sprintf(
868
+			_x('%3$s%1$s of %2$s%4$s', 'paging'),
869
+			$html_current_page,
870
+			$html_total_pages,
871
+			'<span class="paging-input">',
872
+			'</span>'
873
+		);
874
+
875
+		$page_links[] = sprintf(
876
+			'<a class="%s" title="%s" href="%s">%s</a>',
877
+			'next-page' . $disable_last,
878
+			esc_attr__('Go to the next page'),
879
+			esc_url(add_query_arg($paged_arg_name, min($total_pages, $current + 1), $url)),
880
+			'&rsaquo;'
881
+		);
882
+
883
+		$page_links[] = sprintf(
884
+			'<a class="%s" title="%s" href="%s">%s</a>',
885
+			'last-page' . $disable_last,
886
+			esc_attr__('Go to the last page'),
887
+			esc_url(add_query_arg($paged_arg_name, $total_pages, $url)),
888
+			'&raquo;'
889
+		);
890
+
891
+		$output .= "\n" . '<span class="pagination-links">' . join("\n", $page_links) . '</span>';
892
+		// set page class
893
+		if ($total_pages) {
894
+			$page_class = $total_pages < 2 ? ' one-page' : '';
895
+		} else {
896
+			$page_class = ' no-pages';
897
+		}
898
+
899
+		return '<div class="tablenav"><div class="tablenav-pages' . $page_class . '">' . $output . '</div></div>';
900
+	}
901
+
902
+
903
+	/**
904
+	 * @param string $wrap_class
905
+	 * @param string $wrap_id
906
+	 * @return string
907
+	 */
908
+	public static function powered_by_event_espresso($wrap_class = '', $wrap_id = '', array $query_args = array())
909
+	{
910
+		$admin = is_admin() && ! (defined('DOING_AJAX') && DOING_AJAX);
911
+		if (
912
+			! $admin &&
913
+			! apply_filters(
914
+				'FHEE__EEH_Template__powered_by_event_espresso__show_reg_footer',
915
+				EE_Registry::instance()->CFG->admin->show_reg_footer
916
+			)
917
+		) {
918
+			return '';
919
+		}
920
+		$tag        = $admin ? 'span' : 'div';
921
+		$attributes = ! empty($wrap_id) ? " id=\"{$wrap_id}\"" : '';
922
+		$wrap_class = $admin ? "{$wrap_class} float-left" : $wrap_class;
923
+		$attributes .= ! empty($wrap_class)
924
+			? " class=\"{$wrap_class} powered-by-event-espresso-credit\""
925
+			: ' class="powered-by-event-espresso-credit"';
926
+		$query_args = array_merge(
927
+			array(
928
+				'ap_id'        => EE_Registry::instance()->CFG->admin->affiliate_id(),
929
+				'utm_source'   => 'powered_by_event_espresso',
930
+				'utm_medium'   => 'link',
931
+				'utm_campaign' => 'powered_by',
932
+			),
933
+			$query_args
934
+		);
935
+		$powered_by = apply_filters('FHEE__EEH_Template__powered_by_event_espresso_text',
936
+			$admin ? 'Event Espresso - ' . EVENT_ESPRESSO_VERSION : 'Event Espresso');
937
+		$url        = add_query_arg($query_args, 'https://eventespresso.com/');
938
+		$url        = apply_filters('FHEE__EEH_Template__powered_by_event_espresso__url', $url);
939
+		return (string)apply_filters(
940
+			'FHEE__EEH_Template__powered_by_event_espresso__html',
941
+			sprintf(
942
+				esc_html_x(
943
+					'%3$s%1$sOnline event registration and ticketing powered by %2$s%3$s',
944
+					'Online event registration and ticketing powered by [link to eventespresso.com]',
945
+					'event_espresso'
946
+				),
947
+				"<{$tag}{$attributes}>",
948
+				"<a href=\"{$url}\" target=\"_blank\" rel=\"nofollow\">{$powered_by}</a></{$tag}>",
949
+				$admin ? '' : '<br />'
950
+			),
951
+			$wrap_class,
952
+			$wrap_id
953
+		);
954
+	}
955 955
 
956 956
 
957 957
 } //end EEH_Template class
@@ -960,33 +960,33 @@  discard block
 block discarded – undo
960 960
 
961 961
 
962 962
 if ( ! function_exists('espresso_pagination')) {
963
-    /**
964
-     *    espresso_pagination
965
-     *
966
-     * @access    public
967
-     * @return    void
968
-     */
969
-    function espresso_pagination()
970
-    {
971
-        global $wp_query;
972
-        $big        = 999999999; // need an unlikely integer
973
-        $pagination = paginate_links(
974
-            array(
975
-                'base'         => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
976
-                'format'       => '?paged=%#%',
977
-                'current'      => max(1, get_query_var('paged')),
978
-                'total'        => $wp_query->max_num_pages,
979
-                'show_all'     => true,
980
-                'end_size'     => 10,
981
-                'mid_size'     => 6,
982
-                'prev_next'    => true,
983
-                'prev_text'    => __('&lsaquo; PREV', 'event_espresso'),
984
-                'next_text'    => __('NEXT &rsaquo;', 'event_espresso'),
985
-                'type'         => 'plain',
986
-                'add_args'     => false,
987
-                'add_fragment' => '',
988
-            )
989
-        );
990
-        echo ! empty($pagination) ? '<div class="ee-pagination-dv clear">' . $pagination . '</div>' : '';
991
-    }
963
+	/**
964
+	 *    espresso_pagination
965
+	 *
966
+	 * @access    public
967
+	 * @return    void
968
+	 */
969
+	function espresso_pagination()
970
+	{
971
+		global $wp_query;
972
+		$big        = 999999999; // need an unlikely integer
973
+		$pagination = paginate_links(
974
+			array(
975
+				'base'         => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
976
+				'format'       => '?paged=%#%',
977
+				'current'      => max(1, get_query_var('paged')),
978
+				'total'        => $wp_query->max_num_pages,
979
+				'show_all'     => true,
980
+				'end_size'     => 10,
981
+				'mid_size'     => 6,
982
+				'prev_next'    => true,
983
+				'prev_text'    => __('&lsaquo; PREV', 'event_espresso'),
984
+				'next_text'    => __('NEXT &rsaquo;', 'event_espresso'),
985
+				'type'         => 'plain',
986
+				'add_args'     => false,
987
+				'add_fragment' => '',
988
+			)
989
+		);
990
+		echo ! empty($pagination) ? '<div class="ee-pagination-dv clear">' . $pagination . '</div>' : '';
991
+	}
992 992
 }
993 993
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +65 added lines, -65 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
 /**
@@ -81,8 +81,8 @@  discard block
 block discarded – undo
81 81
     public static function load_espresso_theme_functions()
82 82
     {
83 83
         if ( ! defined('EE_THEME_FUNCTIONS_LOADED')) {
84
-            if (is_readable(EE_PUBLIC . EE_Config::get_current_theme() . DS . 'functions.php')) {
85
-                require_once(EE_PUBLIC . EE_Config::get_current_theme() . DS . 'functions.php');
84
+            if (is_readable(EE_PUBLIC.EE_Config::get_current_theme().DS.'functions.php')) {
85
+                require_once(EE_PUBLIC.EE_Config::get_current_theme().DS.'functions.php');
86 86
             }
87 87
         }
88 88
     }
@@ -96,7 +96,7 @@  discard block
 block discarded – undo
96 96
     public static function get_espresso_themes()
97 97
     {
98 98
         if (empty(EEH_Template::$_espresso_themes)) {
99
-            $espresso_themes = glob(EE_PUBLIC . '*', GLOB_ONLYDIR);
99
+            $espresso_themes = glob(EE_PUBLIC.'*', GLOB_ONLYDIR);
100 100
             if (empty($espresso_themes)) {
101 101
                 return array();
102 102
             }
@@ -132,7 +132,7 @@  discard block
 block discarded – undo
132 132
     ) {
133 133
         do_action("get_template_part_{$slug}-{$name}", $slug, $name);
134 134
         $templates = array();
135
-        $name      = (string)$name;
135
+        $name      = (string) $name;
136 136
         if ($name != '') {
137 137
             $templates[] = "{$slug}-{$name}.php";
138 138
         }
@@ -211,7 +211,7 @@  discard block
 block discarded – undo
211 211
                 if (isset($EE_CPTs[$post_type])) {
212 212
                     $archive_or_single = is_archive() ? 'archive' : '';
213 213
                     $archive_or_single = is_single() ? 'single' : $archive_or_single;
214
-                    $templates         = $archive_or_single . '-' . $post_type . '.php';
214
+                    $templates         = $archive_or_single.'-'.$post_type.'.php';
215 215
                 }
216 216
             }
217 217
             // currently active EE template theme
@@ -220,18 +220,18 @@  discard block
 block discarded – undo
220 220
             // array of paths to folders that may contain templates
221 221
             $template_folder_paths = array(
222 222
                 // first check the /wp-content/uploads/espresso/templates/(current EE theme)/  folder for an EE theme template file
223
-                EVENT_ESPRESSO_TEMPLATE_DIR . $current_theme,
223
+                EVENT_ESPRESSO_TEMPLATE_DIR.$current_theme,
224 224
                 // then in the root of the /wp-content/uploads/espresso/templates/ folder
225 225
                 EVENT_ESPRESSO_TEMPLATE_DIR,
226 226
             );
227 227
 
228 228
             //add core plugin folders for checking only if we're not $check_if_custom
229 229
             if ( ! $check_if_custom) {
230
-                $core_paths            = array(
230
+                $core_paths = array(
231 231
                     // in the  /wp-content/plugins/(EE4 folder)/public/(current EE theme)/ folder within the plugin
232
-                    EE_PUBLIC . $current_theme,
232
+                    EE_PUBLIC.$current_theme,
233 233
                     // in the  /wp-content/plugins/(EE4 folder)/core/templates/(current EE theme)/ folder within the plugin
234
-                    EE_TEMPLATES . $current_theme,
234
+                    EE_TEMPLATES.$current_theme,
235 235
                     // or maybe relative from the plugin root: /wp-content/plugins/(EE4 folder)/
236 236
                     EE_PLUGIN_DIR_PATH,
237 237
                 );
@@ -262,10 +262,10 @@  discard block
 block discarded – undo
262 262
                     );
263 263
                     if ($common_base_path !== '') {
264 264
                         // both paths have a common base, so just tack the filename onto our search path
265
-                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $file_name;
265
+                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path).$file_name;
266 266
                     } else {
267 267
                         // no common base path, so let's just concatenate
268
-                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $template;
268
+                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path).$template;
269 269
                     }
270 270
                     // build up our template locations array by adding our resolved paths
271 271
                     $full_template_paths[] = $resolved_path;
@@ -273,13 +273,13 @@  discard block
 block discarded – undo
273 273
                 // if $template is an absolute path, then we'll tack it onto the start of our array so that it gets searched first
274 274
                 array_unshift($full_template_paths, $template);
275 275
                 // path to the directory of the current theme: /wp-content/themes/(current WP theme)/
276
-                array_unshift($full_template_paths, get_stylesheet_directory() . DS . $file_name);
276
+                array_unshift($full_template_paths, get_stylesheet_directory().DS.$file_name);
277 277
             }
278 278
             // filter final array of full template paths
279 279
             $full_template_paths = apply_filters('FHEE__EEH_Template__locate_template__full_template_paths',
280 280
                 $full_template_paths, $file_name);
281 281
             // now loop through our final array of template location paths and check each location
282
-            foreach ((array)$full_template_paths as $full_template_path) {
282
+            foreach ((array) $full_template_paths as $full_template_path) {
283 283
                 if (is_readable($full_template_path)) {
284 284
                     $template_path = str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, $full_template_path);
285 285
                     // hook that can be used to display the full template path that will be used
@@ -364,9 +364,9 @@  discard block
 block discarded – undo
364 364
         if ( ! is_array($template_args) && ! is_object($template_args)) {
365 365
             $template_args = array($template_args);
366 366
         }
367
-        extract( $template_args, EXTR_SKIP );
367
+        extract($template_args, EXTR_SKIP);
368 368
         // ignore whether template is accessible ?
369
-        if ( $throw_exceptions && ! is_readable( $template_path ) ) {
369
+        if ($throw_exceptions && ! is_readable($template_path)) {
370 370
             throw new \DomainException(
371 371
                     esc_html__(
372 372
                             'Invalid, unreadable, or missing file.',
@@ -399,11 +399,11 @@  discard block
 block discarded – undo
399 399
     public static function get_object_css_class($object = null, $prefix = '', $suffix = '')
400 400
     {
401 401
         // in the beginning...
402
-        $prefix = ! empty($prefix) ? rtrim($prefix, '-') . '-' : '';
402
+        $prefix = ! empty($prefix) ? rtrim($prefix, '-').'-' : '';
403 403
         // da muddle
404 404
         $class = '';
405 405
         // the end
406
-        $suffix = ! empty($suffix) ? '-' . ltrim($suffix, '-') : '';
406
+        $suffix = ! empty($suffix) ? '-'.ltrim($suffix, '-') : '';
407 407
         // is the passed object an EE object ?
408 408
         if ($object instanceof EE_Base_Class) {
409 409
             // grab the exact type of object
@@ -413,11 +413,11 @@  discard block
 block discarded – undo
413 413
                 // no specifics just yet...
414 414
                 default :
415 415
                     $class = strtolower(str_replace('_', '-', $obj_class));
416
-                    $class .= method_exists($obj_class, 'name') ? '-' . sanitize_title($object->name()) : '';
416
+                    $class .= method_exists($obj_class, 'name') ? '-'.sanitize_title($object->name()) : '';
417 417
 
418 418
             }
419 419
         }
420
-        return $prefix . $class . $suffix;
420
+        return $prefix.$class.$suffix;
421 421
     }
422 422
 
423 423
 
@@ -449,7 +449,7 @@  discard block
 block discarded – undo
449 449
             return '';
450 450
         }
451 451
         //ensure amount is float
452
-        $amount  = apply_filters('FHEE__EEH_Template__format_currency__raw_amount', (float)$amount);
452
+        $amount  = apply_filters('FHEE__EEH_Template__format_currency__raw_amount', (float) $amount);
453 453
         $CNT_ISO = apply_filters('FHEE__EEH_Template__format_currency__CNT_ISO', $CNT_ISO, $amount);
454 454
         // filter raw amount (allows 0.00 to be changed to "free" for example)
455 455
         $amount_formatted = apply_filters('FHEE__EEH_Template__format_currency__amount', $amount, $return_raw);
@@ -471,20 +471,20 @@  discard block
 block discarded – undo
471 471
                 // add currency sign
472 472
                 if ($mny->sign_b4) {
473 473
                     if ($amount >= 0) {
474
-                        $amount_formatted = $mny->sign . $amount_formatted;
474
+                        $amount_formatted = $mny->sign.$amount_formatted;
475 475
                     } else {
476
-                        $amount_formatted = '-' . $mny->sign . str_replace('-', '', $amount_formatted);
476
+                        $amount_formatted = '-'.$mny->sign.str_replace('-', '', $amount_formatted);
477 477
                     }
478 478
 
479 479
                 } else {
480
-                    $amount_formatted = $amount_formatted . $mny->sign;
480
+                    $amount_formatted = $amount_formatted.$mny->sign;
481 481
                 }
482 482
 
483 483
                 // filter to allow global setting of display_code
484 484
                 $display_code = apply_filters('FHEE__EEH_Template__format_currency__display_code', $display_code);
485 485
 
486 486
                 // add currency code ?
487
-                $amount_formatted = $display_code ? $amount_formatted . ' <span class="' . $cur_code_span_class . '">(' . $mny->code . ')</span>' : $amount_formatted;
487
+                $amount_formatted = $display_code ? $amount_formatted.' <span class="'.$cur_code_span_class.'">('.$mny->code.')</span>' : $amount_formatted;
488 488
             }
489 489
             // filter results
490 490
             $amount_formatted = apply_filters('FHEE__EEH_Template__format_currency__amount_formatted',
@@ -538,12 +538,12 @@  discard block
 block discarded – undo
538 538
             $icon_html .= $count > 1 ? '<span class="ee-composite-dashicon">' : '';
539 539
             foreach ($dashicons as $dashicon) {
540 540
                 $type = strpos($dashicon, 'ee-icon') !== false ? 'ee-icon ' : 'dashicons ';
541
-                $icon_html .= '<span class="' . $type . $dashicon . '"></span>';
541
+                $icon_html .= '<span class="'.$type.$dashicon.'"></span>';
542 542
             }
543 543
             $icon_html .= $count > 1 ? '</span>' : '';
544 544
         }
545
-        $label  = ! empty($icon) ? $icon_html . $label : $label;
546
-        $button = '<a id="' . sanitize_title_with_dashes($label) . '" href="' . $url . '" class="' . $class . '" title="' . $title . '">' . $label . '</a>';
545
+        $label  = ! empty($icon) ? $icon_html.$label : $label;
546
+        $button = '<a id="'.sanitize_title_with_dashes($label).'" href="'.$url.'" class="'.$class.'" title="'.$title.'">'.$label.'</a>';
547 547
         return $button;
548 548
     }
549 549
 
@@ -577,11 +577,11 @@  discard block
 block discarded – undo
577 577
         $action = empty($action) ? 'default' : $action;
578 578
 
579 579
 
580
-        $help_tab_lnk = $page . '-' . $action . '-' . $help_tab_id;
580
+        $help_tab_lnk = $page.'-'.$action.'-'.$help_tab_id;
581 581
         $icon         = ! $icon_style ? ' dashicons-editor-help' : $icon_style;
582 582
         $help_text    = ! $help_text ? '' : $help_text;
583
-        return '<a id="' . $help_tab_lnk . '" class="ee-clickable dashicons espresso-help-tab-lnk ee-icon-size-22' . $icon . '" title="' . esc_attr__('Click to open the \'Help\' tab for more information about this feature.',
584
-                'event_espresso') . '" > ' . $help_text . ' </a>';
583
+        return '<a id="'.$help_tab_lnk.'" class="ee-clickable dashicons espresso-help-tab-lnk ee-icon-size-22'.$icon.'" title="'.esc_attr__('Click to open the \'Help\' tab for more information about this feature.',
584
+                'event_espresso').'" > '.$help_text.' </a>';
585 585
     }
586 586
 
587 587
 
@@ -598,11 +598,11 @@  discard block
 block discarded – undo
598 598
         $id    = $tour->get_slug();
599 599
         $stops = $tour->get_stops();
600 600
 
601
-        $content = '<ol style="display:none" id="' . $id . '">';
601
+        $content = '<ol style="display:none" id="'.$id.'">';
602 602
 
603 603
         foreach ($stops as $stop) {
604
-            $data_id    = ! empty($stop['id']) ? ' data-id="' . $stop['id'] . '"' : '';
605
-            $data_class = empty($data_id) && ! empty($stop['class']) ? ' data-class="' . $stop['class'] . '"' : '';
604
+            $data_id    = ! empty($stop['id']) ? ' data-id="'.$stop['id'].'"' : '';
605
+            $data_class = empty($data_id) && ! empty($stop['class']) ? ' data-class="'.$stop['class'].'"' : '';
606 606
 
607 607
             //if container is set to modal then let's make sure we set the options accordingly
608 608
             if (empty($data_id) && empty($data_class)) {
@@ -610,15 +610,15 @@  discard block
 block discarded – undo
610 610
                 $stop['options']['expose'] = true;
611 611
             }
612 612
 
613
-            $custom_class  = ! empty($stop['custom_class']) ? ' class="' . $stop['custom_class'] . '"' : '';
614
-            $button_text   = ! empty($stop['button_text']) ? ' data-button="' . $stop['button_text'] . '"' : '';
613
+            $custom_class  = ! empty($stop['custom_class']) ? ' class="'.$stop['custom_class'].'"' : '';
614
+            $button_text   = ! empty($stop['button_text']) ? ' data-button="'.$stop['button_text'].'"' : '';
615 615
             $inner_content = isset($stop['content']) ? $stop['content'] : '';
616 616
 
617 617
             //options
618 618
             if (isset($stop['options']) && is_array($stop['options'])) {
619 619
                 $options = ' data-options="';
620 620
                 foreach ($stop['options'] as $option => $value) {
621
-                    $options .= $option . ':' . $value . ';';
621
+                    $options .= $option.':'.$value.';';
622 622
                 }
623 623
                 $options .= '"';
624 624
             } else {
@@ -626,7 +626,7 @@  discard block
 block discarded – undo
626 626
             }
627 627
 
628 628
             //let's put all together
629
-            $content .= '<li' . $data_id . $data_class . $custom_class . $button_text . $options . '>' . $inner_content . '</li>';
629
+            $content .= '<li'.$data_id.$data_class.$custom_class.$button_text.$options.'>'.$inner_content.'</li>';
630 630
         }
631 631
 
632 632
         $content .= '</ol>';
@@ -658,24 +658,24 @@  discard block
 block discarded – undo
658 658
         $setup_array = array();
659 659
         foreach ($status_array as $item => $status) {
660 660
             $setup_array[$item] = array(
661
-                'class'  => 'ee-status-legend ee-status-legend-' . $status,
661
+                'class'  => 'ee-status-legend ee-status-legend-'.$status,
662 662
                 'desc'   => EEH_Template::pretty_status($status, false, 'sentence'),
663 663
                 'status' => $status,
664 664
             );
665 665
         }
666 666
 
667
-        $content = '<div class="ee-list-table-legend-container">' . "\n";
668
-        $content .= '<h4 class="status-legend-title">' . esc_html__('Status Legend', 'event_espresso') . '</h4>' . "\n";
669
-        $content .= '<dl class="ee-list-table-legend">' . "\n\t";
667
+        $content = '<div class="ee-list-table-legend-container">'."\n";
668
+        $content .= '<h4 class="status-legend-title">'.esc_html__('Status Legend', 'event_espresso').'</h4>'."\n";
669
+        $content .= '<dl class="ee-list-table-legend">'."\n\t";
670 670
         foreach ($setup_array as $item => $details) {
671 671
             $active_class = $active_status == $details['status'] ? ' class="ee-is-active-status"' : '';
672
-            $content .= '<dt id="ee-legend-item-tooltip-' . $item . '"' . $active_class . '>' . "\n\t\t";
673
-            $content .= '<span class="' . $details['class'] . '"></span>' . "\n\t\t";
674
-            $content .= '<span class="ee-legend-description">' . $details['desc'] . '</span>' . "\n\t";
675
-            $content .= '</dt>' . "\n";
672
+            $content .= '<dt id="ee-legend-item-tooltip-'.$item.'"'.$active_class.'>'."\n\t\t";
673
+            $content .= '<span class="'.$details['class'].'"></span>'."\n\t\t";
674
+            $content .= '<span class="ee-legend-description">'.$details['desc'].'</span>'."\n\t";
675
+            $content .= '</dt>'."\n";
676 676
         }
677
-        $content .= '</dl>' . "\n";
678
-        $content .= '</div>' . "\n";
677
+        $content .= '</dl>'."\n";
678
+        $content .= '</div>'."\n";
679 679
         return $content;
680 680
     }
681 681
 
@@ -690,7 +690,7 @@  discard block
 block discarded – undo
690 690
     public static function layout_array_as_table($data)
691 691
     {
692 692
         if (is_object($data) || $data instanceof __PHP_Incomplete_Class) {
693
-            $data = (array)$data;
693
+            $data = (array) $data;
694 694
         }
695 695
         ob_start();
696 696
         if (is_array($data)) {
@@ -791,9 +791,9 @@  discard block
 block discarded – undo
791 791
     ) {
792 792
         $page_links     = array();
793 793
         $disable_first  = $disable_last = '';
794
-        $total_items    = (int)$total_items;
795
-        $per_page       = (int)$per_page;
796
-        $current        = (int)$current;
794
+        $total_items    = (int) $total_items;
795
+        $per_page       = (int) $per_page;
796
+        $current        = (int) $current;
797 797
         $paged_arg_name = empty($paged_arg_name) ? 'paged' : sanitize_key($paged_arg_name);
798 798
 
799 799
         //filter items_label
@@ -813,8 +813,8 @@  discard block
 block discarded – undo
813 813
             );
814 814
         } else {
815 815
             $items_label = array(
816
-                'single' => '1 ' . esc_html($items_label['single']),
817
-                'plural' => '%s ' . esc_html($items_label['plural']),
816
+                'single' => '1 '.esc_html($items_label['single']),
817
+                'plural' => '%s '.esc_html($items_label['plural']),
818 818
             );
819 819
         }
820 820
 
@@ -826,7 +826,7 @@  discard block
 block discarded – undo
826 826
 
827 827
         $item_label = $total_items > 1 ? sprintf($items_label['plural'], $total_items) : $items_label['single'];
828 828
 
829
-        $output = '<span class="displaying-num">' . $item_label . '</span>';
829
+        $output = '<span class="displaying-num">'.$item_label.'</span>';
830 830
 
831 831
         if ($current === 1) {
832 832
             $disable_first = ' disabled';
@@ -836,7 +836,7 @@  discard block
 block discarded – undo
836 836
         }
837 837
 
838 838
         $page_links[] = sprintf("<a class='%s' title='%s' href='%s'>%s</a>",
839
-            'first-page' . $disable_first,
839
+            'first-page'.$disable_first,
840 840
             esc_attr__('Go to the first page'),
841 841
             esc_url(remove_query_arg($paged_arg_name, $url)),
842 842
             '&laquo;'
@@ -844,7 +844,7 @@  discard block
 block discarded – undo
844 844
 
845 845
         $page_links[] = sprintf(
846 846
             '<a class="%s" title="%s" href="%s">%s</a>',
847
-            'prev-page' . $disable_first,
847
+            'prev-page'.$disable_first,
848 848
             esc_attr__('Go to the previous page'),
849 849
             esc_url(add_query_arg($paged_arg_name, max(1, $current - 1), $url)),
850 850
             '&lsaquo;'
@@ -864,7 +864,7 @@  discard block
 block discarded – undo
864 864
             '<span class="total-pages">%s</span>',
865 865
             number_format_i18n($total_pages)
866 866
         );
867
-        $page_links[]     = sprintf(
867
+        $page_links[] = sprintf(
868 868
             _x('%3$s%1$s of %2$s%4$s', 'paging'),
869 869
             $html_current_page,
870 870
             $html_total_pages,
@@ -874,7 +874,7 @@  discard block
 block discarded – undo
874 874
 
875 875
         $page_links[] = sprintf(
876 876
             '<a class="%s" title="%s" href="%s">%s</a>',
877
-            'next-page' . $disable_last,
877
+            'next-page'.$disable_last,
878 878
             esc_attr__('Go to the next page'),
879 879
             esc_url(add_query_arg($paged_arg_name, min($total_pages, $current + 1), $url)),
880 880
             '&rsaquo;'
@@ -882,13 +882,13 @@  discard block
 block discarded – undo
882 882
 
883 883
         $page_links[] = sprintf(
884 884
             '<a class="%s" title="%s" href="%s">%s</a>',
885
-            'last-page' . $disable_last,
885
+            'last-page'.$disable_last,
886 886
             esc_attr__('Go to the last page'),
887 887
             esc_url(add_query_arg($paged_arg_name, $total_pages, $url)),
888 888
             '&raquo;'
889 889
         );
890 890
 
891
-        $output .= "\n" . '<span class="pagination-links">' . join("\n", $page_links) . '</span>';
891
+        $output .= "\n".'<span class="pagination-links">'.join("\n", $page_links).'</span>';
892 892
         // set page class
893 893
         if ($total_pages) {
894 894
             $page_class = $total_pages < 2 ? ' one-page' : '';
@@ -896,7 +896,7 @@  discard block
 block discarded – undo
896 896
             $page_class = ' no-pages';
897 897
         }
898 898
 
899
-        return '<div class="tablenav"><div class="tablenav-pages' . $page_class . '">' . $output . '</div></div>';
899
+        return '<div class="tablenav"><div class="tablenav-pages'.$page_class.'">'.$output.'</div></div>';
900 900
     }
901 901
 
902 902
 
@@ -933,10 +933,10 @@  discard block
 block discarded – undo
933 933
             $query_args
934 934
         );
935 935
         $powered_by = apply_filters('FHEE__EEH_Template__powered_by_event_espresso_text',
936
-            $admin ? 'Event Espresso - ' . EVENT_ESPRESSO_VERSION : 'Event Espresso');
936
+            $admin ? 'Event Espresso - '.EVENT_ESPRESSO_VERSION : 'Event Espresso');
937 937
         $url        = add_query_arg($query_args, 'https://eventespresso.com/');
938 938
         $url        = apply_filters('FHEE__EEH_Template__powered_by_event_espresso__url', $url);
939
-        return (string)apply_filters(
939
+        return (string) apply_filters(
940 940
             'FHEE__EEH_Template__powered_by_event_espresso__html',
941 941
             sprintf(
942 942
                 esc_html_x(
@@ -987,6 +987,6 @@  discard block
 block discarded – undo
987 987
                 'add_fragment' => '',
988 988
             )
989 989
         );
990
-        echo ! empty($pagination) ? '<div class="ee-pagination-dv clear">' . $pagination . '</div>' : '';
990
+        echo ! empty($pagination) ? '<div class="ee-pagination-dv clear">'.$pagination.'</div>' : '';
991 991
     }
992 992
 }
993 993
\ No newline at end of file
Please login to merge, or discard this patch.
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -304,7 +304,7 @@  discard block
 block discarded – undo
304 304
      * _find_common_base_path
305 305
      * given two paths, this determines if there is a common base path between the two
306 306
      *
307
-     * @param array $paths
307
+     * @param string[] $paths
308 308
      * @return string
309 309
      */
310 310
     protected static function _find_common_base_path($paths)
@@ -334,7 +334,7 @@  discard block
 block discarded – undo
334 334
      * @param  boolean    $return_string whether to send output immediately to screen, or capture and return as a string
335 335
      * @param bool        $throw_exceptions if set to true, will throw an exception if the template is either
336 336
      *                                      not found or is not readable
337
-     * @return mixed string
337
+     * @return string string
338 338
      * @throws \DomainException
339 339
      */
340 340
 	public static function display_template(
Please login to merge, or discard this patch.
core/libraries/form_sections/base/EE_Form_Section_Proper.form.php 1 patch
Indentation   +1348 added lines, -1348 removed lines patch added patch discarded remove patch
@@ -13,1354 +13,1354 @@
 block discarded – undo
13 13
 class EE_Form_Section_Proper extends EE_Form_Section_Validatable
14 14
 {
15 15
 
16
-    const SUBMITTED_FORM_DATA_SSN_KEY = 'submitted_form_data';
17
-
18
-    /**
19
-     * Subsections
20
-     *
21
-     * @var EE_Form_Section_Validatable[]
22
-     */
23
-    protected $_subsections = array();
24
-
25
-    /**
26
-     * Strategy for laying out the form
27
-     *
28
-     * @var EE_Form_Section_Layout_Base
29
-     */
30
-    protected $_layout_strategy;
31
-
32
-    /**
33
-     * Whether or not this form has received and validated a form submission yet
34
-     *
35
-     * @var boolean
36
-     */
37
-    protected $_received_submission = false;
38
-
39
-    /**
40
-     * message displayed to users upon successful form submission
41
-     *
42
-     * @var string
43
-     */
44
-    protected $_form_submission_success_message = '';
45
-
46
-    /**
47
-     * message displayed to users upon unsuccessful form submission
48
-     *
49
-     * @var string
50
-     */
51
-    protected $_form_submission_error_message = '';
52
-
53
-    /**
54
-     * Stores all the data that will localized for form validation
55
-     *
56
-     * @var array
57
-     */
58
-    static protected $_js_localization = array();
59
-
60
-    /**
61
-     * whether or not the form's localized validation JS vars have been set
62
-     *
63
-     * @type boolean
64
-     */
65
-    static protected $_scripts_localized = false;
66
-
67
-
68
-
69
-    /**
70
-     * when constructing a proper form section, calls _construct_finalize on children
71
-     * so that they know who their parent is, and what name they've been given.
72
-     *
73
-     * @param array $options_array   {
74
-     * @type        $subsections     EE_Form_Section_Validatable[] where keys are the section's name
75
-     * @type        $include         string[] numerically-indexed where values are section names to be included,
76
-     *                               and in that order. This is handy if you want
77
-     *                               the subsections to be ordered differently than the default, and if you override
78
-     *                               which fields are shown
79
-     * @type        $exclude         string[] values are subsections to be excluded. This is handy if you want
80
-     *                               to remove certain default subsections (note: if you specify BOTH 'include' AND
81
-     *                               'exclude', the inclusions will be applied first, and the exclusions will exclude
82
-     *                               items from that list of inclusions)
83
-     * @type        $layout_strategy EE_Form_Section_Layout_Base strategy for laying out the form
84
-     *                               } @see EE_Form_Section_Validatable::__construct()
85
-     * @throws \EE_Error
86
-     */
87
-    public function __construct($options_array = array())
88
-    {
89
-        $options_array = (array)apply_filters('FHEE__EE_Form_Section_Proper___construct__options_array', $options_array,
90
-            $this);
91
-        //call parent first, as it may be setting the name
92
-        parent::__construct($options_array);
93
-        //if they've included subsections in the constructor, add them now
94
-        if (isset($options_array['include'])) {
95
-            //we are going to make sure we ONLY have those subsections to include
96
-            //AND we are going to make sure they're in that specified order
97
-            $reordered_subsections = array();
98
-            foreach ($options_array['include'] as $input_name) {
99
-                if (isset($this->_subsections[$input_name])) {
100
-                    $reordered_subsections[$input_name] = $this->_subsections[$input_name];
101
-                }
102
-            }
103
-            $this->_subsections = $reordered_subsections;
104
-        }
105
-        if (isset($options_array['exclude'])) {
106
-            $exclude = $options_array['exclude'];
107
-            $this->_subsections = array_diff_key($this->_subsections, array_flip($exclude));
108
-        }
109
-        if (isset($options_array['layout_strategy'])) {
110
-            $this->_layout_strategy = $options_array['layout_strategy'];
111
-        }
112
-        if ( ! $this->_layout_strategy) {
113
-            $this->_layout_strategy = is_admin() ? new EE_Admin_Two_Column_Layout() : new EE_Two_Column_Layout();
114
-        }
115
-        $this->_layout_strategy->_construct_finalize($this);
116
-        //ok so we are definitely going to want the forms JS,
117
-        //so enqueue it or remember to enqueue it during wp_enqueue_scripts
118
-        if (did_action('wp_enqueue_scripts')
119
-            || did_action('admin_enqueue_scripts')
120
-        ) {
121
-            //ok so they've constructed this object after when they should have.
122
-            //just enqueue the generic form scripts and initialize the form immediately in the JS
123
-            \EE_Form_Section_Proper::wp_enqueue_scripts(true);
124
-        } else {
125
-            add_action('wp_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts'));
126
-            add_action('admin_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts'));
127
-        }
128
-        add_action('wp_footer', array($this, 'ensure_scripts_localized'), 1);
129
-        if (isset($options_array['name'])) {
130
-            $this->_construct_finalize(null, $options_array['name']);
131
-        }
132
-    }
133
-
134
-
135
-
136
-    /**
137
-     * Finishes construction given the parent form section and this form section's name
138
-     *
139
-     * @param EE_Form_Section_Proper $parent_form_section
140
-     * @param string                 $name
141
-     * @throws \EE_Error
142
-     */
143
-    public function _construct_finalize($parent_form_section, $name)
144
-    {
145
-        parent::_construct_finalize($parent_form_section, $name);
146
-        $this->_set_default_name_if_empty();
147
-        $this->_set_default_html_id_if_empty();
148
-        foreach ($this->_subsections as $subsection_name => $subsection) {
149
-            if ($subsection instanceof EE_Form_Section_Base) {
150
-                $subsection->_construct_finalize($this, $subsection_name);
151
-            } else {
152
-                throw new EE_Error(
153
-                    sprintf(
154
-                        __('Subsection "%s" is not an instanceof EE_Form_Section_Base on form "%s". It is a "%s"',
155
-                            'event_espresso'),
156
-                        $subsection_name,
157
-                        get_class($this),
158
-                        $subsection ? get_class($subsection) : __('NULL', 'event_espresso')
159
-                    )
160
-                );
161
-            }
162
-        }
163
-        do_action('AHEE__EE_Form_Section_Proper___construct_finalize__end', $this, $parent_form_section, $name);
164
-    }
165
-
166
-
167
-
168
-    /**
169
-     * Gets the layout strategy for this form section
170
-     *
171
-     * @return EE_Form_Section_Layout_Base
172
-     */
173
-    public function get_layout_strategy()
174
-    {
175
-        return $this->_layout_strategy;
176
-    }
177
-
178
-
179
-
180
-    /**
181
-     * Gets the HTML for a single input for this form section according
182
-     * to the layout strategy
183
-     *
184
-     * @param EE_Form_Input_Base $input
185
-     * @return string
186
-     */
187
-    public function get_html_for_input($input)
188
-    {
189
-        return $this->_layout_strategy->layout_input($input);
190
-    }
191
-
192
-
193
-
194
-    /**
195
-     * was_submitted - checks if form inputs are present in request data
196
-     * Basically an alias for form_data_present_in() (which is used by both
197
-     * proper form sections and form inputs)
198
-     *
199
-     * @param null $form_data
200
-     * @return boolean
201
-     */
202
-    public function was_submitted($form_data = null)
203
-    {
204
-        return $this->form_data_present_in($form_data);
205
-    }
206
-
207
-
208
-
209
-    /**
210
-     * After the form section is initially created, call this to sanitize the data in the submission
211
-     * which relates to this form section, validate it, and set it as properties on the form.
212
-     *
213
-     * @param array|null $req_data should usually be $_POST (the default).
214
-     *                             However, you CAN supply a different array.
215
-     *                             Consider using set_defaults() instead however.
216
-     *                             (If you rendered the form in the page using echo $form_x->get_html()
217
-     *                             the inputs will have the correct name in the request data for this function
218
-     *                             to find them and populate the form with them.
219
-     *                             If you have a flat form (with only input subsections),
220
-     *                             you can supply a flat array where keys
221
-     *                             are the form input names and values are their values)
222
-     * @param boolean    $validate whether or not to perform validation on this data. Default is,
223
-     *                             of course, to validate that data, and set errors on the invalid values.
224
-     *                             But if the data has already been validated
225
-     *                             (eg you validated the data then stored it in the DB)
226
-     *                             you may want to skip this step.
227
-     */
228
-    public function receive_form_submission($req_data = null, $validate = true)
229
-    {
230
-        $req_data = apply_filters('FHEE__EE_Form_Section_Proper__receive_form_submission__req_data', $req_data, $this,
231
-            $validate);
232
-        if ($req_data === null) {
233
-            $req_data = array_merge($_GET, $_POST);
234
-        }
235
-        $req_data = apply_filters('FHEE__EE_Form_Section_Proper__receive_form_submission__request_data', $req_data,
236
-            $this);
237
-        $this->_normalize($req_data);
238
-        if ($validate) {
239
-            $this->_validate();
240
-            //if it's invalid, we're going to want to re-display so remember what they submitted
241
-            if ( ! $this->is_valid()) {
242
-                $this->store_submitted_form_data_in_session();
243
-            }
244
-        }
245
-        do_action('AHEE__EE_Form_Section_Proper__receive_form_submission__end', $req_data, $this, $validate);
246
-    }
247
-
248
-
249
-
250
-    /**
251
-     * caches the originally submitted input values in the session
252
-     * so that they can be used to repopulate the form if it failed validation
253
-     *
254
-     * @return boolean whether or not the data was successfully stored in the session
255
-     */
256
-    protected function store_submitted_form_data_in_session()
257
-    {
258
-        return EE_Registry::instance()->SSN->set_session_data(
259
-            array(
260
-                \EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY => $this->submitted_values(true),
261
-            )
262
-        );
263
-    }
264
-
265
-
266
-
267
-    /**
268
-     * retrieves the originally submitted input values in the session
269
-     * so that they can be used to repopulate the form if it failed validation
270
-     *
271
-     * @return array
272
-     */
273
-    protected function get_submitted_form_data_from_session()
274
-    {
275
-        $session = EE_Registry::instance()->SSN;
276
-        if ($session instanceof EE_Session) {
277
-            return $session->get_session_data(
278
-                \EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY
279
-            );
280
-        } else {
281
-            return array();
282
-        }
283
-    }
284
-
285
-
286
-
287
-    /**
288
-     * flushed the originally submitted input values from the session
289
-     *
290
-     * @return boolean whether or not the data was successfully removed from the session
291
-     */
292
-    protected function flush_submitted_form_data_from_session()
293
-    {
294
-        return EE_Registry::instance()->SSN->reset_data(
295
-            array(\EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY)
296
-        );
297
-    }
298
-
299
-
300
-
301
-    /**
302
-     * Populates this form and its subsections with data from the session.
303
-     * (Wrapper for EE_Form_Section_Proper::receive_form_submission, so it shows
304
-     * validation errors when displaying too)
305
-     * Returns true if the form was populated from the session, false otherwise
306
-     *
307
-     * @return boolean
308
-     */
309
-    public function populate_from_session()
310
-    {
311
-        $form_data_in_session = $this->get_submitted_form_data_from_session();
312
-        if (empty($form_data_in_session)) {
313
-            return false;
314
-        }
315
-        $this->receive_form_submission($form_data_in_session);
316
-        $this->flush_submitted_form_data_from_session();
317
-        if ($this->form_data_present_in($form_data_in_session)) {
318
-            return true;
319
-        } else {
320
-            return false;
321
-        }
322
-    }
323
-
324
-
325
-
326
-    /**
327
-     * Populates the default data for the form, given an array where keys are
328
-     * the input names, and values are their values (preferably normalized to be their
329
-     * proper PHP types, not all strings... although that should be ok too).
330
-     * Proper subsections are sub-arrays, the key being the subsection's name, and
331
-     * the value being an array formatted in teh same way
332
-     *
333
-     * @param array $default_data
334
-     */
335
-    public function populate_defaults($default_data)
336
-    {
337
-        foreach ($this->subsections() as $subsection_name => $subsection) {
338
-            if (isset($default_data[$subsection_name])) {
339
-                if ($subsection instanceof EE_Form_Input_Base) {
340
-                    $subsection->set_default($default_data[$subsection_name]);
341
-                } elseif ($subsection instanceof EE_Form_Section_Proper) {
342
-                    $subsection->populate_defaults($default_data[$subsection_name]);
343
-                }
344
-            }
345
-        }
346
-    }
347
-
348
-
349
-
350
-    /**
351
-     * returns true if subsection exists
352
-     *
353
-     * @param string $name
354
-     * @return boolean
355
-     */
356
-    public function subsection_exists($name)
357
-    {
358
-        return isset($this->_subsections[$name]) ? true : false;
359
-    }
360
-
361
-
362
-
363
-    /**
364
-     * Gets the subsection specified by its name
365
-     *
366
-     * @param string  $name
367
-     * @param boolean $require_construction_to_be_finalized most client code should leave this as TRUE
368
-     *                                                      so that the inputs will be properly configured.
369
-     *                                                      However, some client code may be ok
370
-     *                                                      with construction finalize being called later
371
-     *                                                      (realizing that the subsections' html names
372
-     *                                                      might not be set yet, etc.)
373
-     * @return EE_Form_Section_Base
374
-     * @throws \EE_Error
375
-     */
376
-    public function get_subsection($name, $require_construction_to_be_finalized = true)
377
-    {
378
-        if ($require_construction_to_be_finalized) {
379
-            $this->ensure_construct_finalized_called();
380
-        }
381
-        return $this->subsection_exists($name) ? $this->_subsections[$name] : null;
382
-    }
383
-
384
-
385
-
386
-    /**
387
-     * Gets all the validatable subsections of this form section
388
-     *
389
-     * @return EE_Form_Section_Validatable[]
390
-     */
391
-    public function get_validatable_subsections()
392
-    {
393
-        $validatable_subsections = array();
394
-        foreach ($this->subsections() as $name => $obj) {
395
-            if ($obj instanceof EE_Form_Section_Validatable) {
396
-                $validatable_subsections[$name] = $obj;
397
-            }
398
-        }
399
-        return $validatable_subsections;
400
-    }
401
-
402
-
403
-
404
-    /**
405
-     * Gets an input by the given name. If not found, or if its not an EE_FOrm_Input_Base child,
406
-     * throw an EE_Error.
407
-     *
408
-     * @param string  $name
409
-     * @param boolean $require_construction_to_be_finalized most client code should
410
-     *                                                      leave this as TRUE so that the inputs will be properly
411
-     *                                                      configured. However, some client code may be ok with
412
-     *                                                      construction finalize being called later
413
-     *                                                      (realizing that the subsections' html names might not be
414
-     *                                                      set yet, etc.)
415
-     * @return EE_Form_Input_Base
416
-     * @throws EE_Error
417
-     */
418
-    public function get_input($name, $require_construction_to_be_finalized = true)
419
-    {
420
-        $subsection = $this->get_subsection($name, $require_construction_to_be_finalized);
421
-        if ( ! $subsection instanceof EE_Form_Input_Base) {
422
-            throw new EE_Error(
423
-                sprintf(
424
-                    __(
425
-                        "Subsection '%s' is not an instanceof EE_Form_Input_Base on form '%s'. It is a '%s'",
426
-                        'event_espresso'
427
-                    ),
428
-                    $name,
429
-                    get_class($this),
430
-                    $subsection ? get_class($subsection) : __("NULL", 'event_espresso')
431
-                )
432
-            );
433
-        }
434
-        return $subsection;
435
-    }
436
-
437
-
438
-
439
-    /**
440
-     * Like get_input(), gets the proper subsection of the form given the name,
441
-     * otherwise throws an EE_Error
442
-     *
443
-     * @param string  $name
444
-     * @param boolean $require_construction_to_be_finalized most client code should
445
-     *                                                      leave this as TRUE so that the inputs will be properly
446
-     *                                                      configured. However, some client code may be ok with
447
-     *                                                      construction finalize being called later
448
-     *                                                      (realizing that the subsections' html names might not be
449
-     *                                                      set yet, etc.)
450
-     * @return EE_Form_Section_Proper
451
-     * @throws EE_Error
452
-     */
453
-    public function get_proper_subsection($name, $require_construction_to_be_finalized = true)
454
-    {
455
-        $subsection = $this->get_subsection($name, $require_construction_to_be_finalized);
456
-        if ( ! $subsection instanceof EE_Form_Section_Proper) {
457
-            throw new EE_Error(
458
-                sprintf(
459
-                    __("Subsection '%'s is not an instanceof EE_Form_Section_Proper on form '%s'", 'event_espresso'),
460
-                    $name,
461
-                    get_class($this)
462
-                )
463
-            );
464
-        }
465
-        return $subsection;
466
-    }
467
-
468
-
469
-
470
-    /**
471
-     * Gets the value of the specified input. Should be called after receive_form_submission()
472
-     * or populate_defaults() on the form, where the normalized value on the input is set.
473
-     *
474
-     * @param string $name
475
-     * @return mixed depending on the input's type and its normalization strategy
476
-     * @throws \EE_Error
477
-     */
478
-    public function get_input_value($name)
479
-    {
480
-        $input = $this->get_input($name);
481
-        return $input->normalized_value();
482
-    }
483
-
484
-
485
-
486
-    /**
487
-     * Checks if this form section itself is valid, and then checks its subsections
488
-     *
489
-     * @throws EE_Error
490
-     * @return boolean
491
-     */
492
-    public function is_valid()
493
-    {
494
-        if ( ! $this->has_received_submission()) {
495
-            throw new EE_Error(
496
-                sprintf(
497
-                    __(
498
-                        "You cannot check if a form is valid before receiving the form submission using receive_form_submission",
499
-                        "event_espresso"
500
-                    )
501
-                )
502
-            );
503
-        }
504
-        if ( ! parent::is_valid()) {
505
-            return false;
506
-        }
507
-        // ok so no general errors to this entire form section.
508
-        // so let's check the subsections, but only set errors if that hasn't been done yet
509
-        $set_submission_errors = $this->submission_error_message() === '' ? true : false;
510
-        foreach ($this->get_validatable_subsections() as $subsection) {
511
-            if ( ! $subsection->is_valid() || $subsection->get_validation_error_string() !== '') {
512
-                if ($set_submission_errors) {
513
-                    $this->set_submission_error_message($subsection->get_validation_error_string());
514
-                }
515
-                return false;
516
-            }
517
-        }
518
-        return true;
519
-    }
520
-
521
-
522
-
523
-    /**
524
-     * gets teh default name of this form section if none is specified
525
-     *
526
-     * @return string
527
-     */
528
-    protected function _set_default_name_if_empty()
529
-    {
530
-        if ( ! $this->_name) {
531
-            $classname = get_class($this);
532
-            $default_name = str_replace("EE_", "", $classname);
533
-            $this->_name = $default_name;
534
-        }
535
-    }
536
-
537
-
538
-
539
-    /**
540
-     * Returns the HTML for the form, except for the form opening and closing tags
541
-     * (as the form section doesn't know where you necessarily want to send the information to),
542
-     * and except for a submit button. Enqueus JS and CSS; if called early enough we will
543
-     * try to enqueue them in the header, otherwise they'll be enqueued in the footer.
544
-     * Not doing_it_wrong because theoretically this CAN be used properly,
545
-     * provided its used during "wp_enqueue_scripts", or it doesn't need to enqueue
546
-     * any CSS.
547
-     *
548
-     * @throws \EE_Error
549
-     */
550
-    public function get_html_and_js()
551
-    {
552
-        $this->enqueue_js();
553
-        return $this->get_html();
554
-    }
555
-
556
-
557
-
558
-    /**
559
-     * returns HTML for displaying this form section. recursively calls display_section() on all subsections
560
-     *
561
-     * @param bool $display_previously_submitted_data
562
-     * @return string
563
-     */
564
-    public function get_html($display_previously_submitted_data = true)
565
-    {
566
-        $this->ensure_construct_finalized_called();
567
-        if ($display_previously_submitted_data) {
568
-            $this->populate_from_session();
569
-        }
570
-        return $this->_layout_strategy->layout_form();
571
-    }
572
-
573
-
574
-
575
-    /**
576
-     * enqueues JS and CSS for the form.
577
-     * It is preferred to call this before wp_enqueue_scripts so the
578
-     * scripts and styles can be put in the header, but if called later
579
-     * they will be put in the footer (which is OK for JS, but in HTML4 CSS should
580
-     * only be in the header; but in HTML5 its ok in the body.
581
-     * See http://stackoverflow.com/questions/4957446/load-external-css-file-in-body-tag.
582
-     * So if your form enqueues CSS, it's preferred to call this before wp_enqueue_scripts.)
583
-     *
584
-     * @return string
585
-     * @throws \EE_Error
586
-     */
587
-    public function enqueue_js()
588
-    {
589
-        $this->_enqueue_and_localize_form_js();
590
-        foreach ($this->subsections() as $subsection) {
591
-            $subsection->enqueue_js();
592
-        }
593
-    }
594
-
595
-
596
-
597
-    /**
598
-     * adds a filter so that jquery validate gets enqueued in EE_System::wp_enqueue_scripts().
599
-     * This must be done BEFORE wp_enqueue_scripts() gets called, which is on
600
-     * the wp_enqueue_scripts hook.
601
-     * However, registering the form js and localizing it can happen when we
602
-     * actually output the form (which is preferred, seeing how teh form's fields
603
-     * could change until it's actually outputted)
604
-     *
605
-     * @param boolean $init_form_validation_automatically whether or not we want the form validation
606
-     *                                                    to be triggered automatically or not
607
-     * @return void
608
-     */
609
-    public static function wp_enqueue_scripts($init_form_validation_automatically = true)
610
-    {
611
-        add_filter('FHEE_load_jquery_validate', '__return_true');
612
-        wp_register_script(
613
-            'ee_form_section_validation',
614
-            EE_GLOBAL_ASSETS_URL . 'scripts' . DS . 'form_section_validation.js',
615
-            array('jquery-validate', 'jquery-ui-datepicker', 'jquery-validate-extra-methods'),
616
-            EVENT_ESPRESSO_VERSION,
617
-            true
618
-        );
619
-        wp_localize_script(
620
-            'ee_form_section_validation',
621
-            'ee_form_section_validation_init',
622
-            array('init' => $init_form_validation_automatically ? true : false)
623
-        );
624
-    }
625
-
626
-
627
-
628
-    /**
629
-     * gets the variables used by form_section_validation.js.
630
-     * This needs to be called AFTER we've called $this->_enqueue_jquery_validate_script,
631
-     * but before the wordpress hook wp_loaded
632
-     *
633
-     * @throws \EE_Error
634
-     */
635
-    public function _enqueue_and_localize_form_js()
636
-    {
637
-        $this->ensure_construct_finalized_called();
638
-        //actually, we don't want to localize just yet. There may be other forms on the page.
639
-        //so we need to add our form section data to a static variable accessible by all form sections
640
-        //and localize it just before the footer
641
-        $this->localize_validation_rules();
642
-        add_action('wp_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'), 2);
643
-        add_action('admin_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'));
644
-    }
645
-
646
-
647
-
648
-    /**
649
-     * add our form section data to a static variable accessible by all form sections
650
-     *
651
-     * @param bool $return_for_subsection
652
-     * @return void
653
-     * @throws \EE_Error
654
-     */
655
-    public function localize_validation_rules($return_for_subsection = false)
656
-    {
657
-        // we only want to localize vars ONCE for the entire form,
658
-        // so if the form section doesn't have a parent, then it must be the top dog
659
-        if ($return_for_subsection || ! $this->parent_section()) {
660
-            EE_Form_Section_Proper::$_js_localization['form_data'][$this->html_id()] = array(
661
-                'form_section_id'  => $this->html_id(true),
662
-                'validation_rules' => $this->get_jquery_validation_rules(),
663
-                'other_data'       => $this->get_other_js_data(),
664
-                'errors'           => $this->subsection_validation_errors_by_html_name(),
665
-            );
666
-            EE_Form_Section_Proper::$_scripts_localized = true;
667
-        }
668
-    }
669
-
670
-
671
-
672
-    /**
673
-     * Gets an array of extra data that will be useful for client-side javascript.
674
-     * This is primarily data added by inputs and forms in addition to any
675
-     * scripts they might enqueue
676
-     *
677
-     * @param array $form_other_js_data
678
-     * @return array
679
-     */
680
-    public function get_other_js_data($form_other_js_data = array())
681
-    {
682
-        foreach ($this->subsections() as $subsection) {
683
-            $form_other_js_data = $subsection->get_other_js_data($form_other_js_data);
684
-        }
685
-        return $form_other_js_data;
686
-    }
687
-
688
-
689
-
690
-    /**
691
-     * Gets a flat array of inputs for this form section and its subsections.
692
-     * Keys are their form names, and values are the inputs themselves
693
-     *
694
-     * @return EE_Form_Input_Base
695
-     */
696
-    public function inputs_in_subsections()
697
-    {
698
-        $inputs = array();
699
-        foreach ($this->subsections() as $subsection) {
700
-            if ($subsection instanceof EE_Form_Input_Base) {
701
-                $inputs[$subsection->html_name()] = $subsection;
702
-            } elseif ($subsection instanceof EE_Form_Section_Proper) {
703
-                $inputs += $subsection->inputs_in_subsections();
704
-            }
705
-        }
706
-        return $inputs;
707
-    }
708
-
709
-
710
-
711
-    /**
712
-     * Gets a flat array of all the validation errors.
713
-     * Keys are html names (because those should be unique)
714
-     * and values are a string of all their validation errors
715
-     *
716
-     * @return string[]
717
-     */
718
-    public function subsection_validation_errors_by_html_name()
719
-    {
720
-        $inputs = $this->inputs();
721
-        $errors = array();
722
-        foreach ($inputs as $form_input) {
723
-            if ($form_input instanceof EE_Form_Input_Base && $form_input->get_validation_errors()) {
724
-                $errors[$form_input->html_name()] = $form_input->get_validation_error_string();
725
-            }
726
-        }
727
-        return $errors;
728
-    }
729
-
730
-
731
-
732
-    /**
733
-     * passes all the form data required by the JS to the JS, and enqueues the few required JS files.
734
-     * Should be setup by each form during the _enqueues_and_localize_form_js
735
-     */
736
-    public static function localize_script_for_all_forms()
737
-    {
738
-        //allow inputs and stuff to hook in their JS and stuff here
739
-        do_action('AHEE__EE_Form_Section_Proper__localize_script_for_all_forms__begin');
740
-        EE_Form_Section_Proper::$_js_localization['localized_error_messages'] = EE_Form_Section_Proper::_get_localized_error_messages();
741
-        $email_validation_level = isset(EE_Registry::instance()->CFG->registration->email_validation_level)
742
-            ? EE_Registry::instance()->CFG->registration->email_validation_level
743
-            : 'wp_default';
744
-        EE_Form_Section_Proper::$_js_localization['email_validation_level'] = $email_validation_level;
745
-        wp_enqueue_script('ee_form_section_validation');
746
-        wp_localize_script(
747
-            'ee_form_section_validation',
748
-            'ee_form_section_vars',
749
-            EE_Form_Section_Proper::$_js_localization
750
-        );
751
-    }
752
-
753
-
754
-
755
-    /**
756
-     * ensure_scripts_localized
757
-     */
758
-    public function ensure_scripts_localized()
759
-    {
760
-        if ( ! EE_Form_Section_Proper::$_scripts_localized) {
761
-            $this->_enqueue_and_localize_form_js();
762
-        }
763
-    }
764
-
765
-
766
-
767
-    /**
768
-     * Gets the hard-coded validation error messages to be used in the JS. The convention
769
-     * is that the key here should be the same as the custom validation rule put in the JS file
770
-     *
771
-     * @return array keys are custom validation rules, and values are internationalized strings
772
-     */
773
-    private static function _get_localized_error_messages()
774
-    {
775
-        return array(
776
-            'validUrl' => __("This is not a valid absolute URL. Eg, http://domain.com/monkey.jpg", "event_espresso"),
777
-            'regex'    => __('Please check your input', 'event_espresso'),
778
-        );
779
-    }
780
-
781
-
782
-
783
-    /**
784
-     * @return array
785
-     */
786
-    public static function js_localization()
787
-    {
788
-        return self::$_js_localization;
789
-    }
790
-
791
-
792
-
793
-    /**
794
-     * @return array
795
-     */
796
-    public static function reset_js_localization()
797
-    {
798
-        self::$_js_localization = array();
799
-    }
800
-
801
-
802
-
803
-    /**
804
-     * Gets the JS to put inside the jquery validation rules for subsection of this form section.
805
-     * See parent function for more...
806
-     *
807
-     * @return array
808
-     */
809
-    public function get_jquery_validation_rules()
810
-    {
811
-        $jquery_validation_rules = array();
812
-        foreach ($this->get_validatable_subsections() as $subsection) {
813
-            $jquery_validation_rules = array_merge(
814
-                $jquery_validation_rules,
815
-                $subsection->get_jquery_validation_rules()
816
-            );
817
-        }
818
-        return $jquery_validation_rules;
819
-    }
820
-
821
-
822
-
823
-    /**
824
-     * Sanitizes all the data and sets the sanitized value of each field
825
-     *
826
-     * @param array $req_data like $_POST
827
-     * @return void
828
-     */
829
-    protected function _normalize($req_data)
830
-    {
831
-        $this->_received_submission = true;
832
-        $this->_validation_errors = array();
833
-        foreach ($this->get_validatable_subsections() as $subsection) {
834
-            try {
835
-                $subsection->_normalize($req_data);
836
-            } catch (EE_Validation_Error $e) {
837
-                $subsection->add_validation_error($e);
838
-            }
839
-        }
840
-    }
841
-
842
-
843
-
844
-    /**
845
-     * Performs validation on this form section and its subsections.
846
-     * For each subsection,
847
-     * calls _validate_{subsection_name} on THIS form (if the function exists)
848
-     * and passes it the subsection, then calls _validate on that subsection.
849
-     * If you need to perform validation on the form as a whole (considering multiple)
850
-     * you would be best to override this _validate method,
851
-     * calling parent::_validate() first.
852
-     */
853
-    protected function _validate()
854
-    {
855
-        foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) {
856
-            if (method_exists($this, '_validate_' . $subsection_name)) {
857
-                call_user_func_array(array($this, '_validate_' . $subsection_name), array($subsection));
858
-            }
859
-            $subsection->_validate();
860
-        }
861
-    }
862
-
863
-
864
-
865
-    /**
866
-     * Gets all the validated inputs for the form section
867
-     *
868
-     * @return array
869
-     */
870
-    public function valid_data()
871
-    {
872
-        $inputs = array();
873
-        foreach ($this->subsections() as $subsection_name => $subsection) {
874
-            if ($subsection instanceof EE_Form_Section_Proper) {
875
-                $inputs[$subsection_name] = $subsection->valid_data();
876
-            } else if ($subsection instanceof EE_Form_Input_Base) {
877
-                $inputs[$subsection_name] = $subsection->normalized_value();
878
-            }
879
-        }
880
-        return $inputs;
881
-    }
882
-
883
-
884
-
885
-    /**
886
-     * Gets all the inputs on this form section
887
-     *
888
-     * @return EE_Form_Input_Base[]
889
-     */
890
-    public function inputs()
891
-    {
892
-        $inputs = array();
893
-        foreach ($this->subsections() as $subsection_name => $subsection) {
894
-            if ($subsection instanceof EE_Form_Input_Base) {
895
-                $inputs[$subsection_name] = $subsection;
896
-            }
897
-        }
898
-        return $inputs;
899
-    }
900
-
901
-
902
-
903
-    /**
904
-     * Gets all the subsections which are a proper form
905
-     *
906
-     * @return EE_Form_Section_Proper[]
907
-     */
908
-    public function subforms()
909
-    {
910
-        $form_sections = array();
911
-        foreach ($this->subsections() as $name => $obj) {
912
-            if ($obj instanceof EE_Form_Section_Proper) {
913
-                $form_sections[$name] = $obj;
914
-            }
915
-        }
916
-        return $form_sections;
917
-    }
918
-
919
-
920
-
921
-    /**
922
-     * Gets all the subsections (inputs, proper subsections, or html-only sections).
923
-     * Consider using inputs() or subforms()
924
-     * if you only want form inputs or proper form sections.
925
-     *
926
-     * @return EE_Form_Section_Proper[]
927
-     */
928
-    public function subsections()
929
-    {
930
-        $this->ensure_construct_finalized_called();
931
-        return $this->_subsections;
932
-    }
933
-
934
-
935
-
936
-    /**
937
-     * Returns a simple array where keys are input names, and values are their normalized
938
-     * values. (Similar to calling get_input_value on inputs)
939
-     *
940
-     * @param boolean $include_subform_inputs Whether to include inputs from subforms,
941
-     *                                        or just this forms' direct children inputs
942
-     * @param boolean $flatten                Whether to force the results into 1-dimensional array,
943
-     *                                        or allow multidimensional array
944
-     * @return array if $flatten is TRUE it will always be a 1-dimensional array
945
-     *                                        with array keys being input names
946
-     *                                        (regardless of whether they are from a subsection or not),
947
-     *                                        and if $flatten is FALSE it can be a multidimensional array
948
-     *                                        where keys are always subsection names and values are either
949
-     *                                        the input's normalized value, or an array like the top-level array
950
-     */
951
-    public function input_values($include_subform_inputs = false, $flatten = false)
952
-    {
953
-        return $this->_input_values(false, $include_subform_inputs, $flatten);
954
-    }
955
-
956
-
957
-
958
-    /**
959
-     * Similar to EE_Form_Section_Proper::input_values(), except this returns the 'display_value'
960
-     * of each input. On some inputs (especially radio boxes or checkboxes), the value stored
961
-     * is not necessarily the value we want to display to users. This creates an array
962
-     * where keys are the input names, and values are their display values
963
-     *
964
-     * @param boolean $include_subform_inputs Whether to include inputs from subforms,
965
-     *                                        or just this forms' direct children inputs
966
-     * @param boolean $flatten                Whether to force the results into 1-dimensional array,
967
-     *                                        or allow multidimensional array
968
-     * @return array if $flatten is TRUE it will always be a 1-dimensional array
969
-     *                                        with array keys being input names
970
-     *                                        (regardless of whether they are from a subsection or not),
971
-     *                                        and if $flatten is FALSE it can be a multidimensional array
972
-     *                                        where keys are always subsection names and values are either
973
-     *                                        the input's normalized value, or an array like the top-level array
974
-     */
975
-    public function input_pretty_values($include_subform_inputs = false, $flatten = false)
976
-    {
977
-        return $this->_input_values(true, $include_subform_inputs, $flatten);
978
-    }
979
-
980
-
981
-
982
-    /**
983
-     * Gets the input values from the form
984
-     *
985
-     * @param boolean $pretty                 Whether to retrieve the pretty value,
986
-     *                                        or just the normalized value
987
-     * @param boolean $include_subform_inputs Whether to include inputs from subforms,
988
-     *                                        or just this forms' direct children inputs
989
-     * @param boolean $flatten                Whether to force the results into 1-dimensional array,
990
-     *                                        or allow multidimensional array
991
-     * @return array if $flatten is TRUE it will always be a 1-dimensional array with array keys being
992
-     *                                        input names (regardless of whether they are from a subsection or not),
993
-     *                                        and if $flatten is FALSE it can be a multidimensional array
994
-     *                                        where keys are always subsection names and values are either
995
-     *                                        the input's normalized value, or an array like the top-level array
996
-     */
997
-    public function _input_values($pretty = false, $include_subform_inputs = false, $flatten = false)
998
-    {
999
-        $input_values = array();
1000
-        foreach ($this->subsections() as $subsection_name => $subsection) {
1001
-            if ($subsection instanceof EE_Form_Input_Base) {
1002
-                $input_values[$subsection_name] = $pretty
1003
-                    ? $subsection->pretty_value()
1004
-                    : $subsection->normalized_value();
1005
-            } else if ($subsection instanceof EE_Form_Section_Proper && $include_subform_inputs) {
1006
-                $subform_input_values = $subsection->_input_values($pretty, $include_subform_inputs, $flatten);
1007
-                if ($flatten) {
1008
-                    $input_values = array_merge($input_values, $subform_input_values);
1009
-                } else {
1010
-                    $input_values[$subsection_name] = $subform_input_values;
1011
-                }
1012
-            }
1013
-        }
1014
-        return $input_values;
1015
-    }
1016
-
1017
-
1018
-
1019
-    /**
1020
-     * Gets the originally submitted input values from the form
1021
-     *
1022
-     * @param boolean $include_subforms  Whether to include inputs from subforms,
1023
-     *                                   or just this forms' direct children inputs
1024
-     * @return array                     if $flatten is TRUE it will always be a 1-dimensional array
1025
-     *                                   with array keys being input names
1026
-     *                                   (regardless of whether they are from a subsection or not),
1027
-     *                                   and if $flatten is FALSE it can be a multidimensional array
1028
-     *                                   where keys are always subsection names and values are either
1029
-     *                                   the input's normalized value, or an array like the top-level array
1030
-     */
1031
-    public function submitted_values($include_subforms = false)
1032
-    {
1033
-        $submitted_values = array();
1034
-        foreach ($this->subsections() as $subsection) {
1035
-            if ($subsection instanceof EE_Form_Input_Base) {
1036
-                // is this input part of an array of inputs?
1037
-                if (strpos($subsection->html_name(), '[') !== false) {
1038
-                    $full_input_name = \EEH_Array::convert_array_values_to_keys(
1039
-                        explode('[', str_replace(']', '', $subsection->html_name())),
1040
-                        $subsection->raw_value()
1041
-                    );
1042
-                    $submitted_values = array_replace_recursive($submitted_values, $full_input_name);
1043
-                } else {
1044
-                    $submitted_values[$subsection->html_name()] = $subsection->raw_value();
1045
-                }
1046
-            } else if ($subsection instanceof EE_Form_Section_Proper && $include_subforms) {
1047
-                $subform_input_values = $subsection->submitted_values($include_subforms);
1048
-                $submitted_values = array_replace_recursive($submitted_values, $subform_input_values);
1049
-            }
1050
-        }
1051
-        return $submitted_values;
1052
-    }
1053
-
1054
-
1055
-
1056
-    /**
1057
-     * Indicates whether or not this form has received a submission yet
1058
-     * (ie, had receive_form_submission called on it yet)
1059
-     *
1060
-     * @return boolean
1061
-     * @throws \EE_Error
1062
-     */
1063
-    public function has_received_submission()
1064
-    {
1065
-        $this->ensure_construct_finalized_called();
1066
-        return $this->_received_submission;
1067
-    }
1068
-
1069
-
1070
-
1071
-    /**
1072
-     * Equivalent to passing 'exclude' in the constructor's options array.
1073
-     * Removes the listed inputs from the form
1074
-     *
1075
-     * @param array $inputs_to_exclude values are the input names
1076
-     * @return void
1077
-     */
1078
-    public function exclude(array $inputs_to_exclude = array())
1079
-    {
1080
-        foreach ($inputs_to_exclude as $input_to_exclude_name) {
1081
-            unset($this->_subsections[$input_to_exclude_name]);
1082
-        }
1083
-    }
1084
-
1085
-
1086
-
1087
-    /**
1088
-     * @param array $inputs_to_hide
1089
-     * @throws \EE_Error
1090
-     */
1091
-    public function hide(array $inputs_to_hide = array())
1092
-    {
1093
-        foreach ($inputs_to_hide as $input_to_hide) {
1094
-            $input = $this->get_input($input_to_hide);
1095
-            $input->set_display_strategy(new EE_Hidden_Display_Strategy());
1096
-        }
1097
-    }
1098
-
1099
-
1100
-
1101
-    /**
1102
-     * add_subsections
1103
-     * Adds the listed subsections to the form section.
1104
-     * If $subsection_name_to_target is provided,
1105
-     * then new subsections are added before or after that subsection,
1106
-     * otherwise to the start or end of the entire subsections array.
1107
-     *
1108
-     * @param EE_Form_Section_Base[] $new_subsections           array of new form subsections
1109
-     *                                                          where keys are their names
1110
-     * @param string                 $subsection_name_to_target an existing for section that $new_subsections
1111
-     *                                                          should be added before or after
1112
-     *                                                          IF $subsection_name_to_target is null,
1113
-     *                                                          then $new_subsections will be added to
1114
-     *                                                          the beginning or end of the entire subsections array
1115
-     * @param boolean                $add_before                whether to add $new_subsections, before or after
1116
-     *                                                          $subsection_name_to_target,
1117
-     *                                                          or if $subsection_name_to_target is null,
1118
-     *                                                          before or after entire subsections array
1119
-     * @return void
1120
-     * @throws \EE_Error
1121
-     */
1122
-    public function add_subsections($new_subsections, $subsection_name_to_target = null, $add_before = true)
1123
-    {
1124
-        foreach ($new_subsections as $subsection_name => $subsection) {
1125
-            if ( ! $subsection instanceof EE_Form_Section_Base) {
1126
-                EE_Error::add_error(
1127
-                    sprintf(
1128
-                        __(
1129
-                            "Trying to add a %s as a subsection (it was named '%s') to the form section '%s'. It was removed.",
1130
-                            "event_espresso"
1131
-                        ),
1132
-                        get_class($subsection),
1133
-                        $subsection_name,
1134
-                        $this->name()
1135
-                    )
1136
-                );
1137
-                unset($new_subsections[$subsection_name]);
1138
-            }
1139
-        }
1140
-        $this->_subsections = EEH_Array::insert_into_array(
1141
-            $this->_subsections,
1142
-            $new_subsections,
1143
-            $subsection_name_to_target,
1144
-            $add_before
1145
-        );
1146
-        if ($this->_construction_finalized) {
1147
-            foreach ($this->_subsections as $name => $subsection) {
1148
-                $subsection->_construct_finalize($this, $name);
1149
-            }
1150
-        }
1151
-    }
1152
-
1153
-
1154
-
1155
-    /**
1156
-     * Just gets all validatable subsections to clean their sensitive data
1157
-     */
1158
-    public function clean_sensitive_data()
1159
-    {
1160
-        foreach ($this->get_validatable_subsections() as $subsection) {
1161
-            $subsection->clean_sensitive_data();
1162
-        }
1163
-    }
1164
-
1165
-
1166
-
1167
-    /**
1168
-     * @param string $form_submission_error_message
1169
-     */
1170
-    public function set_submission_error_message($form_submission_error_message = '')
1171
-    {
1172
-        $this->_form_submission_error_message .= ! empty($form_submission_error_message)
1173
-            ? $form_submission_error_message
1174
-            : __('Form submission failed due to errors', 'event_espresso');
1175
-    }
1176
-
1177
-
1178
-
1179
-    /**
1180
-     * @return string
1181
-     */
1182
-    public function submission_error_message()
1183
-    {
1184
-        return $this->_form_submission_error_message;
1185
-    }
1186
-
1187
-
1188
-
1189
-    /**
1190
-     * @param string $form_submission_success_message
1191
-     */
1192
-    public function set_submission_success_message($form_submission_success_message)
1193
-    {
1194
-        $this->_form_submission_success_message .= ! empty($form_submission_success_message)
1195
-            ? $form_submission_success_message
1196
-            : __('Form submitted successfully', 'event_espresso');
1197
-    }
1198
-
1199
-
1200
-
1201
-    /**
1202
-     * @return string
1203
-     */
1204
-    public function submission_success_message()
1205
-    {
1206
-        return $this->_form_submission_success_message;
1207
-    }
1208
-
1209
-
1210
-
1211
-    /**
1212
-     * Returns the prefix that should be used on child of this form section for
1213
-     * their html names. If this form section itself has a parent, prepends ITS
1214
-     * prefix onto this form section's prefix. Used primarily by
1215
-     * EE_Form_Input_Base::_set_default_html_name_if_empty
1216
-     *
1217
-     * @return string
1218
-     * @throws \EE_Error
1219
-     */
1220
-    public function html_name_prefix()
1221
-    {
1222
-        if ($this->parent_section() instanceof EE_Form_Section_Proper) {
1223
-            return $this->parent_section()->html_name_prefix() . '[' . $this->name() . ']';
1224
-        } else {
1225
-            return $this->name();
1226
-        }
1227
-    }
1228
-
1229
-
1230
-
1231
-    /**
1232
-     * Gets the name, but first checks _construct_finalize has been called. If not,
1233
-     * calls it (assumes there is no parent and that we want the name to be whatever
1234
-     * was set, which is probably nothing, or the classname)
1235
-     *
1236
-     * @return string
1237
-     * @throws \EE_Error
1238
-     */
1239
-    public function name()
1240
-    {
1241
-        $this->ensure_construct_finalized_called();
1242
-        return parent::name();
1243
-    }
1244
-
1245
-
1246
-
1247
-    /**
1248
-     * @return EE_Form_Section_Proper
1249
-     * @throws \EE_Error
1250
-     */
1251
-    public function parent_section()
1252
-    {
1253
-        $this->ensure_construct_finalized_called();
1254
-        return parent::parent_section();
1255
-    }
1256
-
1257
-
1258
-
1259
-    /**
1260
-     * make sure construction finalized was called, otherwise children might not be ready
1261
-     *
1262
-     * @return void
1263
-     * @throws \EE_Error
1264
-     */
1265
-    public function ensure_construct_finalized_called()
1266
-    {
1267
-        if ( ! $this->_construction_finalized) {
1268
-            $this->_construct_finalize($this->_parent_section, $this->_name);
1269
-        }
1270
-    }
1271
-
1272
-
1273
-
1274
-    /**
1275
-     * Checks if any of this form section's inputs, or any of its children's inputs,
1276
-     * are in teh form data. If any are found, returns true. Else false
1277
-     *
1278
-     * @param array $req_data
1279
-     * @return boolean
1280
-     */
1281
-    public function form_data_present_in($req_data = null)
1282
-    {
1283
-        if ($req_data === null) {
1284
-            $req_data = $_POST;
1285
-        }
1286
-        foreach ($this->subsections() as $subsection) {
1287
-            if ($subsection instanceof EE_Form_Input_Base) {
1288
-                if ($subsection->form_data_present_in($req_data)) {
1289
-                    return true;
1290
-                }
1291
-            } elseif ($subsection instanceof EE_Form_Section_Proper) {
1292
-                if ($subsection->form_data_present_in($req_data)) {
1293
-                    return true;
1294
-                }
1295
-            }
1296
-        }
1297
-        return false;
1298
-    }
1299
-
1300
-
1301
-
1302
-    /**
1303
-     * Gets validation errors for this form section and subsections
1304
-     * Similar to EE_Form_Section_Validatable::get_validation_errors() except this
1305
-     * gets the validation errors for ALL subsection
1306
-     *
1307
-     * @return EE_Validation_Error[]
1308
-     */
1309
-    public function get_validation_errors_accumulated()
1310
-    {
1311
-        $validation_errors = $this->get_validation_errors();
1312
-        foreach ($this->get_validatable_subsections() as $subsection) {
1313
-            if ($subsection instanceof EE_Form_Section_Proper) {
1314
-                $validation_errors_on_this_subsection = $subsection->get_validation_errors_accumulated();
1315
-            } else {
1316
-                $validation_errors_on_this_subsection = $subsection->get_validation_errors();
1317
-            }
1318
-            if ($validation_errors_on_this_subsection) {
1319
-                $validation_errors = array_merge($validation_errors, $validation_errors_on_this_subsection);
1320
-            }
1321
-        }
1322
-        return $validation_errors;
1323
-    }
1324
-
1325
-
1326
-
1327
-    /**
1328
-     * This isn't just the name of an input, it's a path pointing to an input. The
1329
-     * path is similar to a folder path: slash (/) means to descend into a subsection,
1330
-     * dot-dot-slash (../) means to ascend into the parent section.
1331
-     * After a series of slashes and dot-dot-slashes, there should be the name of an input,
1332
-     * which will be returned.
1333
-     * Eg, if you want the related input to be conditional on a sibling input name 'foobar'
1334
-     * just use 'foobar'. If you want it to be conditional on an aunt/uncle input name
1335
-     * 'baz', use '../baz'. If you want it to be conditional on a cousin input,
1336
-     * the child of 'baz_section' named 'baz_child', use '../baz_section/baz_child'.
1337
-     * Etc
1338
-     *
1339
-     * @param string|false $form_section_path we accept false also because substr( '../', '../' ) = false
1340
-     * @return EE_Form_Section_Base
1341
-     */
1342
-    public function find_section_from_path($form_section_path)
1343
-    {
1344
-        //check if we can find the input from purely going straight up the tree
1345
-        $input = parent::find_section_from_path($form_section_path);
1346
-        if ($input instanceof EE_Form_Section_Base) {
1347
-            return $input;
1348
-        }
1349
-        $next_slash_pos = strpos($form_section_path, '/');
1350
-        if ($next_slash_pos !== false) {
1351
-            $child_section_name = substr($form_section_path, 0, $next_slash_pos);
1352
-            $subpath = substr($form_section_path, $next_slash_pos + 1);
1353
-        } else {
1354
-            $child_section_name = $form_section_path;
1355
-            $subpath = '';
1356
-        }
1357
-        $child_section = $this->get_subsection($child_section_name);
1358
-        if ($child_section instanceof EE_Form_Section_Base) {
1359
-            return $child_section->find_section_from_path($subpath);
1360
-        } else {
1361
-            return null;
1362
-        }
1363
-    }
16
+	const SUBMITTED_FORM_DATA_SSN_KEY = 'submitted_form_data';
17
+
18
+	/**
19
+	 * Subsections
20
+	 *
21
+	 * @var EE_Form_Section_Validatable[]
22
+	 */
23
+	protected $_subsections = array();
24
+
25
+	/**
26
+	 * Strategy for laying out the form
27
+	 *
28
+	 * @var EE_Form_Section_Layout_Base
29
+	 */
30
+	protected $_layout_strategy;
31
+
32
+	/**
33
+	 * Whether or not this form has received and validated a form submission yet
34
+	 *
35
+	 * @var boolean
36
+	 */
37
+	protected $_received_submission = false;
38
+
39
+	/**
40
+	 * message displayed to users upon successful form submission
41
+	 *
42
+	 * @var string
43
+	 */
44
+	protected $_form_submission_success_message = '';
45
+
46
+	/**
47
+	 * message displayed to users upon unsuccessful form submission
48
+	 *
49
+	 * @var string
50
+	 */
51
+	protected $_form_submission_error_message = '';
52
+
53
+	/**
54
+	 * Stores all the data that will localized for form validation
55
+	 *
56
+	 * @var array
57
+	 */
58
+	static protected $_js_localization = array();
59
+
60
+	/**
61
+	 * whether or not the form's localized validation JS vars have been set
62
+	 *
63
+	 * @type boolean
64
+	 */
65
+	static protected $_scripts_localized = false;
66
+
67
+
68
+
69
+	/**
70
+	 * when constructing a proper form section, calls _construct_finalize on children
71
+	 * so that they know who their parent is, and what name they've been given.
72
+	 *
73
+	 * @param array $options_array   {
74
+	 * @type        $subsections     EE_Form_Section_Validatable[] where keys are the section's name
75
+	 * @type        $include         string[] numerically-indexed where values are section names to be included,
76
+	 *                               and in that order. This is handy if you want
77
+	 *                               the subsections to be ordered differently than the default, and if you override
78
+	 *                               which fields are shown
79
+	 * @type        $exclude         string[] values are subsections to be excluded. This is handy if you want
80
+	 *                               to remove certain default subsections (note: if you specify BOTH 'include' AND
81
+	 *                               'exclude', the inclusions will be applied first, and the exclusions will exclude
82
+	 *                               items from that list of inclusions)
83
+	 * @type        $layout_strategy EE_Form_Section_Layout_Base strategy for laying out the form
84
+	 *                               } @see EE_Form_Section_Validatable::__construct()
85
+	 * @throws \EE_Error
86
+	 */
87
+	public function __construct($options_array = array())
88
+	{
89
+		$options_array = (array)apply_filters('FHEE__EE_Form_Section_Proper___construct__options_array', $options_array,
90
+			$this);
91
+		//call parent first, as it may be setting the name
92
+		parent::__construct($options_array);
93
+		//if they've included subsections in the constructor, add them now
94
+		if (isset($options_array['include'])) {
95
+			//we are going to make sure we ONLY have those subsections to include
96
+			//AND we are going to make sure they're in that specified order
97
+			$reordered_subsections = array();
98
+			foreach ($options_array['include'] as $input_name) {
99
+				if (isset($this->_subsections[$input_name])) {
100
+					$reordered_subsections[$input_name] = $this->_subsections[$input_name];
101
+				}
102
+			}
103
+			$this->_subsections = $reordered_subsections;
104
+		}
105
+		if (isset($options_array['exclude'])) {
106
+			$exclude = $options_array['exclude'];
107
+			$this->_subsections = array_diff_key($this->_subsections, array_flip($exclude));
108
+		}
109
+		if (isset($options_array['layout_strategy'])) {
110
+			$this->_layout_strategy = $options_array['layout_strategy'];
111
+		}
112
+		if ( ! $this->_layout_strategy) {
113
+			$this->_layout_strategy = is_admin() ? new EE_Admin_Two_Column_Layout() : new EE_Two_Column_Layout();
114
+		}
115
+		$this->_layout_strategy->_construct_finalize($this);
116
+		//ok so we are definitely going to want the forms JS,
117
+		//so enqueue it or remember to enqueue it during wp_enqueue_scripts
118
+		if (did_action('wp_enqueue_scripts')
119
+			|| did_action('admin_enqueue_scripts')
120
+		) {
121
+			//ok so they've constructed this object after when they should have.
122
+			//just enqueue the generic form scripts and initialize the form immediately in the JS
123
+			\EE_Form_Section_Proper::wp_enqueue_scripts(true);
124
+		} else {
125
+			add_action('wp_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts'));
126
+			add_action('admin_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts'));
127
+		}
128
+		add_action('wp_footer', array($this, 'ensure_scripts_localized'), 1);
129
+		if (isset($options_array['name'])) {
130
+			$this->_construct_finalize(null, $options_array['name']);
131
+		}
132
+	}
133
+
134
+
135
+
136
+	/**
137
+	 * Finishes construction given the parent form section and this form section's name
138
+	 *
139
+	 * @param EE_Form_Section_Proper $parent_form_section
140
+	 * @param string                 $name
141
+	 * @throws \EE_Error
142
+	 */
143
+	public function _construct_finalize($parent_form_section, $name)
144
+	{
145
+		parent::_construct_finalize($parent_form_section, $name);
146
+		$this->_set_default_name_if_empty();
147
+		$this->_set_default_html_id_if_empty();
148
+		foreach ($this->_subsections as $subsection_name => $subsection) {
149
+			if ($subsection instanceof EE_Form_Section_Base) {
150
+				$subsection->_construct_finalize($this, $subsection_name);
151
+			} else {
152
+				throw new EE_Error(
153
+					sprintf(
154
+						__('Subsection "%s" is not an instanceof EE_Form_Section_Base on form "%s". It is a "%s"',
155
+							'event_espresso'),
156
+						$subsection_name,
157
+						get_class($this),
158
+						$subsection ? get_class($subsection) : __('NULL', 'event_espresso')
159
+					)
160
+				);
161
+			}
162
+		}
163
+		do_action('AHEE__EE_Form_Section_Proper___construct_finalize__end', $this, $parent_form_section, $name);
164
+	}
165
+
166
+
167
+
168
+	/**
169
+	 * Gets the layout strategy for this form section
170
+	 *
171
+	 * @return EE_Form_Section_Layout_Base
172
+	 */
173
+	public function get_layout_strategy()
174
+	{
175
+		return $this->_layout_strategy;
176
+	}
177
+
178
+
179
+
180
+	/**
181
+	 * Gets the HTML for a single input for this form section according
182
+	 * to the layout strategy
183
+	 *
184
+	 * @param EE_Form_Input_Base $input
185
+	 * @return string
186
+	 */
187
+	public function get_html_for_input($input)
188
+	{
189
+		return $this->_layout_strategy->layout_input($input);
190
+	}
191
+
192
+
193
+
194
+	/**
195
+	 * was_submitted - checks if form inputs are present in request data
196
+	 * Basically an alias for form_data_present_in() (which is used by both
197
+	 * proper form sections and form inputs)
198
+	 *
199
+	 * @param null $form_data
200
+	 * @return boolean
201
+	 */
202
+	public function was_submitted($form_data = null)
203
+	{
204
+		return $this->form_data_present_in($form_data);
205
+	}
206
+
207
+
208
+
209
+	/**
210
+	 * After the form section is initially created, call this to sanitize the data in the submission
211
+	 * which relates to this form section, validate it, and set it as properties on the form.
212
+	 *
213
+	 * @param array|null $req_data should usually be $_POST (the default).
214
+	 *                             However, you CAN supply a different array.
215
+	 *                             Consider using set_defaults() instead however.
216
+	 *                             (If you rendered the form in the page using echo $form_x->get_html()
217
+	 *                             the inputs will have the correct name in the request data for this function
218
+	 *                             to find them and populate the form with them.
219
+	 *                             If you have a flat form (with only input subsections),
220
+	 *                             you can supply a flat array where keys
221
+	 *                             are the form input names and values are their values)
222
+	 * @param boolean    $validate whether or not to perform validation on this data. Default is,
223
+	 *                             of course, to validate that data, and set errors on the invalid values.
224
+	 *                             But if the data has already been validated
225
+	 *                             (eg you validated the data then stored it in the DB)
226
+	 *                             you may want to skip this step.
227
+	 */
228
+	public function receive_form_submission($req_data = null, $validate = true)
229
+	{
230
+		$req_data = apply_filters('FHEE__EE_Form_Section_Proper__receive_form_submission__req_data', $req_data, $this,
231
+			$validate);
232
+		if ($req_data === null) {
233
+			$req_data = array_merge($_GET, $_POST);
234
+		}
235
+		$req_data = apply_filters('FHEE__EE_Form_Section_Proper__receive_form_submission__request_data', $req_data,
236
+			$this);
237
+		$this->_normalize($req_data);
238
+		if ($validate) {
239
+			$this->_validate();
240
+			//if it's invalid, we're going to want to re-display so remember what they submitted
241
+			if ( ! $this->is_valid()) {
242
+				$this->store_submitted_form_data_in_session();
243
+			}
244
+		}
245
+		do_action('AHEE__EE_Form_Section_Proper__receive_form_submission__end', $req_data, $this, $validate);
246
+	}
247
+
248
+
249
+
250
+	/**
251
+	 * caches the originally submitted input values in the session
252
+	 * so that they can be used to repopulate the form if it failed validation
253
+	 *
254
+	 * @return boolean whether or not the data was successfully stored in the session
255
+	 */
256
+	protected function store_submitted_form_data_in_session()
257
+	{
258
+		return EE_Registry::instance()->SSN->set_session_data(
259
+			array(
260
+				\EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY => $this->submitted_values(true),
261
+			)
262
+		);
263
+	}
264
+
265
+
266
+
267
+	/**
268
+	 * retrieves the originally submitted input values in the session
269
+	 * so that they can be used to repopulate the form if it failed validation
270
+	 *
271
+	 * @return array
272
+	 */
273
+	protected function get_submitted_form_data_from_session()
274
+	{
275
+		$session = EE_Registry::instance()->SSN;
276
+		if ($session instanceof EE_Session) {
277
+			return $session->get_session_data(
278
+				\EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY
279
+			);
280
+		} else {
281
+			return array();
282
+		}
283
+	}
284
+
285
+
286
+
287
+	/**
288
+	 * flushed the originally submitted input values from the session
289
+	 *
290
+	 * @return boolean whether or not the data was successfully removed from the session
291
+	 */
292
+	protected function flush_submitted_form_data_from_session()
293
+	{
294
+		return EE_Registry::instance()->SSN->reset_data(
295
+			array(\EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY)
296
+		);
297
+	}
298
+
299
+
300
+
301
+	/**
302
+	 * Populates this form and its subsections with data from the session.
303
+	 * (Wrapper for EE_Form_Section_Proper::receive_form_submission, so it shows
304
+	 * validation errors when displaying too)
305
+	 * Returns true if the form was populated from the session, false otherwise
306
+	 *
307
+	 * @return boolean
308
+	 */
309
+	public function populate_from_session()
310
+	{
311
+		$form_data_in_session = $this->get_submitted_form_data_from_session();
312
+		if (empty($form_data_in_session)) {
313
+			return false;
314
+		}
315
+		$this->receive_form_submission($form_data_in_session);
316
+		$this->flush_submitted_form_data_from_session();
317
+		if ($this->form_data_present_in($form_data_in_session)) {
318
+			return true;
319
+		} else {
320
+			return false;
321
+		}
322
+	}
323
+
324
+
325
+
326
+	/**
327
+	 * Populates the default data for the form, given an array where keys are
328
+	 * the input names, and values are their values (preferably normalized to be their
329
+	 * proper PHP types, not all strings... although that should be ok too).
330
+	 * Proper subsections are sub-arrays, the key being the subsection's name, and
331
+	 * the value being an array formatted in teh same way
332
+	 *
333
+	 * @param array $default_data
334
+	 */
335
+	public function populate_defaults($default_data)
336
+	{
337
+		foreach ($this->subsections() as $subsection_name => $subsection) {
338
+			if (isset($default_data[$subsection_name])) {
339
+				if ($subsection instanceof EE_Form_Input_Base) {
340
+					$subsection->set_default($default_data[$subsection_name]);
341
+				} elseif ($subsection instanceof EE_Form_Section_Proper) {
342
+					$subsection->populate_defaults($default_data[$subsection_name]);
343
+				}
344
+			}
345
+		}
346
+	}
347
+
348
+
349
+
350
+	/**
351
+	 * returns true if subsection exists
352
+	 *
353
+	 * @param string $name
354
+	 * @return boolean
355
+	 */
356
+	public function subsection_exists($name)
357
+	{
358
+		return isset($this->_subsections[$name]) ? true : false;
359
+	}
360
+
361
+
362
+
363
+	/**
364
+	 * Gets the subsection specified by its name
365
+	 *
366
+	 * @param string  $name
367
+	 * @param boolean $require_construction_to_be_finalized most client code should leave this as TRUE
368
+	 *                                                      so that the inputs will be properly configured.
369
+	 *                                                      However, some client code may be ok
370
+	 *                                                      with construction finalize being called later
371
+	 *                                                      (realizing that the subsections' html names
372
+	 *                                                      might not be set yet, etc.)
373
+	 * @return EE_Form_Section_Base
374
+	 * @throws \EE_Error
375
+	 */
376
+	public function get_subsection($name, $require_construction_to_be_finalized = true)
377
+	{
378
+		if ($require_construction_to_be_finalized) {
379
+			$this->ensure_construct_finalized_called();
380
+		}
381
+		return $this->subsection_exists($name) ? $this->_subsections[$name] : null;
382
+	}
383
+
384
+
385
+
386
+	/**
387
+	 * Gets all the validatable subsections of this form section
388
+	 *
389
+	 * @return EE_Form_Section_Validatable[]
390
+	 */
391
+	public function get_validatable_subsections()
392
+	{
393
+		$validatable_subsections = array();
394
+		foreach ($this->subsections() as $name => $obj) {
395
+			if ($obj instanceof EE_Form_Section_Validatable) {
396
+				$validatable_subsections[$name] = $obj;
397
+			}
398
+		}
399
+		return $validatable_subsections;
400
+	}
401
+
402
+
403
+
404
+	/**
405
+	 * Gets an input by the given name. If not found, or if its not an EE_FOrm_Input_Base child,
406
+	 * throw an EE_Error.
407
+	 *
408
+	 * @param string  $name
409
+	 * @param boolean $require_construction_to_be_finalized most client code should
410
+	 *                                                      leave this as TRUE so that the inputs will be properly
411
+	 *                                                      configured. However, some client code may be ok with
412
+	 *                                                      construction finalize being called later
413
+	 *                                                      (realizing that the subsections' html names might not be
414
+	 *                                                      set yet, etc.)
415
+	 * @return EE_Form_Input_Base
416
+	 * @throws EE_Error
417
+	 */
418
+	public function get_input($name, $require_construction_to_be_finalized = true)
419
+	{
420
+		$subsection = $this->get_subsection($name, $require_construction_to_be_finalized);
421
+		if ( ! $subsection instanceof EE_Form_Input_Base) {
422
+			throw new EE_Error(
423
+				sprintf(
424
+					__(
425
+						"Subsection '%s' is not an instanceof EE_Form_Input_Base on form '%s'. It is a '%s'",
426
+						'event_espresso'
427
+					),
428
+					$name,
429
+					get_class($this),
430
+					$subsection ? get_class($subsection) : __("NULL", 'event_espresso')
431
+				)
432
+			);
433
+		}
434
+		return $subsection;
435
+	}
436
+
437
+
438
+
439
+	/**
440
+	 * Like get_input(), gets the proper subsection of the form given the name,
441
+	 * otherwise throws an EE_Error
442
+	 *
443
+	 * @param string  $name
444
+	 * @param boolean $require_construction_to_be_finalized most client code should
445
+	 *                                                      leave this as TRUE so that the inputs will be properly
446
+	 *                                                      configured. However, some client code may be ok with
447
+	 *                                                      construction finalize being called later
448
+	 *                                                      (realizing that the subsections' html names might not be
449
+	 *                                                      set yet, etc.)
450
+	 * @return EE_Form_Section_Proper
451
+	 * @throws EE_Error
452
+	 */
453
+	public function get_proper_subsection($name, $require_construction_to_be_finalized = true)
454
+	{
455
+		$subsection = $this->get_subsection($name, $require_construction_to_be_finalized);
456
+		if ( ! $subsection instanceof EE_Form_Section_Proper) {
457
+			throw new EE_Error(
458
+				sprintf(
459
+					__("Subsection '%'s is not an instanceof EE_Form_Section_Proper on form '%s'", 'event_espresso'),
460
+					$name,
461
+					get_class($this)
462
+				)
463
+			);
464
+		}
465
+		return $subsection;
466
+	}
467
+
468
+
469
+
470
+	/**
471
+	 * Gets the value of the specified input. Should be called after receive_form_submission()
472
+	 * or populate_defaults() on the form, where the normalized value on the input is set.
473
+	 *
474
+	 * @param string $name
475
+	 * @return mixed depending on the input's type and its normalization strategy
476
+	 * @throws \EE_Error
477
+	 */
478
+	public function get_input_value($name)
479
+	{
480
+		$input = $this->get_input($name);
481
+		return $input->normalized_value();
482
+	}
483
+
484
+
485
+
486
+	/**
487
+	 * Checks if this form section itself is valid, and then checks its subsections
488
+	 *
489
+	 * @throws EE_Error
490
+	 * @return boolean
491
+	 */
492
+	public function is_valid()
493
+	{
494
+		if ( ! $this->has_received_submission()) {
495
+			throw new EE_Error(
496
+				sprintf(
497
+					__(
498
+						"You cannot check if a form is valid before receiving the form submission using receive_form_submission",
499
+						"event_espresso"
500
+					)
501
+				)
502
+			);
503
+		}
504
+		if ( ! parent::is_valid()) {
505
+			return false;
506
+		}
507
+		// ok so no general errors to this entire form section.
508
+		// so let's check the subsections, but only set errors if that hasn't been done yet
509
+		$set_submission_errors = $this->submission_error_message() === '' ? true : false;
510
+		foreach ($this->get_validatable_subsections() as $subsection) {
511
+			if ( ! $subsection->is_valid() || $subsection->get_validation_error_string() !== '') {
512
+				if ($set_submission_errors) {
513
+					$this->set_submission_error_message($subsection->get_validation_error_string());
514
+				}
515
+				return false;
516
+			}
517
+		}
518
+		return true;
519
+	}
520
+
521
+
522
+
523
+	/**
524
+	 * gets teh default name of this form section if none is specified
525
+	 *
526
+	 * @return string
527
+	 */
528
+	protected function _set_default_name_if_empty()
529
+	{
530
+		if ( ! $this->_name) {
531
+			$classname = get_class($this);
532
+			$default_name = str_replace("EE_", "", $classname);
533
+			$this->_name = $default_name;
534
+		}
535
+	}
536
+
537
+
538
+
539
+	/**
540
+	 * Returns the HTML for the form, except for the form opening and closing tags
541
+	 * (as the form section doesn't know where you necessarily want to send the information to),
542
+	 * and except for a submit button. Enqueus JS and CSS; if called early enough we will
543
+	 * try to enqueue them in the header, otherwise they'll be enqueued in the footer.
544
+	 * Not doing_it_wrong because theoretically this CAN be used properly,
545
+	 * provided its used during "wp_enqueue_scripts", or it doesn't need to enqueue
546
+	 * any CSS.
547
+	 *
548
+	 * @throws \EE_Error
549
+	 */
550
+	public function get_html_and_js()
551
+	{
552
+		$this->enqueue_js();
553
+		return $this->get_html();
554
+	}
555
+
556
+
557
+
558
+	/**
559
+	 * returns HTML for displaying this form section. recursively calls display_section() on all subsections
560
+	 *
561
+	 * @param bool $display_previously_submitted_data
562
+	 * @return string
563
+	 */
564
+	public function get_html($display_previously_submitted_data = true)
565
+	{
566
+		$this->ensure_construct_finalized_called();
567
+		if ($display_previously_submitted_data) {
568
+			$this->populate_from_session();
569
+		}
570
+		return $this->_layout_strategy->layout_form();
571
+	}
572
+
573
+
574
+
575
+	/**
576
+	 * enqueues JS and CSS for the form.
577
+	 * It is preferred to call this before wp_enqueue_scripts so the
578
+	 * scripts and styles can be put in the header, but if called later
579
+	 * they will be put in the footer (which is OK for JS, but in HTML4 CSS should
580
+	 * only be in the header; but in HTML5 its ok in the body.
581
+	 * See http://stackoverflow.com/questions/4957446/load-external-css-file-in-body-tag.
582
+	 * So if your form enqueues CSS, it's preferred to call this before wp_enqueue_scripts.)
583
+	 *
584
+	 * @return string
585
+	 * @throws \EE_Error
586
+	 */
587
+	public function enqueue_js()
588
+	{
589
+		$this->_enqueue_and_localize_form_js();
590
+		foreach ($this->subsections() as $subsection) {
591
+			$subsection->enqueue_js();
592
+		}
593
+	}
594
+
595
+
596
+
597
+	/**
598
+	 * adds a filter so that jquery validate gets enqueued in EE_System::wp_enqueue_scripts().
599
+	 * This must be done BEFORE wp_enqueue_scripts() gets called, which is on
600
+	 * the wp_enqueue_scripts hook.
601
+	 * However, registering the form js and localizing it can happen when we
602
+	 * actually output the form (which is preferred, seeing how teh form's fields
603
+	 * could change until it's actually outputted)
604
+	 *
605
+	 * @param boolean $init_form_validation_automatically whether or not we want the form validation
606
+	 *                                                    to be triggered automatically or not
607
+	 * @return void
608
+	 */
609
+	public static function wp_enqueue_scripts($init_form_validation_automatically = true)
610
+	{
611
+		add_filter('FHEE_load_jquery_validate', '__return_true');
612
+		wp_register_script(
613
+			'ee_form_section_validation',
614
+			EE_GLOBAL_ASSETS_URL . 'scripts' . DS . 'form_section_validation.js',
615
+			array('jquery-validate', 'jquery-ui-datepicker', 'jquery-validate-extra-methods'),
616
+			EVENT_ESPRESSO_VERSION,
617
+			true
618
+		);
619
+		wp_localize_script(
620
+			'ee_form_section_validation',
621
+			'ee_form_section_validation_init',
622
+			array('init' => $init_form_validation_automatically ? true : false)
623
+		);
624
+	}
625
+
626
+
627
+
628
+	/**
629
+	 * gets the variables used by form_section_validation.js.
630
+	 * This needs to be called AFTER we've called $this->_enqueue_jquery_validate_script,
631
+	 * but before the wordpress hook wp_loaded
632
+	 *
633
+	 * @throws \EE_Error
634
+	 */
635
+	public function _enqueue_and_localize_form_js()
636
+	{
637
+		$this->ensure_construct_finalized_called();
638
+		//actually, we don't want to localize just yet. There may be other forms on the page.
639
+		//so we need to add our form section data to a static variable accessible by all form sections
640
+		//and localize it just before the footer
641
+		$this->localize_validation_rules();
642
+		add_action('wp_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'), 2);
643
+		add_action('admin_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'));
644
+	}
645
+
646
+
647
+
648
+	/**
649
+	 * add our form section data to a static variable accessible by all form sections
650
+	 *
651
+	 * @param bool $return_for_subsection
652
+	 * @return void
653
+	 * @throws \EE_Error
654
+	 */
655
+	public function localize_validation_rules($return_for_subsection = false)
656
+	{
657
+		// we only want to localize vars ONCE for the entire form,
658
+		// so if the form section doesn't have a parent, then it must be the top dog
659
+		if ($return_for_subsection || ! $this->parent_section()) {
660
+			EE_Form_Section_Proper::$_js_localization['form_data'][$this->html_id()] = array(
661
+				'form_section_id'  => $this->html_id(true),
662
+				'validation_rules' => $this->get_jquery_validation_rules(),
663
+				'other_data'       => $this->get_other_js_data(),
664
+				'errors'           => $this->subsection_validation_errors_by_html_name(),
665
+			);
666
+			EE_Form_Section_Proper::$_scripts_localized = true;
667
+		}
668
+	}
669
+
670
+
671
+
672
+	/**
673
+	 * Gets an array of extra data that will be useful for client-side javascript.
674
+	 * This is primarily data added by inputs and forms in addition to any
675
+	 * scripts they might enqueue
676
+	 *
677
+	 * @param array $form_other_js_data
678
+	 * @return array
679
+	 */
680
+	public function get_other_js_data($form_other_js_data = array())
681
+	{
682
+		foreach ($this->subsections() as $subsection) {
683
+			$form_other_js_data = $subsection->get_other_js_data($form_other_js_data);
684
+		}
685
+		return $form_other_js_data;
686
+	}
687
+
688
+
689
+
690
+	/**
691
+	 * Gets a flat array of inputs for this form section and its subsections.
692
+	 * Keys are their form names, and values are the inputs themselves
693
+	 *
694
+	 * @return EE_Form_Input_Base
695
+	 */
696
+	public function inputs_in_subsections()
697
+	{
698
+		$inputs = array();
699
+		foreach ($this->subsections() as $subsection) {
700
+			if ($subsection instanceof EE_Form_Input_Base) {
701
+				$inputs[$subsection->html_name()] = $subsection;
702
+			} elseif ($subsection instanceof EE_Form_Section_Proper) {
703
+				$inputs += $subsection->inputs_in_subsections();
704
+			}
705
+		}
706
+		return $inputs;
707
+	}
708
+
709
+
710
+
711
+	/**
712
+	 * Gets a flat array of all the validation errors.
713
+	 * Keys are html names (because those should be unique)
714
+	 * and values are a string of all their validation errors
715
+	 *
716
+	 * @return string[]
717
+	 */
718
+	public function subsection_validation_errors_by_html_name()
719
+	{
720
+		$inputs = $this->inputs();
721
+		$errors = array();
722
+		foreach ($inputs as $form_input) {
723
+			if ($form_input instanceof EE_Form_Input_Base && $form_input->get_validation_errors()) {
724
+				$errors[$form_input->html_name()] = $form_input->get_validation_error_string();
725
+			}
726
+		}
727
+		return $errors;
728
+	}
729
+
730
+
731
+
732
+	/**
733
+	 * passes all the form data required by the JS to the JS, and enqueues the few required JS files.
734
+	 * Should be setup by each form during the _enqueues_and_localize_form_js
735
+	 */
736
+	public static function localize_script_for_all_forms()
737
+	{
738
+		//allow inputs and stuff to hook in their JS and stuff here
739
+		do_action('AHEE__EE_Form_Section_Proper__localize_script_for_all_forms__begin');
740
+		EE_Form_Section_Proper::$_js_localization['localized_error_messages'] = EE_Form_Section_Proper::_get_localized_error_messages();
741
+		$email_validation_level = isset(EE_Registry::instance()->CFG->registration->email_validation_level)
742
+			? EE_Registry::instance()->CFG->registration->email_validation_level
743
+			: 'wp_default';
744
+		EE_Form_Section_Proper::$_js_localization['email_validation_level'] = $email_validation_level;
745
+		wp_enqueue_script('ee_form_section_validation');
746
+		wp_localize_script(
747
+			'ee_form_section_validation',
748
+			'ee_form_section_vars',
749
+			EE_Form_Section_Proper::$_js_localization
750
+		);
751
+	}
752
+
753
+
754
+
755
+	/**
756
+	 * ensure_scripts_localized
757
+	 */
758
+	public function ensure_scripts_localized()
759
+	{
760
+		if ( ! EE_Form_Section_Proper::$_scripts_localized) {
761
+			$this->_enqueue_and_localize_form_js();
762
+		}
763
+	}
764
+
765
+
766
+
767
+	/**
768
+	 * Gets the hard-coded validation error messages to be used in the JS. The convention
769
+	 * is that the key here should be the same as the custom validation rule put in the JS file
770
+	 *
771
+	 * @return array keys are custom validation rules, and values are internationalized strings
772
+	 */
773
+	private static function _get_localized_error_messages()
774
+	{
775
+		return array(
776
+			'validUrl' => __("This is not a valid absolute URL. Eg, http://domain.com/monkey.jpg", "event_espresso"),
777
+			'regex'    => __('Please check your input', 'event_espresso'),
778
+		);
779
+	}
780
+
781
+
782
+
783
+	/**
784
+	 * @return array
785
+	 */
786
+	public static function js_localization()
787
+	{
788
+		return self::$_js_localization;
789
+	}
790
+
791
+
792
+
793
+	/**
794
+	 * @return array
795
+	 */
796
+	public static function reset_js_localization()
797
+	{
798
+		self::$_js_localization = array();
799
+	}
800
+
801
+
802
+
803
+	/**
804
+	 * Gets the JS to put inside the jquery validation rules for subsection of this form section.
805
+	 * See parent function for more...
806
+	 *
807
+	 * @return array
808
+	 */
809
+	public function get_jquery_validation_rules()
810
+	{
811
+		$jquery_validation_rules = array();
812
+		foreach ($this->get_validatable_subsections() as $subsection) {
813
+			$jquery_validation_rules = array_merge(
814
+				$jquery_validation_rules,
815
+				$subsection->get_jquery_validation_rules()
816
+			);
817
+		}
818
+		return $jquery_validation_rules;
819
+	}
820
+
821
+
822
+
823
+	/**
824
+	 * Sanitizes all the data and sets the sanitized value of each field
825
+	 *
826
+	 * @param array $req_data like $_POST
827
+	 * @return void
828
+	 */
829
+	protected function _normalize($req_data)
830
+	{
831
+		$this->_received_submission = true;
832
+		$this->_validation_errors = array();
833
+		foreach ($this->get_validatable_subsections() as $subsection) {
834
+			try {
835
+				$subsection->_normalize($req_data);
836
+			} catch (EE_Validation_Error $e) {
837
+				$subsection->add_validation_error($e);
838
+			}
839
+		}
840
+	}
841
+
842
+
843
+
844
+	/**
845
+	 * Performs validation on this form section and its subsections.
846
+	 * For each subsection,
847
+	 * calls _validate_{subsection_name} on THIS form (if the function exists)
848
+	 * and passes it the subsection, then calls _validate on that subsection.
849
+	 * If you need to perform validation on the form as a whole (considering multiple)
850
+	 * you would be best to override this _validate method,
851
+	 * calling parent::_validate() first.
852
+	 */
853
+	protected function _validate()
854
+	{
855
+		foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) {
856
+			if (method_exists($this, '_validate_' . $subsection_name)) {
857
+				call_user_func_array(array($this, '_validate_' . $subsection_name), array($subsection));
858
+			}
859
+			$subsection->_validate();
860
+		}
861
+	}
862
+
863
+
864
+
865
+	/**
866
+	 * Gets all the validated inputs for the form section
867
+	 *
868
+	 * @return array
869
+	 */
870
+	public function valid_data()
871
+	{
872
+		$inputs = array();
873
+		foreach ($this->subsections() as $subsection_name => $subsection) {
874
+			if ($subsection instanceof EE_Form_Section_Proper) {
875
+				$inputs[$subsection_name] = $subsection->valid_data();
876
+			} else if ($subsection instanceof EE_Form_Input_Base) {
877
+				$inputs[$subsection_name] = $subsection->normalized_value();
878
+			}
879
+		}
880
+		return $inputs;
881
+	}
882
+
883
+
884
+
885
+	/**
886
+	 * Gets all the inputs on this form section
887
+	 *
888
+	 * @return EE_Form_Input_Base[]
889
+	 */
890
+	public function inputs()
891
+	{
892
+		$inputs = array();
893
+		foreach ($this->subsections() as $subsection_name => $subsection) {
894
+			if ($subsection instanceof EE_Form_Input_Base) {
895
+				$inputs[$subsection_name] = $subsection;
896
+			}
897
+		}
898
+		return $inputs;
899
+	}
900
+
901
+
902
+
903
+	/**
904
+	 * Gets all the subsections which are a proper form
905
+	 *
906
+	 * @return EE_Form_Section_Proper[]
907
+	 */
908
+	public function subforms()
909
+	{
910
+		$form_sections = array();
911
+		foreach ($this->subsections() as $name => $obj) {
912
+			if ($obj instanceof EE_Form_Section_Proper) {
913
+				$form_sections[$name] = $obj;
914
+			}
915
+		}
916
+		return $form_sections;
917
+	}
918
+
919
+
920
+
921
+	/**
922
+	 * Gets all the subsections (inputs, proper subsections, or html-only sections).
923
+	 * Consider using inputs() or subforms()
924
+	 * if you only want form inputs or proper form sections.
925
+	 *
926
+	 * @return EE_Form_Section_Proper[]
927
+	 */
928
+	public function subsections()
929
+	{
930
+		$this->ensure_construct_finalized_called();
931
+		return $this->_subsections;
932
+	}
933
+
934
+
935
+
936
+	/**
937
+	 * Returns a simple array where keys are input names, and values are their normalized
938
+	 * values. (Similar to calling get_input_value on inputs)
939
+	 *
940
+	 * @param boolean $include_subform_inputs Whether to include inputs from subforms,
941
+	 *                                        or just this forms' direct children inputs
942
+	 * @param boolean $flatten                Whether to force the results into 1-dimensional array,
943
+	 *                                        or allow multidimensional array
944
+	 * @return array if $flatten is TRUE it will always be a 1-dimensional array
945
+	 *                                        with array keys being input names
946
+	 *                                        (regardless of whether they are from a subsection or not),
947
+	 *                                        and if $flatten is FALSE it can be a multidimensional array
948
+	 *                                        where keys are always subsection names and values are either
949
+	 *                                        the input's normalized value, or an array like the top-level array
950
+	 */
951
+	public function input_values($include_subform_inputs = false, $flatten = false)
952
+	{
953
+		return $this->_input_values(false, $include_subform_inputs, $flatten);
954
+	}
955
+
956
+
957
+
958
+	/**
959
+	 * Similar to EE_Form_Section_Proper::input_values(), except this returns the 'display_value'
960
+	 * of each input. On some inputs (especially radio boxes or checkboxes), the value stored
961
+	 * is not necessarily the value we want to display to users. This creates an array
962
+	 * where keys are the input names, and values are their display values
963
+	 *
964
+	 * @param boolean $include_subform_inputs Whether to include inputs from subforms,
965
+	 *                                        or just this forms' direct children inputs
966
+	 * @param boolean $flatten                Whether to force the results into 1-dimensional array,
967
+	 *                                        or allow multidimensional array
968
+	 * @return array if $flatten is TRUE it will always be a 1-dimensional array
969
+	 *                                        with array keys being input names
970
+	 *                                        (regardless of whether they are from a subsection or not),
971
+	 *                                        and if $flatten is FALSE it can be a multidimensional array
972
+	 *                                        where keys are always subsection names and values are either
973
+	 *                                        the input's normalized value, or an array like the top-level array
974
+	 */
975
+	public function input_pretty_values($include_subform_inputs = false, $flatten = false)
976
+	{
977
+		return $this->_input_values(true, $include_subform_inputs, $flatten);
978
+	}
979
+
980
+
981
+
982
+	/**
983
+	 * Gets the input values from the form
984
+	 *
985
+	 * @param boolean $pretty                 Whether to retrieve the pretty value,
986
+	 *                                        or just the normalized value
987
+	 * @param boolean $include_subform_inputs Whether to include inputs from subforms,
988
+	 *                                        or just this forms' direct children inputs
989
+	 * @param boolean $flatten                Whether to force the results into 1-dimensional array,
990
+	 *                                        or allow multidimensional array
991
+	 * @return array if $flatten is TRUE it will always be a 1-dimensional array with array keys being
992
+	 *                                        input names (regardless of whether they are from a subsection or not),
993
+	 *                                        and if $flatten is FALSE it can be a multidimensional array
994
+	 *                                        where keys are always subsection names and values are either
995
+	 *                                        the input's normalized value, or an array like the top-level array
996
+	 */
997
+	public function _input_values($pretty = false, $include_subform_inputs = false, $flatten = false)
998
+	{
999
+		$input_values = array();
1000
+		foreach ($this->subsections() as $subsection_name => $subsection) {
1001
+			if ($subsection instanceof EE_Form_Input_Base) {
1002
+				$input_values[$subsection_name] = $pretty
1003
+					? $subsection->pretty_value()
1004
+					: $subsection->normalized_value();
1005
+			} else if ($subsection instanceof EE_Form_Section_Proper && $include_subform_inputs) {
1006
+				$subform_input_values = $subsection->_input_values($pretty, $include_subform_inputs, $flatten);
1007
+				if ($flatten) {
1008
+					$input_values = array_merge($input_values, $subform_input_values);
1009
+				} else {
1010
+					$input_values[$subsection_name] = $subform_input_values;
1011
+				}
1012
+			}
1013
+		}
1014
+		return $input_values;
1015
+	}
1016
+
1017
+
1018
+
1019
+	/**
1020
+	 * Gets the originally submitted input values from the form
1021
+	 *
1022
+	 * @param boolean $include_subforms  Whether to include inputs from subforms,
1023
+	 *                                   or just this forms' direct children inputs
1024
+	 * @return array                     if $flatten is TRUE it will always be a 1-dimensional array
1025
+	 *                                   with array keys being input names
1026
+	 *                                   (regardless of whether they are from a subsection or not),
1027
+	 *                                   and if $flatten is FALSE it can be a multidimensional array
1028
+	 *                                   where keys are always subsection names and values are either
1029
+	 *                                   the input's normalized value, or an array like the top-level array
1030
+	 */
1031
+	public function submitted_values($include_subforms = false)
1032
+	{
1033
+		$submitted_values = array();
1034
+		foreach ($this->subsections() as $subsection) {
1035
+			if ($subsection instanceof EE_Form_Input_Base) {
1036
+				// is this input part of an array of inputs?
1037
+				if (strpos($subsection->html_name(), '[') !== false) {
1038
+					$full_input_name = \EEH_Array::convert_array_values_to_keys(
1039
+						explode('[', str_replace(']', '', $subsection->html_name())),
1040
+						$subsection->raw_value()
1041
+					);
1042
+					$submitted_values = array_replace_recursive($submitted_values, $full_input_name);
1043
+				} else {
1044
+					$submitted_values[$subsection->html_name()] = $subsection->raw_value();
1045
+				}
1046
+			} else if ($subsection instanceof EE_Form_Section_Proper && $include_subforms) {
1047
+				$subform_input_values = $subsection->submitted_values($include_subforms);
1048
+				$submitted_values = array_replace_recursive($submitted_values, $subform_input_values);
1049
+			}
1050
+		}
1051
+		return $submitted_values;
1052
+	}
1053
+
1054
+
1055
+
1056
+	/**
1057
+	 * Indicates whether or not this form has received a submission yet
1058
+	 * (ie, had receive_form_submission called on it yet)
1059
+	 *
1060
+	 * @return boolean
1061
+	 * @throws \EE_Error
1062
+	 */
1063
+	public function has_received_submission()
1064
+	{
1065
+		$this->ensure_construct_finalized_called();
1066
+		return $this->_received_submission;
1067
+	}
1068
+
1069
+
1070
+
1071
+	/**
1072
+	 * Equivalent to passing 'exclude' in the constructor's options array.
1073
+	 * Removes the listed inputs from the form
1074
+	 *
1075
+	 * @param array $inputs_to_exclude values are the input names
1076
+	 * @return void
1077
+	 */
1078
+	public function exclude(array $inputs_to_exclude = array())
1079
+	{
1080
+		foreach ($inputs_to_exclude as $input_to_exclude_name) {
1081
+			unset($this->_subsections[$input_to_exclude_name]);
1082
+		}
1083
+	}
1084
+
1085
+
1086
+
1087
+	/**
1088
+	 * @param array $inputs_to_hide
1089
+	 * @throws \EE_Error
1090
+	 */
1091
+	public function hide(array $inputs_to_hide = array())
1092
+	{
1093
+		foreach ($inputs_to_hide as $input_to_hide) {
1094
+			$input = $this->get_input($input_to_hide);
1095
+			$input->set_display_strategy(new EE_Hidden_Display_Strategy());
1096
+		}
1097
+	}
1098
+
1099
+
1100
+
1101
+	/**
1102
+	 * add_subsections
1103
+	 * Adds the listed subsections to the form section.
1104
+	 * If $subsection_name_to_target is provided,
1105
+	 * then new subsections are added before or after that subsection,
1106
+	 * otherwise to the start or end of the entire subsections array.
1107
+	 *
1108
+	 * @param EE_Form_Section_Base[] $new_subsections           array of new form subsections
1109
+	 *                                                          where keys are their names
1110
+	 * @param string                 $subsection_name_to_target an existing for section that $new_subsections
1111
+	 *                                                          should be added before or after
1112
+	 *                                                          IF $subsection_name_to_target is null,
1113
+	 *                                                          then $new_subsections will be added to
1114
+	 *                                                          the beginning or end of the entire subsections array
1115
+	 * @param boolean                $add_before                whether to add $new_subsections, before or after
1116
+	 *                                                          $subsection_name_to_target,
1117
+	 *                                                          or if $subsection_name_to_target is null,
1118
+	 *                                                          before or after entire subsections array
1119
+	 * @return void
1120
+	 * @throws \EE_Error
1121
+	 */
1122
+	public function add_subsections($new_subsections, $subsection_name_to_target = null, $add_before = true)
1123
+	{
1124
+		foreach ($new_subsections as $subsection_name => $subsection) {
1125
+			if ( ! $subsection instanceof EE_Form_Section_Base) {
1126
+				EE_Error::add_error(
1127
+					sprintf(
1128
+						__(
1129
+							"Trying to add a %s as a subsection (it was named '%s') to the form section '%s'. It was removed.",
1130
+							"event_espresso"
1131
+						),
1132
+						get_class($subsection),
1133
+						$subsection_name,
1134
+						$this->name()
1135
+					)
1136
+				);
1137
+				unset($new_subsections[$subsection_name]);
1138
+			}
1139
+		}
1140
+		$this->_subsections = EEH_Array::insert_into_array(
1141
+			$this->_subsections,
1142
+			$new_subsections,
1143
+			$subsection_name_to_target,
1144
+			$add_before
1145
+		);
1146
+		if ($this->_construction_finalized) {
1147
+			foreach ($this->_subsections as $name => $subsection) {
1148
+				$subsection->_construct_finalize($this, $name);
1149
+			}
1150
+		}
1151
+	}
1152
+
1153
+
1154
+
1155
+	/**
1156
+	 * Just gets all validatable subsections to clean their sensitive data
1157
+	 */
1158
+	public function clean_sensitive_data()
1159
+	{
1160
+		foreach ($this->get_validatable_subsections() as $subsection) {
1161
+			$subsection->clean_sensitive_data();
1162
+		}
1163
+	}
1164
+
1165
+
1166
+
1167
+	/**
1168
+	 * @param string $form_submission_error_message
1169
+	 */
1170
+	public function set_submission_error_message($form_submission_error_message = '')
1171
+	{
1172
+		$this->_form_submission_error_message .= ! empty($form_submission_error_message)
1173
+			? $form_submission_error_message
1174
+			: __('Form submission failed due to errors', 'event_espresso');
1175
+	}
1176
+
1177
+
1178
+
1179
+	/**
1180
+	 * @return string
1181
+	 */
1182
+	public function submission_error_message()
1183
+	{
1184
+		return $this->_form_submission_error_message;
1185
+	}
1186
+
1187
+
1188
+
1189
+	/**
1190
+	 * @param string $form_submission_success_message
1191
+	 */
1192
+	public function set_submission_success_message($form_submission_success_message)
1193
+	{
1194
+		$this->_form_submission_success_message .= ! empty($form_submission_success_message)
1195
+			? $form_submission_success_message
1196
+			: __('Form submitted successfully', 'event_espresso');
1197
+	}
1198
+
1199
+
1200
+
1201
+	/**
1202
+	 * @return string
1203
+	 */
1204
+	public function submission_success_message()
1205
+	{
1206
+		return $this->_form_submission_success_message;
1207
+	}
1208
+
1209
+
1210
+
1211
+	/**
1212
+	 * Returns the prefix that should be used on child of this form section for
1213
+	 * their html names. If this form section itself has a parent, prepends ITS
1214
+	 * prefix onto this form section's prefix. Used primarily by
1215
+	 * EE_Form_Input_Base::_set_default_html_name_if_empty
1216
+	 *
1217
+	 * @return string
1218
+	 * @throws \EE_Error
1219
+	 */
1220
+	public function html_name_prefix()
1221
+	{
1222
+		if ($this->parent_section() instanceof EE_Form_Section_Proper) {
1223
+			return $this->parent_section()->html_name_prefix() . '[' . $this->name() . ']';
1224
+		} else {
1225
+			return $this->name();
1226
+		}
1227
+	}
1228
+
1229
+
1230
+
1231
+	/**
1232
+	 * Gets the name, but first checks _construct_finalize has been called. If not,
1233
+	 * calls it (assumes there is no parent and that we want the name to be whatever
1234
+	 * was set, which is probably nothing, or the classname)
1235
+	 *
1236
+	 * @return string
1237
+	 * @throws \EE_Error
1238
+	 */
1239
+	public function name()
1240
+	{
1241
+		$this->ensure_construct_finalized_called();
1242
+		return parent::name();
1243
+	}
1244
+
1245
+
1246
+
1247
+	/**
1248
+	 * @return EE_Form_Section_Proper
1249
+	 * @throws \EE_Error
1250
+	 */
1251
+	public function parent_section()
1252
+	{
1253
+		$this->ensure_construct_finalized_called();
1254
+		return parent::parent_section();
1255
+	}
1256
+
1257
+
1258
+
1259
+	/**
1260
+	 * make sure construction finalized was called, otherwise children might not be ready
1261
+	 *
1262
+	 * @return void
1263
+	 * @throws \EE_Error
1264
+	 */
1265
+	public function ensure_construct_finalized_called()
1266
+	{
1267
+		if ( ! $this->_construction_finalized) {
1268
+			$this->_construct_finalize($this->_parent_section, $this->_name);
1269
+		}
1270
+	}
1271
+
1272
+
1273
+
1274
+	/**
1275
+	 * Checks if any of this form section's inputs, or any of its children's inputs,
1276
+	 * are in teh form data. If any are found, returns true. Else false
1277
+	 *
1278
+	 * @param array $req_data
1279
+	 * @return boolean
1280
+	 */
1281
+	public function form_data_present_in($req_data = null)
1282
+	{
1283
+		if ($req_data === null) {
1284
+			$req_data = $_POST;
1285
+		}
1286
+		foreach ($this->subsections() as $subsection) {
1287
+			if ($subsection instanceof EE_Form_Input_Base) {
1288
+				if ($subsection->form_data_present_in($req_data)) {
1289
+					return true;
1290
+				}
1291
+			} elseif ($subsection instanceof EE_Form_Section_Proper) {
1292
+				if ($subsection->form_data_present_in($req_data)) {
1293
+					return true;
1294
+				}
1295
+			}
1296
+		}
1297
+		return false;
1298
+	}
1299
+
1300
+
1301
+
1302
+	/**
1303
+	 * Gets validation errors for this form section and subsections
1304
+	 * Similar to EE_Form_Section_Validatable::get_validation_errors() except this
1305
+	 * gets the validation errors for ALL subsection
1306
+	 *
1307
+	 * @return EE_Validation_Error[]
1308
+	 */
1309
+	public function get_validation_errors_accumulated()
1310
+	{
1311
+		$validation_errors = $this->get_validation_errors();
1312
+		foreach ($this->get_validatable_subsections() as $subsection) {
1313
+			if ($subsection instanceof EE_Form_Section_Proper) {
1314
+				$validation_errors_on_this_subsection = $subsection->get_validation_errors_accumulated();
1315
+			} else {
1316
+				$validation_errors_on_this_subsection = $subsection->get_validation_errors();
1317
+			}
1318
+			if ($validation_errors_on_this_subsection) {
1319
+				$validation_errors = array_merge($validation_errors, $validation_errors_on_this_subsection);
1320
+			}
1321
+		}
1322
+		return $validation_errors;
1323
+	}
1324
+
1325
+
1326
+
1327
+	/**
1328
+	 * This isn't just the name of an input, it's a path pointing to an input. The
1329
+	 * path is similar to a folder path: slash (/) means to descend into a subsection,
1330
+	 * dot-dot-slash (../) means to ascend into the parent section.
1331
+	 * After a series of slashes and dot-dot-slashes, there should be the name of an input,
1332
+	 * which will be returned.
1333
+	 * Eg, if you want the related input to be conditional on a sibling input name 'foobar'
1334
+	 * just use 'foobar'. If you want it to be conditional on an aunt/uncle input name
1335
+	 * 'baz', use '../baz'. If you want it to be conditional on a cousin input,
1336
+	 * the child of 'baz_section' named 'baz_child', use '../baz_section/baz_child'.
1337
+	 * Etc
1338
+	 *
1339
+	 * @param string|false $form_section_path we accept false also because substr( '../', '../' ) = false
1340
+	 * @return EE_Form_Section_Base
1341
+	 */
1342
+	public function find_section_from_path($form_section_path)
1343
+	{
1344
+		//check if we can find the input from purely going straight up the tree
1345
+		$input = parent::find_section_from_path($form_section_path);
1346
+		if ($input instanceof EE_Form_Section_Base) {
1347
+			return $input;
1348
+		}
1349
+		$next_slash_pos = strpos($form_section_path, '/');
1350
+		if ($next_slash_pos !== false) {
1351
+			$child_section_name = substr($form_section_path, 0, $next_slash_pos);
1352
+			$subpath = substr($form_section_path, $next_slash_pos + 1);
1353
+		} else {
1354
+			$child_section_name = $form_section_path;
1355
+			$subpath = '';
1356
+		}
1357
+		$child_section = $this->get_subsection($child_section_name);
1358
+		if ($child_section instanceof EE_Form_Section_Base) {
1359
+			return $child_section->find_section_from_path($subpath);
1360
+		} else {
1361
+			return null;
1362
+		}
1363
+	}
1364 1364
 
1365 1365
 }
1366 1366
 
Please login to merge, or discard this patch.